This is an automated email from the ASF dual-hosted git repository.

yuqi1129 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new b182a168d0 [MINOR] improvement(ci): report Fork CI and ASF Allowlist 
Check only as commit statuses (#14202)
b182a168d0 is described below

commit b182a168d0f81ac94fb943256321e73e68b278bb
Author: Qi Yu <[email protected]>
AuthorDate: Mon Oct 26 09:56:56 2026 +0800

    [MINOR] improvement(ci): report Fork CI and ASF Allowlist Check only as 
commit statuses (#14202)
    
    ### What changes were proposed in this pull request?
    
    - Report **Fork CI** and **ASF Allowlist Check** only as commit
    statuses. The publishers no longer create check runs, so each check
    appears once on the PR instead of also as `Conflict Marker Check / Fork
    CI (pull_request)` and `Conflict Marker Check / ASF Allowlist Check
    (pull_request)`.
    - The Fork CI status link now names the run attempt it reports,
    `https://github.com/{owner}/{repo}/actions/runs/{id}/attempts/{n}` (plus
    `#fork-run-{id}-{n}` for a trusted result, recording the fork run it was
    chosen over). The publisher uses that link instead of the check run's
    JSON record: it never replaces a newer attempt or a finished result with
    a running one, and sweeps leave a status settled while the runs it
    depends on are unchanged.
    - Retiring a cancelled previous head now reads that head's status: only
    a status still pending on exactly that fork attempt becomes `Fork CI
    cancelled for a previous commit`. A retired status is no longer pending,
    so it needs no marker.
    - Failed and cancelled results add `; re-run it in your fork` when it
    fits the 140-character description. Without a run, the status links to
    the fork's Fork CI page instead of the PR.
    - Passes start on a fixed one-minute cadence. A pass took 30-40 seconds
    of API calls on apache/gravitino, so sleeping a full minute afterwards
    made passes about 1.6 minutes apart.
    - Every `workflow_run` other than a trusted run refreshes only the PRs
    with that run's head, once. A finished Fork CI push run (for example on
    `main` after a merge) used to start an 11-minute polling sweep in the
    signal queue, blocking PR signals; on apache/gravitino one such job ran
    from 11:57 to 12:08 on 2026-10-23.
    - Remove `checks: write` from both publishers and update CONTRIBUTING.
    
    ### Why are the changes needed?
    
    After #14192, every PR shows Fork CI and ASF Allowlist Check twice: once
    as the commit status and once as a check run that GitHub attaches to an
    arbitrary workflow suite (here Conflict Marker Check). The check runs
    only stored metadata for the publisher, and they could disappear from
    the PR's latest-check view anyway.
    
    Fix: N/A
    
    ### Does this PR introduce _any_ user-facing change?
    
    Contributors and reviewers see one **Fork CI** and one **ASF Allowlist
    Check** row. **Details** opens the exact fork run attempt. The Checks
    tab no longer has a Fork CI page with a summary; that page's **Re-run**
    button only refreshed the status.
    
    ### How was this patch tested?
    
    - 90 Node tests in `.github/scripts/tests`, rewritten around statuses:
    links to the exact attempt and no check run, the lifecycle states and
    descriptions, the re-run hint and its length limit, stale-attempt and
    running-over-finished guards, legacy links without an attempt, sweep
    settlement for fork and trusted results (including a fork rerun under a
    trusted result), retirement of previous heads, the fixed cadence, and
    `workflow_run` push events refreshing only their head without sleeping.
    Ten mutations of the new logic were each rejected by a test. actionlint
    reports only the known `concurrency.queue` diagnostic.
    - Sandbox (timelyflow/gravitino with contributor fork
    yuqi1129/gravitino):
    [timelyflow/gravitino#38](https://github.com/timelyflow/gravitino/pull/38)
    lists only `Fork CI` and `ASF Allowlist Check` as statuses; its check
    runs are only `conflict-marker-check` and `signal`. The status linked
    `…/runs/39950637328/attempts/1`, showed `Failed: build / changes (+1
    more); re-run it in your fork` for a failing run, and turned to `All
    required suites passed` 32 seconds after the run finished.
    
    ---------
    
    Co-authored-by: yuqi <[email protected]>
---
 .github/scripts/allowlist-pr.cjs              |   6 +-
 .github/scripts/publish-ci-status.cjs         |  49 ++-
 .github/scripts/retire-fork-ci.cjs            |  36 +-
 .github/scripts/tests/fork-ci.test.cjs        | 478 ++++++++++++--------------
 .github/scripts/tests/retire-fork-ci.test.cjs |  70 ++--
 .github/scripts/update-fork-ci.cjs            | 148 +++-----
 .github/workflows/asf-allowlist-trusted.yml   |   3 +-
 .github/workflows/fork-ci-status-update.yml   |   6 +-
 CONTRIBUTING.md                               |  12 +-
 9 files changed, 375 insertions(+), 433 deletions(-)

diff --git a/.github/scripts/allowlist-pr.cjs b/.github/scripts/allowlist-pr.cjs
index 7b0f994851..fcc9fb7c7c 100644
--- a/.github/scripts/allowlist-pr.cjs
+++ b/.github/scripts/allowlist-pr.cjs
@@ -84,11 +84,7 @@ async function publish({ github, context, core }) {
     if (current.state !== 'open' || current.head.sha !== pr.sha) continue;
     const success = process.env.SCAN_OUTCOME === 'success';
     const details = 
`${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
-    await github.rest.checks.create({ ...context.repo, name: 'ASF Allowlist 
Check', head_sha: pr.sha,
-      status: 'completed', conclusion: success ? 'success' : 'failure',
-      details_url: details,
-      output: { title: success ? 'Workflow actions are allowlisted' : 
'Workflow allowlist scan failed',
-        summary: 'Scanned PR YAML as data with the reviewed default-branch 
workflow. No PR code was executed.' } });
+    // Scanned PR YAML as data with the reviewed default-branch workflow; no 
PR code was executed.
     await publishStatus({ github, repo: context.repo, sha: pr.sha, context: 
'ASF Allowlist Check',
       state: success ? 'success' : 'failure',
       description: success ? 'Workflow actions are allowlisted' : 'Workflow 
allowlist scan failed', targetUrl: details });
diff --git a/.github/scripts/publish-ci-status.cjs 
b/.github/scripts/publish-ci-status.cjs
index b9af636517..b4458b8911 100644
--- a/.github/scripts/publish-ci-status.cjs
+++ b/.github/scripts/publish-ci-status.cjs
@@ -13,14 +13,41 @@
  * limitations under the License.
  */
 'use strict';
+const UPSTREAM = { owner: 'apache', repo: 'gravitino' };
 
-// Custom checks created with GITHUB_TOKEN can be attached to an older Actions 
suite and
-// disappear from the PR's latest-check view. Publish a commit status as the 
visible signal;
-// retain the check run separately for the immutable run/attempt metadata used 
by the updater.
-async function publishStatus({ github, repo, sha, context, state, description, 
targetUrl }) {
-  const params = { ...repo, sha, context, state, description: 
description.slice(0, 140), target_url: targetUrl };
+// Commit statuses are the only signal on the PR: check runs created with 
GITHUB_TOKEN are
+// attached to an arbitrary Actions suite, show up as duplicates such as
+// "Conflict Marker Check / Fork CI", and can disappear from the PR's 
latest-check view.
+// The status link therefore also records which run and attempt the status 
mirrors:
+// https://github.com/{owner}/{repo}/actions/runs/{id}/attempts/{attempt}, plus
+// #fork-run-{id}-{attempt} for a trusted result, naming the fork run seen at 
that time.
+const RUN_URL = 
/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/actions\/runs\/(\d+)(?:\/attempts\/(\d+))?(?:#fork-run-(\d+)-(\d+))?$/;
+
+function runUrl(owner, repo, run, fork) {
+  return 
`https://github.com/${owner}/${repo}/actions/runs/${run.id}/attempts/${run.run_attempt
 || 1}` +
+    (fork ? `#fork-run-${fork.id}-${fork.run_attempt || 1}` : '');
+}
+
+// Returns the run a status links to, or undefined for a status without a run. 
Links written
+// before attempts were recorded have no run_attempt.
+function parseRunUrl(url) {
+  const match = RUN_URL.exec(url || '');
+  if (!match) return undefined;
+  const [, owner, repo, id, attempt, forkId, forkAttempt] = match;
+  return { owner, repo, run_id: Number(id), run_attempt: attempt && 
Number(attempt),
+    trusted: owner === UPSTREAM.owner && repo === UPSTREAM.repo,
+    fork_run_id: forkId && Number(forkId), fork_run_attempt: forkAttempt && 
Number(forkAttempt) };
+}
+
+async function latestStatus({ github, repo, sha, context }) {
   const { data } = await github.rest.repos.getCombinedStatusForRef({ ...repo, 
ref: sha, per_page: 100 });
-  const previous = data.statuses.find(status => status.context === context);
+  return data.statuses.find(status => status.context === context);
+}
+
+// Pass the latest status as previous when it was just read; undefined reads 
it here.
+async function publishStatus({ github, repo, sha, context, state, description, 
targetUrl, previous }) {
+  const params = { ...repo, sha, context, state, description: 
description.slice(0, 140), target_url: targetUrl };
+  if (previous === undefined) previous = await latestStatus({ github, repo, 
sha, context });
   if (previous?.state === state && previous.description === params.description 
&& previous.target_url === targetUrl) return;
   await github.rest.repos.createCommitStatus(params);
 }
@@ -28,12 +55,16 @@ async function publishStatus({ github, repo, sha, context, 
state, description, t
 // Waiting for a committer is not a failure of the contributor's change.
 const TRUSTED_REQUIRED = 'Fork CI passed; trusted verification required';
 
-// Accepts a computed result ({ status, conclusion, title }) or a check run 
(title in output).
 function statusState(result) {
   if (result.status !== 'completed') return 'pending';
-  if ((result.title ?? result.output?.title) === TRUSTED_REQUIRED) return 
'pending';
+  if (result.title === TRUSTED_REQUIRED) return 'pending';
   if (result.conclusion === 'success') return 'success';
   return result.conclusion === 'failure' || result.conclusion === 'timed_out' 
? 'failure' : 'error';
 }
 
-module.exports = { TRUSTED_REQUIRED, publishStatus, statusState };
+// Whether a published status reports a finished execution, including pending 
trusted verification.
+function statusCompleted(status) {
+  return status.state !== 'pending' || status.description === TRUSTED_REQUIRED;
+}
+
+module.exports = { TRUSTED_REQUIRED, latestStatus, parseRunUrl, publishStatus, 
runUrl, statusCompleted, statusState };
diff --git a/.github/scripts/retire-fork-ci.cjs 
b/.github/scripts/retire-fork-ci.cjs
index 7749498a69..fd64db8106 100644
--- a/.github/scripts/retire-fork-ci.cjs
+++ b/.github/scripts/retire-fork-ci.cjs
@@ -13,9 +13,10 @@
  * limitations under the License.
  */
 'use strict';
-const { publishStatus } = require('./publish-ci-status.cjs');
+const { latestStatus, parseRunUrl, publishStatus, runUrl, statusCompleted } = 
require('./publish-ci-status.cjs');
 const { FORK_EVENTS } = require('./fork-ci-status.cjs');
 
+// A push cancels the fork run of the previous head, whose status would 
otherwise stay pending.
 async function retireCancelled({ github, repo, pr }) {
   if (!pr.head.repo || !pr.head.ref) return;
   const fork = { owner: pr.head.repo.owner.login, repo: pr.head.repo.name };
@@ -33,36 +34,21 @@ async function retireCancelled({ github, repo, pr }) {
     if (run.head_sha === pr.head.sha || run.head_branch !== pr.head.ref ||
         run.path !== '.github/workflows/fork-ci.yml' || 
!FORK_EVENTS.includes(run.event) ||
         run.status !== 'completed' || run.conclusion !== 'cancelled') continue;
-    const checks = await github.paginate(github.rest.checks.listForRef, {
-      ...repo, ref: run.head_sha, check_name: 'Fork CI', filter: 'all', 
per_page: 100 });
-    const latest = checks.filter(check => check.app?.slug === 
'github-actions').sort((a, b) => b.id - a.id)[0];
-    let record;
-    try { record = JSON.parse(latest?.output?.text || '{}'); } catch { 
continue; }
-    // Never replace a trusted result, a newer attempt, or another run's 
metadata.
-    if (!latest || record.owner !== fork.owner || record.repo !== fork.repo || 
record.trusted ||
-        record.run_id !== run.id || record.run_attempt !== run.run_attempt ||
-        (latest.status === 'completed' && !record.superseded_by)) continue;
-    // A retired attempt is immutable. Remember a successful status write on 
the trusted
-    // check so later sweeps do not keep fetching its attempt, PR and status 
forever.
-    if (latest.status === 'completed' && latest.conclusion === 'cancelled' && 
record.retired_status_published) continue;
+    const latest = await latestStatus({ github, repo, sha: run.head_sha, 
context: 'Fork CI' });
+    const shown = parseRunUrl(latest?.target_url);
+    // Only finish a status still waiting on exactly this fork attempt. A 
retired status is no
+    // longer pending, so later sweeps skip it with this one read. Never 
replace a trusted
+    // result, a verdict, or a newer attempt; links without an attempt predate 
attempt records.
+    if (!latest || statusCompleted(latest) || !shown || shown.owner !== 
fork.owner || shown.repo !== fork.repo ||
+        shown.run_id !== run.id || (shown.run_attempt && shown.run_attempt !== 
run.run_attempt)) continue;
     const { data: actual } = await github.rest.actions.getWorkflowRunAttempt({ 
...fork,
       run_id: run.id, attempt_number: run.run_attempt });
     if (actual.head_sha !== run.head_sha || actual.status !== 'completed' || 
actual.conclusion !== 'cancelled') continue;
     const { data: current } = await github.rest.pulls.get({ ...repo, 
pull_number: pr.number });
     if (current.state !== 'open' || current.head.sha !== pr.head.sha ||
         current.head.repo?.full_name !== pr.head.repo.full_name) return;
-    const title = 'Fork CI cancelled for a previous commit';
-    const details = 
`https://github.com/${fork.owner}/${fork.repo}/actions/runs/${run.id}`;
-    const output = { title, summary: `[See fork CI results](${details})\n\n` +
-      `This cancelled run tested a previous PR commit. Current head: 
${pr.head.sha}.`,
-      text: JSON.stringify({ ...record, run_status: 'completed', 
run_conclusion: 'cancelled', superseded_by: pr.head.sha }) };
-    if (latest.status !== 'completed') await github.rest.checks.update({ 
...repo,
-      check_run_id: latest.id, status: 'completed', conclusion: 'cancelled', 
output });
-    // Retry this independently if a previous write completed the check but 
lost its status.
-    await publishStatus({ github, repo, sha: run.head_sha, context: 'Fork CI',
-      state: 'error', description: title, targetUrl: details });
-    await github.rest.checks.update({ ...repo, check_run_id: latest.id,
-      output: { ...output, text: JSON.stringify({ ...JSON.parse(output.text), 
retired_status_published: true }) } });
+    await publishStatus({ github, repo, sha: run.head_sha, context: 'Fork CI', 
state: 'error',
+      description: 'Fork CI cancelled for a previous commit', targetUrl: 
runUrl(fork.owner, fork.repo, run), previous: latest });
   }
 }
 module.exports = { retireCancelled };
diff --git a/.github/scripts/tests/fork-ci.test.cjs 
b/.github/scripts/tests/fork-ci.test.cjs
index e42a4c6688..65c2bbadc0 100644
--- a/.github/scripts/tests/fork-ci.test.cjs
+++ b/.github/scripts/tests/fork-ci.test.cjs
@@ -266,38 +266,34 @@ test('immutable CI definition comparisons are cached by 
repository, head and bas
 });
 
 const { update } = require('../update-fork-ci.cjs');
+// The status link records the fork run and attempt it mirrors.
+const url = (id = 1, attempt = 1, owner = 'fork', repo = 'repo') =>
+  `https://github.com/${owner}/${repo}/actions/runs/${id}/attempts/${attempt}`;
+const forkStatus = (state, description, target_url = url()) => ({ context: 
'Fork CI', state, description, target_url });
 function publisherMock({ current = pr(), latest, rerun = run(), failTrees = 
false } = {}) {
   const github = serviceMock();
-  const writes = [];
   const counters = { runs: 0 };
+  // Every status written, and the statuses GitHub returns per commit (newest 
first per context).
   const statuses = [];
-  let combinedStatuses = [];
-  const listForRef = () => {};
+  const stored = new Map([[A, latest ? [{ ...latest }] : []]]);
   const listPulls = () => {};
   let reads = 0;
   github.rest.pulls = { list: listPulls, get: async () => ({ data: ++reads === 
1 ? pr() : current }) };
   github.rest.repos = { getContent: async () => ({ data: {} }),
-    getCombinedStatusForRef: async () => ({ data: { statuses: combinedStatuses 
} }),
-    createCommitStatus: async args => { statuses.push(args); combinedStatuses 
= [{ ...args }, ...combinedStatuses.filter(s => s.context !== args.context)]; } 
};
+    getCombinedStatusForRef: async ({ ref }) => ({ data: { statuses: 
stored.get(ref) || [] } }),
+    createCommitStatus: async args => { statuses.push(args);
+      stored.set(args.sha, [{ ...args }, ...(stored.get(args.sha) || 
[]).filter(s => s.context !== args.context)]); } };
   github.rest.rateLimit = { get: async () => ({ data: { resources: { core: { 
remaining: 900, limit: 1000 } } } }) };
-  // Writes are visible to later reads, as on GitHub: the status is derived 
from the check as stored.
-  let stored = latest ? [{ ...latest }] : [];
-  github.rest.checks = { listForRef,
-    create: async args => { writes.push({ create: args });
-      stored = [...stored, { id: 1000 + writes.length, app: { slug: 
'github-actions' }, ...args }]; },
-    update: async args => { writes.push({ update: args });
-      const check = stored.find(c => c.id === args.check_run_id);
-      if (check) Object.assign(check, args, args.status !== 'completed' ? { 
conclusion: null } : {}); } };
   github.rest.actions.listWorkflowRuns = async args => {
     counters.runs++;
     return { data: { workflow_runs: args.event !== 'workflow_dispatch' ? 
[rerun] : [] } };
   };
   if (failTrees) github.rest.git.getTree = async () => { throw new Error('API 
unavailable'); };
-  github.paginate = async (endpoint, args) => runsOf(github, endpoint, args) 
?? (endpoint === listPulls ? [pr()]
-    : endpoint === listForRef ? stored : jobs(pr()));
+  github.paginate = async (endpoint, args) => runsOf(github, endpoint, args) 
?? (endpoint === listPulls ? [pr()] : jobs(pr()));
   github.hook = { before() {} };
-  return { github, writes, counters, statuses };
+  return { github, counters, statuses, stored };
 }
+
 async function withPublisher(fn) {
   const directory = await mkdtemp(path.join(os.tmpdir(), 
'fork-ci-publisher-test-'));
   const stateFile = path.join(directory, 'state.json');
@@ -309,44 +305,56 @@ async function withPublisher(fn) {
   try { await fn({ ctx, stateFile, core, failures, outputs }); }
   finally { await rm(directory, { recursive: true, force: true }); }
 }
-test('publisher binds the check to the exact base and current run attempt', 
async () => withPublisher(async ({ ctx, stateFile, core }) => {
-  const { github, writes } = publisherMock();
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes.length, 1);
-  const check = writes[0].create;
-  assert.equal(check.conclusion, 'success');assert.equal(check.head_sha, A);
-  assert.equal(JSON.parse(check.output.text).base_sha, B);
-  assert.equal(JSON.parse(check.output.text).run_attempt, 1);
+test('publisher links the status to the exact fork run attempt and creates no 
check run', async () => withPublisher(async ({ ctx, core }) => {
+  const { github, statuses } = publisherMock({ rerun: { ...run(), run_attempt: 
3 } });
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.deepEqual(statuses, [{ owner: 'apache', repo: 'gravitino', sha: A, 
context: 'Fork CI', state: 'success',
+    description: 'All required suites passed', target_url: url(1, 3) }]);
+  // A check run would be attached to an arbitrary suite and show up twice on 
the PR.
+  assert.equal(github.rest.checks, undefined);
 }));
-test('a push or retarget during publication cannot publish stale success', 
async () => withPublisher(async ({ ctx, stateFile, core }) => {
+
+test('a push or retarget during publication cannot publish stale success', 
async () => withPublisher(async ({ ctx, core }) => {
   const changed = pr(); changed.base.sha = C;
-  const { github, writes } = publisherMock({ current: changed });
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes.length, 0);
+  const { github, statuses } = publisherMock({ current: changed });
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.equal(statuses.length, 0);
 }));
-test('manual publication refreshes a cached final success and observes a 
failed rerun', async () => withPublisher(async ({ ctx, stateFile, core }) => {
-  const old = { id: 55, app: { slug: 'github-actions' }, status: 'completed', 
conclusion: 'success',
-    output: { text: JSON.stringify({ run_id: 1, run_attempt: 1, base_sha: B, 
base_ref: 'main' }) } };
-  const fs = require('node:fs/promises');
-  await fs.writeFile(stateFile, JSON.stringify({ cursor: 0, prs: { 7: { sha: 
A, base: B, base_ref: 'main',
-    updated_at: pr().updated_at, status: 'completed', checked_at: new 
Date().toISOString(), completed_at: new Date().toISOString() } } }));
-  const { github, writes, counters } = publisherMock({ latest: old, rerun: { 
...run(), run_attempt: 2, conclusion: 'failure' } });
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.ok(counters.runs > 0); assert.equal(writes[0].create.conclusion, 
'failure');
-  assert.equal(JSON.parse(writes[0].create.output.text).run_attempt, 2);
+
+test('manual publication refreshes a final success and observes a failed 
rerun', async () => withPublisher(async ({ ctx, core }) => {
+  const { github, statuses, counters } = publisherMock({ latest: 
forkStatus('success', 'All required suites passed'),
+    rerun: { ...run(), run_attempt: 2, conclusion: 'failure' } });
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.ok(counters.runs > 0);
+  assert.equal(statuses[0].state, 'failure'); 
assert.equal(statuses[0].target_url, url(1, 2));
 }));
+
 test('publisher failures remain observable and are retried instead of cached', 
async () => withPublisher(async ({ ctx, stateFile, core, failures }) => {
-  const { github, writes } = publisherMock({ failTrees: true });
+  const { github, statuses } = publisherMock({ failTrees: true });
   await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes.length, 0); assert.equal(failures.length, 1);
+  assert.equal(statuses.length, 0); assert.equal(failures.length, 1);
   await assert.rejects(readFile(stateFile, 'utf8'), { code: 'ENOENT' });
 }));
-test('PR signals prioritize their head and bypass settled state', async () => 
withPublisher(async ({ ctx, stateFile, core }) => {
+
+test('PR signals prioritize their head and bypass settled state', async () => 
withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'workflow_run';delete ctx.payload.inputs;
   ctx.payload.workflow_run = { name: 'Fork CI PR Signal', head_sha: A, event: 
'pull_request' };
-  const { github, writes } = publisherMock();
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes.length, 1);
+  const { github, statuses } = publisherMock();
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.equal(statuses.length, 1);
+}));
+
+test('a finished Fork CI push run refreshes only its head once, without 
polling the signal queue', async () => withPublisher(async ({ ctx, core, 
outputs }) => {
+  ctx.eventName = 'workflow_run';delete ctx.payload.inputs;
+  for (const [head, expected] of [[A, 1], [C, 0]]) {
+    ctx.payload.workflow_run = { name: 'Fork CI', head_sha: head, event: 
'push', display_title: 'Fork CI main' };
+    const { github, statuses } = publisherMock();
+    github.rest.rateLimit.get = async () => ({ data: { resources: { core: { 
remaining: 15000, limit: 15000 } } } });
+    let sleeps = 0;
+    await update({ github, context: ctx, core, sleep: async () => { sleeps++; 
} });
+    assert.equal(sleeps, 0); assert.equal(statuses.length, expected);
+    assert.equal(outputs.chain, undefined);
+  }
 }));
 
 test('scheduled publication ignores poisoned cache state and recomputes 
definitions', async () => withPublisher(async ({ ctx, stateFile, core }) => {
@@ -355,10 +363,10 @@ test('scheduled publication ignores poisoned cache state 
and recomputes definiti
     sha: A, base: B, base_ref: 'main', repository: 'fork/repo', 
definitions_equal: true,
     updated_at: pr().updated_at, status: 'completed', checked_at: new 
Date().toISOString(), completed_at: new Date().toISOString()
   } } }));
-  const { github, writes } = publisherMock();
+  const { github, statuses } = publisherMock();
   github.rest.git = serviceMock({ changed: true }).rest.git;
   await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes[0].create.conclusion, 'action_required');
+  assert.equal(statuses[0].description, 'Fork CI passed; trusted verification 
required');
   const workflow = await readFile(path.join(__dirname, 
'../../workflows/fork-ci-status-update.yml'), 'utf8');
   assert.ok(!workflow.includes('actions/cache/'));
 }));
@@ -419,27 +427,19 @@ test('a run against a newer commit of the PR base branch 
is accepted', async ()
   }
 });
 
-test('scheduled sweeps probe recently updated PRs first and refresh only 
running or rerun checks', async () => withPublisher(async ({ ctx, stateFile, 
core }) => {
+test('scheduled sweeps probe recently updated PRs first and refresh only 
running or rerun results', async () => withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
-  const { github, writes } = publisherMock();
+  const { github, statuses, stored } = publisherMock();
   const recent = new Date().toISOString();
   const old = Array.from({ length: 20 }, (_, i) => ({ ...pr(), number: 100 + i,
     head: { ...pr().head, sha: (100 + i).toString(16).padStart(40, 'd') } }));
   const settled = { ...pr(), number: 8, updated_at: recent, head: { 
...pr().head, sha: 'e'.repeat(40) } };
-  github.rest.repos.getCombinedStatusForRef = async ({ ref }) => ({ data: { 
statuses:
-    ref === settled.head.sha ? [{ context: 'Fork CI', state: 'error', 
description: 'Fork CI cancelled',
-      target_url: 'https://github.com/fork/repo/actions/runs/1' }] : [] } });
+  // Any completed result, not only success, is final until its fork run id or 
attempt changes.
+  stored.set(settled.head.sha, [forkStatus('error', 'Fork CI cancelled')]);
   const failed = { ...pr(), updated_at: recent };
   const all = [...old, settled, failed];
-  const listPulls = github.rest.pulls.list;
-  const listForRef = github.rest.checks.listForRef;
-  const paginate = github.paginate;
-  // Any completed result, not only success, is final until the fork run id or 
attempt changes.
-  const check = completed => ({ id: 1, app: { slug: 'github-actions' }, 
status: completed ? 'completed' : 'in_progress',
-    conclusion: completed ? 'cancelled' : null, output: { title: 'Fork CI 
cancelled', text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: 1,
-      run_status: completed ? 'completed' : 'in_progress' }) } });
-  github.paginate = async (endpoint, args) => endpoint === listPulls ? all
-    : endpoint === listForRef ? [check(args.ref === settled.head.sha)] : 
paginate(endpoint, args);
+  const listPulls = github.rest.pulls.list, paginate = github.paginate;
+  github.paginate = async (endpoint, args) => endpoint === listPulls ? all : 
paginate(endpoint, args);
   github.rest.pulls.get = async ({ pull_number }) => ({ data: all.find(p => 
p.number === pull_number) });
   const runsFor = [];
   const list = github.rest.actions.listWorkflowRuns;
@@ -449,19 +449,20 @@ test('scheduled sweeps probe recently updated PRs first 
and refresh only running
     response.data.workflow_runs = response.data.workflow_runs.map(run => ({ 
...run, head_sha: args.head_sha }));
     return response;
   };
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  // Probe both the fork and trusted runs; neither changed, so no full refresh 
is needed.
-  const written = writes.map(write => write.create || write.update);
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  // The settled PR is probed once (fork and trusted runs unchanged) and never 
rewritten.
   assert.equal(runsFor.filter(sha => sha === settled.head.sha).length, 1);
-  assert.equal(written[0].conclusion, 'success');
-  assert.match(written[0].output.summary, /^\[See fork CI 
results\]\(https:\/\/github\.com\/fork\/repo\/actions\/runs\/1\)/);
+  assert.equal(statuses.filter(s => s.sha === settled.head.sha).length, 0);
+  const current = statuses.find(s => s.sha === A);
+  assert.equal(current.state, 'success'); assert.equal(current.target_url, 
url());
 }));
 
-test('a failed fork run is not summarized as verified', async () => 
withPublisher(async ({ ctx, stateFile, core }) => {
-  const { github, writes } = publisherMock({ rerun: { ...run(), conclusion: 
'failure' } });
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes[0].create.conclusion, 'failure');
-  assert.doesNotMatch(writes[0].create.output.summary, /Verified/);
+test('a failed fork run reports failure and points the author to re-run it in 
the fork', async () => withPublisher(async ({ ctx, core }) => {
+  const { github, statuses } = publisherMock({ rerun: { ...run(), conclusion: 
'failure' } });
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.equal(statuses[0].state, 'failure');
+  assert.equal(statuses[0].description, 'Fork CI failure; re-run it in your 
fork');
+  assert.equal(statuses[0].target_url, url());
 }));
 
 test('signals queue in order while scheduled sweeps poll in their own group', 
async () => {
@@ -474,30 +475,27 @@ test('signals queue in order while scheduled sweeps poll 
in their own group', as
   assert.doesNotMatch(workflow.slice(workflow.indexOf('\n  sweep:')), 
/queue:/);
 });
 
-test('scheduled sweeps refresh a settled check when its fork run is rerun', 
async () => withPublisher(async ({ ctx, stateFile, core }) => {
+test('scheduled sweeps refresh a settled status when its fork run is rerun', 
async () => withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
-  const green = { id: 55, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'success',
-    output: { text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: 1, fork_run_id: 1, fork_run_attempt: 1 }) } };
   const recent = { ...pr(), updated_at: new Date().toISOString() };
-  const { github, writes } = publisherMock({ latest: green, rerun: { ...run(), 
run_attempt: 2, conclusion: 'failure' } });
+  const { github, statuses } = publisherMock({ latest: forkStatus('success', 
'All required suites passed'),
+    rerun: { ...run(), run_attempt: 2, conclusion: 'failure' } });
   const listPulls = github.rest.pulls.list, paginate = github.paginate;
   github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
   github.rest.pulls.get = async () => ({ data: recent });
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes.length, 1);
-  assert.equal(writes[0].create.conclusion, 'failure');
-  assert.equal(JSON.parse(writes[0].create.output.text).fork_run_attempt, 2);
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.equal(statuses.length, 1);
+  assert.equal(statuses[0].state, 'failure'); 
assert.equal(statuses[0].target_url, url(1, 2));
 }));
 
-test('a publisher that observed an older attempt does not overwrite a newer 
result', async () => withPublisher(async ({ ctx, stateFile, core }) => {
+test('a publisher that observed an older attempt does not overwrite a newer 
result', async () => withPublisher(async ({ ctx, core }) => {
   for (const [latest, observed] of [
-    [{ status: 'completed', conclusion: 'failure', attempt: 2 }, { conclusion: 
'success', run_attempt: 1 }],
-    [{ status: 'completed', conclusion: 'success', attempt: 1 }, { status: 
'in_progress', conclusion: null, run_attempt: 1 }]]) {
-    const check = { id: 55, app: { slug: 'github-actions' }, status: 
latest.status, conclusion: latest.conclusion,
-      output: { text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: latest.attempt }) } };
-    const { github, writes } = publisherMock({ latest: check, rerun: { 
...run(), ...observed } });
-    await update({ github, context: ctx, core, stateFile, sleep: async () => 
{} });
-    assert.equal(writes.length, 0);
+    [forkStatus('failure', 'Failed: build / build', url(1, 2)), { conclusion: 
'success', run_attempt: 1 }],
+    [forkStatus('success', 'All required suites passed', url(1, 1)), { status: 
'in_progress', conclusion: null, run_attempt: 1 }],
+    [forkStatus('success', 'All required suites passed', url(5, 1)), { id: 1, 
conclusion: 'failure' }]]) {
+    const { github, statuses } = publisherMock({ latest, rerun: { ...run(), 
...observed } });
+    await update({ github, context: ctx, core, sleep: async () => {} });
+    assert.equal(statuses.length, 0);
   }
 }));
 
@@ -582,28 +580,36 @@ test('every one-minute pass probes all recently updated 
PRs at the apache quota'
   // apache/gravitino has had 13-17 PRs updated within six hours; leave 
headroom.
   const recent = Array.from({ length: 17 }, (_, i) => ({ ...pr(), number: 300 
+ i, updated_at: new Date().toISOString(),
     head: { ...pr().head, sha: (300 + i).toString(16).padStart(40, 'e') } }));
-  const listPulls = github.rest.pulls.list, listForRef = 
github.rest.checks.listForRef, paginate = github.paginate;
+  const listPulls = github.rest.pulls.list, paginate = github.paginate;
   let count = () => {};
   github.hook = { before(_, hook) { count = hook; } };
   github.rest.rateLimit.get = async () => ({ data: { resources: { core: { 
remaining: 15000, limit: 15000 } } } });
-  const record = { owner: 'fork', repo: 'repo', run_id: 1, run_attempt: 1, 
run_status: 'completed', fork_run_id: 1, fork_run_attempt: 1 };
-  const settled = { id: 1, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'success',
-    output: { title: 'All required suites passed', text: 
JSON.stringify(record) } };
-  github.rest.repos.getCombinedStatusForRef = async () => { count(); return { 
data: { statuses: [{ context: 'Fork CI', state: 'success',
-    description: 'All required suites passed', target_url: 
'https://github.com/fork/repo/actions/runs/1' }] } }; };
   const perPass = [new Set()];
-  github.paginate = async (endpoint, args) => {
-    count();
-    if (endpoint === listPulls) return recent;
-    if (endpoint === listForRef) { perPass.at(-1).add(args.ref); return 
[settled]; }
-    return paginate(endpoint, args);
-  };
+  github.rest.repos.getCombinedStatusForRef = async ({ ref }) => { count(); 
perPass.at(-1).add(ref);
+    return { data: { statuses: [forkStatus('success', 'All required suites 
passed')] } }; };
+  github.paginate = async (endpoint, args) => { count(); return endpoint === 
listPulls ? recent : paginate(endpoint, args); };
   let t = Date.now();
   await update({ github, context: ctx, core, clock: () => t, sleep: async ms 
=> { t += ms; perPass.push(new Set()); } });
   assert.equal(perPass.length, 11);
   for (const seen of perPass) assert.equal(seen.size, recent.length);
 }));
 
+test('passes start on a fixed one-minute cadence, however long a pass takes', 
async () => withPublisher(async ({ ctx, core }) => {
+  ctx.eventName = 'schedule'; delete ctx.payload.inputs;
+  const { github } = publisherMock();
+  github.rest.rateLimit.get = async () => ({ data: { resources: { core: { 
remaining: 15000, limit: 15000 } } } });
+  let t = 0;
+  const starts = [];
+  const listPulls = github.rest.pulls.list, paginate = github.paginate;
+  // Each pass spends 35 seconds on API calls, as on apache/gravitino.
+  github.paginate = async (endpoint, args) => {
+    if (endpoint === listPulls) { starts.push(t); t += 35000; }
+    return paginate(endpoint, args);
+  };
+  await update({ github, context: ctx, core, clock: () => t, sleep: async ms 
=> { assert.ok(ms >= 0); t += ms; } });
+  assert.deepEqual(starts, Array.from({ length: 11 }, (_, i) => i * 60000));
+}));
+
 test('each polling sweep dispatches the next; only that job can write Actions 
state', async () => {
   const workflow = await readFile(path.join(__dirname, 
'../../workflows/fork-ci-status-update.yml'), 'utf8');
   assert.match(workflow, /^      sweep:\n\s+description: .*\n\s+required: 
false\n\s+type: boolean\n/m);
@@ -706,16 +712,16 @@ test('closed-PR checks never cancel upstream runs and 
tolerate API errors', asyn
   assert.equal(flaky.calls.cancel, 0); assert.match(warnings[0], /upstream 
pull request: Server Error/);
 });
 
-test('fork results tell the author how to run CI again without a new commit', 
async () => withPublisher(async ({ ctx, core }) => {
-  const { github, writes } = publisherMock({ rerun: { ...run(), conclusion: 
'failure' } });
-  const p = { ...pr(), head: { ...pr().head, ref: 'topic' } };
-  github.rest.pulls.get = async () => ({ data: p });
-  github.paginate = (paginate => async (endpoint, args) => endpoint === 
github.rest.pulls.list ? [p] : paginate(endpoint, args))(github.paginate);
-  await update({ github, context: ctx, core, sleep: async () => {} });
-  const summary = writes[0].create.output.summary;
-  assert.match(summary, /open \[the 
run\]\(https:\/\/github\.com\/fork\/repo\/actions\/runs\/1\) and choose 
\*\*Re-run jobs\*\*/);
-  assert.match(summary, /\[Run 
workflow\]\(https:\/\/github\.com\/fork\/repo\/actions\/workflows\/fork-ci\.yml\)
 on branch `topic`/);
-  assert.match(summary, /Re-run button on this check only refreshes this 
status/);
+test('failed and cancelled fork results suggest re-running in the fork when it 
fits', async () => withPublisher(async ({ ctx, core }) => {
+  for (const [rerun, forkJobs, expected] of [
+    [{ ...run(), conclusion: 'cancelled' }, jobs(pr()), 'Fork CI cancelled; 
re-run it in your fork'],
+    [{ ...run(), conclusion: 'failure' }, [...jobs(pr()), { name: 
'x'.repeat(130), conclusion: 'failure' }], `Failed: 
${'x'.repeat(130)}`.slice(0, 140)],
+    [run(), jobs(pr()), 'All required suites passed']]) {
+    const { github, statuses } = publisherMock({ rerun });
+    github.paginate = (paginate => async (endpoint, args) => args?.run_id ? 
forkJobs : paginate(endpoint, args))(github.paginate);
+    await update({ github, context: ctx, core, sleep: async () => {} });
+    assert.equal(statuses[0].description, expected);
+  }
 }));
 
 test('transient API errors never fail the watcher or the run', async () => {
@@ -782,10 +788,10 @@ test('a fork without the Fork CI workflow asks the author 
to update the branch',
   await assert.rejects(createService(github).mirror(pr()), /Server Error/);
 });
 
-test('sweeps publish the missing-workflow check once and then leave it 
settled', async () => withPublisher(async ({ ctx, core, failures }) => {
+test('sweeps publish the missing-workflow status once and then leave it 
settled', async () => withPublisher(async ({ ctx, core, failures }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
   const recent = { ...pr(), head: { ...pr().head, ref: 'topic' }, updated_at: 
new Date().toISOString() };
-  const { github, writes, statuses } = publisherMock();
+  const { github, statuses } = publisherMock();
   github.rest.actions.listWorkflowRuns = async ({ event }) => {
     if (event !== 'workflow_dispatch') throw notFound();
     return { data: { workflow_runs: [] } };
@@ -796,9 +802,10 @@ test('sweeps publish the missing-workflow check once and 
then leave it settled',
   github.rest.rateLimit.get = async () => ({ data: { resources: { core: { 
remaining: 15000, limit: 15000 } } } });
   await update({ github, context: ctx, core, sleep: async () => {} });
   assert.deepEqual(failures, []);
-  assert.equal(writes.length, 1); assert.equal(writes[0].create.conclusion, 
'action_required');
   assert.equal(statuses.length, 1); assert.equal(statuses[0].state, 'error');
-  assert.equal(statuses[0].target_url, recent.html_url);
+  assert.match(statuses[0].description, /never run in your fork/);
+  // There is no run to open; link to the fork's Fork CI page, where Actions 
can be enabled.
+  assert.equal(statuses[0].target_url, 
'https://github.com/fork/repo/actions/workflows/fork-ci.yml');
 }));
 
 test('scheduled sweeps scale their budget with the hourly quota', async () => 
withPublisher(async ({ ctx, stateFile, core }) => {
@@ -807,20 +814,15 @@ test('scheduled sweeps scale their budget with the hourly 
quota', async () => wi
     const { github } = publisherMock();
     const recent = Array.from({ length: 60 }, (_, i) => ({ ...pr(), number: 
200 + i, updated_at: new Date().toISOString(),
       head: { ...pr().head, sha: (200 + i).toString(16).padStart(40, 'f') } 
}));
-    const listPulls = github.rest.pulls.list, listForRef = 
github.rest.checks.listForRef, paginate = github.paginate;
-    // Count paginated requests, which is what each probe makes.
+    const listPulls = github.rest.pulls.list, paginate = github.paginate;
+    // Count requests, which is what each probe makes.
     let count = () => {};
     github.hook = { before(_, hook) { count = hook; } };
     github.rest.rateLimit.get = async () => ({ data: { resources: { core: { 
remaining: limit, limit } } } });
     const seen = new Set();
-    github.rest.repos.getCombinedStatusForRef = async () => ({ data: { 
statuses: [{ context: 'Fork CI', state: 'success' }] } });
-    github.paginate = async (endpoint, args) => {
-      count();
-      if (endpoint === listPulls) return recent;
-      if (endpoint === listForRef) { seen.add(args.ref); return [{ id: 1, app: 
{ slug: 'github-actions' }, status: 'completed',
-        conclusion: 'success', output: { text: JSON.stringify({ run_id: 1, 
run_attempt: 1 }) } }]; }
-      return paginate(endpoint, args);
-    };
+    github.rest.repos.getCombinedStatusForRef = async ({ ref }) => { count(); 
seen.add(ref);
+      return { data: { statuses: [forkStatus('success', 'All required suites 
passed')] } }; };
+    github.paginate = async (endpoint, args) => { count(); return endpoint === 
listPulls ? recent : paginate(endpoint, args); };
     // Each pass spends its share of the sweep budget, then the sweep sleeps 
until the next pass.
     let t = Date.now(), passes = 0;
     await update({ github, context: ctx, core, stateFile, clock: () => t, 
sleep: async ms => { t += ms; passes++; } });
@@ -840,25 +842,19 @@ test('a missing fork run waits instead of asking the 
author to act', async () =>
   assert.match(result.note, /enable Actions in your fork/);
 });
 
-test('an incomplete run listing does not replace a recorded run', async () => 
withPublisher(async ({ ctx, stateFile, core }) => {
-  const green = { id: 55, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'success',
-    output: { text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: 1 }) } };
-  const { github, writes } = publisherMock({ latest: green });
+test('an incomplete run listing does not replace a status that links a run', 
async () => withPublisher(async ({ ctx, core }) => {
+  const { github, statuses } = publisherMock({ latest: forkStatus('success', 
'All required suites passed') });
   github.rest.actions.listWorkflowRuns = async () => ({ data: { workflow_runs: 
[] } });
-  await update({ github, context: ctx, core, stateFile, sleep: async () => {} 
});
-  assert.equal(writes.length, 0);
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.equal(statuses.length, 0);
 }));
 
-test('successive short scheduled sweeps mirror a fork run from running to 
success', async () => withPublisher(async ({ ctx, stateFile, core }) => {
+test('successive scheduled sweeps mirror a fork run from running to success', 
async () => withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
   const recent = { ...pr(), updated_at: new Date().toISOString() };
-  const { github, writes } = publisherMock({ rerun: { ...run(), status: 
'in_progress', conclusion: null } });
+  const { github, statuses } = publisherMock({ rerun: { ...run(), status: 
'in_progress', conclusion: null } });
   const listPulls = github.rest.pulls.list, paginate = github.paginate, list = 
github.rest.actions.listWorkflowRuns;
-  let latest = null;
-  github.paginate = async (endpoint, args) => endpoint === listPulls ? [recent]
-    : endpoint === github.rest.checks.listForRef ? (latest ? [latest] : []) : 
paginate(endpoint, args);
-  github.rest.checks.create = async args => { writes.push({ create: args }); 
latest = { id: writes.length, app: { slug: 'github-actions' }, ...args }; };
-  github.rest.checks.update = async args => { writes.push({ update: args }); 
Object.assign(latest, args); };
+  github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
   github.rest.pulls.get = async () => ({ data: recent });
   github.rest.rateLimit.get = async () => ({ data: { resources: { core: { 
remaining: 15000, limit: 15000 } } } });
   let t = Date.now(), finished = false;
@@ -867,11 +863,10 @@ test('successive short scheduled sweeps mirror a fork run 
from running to succes
     if (finished) response.data.workflow_runs = 
response.data.workflow_runs.map(r => ({ ...r, status: 'completed', conclusion: 
'success' }));
     return response;
   };
-  await update({ github, context: ctx, core, stateFile, clock: () => t, sleep: 
async ms => { t += ms; } });
+  await update({ github, context: ctx, core, clock: () => t, sleep: async ms 
=> { t += ms; } });
   finished = true; t += 300000;
-  await update({ github, context: ctx, core, stateFile, clock: () => t, sleep: 
async ms => { t += ms; } });
-  assert.equal((writes[0].create || writes[0].update).status, 'in_progress');
-  assert.equal((writes.at(-1).create || writes.at(-1).update).conclusion, 
'success');
+  await update({ github, context: ctx, core, clock: () => t, sleep: async ms 
=> { t += ms; } });
+  assert.deepEqual(statuses.map(s => s.state), ['pending', 'success']);
 }));
 
 test('queued workflow summaries use the actual job state for the PR 
description', () => {
@@ -885,28 +880,26 @@ test('queued workflow summaries use the actual job state 
for the PR description'
 });
 
 test('fork results publish a visible commit status for every lifecycle state', 
async () => withPublisher(async ({ ctx, core }) => {
-  for (const [status, conclusion, expected] of [
-    ['queued', null, 'pending'], ['in_progress', null, 'pending'],
-    ['completed', 'success', 'success'], ['completed', 'failure', 'failure'],
-    ['completed', 'timed_out', 'failure'], ['completed', 'cancelled', 
'error']]) {
+  for (const [status, conclusion, expected, description] of [
+    ['queued', null, 'pending', 'Fork CI is queued, waiting for a runner'], 
['in_progress', null, 'pending', 'Fork CI is running'],
+    ['completed', 'success', 'success', 'All required suites passed'],
+    ['completed', 'failure', 'failure', 'Fork CI failure; re-run it in your 
fork'],
+    ['completed', 'timed_out', 'failure', 'Fork CI timed_out; re-run it in 
your fork'],
+    ['completed', 'cancelled', 'error', 'Fork CI cancelled; re-run it in your 
fork']]) {
     const { github, statuses } = publisherMock({ rerun: { ...run(), status, 
conclusion } });
     await update({ github, context: ctx, core, sleep: async () => {} });
-    assert.equal(statuses.length, 1);
-    assert.deepEqual(statuses[0], { owner: 'apache', repo: 'gravitino', sha: A,
-      context: 'Fork CI', state: expected, description: status === 'queued'
-        ? 'Fork CI is queued, waiting for a runner' : status === 'in_progress' 
? 'Fork CI is running'
-          : conclusion === 'success' ? 'All required suites passed' : `Fork CI 
${conclusion}`,
-      target_url: 'https://github.com/fork/repo/actions/runs/1' });
+    assert.deepEqual(statuses, [{ owner: 'apache', repo: 'gravitino', sha: A,
+      context: 'Fork CI', state: expected, description, target_url: url() }]);
   }
 }));
 
-test('missing fork runs stay pending and link to the PR instead of a 
nonexistent run', async () => withPublisher(async ({ ctx, core }) => {
+test('missing fork runs stay pending and link to the fork Fork CI page instead 
of a nonexistent run', async () => withPublisher(async ({ ctx, core }) => {
   const { github, statuses } = publisherMock();
   github.rest.actions.listWorkflowRuns = async () => ({ data: { workflow_runs: 
[] } });
   await update({ github, context: ctx, core, sleep: async () => {} });
   assert.equal(statuses[0].state, 'pending');
   assert.equal(statuses[0].description, 'Waiting for Fork CI; enable Actions 
in your fork if no run starts');
-  assert.equal(statuses[0].target_url, pr().html_url);
+  assert.equal(statuses[0].target_url, 
'https://github.com/fork/repo/actions/workflows/fork-ci.yml');
 }));
 
 test('changed CI definitions stay pending, not red, until trusted CI verifies 
them', async () => withPublisher(async ({ ctx, core }) => {
@@ -919,70 +912,55 @@ test('changed CI definitions stay pending, not red, until 
trusted CI verifies th
 }));
 
 test('CI edits mirror execution progress and failures without self-approving 
success', async () => withPublisher(async ({ ctx, core }) => {
-  for (const [status, conclusion, expectedStatus, expectedConclusion, state] 
of [
-    ['queued', null, 'queued', undefined, 'pending'],
-    ['in_progress', null, 'in_progress', undefined, 'pending'],
-    ['completed', 'failure', 'completed', 'failure', 'failure'],
-    ['completed', 'cancelled', 'completed', 'cancelled', 'error'],
-    ['completed', 'success', 'completed', 'action_required', 'pending']]) {
-    const { github, writes, statuses } = publisherMock({ rerun: { ...run(), 
status, conclusion } });
+  for (const [status, conclusion, state, description] of [
+    ['queued', null, 'pending', 'Fork CI is queued, waiting for a runner'],
+    ['in_progress', null, 'pending', 'Fork CI is running'],
+    ['completed', 'failure', 'failure', 'Fork CI failure; re-run it in your 
fork'],
+    ['completed', 'cancelled', 'error', 'Fork CI cancelled; re-run it in your 
fork'],
+    ['completed', 'success', 'pending', 'Fork CI passed; trusted verification 
required']]) {
+    const { github, statuses } = publisherMock({ rerun: { ...run(), status, 
conclusion } });
     github.rest.git = serviceMock({ changed: true }).rest.git;
     await update({ github, context: ctx, core, sleep: async () => {} });
-    const check = writes[0].create;
-    assert.equal(check.status, expectedStatus);
-    assert.equal(check.conclusion, expectedConclusion);
-    assert.equal(statuses[0].state, state);
-    assert.match(check.output.summary, /committer must dispatch Fork CI/);
-    assert.equal(JSON.parse(check.output.text).run_status, status);
-    assert.equal(JSON.parse(check.output.text).run_conclusion, conclusion);
+    assert.deepEqual([statuses[0].state, statuses[0].description, 
statuses[0].target_url], [state, description, url()]);
   }
 }));
 
-test('scheduled publishers repair legacy premature terminal checks while the 
same attempt runs', async () => withPublisher(async ({ ctx, core }) => {
+test('scheduled publishers repair legacy statuses without an attempt while the 
run is still running', async () => withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
   const recent = { ...pr(), updated_at: new Date().toISOString() };
-  const latest = { id: 55, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'action_required',
-    output: { text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: 1,
-      base_ref: 'main', base_sha: B }) } };
-  const { github, writes, statuses } = publisherMock({ latest, rerun: { 
...run(), status: 'in_progress', conclusion: null } });
+  // Older publishers linked the run without its attempt and completed CI 
edits prematurely.
+  const legacy = forkStatus('error', 'Fork CI needs attention', 
'https://github.com/fork/repo/actions/runs/1');
+  const { github, statuses } = publisherMock({ latest: legacy, rerun: { 
...run(), status: 'in_progress', conclusion: null } });
   github.rest.git = serviceMock({ changed: true }).rest.git;
-  github.rest.repos.getCombinedStatusForRef = async () => ({ data: { statuses: 
[{ context: 'Fork CI', state: 'error' }] } });
   const listPulls = github.rest.pulls.list, paginate = github.paginate;
   github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
   github.rest.pulls.get = async () => ({ data: recent });
   await update({ github, context: ctx, core, sleep: async () => {} });
-  assert.equal(writes.length, 1);
-  assert.equal((writes[0].create || writes[0].update).status, 'in_progress');
-  assert.equal(statuses[0].state, 'pending');
+  assert.equal(statuses.length, 1);
+  assert.equal(statuses[0].state, 'pending'); 
assert.equal(statuses[0].target_url, url());
 }));
 
-test('known completed action-required executions cannot regress to running on 
a stale API response', async () => withPublisher(async ({ ctx, core }) => {
-  const latest = { id: 55, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'action_required',
-    output: { text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: 1, run_status: 'completed' }) } };
-  const { github, writes, statuses } = publisherMock({ latest, rerun: { 
...run(), status: 'in_progress', conclusion: null } });
-  github.rest.git = serviceMock({ changed: true }).rest.git;
-  await update({ github, context: ctx, core, sleep: async () => {} });
-  assert.equal(writes.length, 0);
-  assert.equal(statuses.length, 0);
+test('a completed execution cannot regress to running on a stale API 
response', async () => withPublisher(async ({ ctx, core }) => {
+  for (const latest of [forkStatus('pending', 'Fork CI passed; trusted 
verification required'),
+    forkStatus('failure', 'Failed: build / build')]) {
+    const { github, statuses } = publisherMock({ latest, rerun: { ...run(), 
status: 'in_progress', conclusion: null } });
+    github.rest.git = serviceMock({ changed: true }).rest.git;
+    await update({ github, context: ctx, core, sleep: async () => {} });
+    assert.equal(statuses.length, 0);
+  }
 }));
 
-test('scheduled probes repair same-state statuses with stale run links or 
descriptions', async () => withPublisher(async ({ ctx, core }) => {
+test('scheduled probes repair statuses that link another run or attempt', 
async () => withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
   const recent = { ...pr(), updated_at: new Date().toISOString() };
-  const manual = { ...ctx, eventName: 'workflow_dispatch', payload: { inputs: 
{ 'pull-request': '7' } } };
-  const initial = publisherMock();
-  await update({ github: initial.github, context: manual, core, sleep: async 
() => {} });
-  const check = { id: 55, app: { slug: 'github-actions' }, 
...initial.writes[0].create };
-  for (const wrong of [{ target_url: 
'https://github.com/fork/repo/actions/runs/0' }, { description: 'Old success' 
}]) {
-    const { github, statuses } = publisherMock({ latest: check });
-    github.rest.repos.getCombinedStatusForRef = async () => ({ data: { 
statuses: [{ ...initial.statuses[0], ...wrong }] } });
+  for (const wrong of [url(0, 1), 
'https://github.com/fork/repo/actions/runs/1']) {
+    const { github, statuses } = publisherMock({ latest: forkStatus('success', 
'All required suites passed', wrong) });
     const listPulls = github.rest.pulls.list, paginate = github.paginate;
     github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
     github.rest.pulls.get = async () => ({ data: recent });
     await update({ github, context: ctx, core, sleep: async () => {} });
     assert.equal(statuses.length, 1);
-    assert.equal(statuses[0].target_url, 
'https://github.com/fork/repo/actions/runs/1');
-    assert.equal(statuses[0].description, 'All required suites passed');
+    assert.equal(statuses[0].target_url, url());
   }
 }));
 
@@ -990,14 +968,8 @@ test('scheduled probes clear settled success when trusted 
CI is dispatched or re
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
   const recent = { ...pr(), updated_at: new Date().toISOString() };
   for (const wasTrusted of [false, true]) {
-    const owner = wasTrusted ? 'apache' : 'fork', repo = wasTrusted ? 
'gravitino' : 'repo';
-    const latest = { id: 55, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'success',
-      output: { title: 'All required suites passed', text: JSON.stringify({ 
owner, repo,
-        run_id: wasTrusted ? 2 : 1, run_attempt: 1, run_status: 'completed', 
trusted: wasTrusted,
-        base_ref: 'main', base_sha: B, fork_run_id: 1, fork_run_attempt: 1 }) 
} };
-    const { github, writes, statuses } = publisherMock({ latest });
-    github.rest.repos.getCombinedStatusForRef = async () => ({ data: { 
statuses: [{ context: 'Fork CI',
-      state: 'success', description: latest.output.title, target_url: 
`https://github.com/${owner}/${repo}/actions/runs/${wasTrusted ? 2 : 1}` }] } 
});
+    const shown = wasTrusted ? `${url(2, 1, 'apache', 
'gravitino')}#fork-run-1-1` : url();
+    const { github, statuses } = publisherMock({ latest: forkStatus('success', 
'All required suites passed', shown) });
     github.rest.actions.listWorkflowRuns = async ({ event }) => ({ data: { 
workflow_runs: event !== 'workflow_dispatch' ? [run()]
       : [{ ...run(), id: 2, head_sha: B, head_branch: 'main', run_attempt: 
wasTrusted ? 2 : 1,
         status: 'in_progress', conclusion: null, display_title: 'Trusted Fork 
CI #7', created_at: '2026-01-02T00:00:00Z' }] } });
@@ -1005,9 +977,30 @@ test('scheduled probes clear settled success when trusted 
CI is dispatched or re
     github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
     github.rest.pulls.get = async () => ({ data: recent });
     await update({ github, context: ctx, core, sleep: async () => {} });
-    assert.equal(writes[0].create.status, 'in_progress');
     assert.equal(statuses[0].state, 'pending');
-    assert.equal(statuses[0].target_url, 
'https://github.com/apache/gravitino/actions/runs/2');
+    // A trusted result also records the fork run it was chosen over.
+    assert.equal(statuses[0].target_url, `${url(2, wasTrusted ? 2 : 1, 
'apache', 'gravitino')}#fork-run-1-1`);
+  }
+}));
+
+test('a trusted result stays settled until its fork run changes', async () => 
withPublisher(async ({ ctx, core }) => {
+  ctx.eventName = 'schedule'; delete ctx.payload.inputs;
+  const recent = { ...pr(), updated_at: new Date().toISOString() };
+  for (const [forkAttempt, writes] of [[1, 0], [2, 1]]) {
+    const shown = `${url(2, 1, 'apache', 'gravitino')}#fork-run-1-1`;
+    const { github, statuses } = publisherMock({ latest: forkStatus('success', 
'All required suites passed', shown) });
+    github.rest.actions.listWorkflowRuns = async ({ event }) => ({ data: { 
workflow_runs: event !== 'workflow_dispatch'
+      ? [{ ...run(), run_attempt: forkAttempt }]
+      : [{ ...run(), id: 2, head_sha: B, head_branch: 'main', display_title: 
'Trusted Fork CI #7', created_at: '2026-01-02T00:00:00Z' }] } });
+    const listPulls = github.rest.pulls.list, paginate = github.paginate;
+    github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
+    github.rest.pulls.get = async () => ({ data: recent });
+    let refreshed = false;
+    const getTree = github.rest.git.getTree;
+    github.rest.git.getTree = async args => { refreshed = true; return 
getTree(args); };
+    await update({ github, context: ctx, core, sleep: async () => {} });
+    assert.equal(refreshed, forkAttempt === 2);
+    assert.equal(statuses.length, writes);
   }
 }));
 
@@ -1037,41 +1030,32 @@ test('trusted verification of CI edits mirrors running, 
failure and success', as
   }
 });
 
-test('an unchanged hidden metadata check still gets its missing visible 
status', async () => withPublisher(async ({ ctx, core }) => {
-  const initial = publisherMock();
-  await update({ github: initial.github, context: ctx, core, sleep: async () 
=> {} });
-  const hidden = { id: 55, app: { slug: 'github-actions' }, 
...initial.writes[0].create };
-  const { github, writes, statuses } = publisherMock({ latest: hidden });
+test('an identical result is not written to the status history again', async 
() => withPublisher(async ({ ctx, core }) => {
+  const { github, statuses } = publisherMock();
   await update({ github, context: ctx, core, sleep: async () => {} });
-  assert.equal(writes.length, 0, 'an identical check need not be recreated');
-  assert.equal(statuses.length, 1, 'the missing PR status must still be 
repaired');
-  assert.equal(statuses[0].state, 'success');
+  await update({ github, context: ctx, core, sleep: async () => {} });
+  assert.equal(statuses.length, 1);
 }));
 
-test('a push, retarget or newer attempt also suppresses stale visible 
statuses', async () => withPublisher(async ({ ctx, core }) => {
+test('a push, retarget or newer attempt suppresses stale statuses', async () 
=> withPublisher(async ({ ctx, core }) => {
   for (const change of [p => p.head.sha = C, p => p.base.ref = 'branch-1.3', p 
=> p.base.sha = C, p => p.state = 'closed']) {
     const changed = pr(); change(changed);
     const { github, statuses } = publisherMock({ current: changed });
     await update({ github, context: ctx, core, sleep: async () => {} });
     assert.equal(statuses.length, 0);
   }
-  const latest = { id: 55, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'failure',
-    output: { text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 1, 
run_attempt: 2 }) } };
-  const { github, statuses } = publisherMock({ latest });
+  const { github, statuses } = publisherMock({ latest: forkStatus('failure', 
'Failed: build / build', url(1, 2)) });
   await update({ github, context: ctx, core, sleep: async () => {} });
   assert.equal(statuses.length, 0);
 }));
 
-test('visible status publication retries a failed write even after the 
metadata check exists', async () => withPublisher(async ({ ctx, core, failures 
}) => {
-  const { github, writes, statuses } = publisherMock();
+test('a failed status write is reported and retried by the next publisher', 
async () => withPublisher(async ({ ctx, core, failures }) => {
+  const { github, statuses } = publisherMock();
   const create = github.rest.repos.createCommitStatus;
   github.rest.repos.createCommitStatus = async () => { throw new Error('status 
API unavailable'); };
   await update({ github, context: ctx, core, sleep: async () => {} });
   assert.match(failures[0], /#7/);
   assert.equal(statuses.length, 0);
-  const check = { id: 55, app: { slug: 'github-actions' }, ...writes[0].create 
};
-  const paginate = github.paginate;
-  github.paginate = async (endpoint, args) => endpoint === 
github.rest.checks.listForRef ? [check] : paginate(endpoint, args);
   github.rest.repos.createCommitStatus = create;
   await update({ github, context: ctx, core, sleep: async () => {} });
   assert.equal(statuses.length, 1);
@@ -1121,25 +1105,24 @@ test('allowlist scans publish their actual verdict as a 
commit status and ignore
   }
 });
 
-test('only trusted publishers receive the status-writing permission', async () 
=> {
+test('only trusted publishers receive the status-writing permission, and 
nobody creates check runs', async () => {
   for (const workflow of ['fork-ci-status-update.yml', 
'asf-allowlist-trusted.yml']) {
     const yaml = await readFile(path.join(__dirname, '../../workflows', 
workflow), 'utf8');
     assert.match(yaml, /^permissions: \{\}/m);
     assert.match(yaml, /^      statuses: write$/m);
+    assert.doesNotMatch(yaml, /checks: write/);
   }
   const signal = await readFile(path.join(__dirname, 
'../../workflows/fork-ci-status.yml'), 'utf8');
   assert.doesNotMatch(signal, /statuses: write/);
+  for (const script of ['update-fork-ci.cjs', 'retire-fork-ci.cjs', 
'allowlist-pr.cjs', 'fork-ci-status.cjs', 'publish-ci-status.cjs']) {
+    assert.doesNotMatch(await readFile(path.join(__dirname, '..', script), 
'utf8'), /\.checks\./, script);
+  }
 });
 
-
-test('scheduled probes repair a settled metadata check whose commit status was 
never published', async () => withPublisher(async ({ ctx, core }) => {
+test('scheduled probes publish a status that was never written', async () => 
withPublisher(async ({ ctx, core }) => {
   ctx.eventName = 'schedule'; delete ctx.payload.inputs;
   const recent = { ...pr(), updated_at: new Date().toISOString() };
-  const initial = publisherMock();
-  const manual = { ...ctx, eventName: 'workflow_dispatch', payload: { inputs: 
{ 'pull-request': '7' } } };
-  await update({ github: initial.github, context: manual, core, sleep: async 
() => {} });
-  const check = { id: 55, app: { slug: 'github-actions' }, 
...initial.writes[0].create };
-  const { github, statuses } = publisherMock({ latest: check });
+  const { github, statuses } = publisherMock();
   const listPulls = github.rest.pulls.list, paginate = github.paginate;
   github.paginate = async (endpoint, args) => endpoint === listPulls ? 
[recent] : paginate(endpoint, args);
   github.rest.pulls.get = async () => ({ data: recent });
@@ -1148,7 +1131,6 @@ test('scheduled probes repair a settled metadata check 
whose commit status was n
   assert.equal(statuses[0].state, 'success');
 }));
 
-
 test('allowlist verdicts share one serialized queue', async () => {
   const yaml = await readFile(path.join(__dirname, 
'../../workflows/asf-allowlist-trusted.yml'), 'utf8');
   assert.match(yaml, /^  group: asf-allowlist-publish$/m);
@@ -1156,40 +1138,34 @@ test('allowlist verdicts share one serialized queue', 
async () => {
   assert.match(yaml, /^  cancel-in-progress: false$/m);
 });
 
-test('the status follows the stored check when a concurrent writer recorded a 
newer result', async () => withPublisher(async ({ ctx, core }) => {
-  // This publisher still sees the run in progress; a concurrent signal has 
just stored success.
-  const { github, statuses } = publisherMock({ rerun: { ...run(), status: 
'in_progress', conclusion: null } });
-  const create = github.rest.checks.create, listForRef = 
github.rest.checks.listForRef, paginate = github.paginate;
-  const newer = { id: 2000, app: { slug: 'github-actions' }, status: 
'completed', conclusion: 'success',
-    output: { title: 'All required suites passed', text: JSON.stringify({ 
owner: 'fork', repo: 'repo', run_id: 1, run_attempt: 1, run_status: 'completed' 
}) } };
-  let raced = false;
-  github.rest.checks.create = async args => { await create(args); raced = 
true; };
-  github.paginate = async (endpoint, args) => endpoint === listForRef && raced 
? [newer] : paginate(endpoint, args);
+test('the publisher reads the status last, so a result a concurrent writer 
just stored wins', async () => withPublisher(async ({ ctx, core }) => {
+  // This publisher still sees the run in progress; a concurrent signal stores 
success meanwhile.
+  const { github, statuses, stored } = publisherMock({ rerun: { ...run(), 
status: 'in_progress', conclusion: null } });
+  const get = github.rest.pulls.get;
+  let reads = 0;
+  github.rest.pulls.get = async args => {
+    if (++reads === 2) stored.set(A, [forkStatus('success', 'All required 
suites passed')]);
+    return get(args);
+  };
   await update({ github, context: ctx, core, sleep: async () => {} });
-  assert.equal(statuses.length, 1);
-  assert.equal(statuses[0].state, 'success');
-  assert.equal(statuses[0].description, 'All required suites passed');
+  assert.equal(statuses.length, 0);
+  assert.equal(stored.get(A)[0].state, 'success');
 }));
 
-test('the publisher settles cancelled previous-head checks after publishing 
the current head', async () => withPublisher(async ({ ctx, core, failures }) => 
{
+test('the publisher settles cancelled previous-head statuses after publishing 
the current head', async () => withPublisher(async ({ ctx, core, failures }) => 
{
   const p = pr();p.head.ref = 'topic';
-  const { github, writes, statuses } = publisherMock();
+  const { github, statuses, stored } = publisherMock();
   github.rest.pulls.get = async () => ({ data: p });
   const oldRun = { ...run(), id: 10, head_sha: C, head_branch: 'topic', event: 
'push', conclusion: 'cancelled' };
-  const oldCheck = { id: 88, app: { slug: 'github-actions' }, status: 
'in_progress', output: {
-    text: JSON.stringify({ owner: 'fork', repo: 'repo', run_id: 10, 
run_attempt: 1 }) } };
-  const list = github.rest.actions.listWorkflowRuns, paginate = 
github.paginate;
+  stored.set(C, [forkStatus('pending', 'Fork CI is running', url(10, 1))]);
+  const list = github.rest.actions.listWorkflowRuns;
   github.rest.actions.listWorkflowRuns = async args => args.branch === 'topic'
     ? { data: { workflow_runs: [oldRun] } } : list(args);
   github.rest.actions.getWorkflowRunAttempt = async () => ({ data: oldRun });
-  github.paginate = async (endpoint, args) => endpoint === 
github.rest.checks.listForRef && args.ref === C
-    ? [oldCheck] : paginate(endpoint, args);
   await update({ github, context: ctx, core, sleep: async () => {} });
   assert.equal(failures.length, 0);
-  assert.equal(writes[0].create.head_sha, A);
-  assert.equal(writes[1].update.check_run_id, 88);
-  assert.equal(writes[1].update.conclusion, 'cancelled');
-  assert.deepEqual(statuses.map(s => [s.sha, s.state]), [[A, 'success'], [C, 
'error']]);
+  assert.deepEqual(statuses.map(s => [s.sha, s.state, s.target_url]), [[A, 
'success', url()], [C, 'error', url(10, 1)]]);
+  assert.equal(statuses[1].description, 'Fork CI cancelled for a previous 
commit');
 }));
 
 test('history cleanup failure leaves the current result published and remains 
observable', async () => withPublisher(async ({ ctx, core, failures }) => {
diff --git a/.github/scripts/tests/retire-fork-ci.test.cjs 
b/.github/scripts/tests/retire-fork-ci.test.cjs
index ad4677ec9f..5620d401c2 100644
--- a/.github/scripts/tests/retire-fork-ci.test.cjs
+++ b/.github/scripts/tests/retire-fork-ci.test.cjs
@@ -17,77 +17,79 @@ const test = require('node:test');
 const assert = require('node:assert/strict');
 const { retireCancelled } = require('../retire-fork-ci.cjs');
 const A = 'a'.repeat(40), B = 'b'.repeat(40);
+const url = (id, attempt) => 
`https://github.com/fork/repo/actions/runs/${id}/attempts/${attempt}`;
 function fixture() {
   const repo = { owner: 'apache', repo: 'gravitino' };
   const pr = { number: 7, state: 'open', head: { sha: A, ref: 'topic',
     repo: { owner: { login: 'fork' }, name: 'repo', full_name: 'fork/repo' } } 
};
   const run = { id: 10, run_attempt: 1, head_sha: B, head_branch: 'topic', 
event: 'push',
     path: '.github/workflows/fork-ci.yml', status: 'completed', conclusion: 
'cancelled' };
-  const record = { owner: 'fork', repo: 'repo', run_id: 10, run_attempt: 1, 
trusted: false };
-  const check = { id: 20, app: { slug: 'github-actions' }, status: 
'in_progress',
-    output: { text: JSON.stringify(record) } };
-  const writes = [], statuses = [];
+  // The previous head's status still waits on the run its push cancelled.
+  const shown = { context: 'Fork CI', state: 'pending', description: 'Fork CI 
is running', target_url: url(10, 1) };
+  const statuses = [], reads = [];
   const actual = { ...run }, current = structuredClone(pr);
   const github = { rest: {
     actions: { listWorkflowRuns: async args => { assert.equal(args.per_page, 
10);return { data: { workflow_runs: [run] } }; },
       getWorkflowRunAttempt: async args => { assert.equal(args.attempt_number, 
1);return { data: actual }; } },
-    checks: { listForRef() {}, update: async args => { 
writes.push(args);Object.assign(check, args); } },
     pulls: { get: async () => ({ data: current }) },
-    repos: { getCombinedStatusForRef: async () => ({ data: { statuses } }),
-      createCommitStatus: async args => { statuses.push(args); } }
-  }, paginate: async () => [check] };
-  return { github, repo, pr, run, record, check, actual, current, writes, 
statuses };
+    repos: { getCombinedStatusForRef: async args => { reads.push(args.ref); 
return { data: { statuses: [shown] } }; },
+      createCommitStatus: async args => { statuses.push(args); 
Object.assign(shown, { state: args.state,
+        description: args.description, target_url: args.target_url }); } }
+  } };
+  return { github, repo, pr, run, shown, actual, current, statuses, reads };
 }
-test('confirmed cancelled previous runs close their metadata check and visible 
status', async () => {
+test('confirmed cancelled previous runs get an error status on their head', 
async () => {
   const f = fixture();await retireCancelled(f);
-  assert.equal(f.writes.length, 2);
-  assert.equal(f.writes[0].status, 'completed');
-  assert.equal(f.writes[0].conclusion, 'cancelled');
-  assert.equal(JSON.parse(f.writes[0].output.text).superseded_by, A);
-  assert.deepEqual(f.statuses[0], { owner: 'apache', repo: 'gravitino', sha: 
B, context: 'Fork CI', state: 'error',
-    description: 'Fork CI cancelled for a previous commit', target_url: 
'https://github.com/fork/repo/actions/runs/10' });
+  assert.deepEqual(f.reads, [B]);
+  assert.deepEqual(f.statuses, [{ owner: 'apache', repo: 'gravitino', sha: B, 
context: 'Fork CI', state: 'error',
+    description: 'Fork CI cancelled for a previous commit', target_url: 
url(10, 1) }]);
 });
-test('history retirement preserves other heads, runs, attempts, trusted 
results and terminal verdicts', async () => {
+test('history retirement preserves other heads, runs, attempts, trusted 
results and verdicts', async () => {
   const changes = [
     f => f.run.head_sha = A, f => f.run.head_branch = 'another', f => 
f.run.event = 'schedule',
     f => f.run.path = '.github/workflows/other.yml', f => f.run.conclusion = 
'success',
-    f => f.record.owner = 'other', f => f.record.repo = 'other', f => 
f.record.trusted = true,
-    f => f.record.run_id = 11, f => f.record.run_attempt = 2,
-    f => { f.check.status = 'completed';f.check.conclusion = 'success'; },
+    f => f.shown.target_url = 
'https://github.com/other/repo/actions/runs/10/attempts/1',
+    f => f.shown.target_url = 
'https://github.com/apache/gravitino/actions/runs/10/attempts/1',
+    f => f.shown.target_url = url(11, 1), f => f.shown.target_url = url(10, 2),
+    f => f.shown.target_url = 
'https://github.com/fork/repo/actions/workflows/fork-ci.yml',
+    f => f.shown.state = 'success', f => f.shown.state = 'failure',
+    f => f.shown.description = 'Fork CI passed; trusted verification required',
+    f => f.shown.context = 'ASF Allowlist Check',
     f => f.actual.status = 'in_progress', f => f.actual.conclusion = 
'failure', f => f.actual.head_sha = A,
     f => f.current.state = 'closed', f => f.current.head.sha = B,
     f => f.current.head.repo.full_name = 'other/repo'
   ];
   for (const change of changes) {
-    const f = fixture();change(f);f.check.output.text = 
JSON.stringify(f.record);
-    await retireCancelled(f);assert.equal(f.writes.length, 
0);assert.equal(f.statuses.length, 0);
+    const f = fixture();change(f);
+    await retireCancelled(f);assert.equal(f.statuses.length, 0, 
change.toString());
   }
-  const f = fixture();f.check.output.text = 'invalid JSON';await 
retireCancelled(f);assert.equal(f.writes.length, 0);
 });
-test('retirement retries a missing status after its metadata write succeeded', 
async () => {
+test('statuses linked before attempts were recorded are retired too', async () 
=> {
+  const f = fixture();f.shown.target_url = 
'https://github.com/fork/repo/actions/runs/10';
+  await retireCancelled(f);
+  assert.equal(f.statuses[0].state, 
'error');assert.equal(f.statuses[0].target_url, url(10, 1));
+});
+test('a failed retirement is retried by the next publisher', async () => {
   const f = fixture(), create = f.github.rest.repos.createCommitStatus;
   f.github.rest.repos.createCommitStatus = async () => { throw new 
Error('Status permission failure'); };
   await assert.rejects(retireCancelled(f), /Status permission failure/);
-  assert.equal(f.check.status, 'completed');assert.equal(f.statuses.length, 0);
   f.github.rest.repos.createCommitStatus = create;await retireCancelled(f);
-  assert.equal(f.writes.length, 2);assert.equal(f.statuses.length, 
1);assert.equal(f.statuses[0].state, 'error');
+  assert.equal(f.statuses.length, 1);assert.equal(f.statuses[0].state, 
'error');
 });
 
-test('settled retired attempts do not repeatedly query the attempt, PR or 
status', async () => {
+test('retired statuses are settled with one status read: no attempt, PR or 
status write', async () => {
   const f = fixture();await retireCancelled(f);
-  assert.equal(JSON.parse(f.check.output.text).retired_status_published, true);
   const unexpected = async () => { throw new Error('Settled history must not 
be fetched again'); };
-  f.github.rest.actions.getWorkflowRunAttempt = unexpected;
-  f.github.rest.pulls.get = 
unexpected;f.github.rest.repos.getCombinedStatusForRef = unexpected;
+  f.github.rest.actions.getWorkflowRunAttempt = 
unexpected;f.github.rest.pulls.get = unexpected;
   await retireCancelled(f);
-  assert.equal(f.writes.length, 2);assert.equal(f.statuses.length, 1);
+  assert.equal(f.statuses.length, 1);assert.deepEqual(f.reads, [B, B]);
 });
 
 test('a fork without the Fork CI workflow has no history to retire', async () 
=> {
-  const { github, repo, pr, writes, statuses } = fixture();
+  const { github, repo, pr, statuses } = fixture();
   github.rest.actions.listWorkflowRuns = async () => { throw Object.assign(new 
Error('Not Found'), { status: 404 }); };
   await retireCancelled({ github, repo, pr });
-  assert.equal(writes.length, 0); assert.equal(statuses.length, 0);
+  assert.equal(statuses.length, 0);
   github.rest.actions.listWorkflowRuns = async () => { throw Object.assign(new 
Error('Server Error'), { status: 500 }); };
   await assert.rejects(retireCancelled({ github, repo, pr }), /Server Error/);
 });
@@ -95,5 +97,5 @@ test('a fork without the Fork CI workflow has no history to 
retire', async () =>
 test('a cancelled run started with Run workflow in the fork is retired like a 
push run', async () => {
   const f = fixture();f.run.event = 'workflow_dispatch';f.actual.event = 
'workflow_dispatch';
   await retireCancelled(f);
-  assert.equal(f.writes[0].conclusion, 
'cancelled');assert.equal(f.statuses[0].state, 'error');
+  assert.equal(f.statuses[0].state, 'error');
 });
diff --git a/.github/scripts/update-fork-ci.cjs 
b/.github/scripts/update-fork-ci.cjs
index 9d140e93b1..7d52c3fcf1 100644
--- a/.github/scripts/update-fork-ci.cjs
+++ b/.github/scripts/update-fork-ci.cjs
@@ -14,7 +14,7 @@
  */
 'use strict';
 const { createService } = require('./fork-ci-status.cjs');
-const { publishStatus, statusState } = require('./publish-ci-status.cjs');
+const { latestStatus, parseRunUrl, publishStatus, runUrl, statusCompleted, 
statusState } = require('./publish-ci-status.cjs');
 const { retireCancelled } = require('./retire-fork-ci.cjs');
 
 const RECENT_MS = 6 * 60 * 60 * 1000;
@@ -29,10 +29,13 @@ const PASS_MS = 60 * 1000;
 const SWEEP_SHARE = 0.4;
 
 async function update({ github, context, core, sleep = ms => new 
Promise(resolve => setTimeout(resolve, ms)), clock = Date.now }) {
-  const signal = context.eventName === 'workflow_run' && 
context.payload.workflow_run.name === 'Fork CI PR Signal';
   const trustedSignal = context.eventName === 'workflow_run' &&
     context.payload.workflow_run.event === 'workflow_dispatch' &&
     /^Trusted Fork CI 
#([1-9][0-9]*)$/.exec(context.payload.workflow_run.display_title || '');
+  // Every other workflow_run, a PR signal or a finished Fork CI push run in 
this repository (for
+  // example a same-repository PR branch, or main after a merge), refreshes 
the PRs with its head
+  // once. It must never become a polling sweep: it runs in the signal queue 
and would block it.
+  const signal = context.eventName === 'workflow_run' && !trustedSignal;
   // A sweep dispatched by the previous sweep runs like a scheduled one.
   const chained = context.eventName === 'workflow_dispatch' && 
String(context.payload.inputs?.sweep) === 'true';
   const manual = (context.eventName === 'workflow_dispatch' && !chained) || 
!!trustedSignal || signal;
@@ -64,13 +67,7 @@ async function update({ github, context, core, sleep = ms => 
new Promise(resolve
   let calls = 0;
   github.hook.before('request', () => { calls++; });
   const failures = new Set();
-  const recordOf = check => { try { return JSON.parse(check?.output?.text || 
'{}'); } catch { return {}; } };
-  async function latestCheck(pr) {
-    const checks = await github.paginate(github.rest.checks.listForRef, {
-      ...context.repo, ref: pr.head.sha, check_name: 'Fork CI', per_page: 100, 
filter: 'all'
-    });
-    return checks.filter(check => check.app?.slug === 
'github-actions').sort((a, b) => b.id - a.id)[0];
-  }
+  const forkStatus = pr => latestStatus({ github, repo: context.repo, sha: 
pr.head.sha, context: 'Fork CI' });
   async function migrated(pr) {
     // Release branches without this CI migration keep their own pull_request 
workflows.
     if (!availableBases.has(pr.base.sha)) {
@@ -82,71 +79,38 @@ async function update({ github, context, core, sleep = ms 
=> new Promise(resolve
     }
     return availableBases.get(pr.base.sha);
   }
-  // apache/gravitino cannot start runs in a contributor's fork, so tell the 
author how to.
-  function rerunHelp(pr, runUrl) {
-    if (!pr.head.repo || !pr.head.ref) return '';
-    const fork = 
`https://github.com/${pr.head.repo.owner.login}/${pr.head.repo.name}`;
-    return '\n\n**Run CI again without a new commit:** ' +
-      (runUrl ? `open [the run](${runUrl}) and choose **Re-run jobs** once it 
has finished ` +
-        '(re-running all jobs also tests the latest base branch), or ' : '') +
-      `start a new run with [Run 
workflow](${fork}/actions/workflows/fork-ci.yml) on branch \`${pr.head.ref}\` 
in your fork. ` +
-      'Closing the PR cancels a running fork run; reopening it does not start 
one. ' +
-      'The Re-run button on this check only refreshes this status.';
+  // Without a run, link to the fork's Fork CI page, where the author can 
enable Actions or start one.
+  function waitingUrl(pr) {
+    return pr.head.repo
+      ? 
`https://github.com/${pr.head.repo.owner.login}/${pr.head.repo.name}/actions/workflows/fork-ci.yml`
 : pr.html_url;
+  }
+  // apache/gravitino cannot re-run jobs in a contributor's fork; the status 
link opens the run.
+  function describe(result, mirror) {
+    const hint = `${result.title}; re-run it in your fork`;
+    return mirror.run && !mirror.trusted && ['failure', 
'error'].includes(statusState(result)) && hint.length <= 140
+      ? hint : result.title;
   }
   async function refresh(pr) {
     if (!(await migrated(pr))) return;
     refreshed.add(pr.number);
     const mirror = await service.mirror(pr);
     const { result, run } = mirror;
-    const note = result.note || (result.status !== 'completed' ? result.title
-      : result.conclusion === 'success' ? 'Verified all caller suites.' : 
'Open the run to see which jobs did not succeed.');
-    const testedBase = mirror.base && mirror.base !== pr.base.sha ? `\nTested 
base: ${mirror.base}` : '';
-    const record = { owner: mirror.owner, repo: mirror.repo, run_id: run?.id,
-      run_attempt: run?.run_attempt, run_status: run?.status, run_conclusion: 
run?.conclusion,
-      base_ref: pr.base.ref, base_sha: pr.base.sha, trusted: mirror.trusted || 
false,
-      fork_run_id: mirror.fork?.id, fork_run_attempt: mirror.fork?.run_attempt 
};
-    const details = run ? 
`https://github.com/${mirror.owner}/${mirror.repo}/actions/runs/${run.id}` : 
pr.html_url;
-    const output = { title: result.title,
-      // GitHub ignores details_url for checks created with GITHUB_TOKEN, so 
link the run here.
-      summary: (run ? `[See fork CI results](${details})\n\n` : '') + note +
-        `\n\nBase: ${pr.base.ref} @ ${pr.base.sha}${testedBase}` + 
rerunHelp(pr, mirror.trusted ? undefined : run && details),
-      text: JSON.stringify(record) };
+    const target = run ? runUrl(mirror.owner, mirror.repo, run, mirror.trusted 
&& mirror.fork) : waitingUrl(pr);
     // Re-read before publishing so a push or retarget during the API calls 
cannot get a stale success.
     const { data: current } = await github.rest.pulls.get({ ...context.repo, 
pull_number: pr.number });
     if (current.head.sha !== pr.head.sha || current.base.sha !== pr.base.sha 
|| current.base.ref !== pr.base.ref || current.state !== 'open') return;
-    const params = { ...context.repo, ...result, output, details_url: details 
};
-    delete params.title;
-    delete params.note;
-    // Signals and sweeps can publish concurrently. Read the check last and 
never replace a newer
-    // attempt of a run from the same repository, or a completed result with a 
running one.
-    const latest = await latestCheck(pr);
-    const oldRecord = recordOf(latest);
-    // A run already recorded for this commit still exists; a listing that 
missed it is incomplete.
-    if (!record.run_id && oldRecord.run_id) return;
-    // Older publishers completed action_required checks before CI edits 
finished running.
-    // Those checks need repair; a terminal execution result must still resist 
stale API reads.
-    const executionCompleted = oldRecord.run_status === 'completed' ||
-      (!oldRecord.run_status && latest?.status === 'completed' && 
latest.conclusion !== 'action_required');
-    if (oldRecord.owner === record.owner && oldRecord.repo === record.repo && 
record.run_id &&
-        (oldRecord.run_id > record.run_id || (oldRecord.run_id === 
record.run_id &&
-          (oldRecord.run_attempt > record.run_attempt ||
-            (oldRecord.run_attempt === record.run_attempt && 
executionCompleted && result.status !== 'completed'))))) return;
-    const sameRun = oldRecord.run_id === record.run_id && 
oldRecord.run_attempt === record.run_attempt && oldRecord.base_sha === 
record.base_sha && oldRecord.base_ref === record.base_ref;
-    if (!latest || (latest.status === 'completed' && (!sameRun || 
result.status !== 'completed'))) {
-      await github.rest.checks.create({ ...params, name: 'Fork CI', head_sha: 
pr.head.sha });
-    } else if (!sameRun || latest.status !== result.status || 
latest.conclusion !== (result.conclusion || null) || latest.output?.summary !== 
output.summary || latest.output?.text !== output.text) {
-      await github.rest.checks.update({ ...params, check_run_id: latest.id });
-    }
-    // Even an unchanged metadata check may be absent from the PR's 
latest-check view, so
-    // backfill the commit status. Derive it from the check as it is now, not 
from this
-    // publisher's snapshot: a concurrent writer may have recorded a newer 
result meanwhile.
-    // Any remaining interleaving is repaired by the next pass, which compares 
both.
-    const settled = (await latestCheck(pr)) || { ...result, output };
-    const settledRecord = recordOf(settled);
+    // Signals and sweeps can publish concurrently. Read the status last and 
never replace a newer
+    // attempt of a run from the same repository, or a completed result with a 
running one. Any
+    // remaining interleaving is repaired by the next pass, which compares the 
status with the runs.
+    const latest = await forkStatus(pr);
+    const shown = parseRunUrl(latest?.target_url);
+    // A run already shown for this commit still exists; a listing that missed 
it is incomplete.
+    if (!run && shown) return;
+    if (run && shown && shown.owner === mirror.owner && shown.repo === 
mirror.repo && (shown.run_id > run.id ||
+        (shown.run_id === run.id && (shown.run_attempt > run.run_attempt ||
+          (shown.run_attempt === run.run_attempt && statusCompleted(latest) && 
result.status !== 'completed'))))) return;
     await publishStatus({ github, repo: context.repo, sha: pr.head.sha, 
context: 'Fork CI',
-      state: statusState(settled), description: settled.output?.title || 
result.title,
-      targetUrl: settledRecord.run_id
-        ? 
`https://github.com/${settledRecord.owner}/${settledRecord.repo}/actions/runs/${settledRecord.run_id}`
 : pr.html_url });
+      state: statusState(result), description: describe(result, mirror), 
targetUrl: target, previous: latest ?? null });
   }
   async function visit(pr, work) {
     processed++;
@@ -170,7 +134,7 @@ async function update({ github, context, core, sleep = ms 
=> new Promise(resolve
   let refreshed = new Set();
   let prs = [];
   let recentCursor = null;
-  async function pass(budget, verifyStatuses) {
+  async function pass(budget) {
     const now = clock();
     prs = await listPrs();
     processed = 0;
@@ -182,46 +146,33 @@ async function update({ github, context, core, sleep = ms 
=> new Promise(resolve
     // signal a refresh, or with a fork rerun, so refresh it only when the 
fork run id or attempt changed.
     const recent = manual ? [] : prs.filter(pr => now - 
Date.parse(pr.updated_at) < RECENT_MS)
       .sort((a, b) => Date.parse(b.updated_at) - Date.parse(a.updated_at));
-    // Probes need up to five calls, so rotate them too and keep a third of 
the budget for older PRs.
+    // Probes need up to three calls, so rotate them too and keep a third of 
the budget for older PRs.
     // Later passes of the same sweep resume where the previous pass stopped.
     const recentBudget = Math.floor(budget * 2 / 3);
     const recentStart = !recent.length ? 0 : (recentCursor ??
-      Math.floor(now / slotMs) * Math.max(1, Math.floor(recentBudget / 5))) % 
recent.length;
+      Math.floor(now / slotMs) * Math.max(1, Math.floor(recentBudget / 3))) % 
recent.length;
     let probed = 0;
     for (let offset = 0; offset < recent.length; offset++) {
-      if (calls + 15 > recentBudget) break; // One PR may need trees, runs, 
paginated jobs and a check write.
+      if (calls + 15 > recentBudget) break; // One PR may need trees, runs, 
paginated jobs and a status write.
       const pr = recent[(recentStart + offset) % recent.length];
       probed++;
       await visit(pr, async () => {
-        const latest = await latestCheck(pr);
-        if (latest?.status === 'completed') {
-          if (!pr.head.repo) return;
-          const record = recordOf(latest);
-          // A fork without fork-ci.yml (404) has no run to watch; its check 
already says so.
+        const latest = await forkStatus(pr);
+        if (latest && statusCompleted(latest) && pr.head.repo) {
+          const shown = parseRunUrl(latest.target_url);
+          // A fork without fork-ci.yml (404) has no run to watch; its status 
already says so.
           const fork = (await service.findRun(pr, false).catch(error => {
             if (error.status !== 404) throw error;
           }))?.run;
-          // Trusted reruns and new dispatches also start without a PR-head 
signal. A
-          // settled fork alone cannot prove the selected trusted execution is 
settled.
+          // Fork reruns, Run workflow, trusted reruns and new dispatches 
start without a PR-head
+          // signal. The result is settled only while every run it depends on 
is unchanged.
           const trusted = (await service.findRun(pr, true))?.run;
-          const trustedSettled = record.trusted
-            ? trusted?.id === record.run_id && trusted.run_attempt === 
record.run_attempt && trusted.status === 'completed'
-            : !trusted;
-          // A completed check without a run (no fork workflow) changes only 
with a push or a run.
-          if (trustedSettled && (record.run_status === 'completed' || 
!record.run_id) && (!fork || (fork.status === 'completed' &&
-              fork.id === (record.fork_run_id ?? record.run_id) &&
-              fork.run_attempt === (record.fork_run_attempt ?? 
record.run_attempt)))) {
-            // A completed metadata check does not prove the visible status 
was written:
-            // the status API can fail after the check write, or this may be a 
pre-migration PR.
-            // Verify that once per sweep, so later passes probe as cheaply as 
on main.
-            if (!verifyStatuses) return;
-            const { data } = await github.rest.repos.getCombinedStatusForRef({
-              ...context.repo, ref: pr.head.sha, per_page: 100 });
-            const details = record.run_id
-              ? 
`https://github.com/${record.owner}/${record.repo}/actions/runs/${record.run_id}`
 : pr.html_url;
-            if (data.statuses.some(status => status.context === 'Fork CI' && 
status.state === statusState(latest) &&
-                status.description === latest.output?.title?.slice(0, 140) && 
status.target_url === details)) return;
-          }
+          const same = (a, id, attempt) => a?.id === id && a.run_attempt === 
attempt && a.status === 'completed';
+          const settled = !shown ? !fork && !trusted
+            : shown.trusted ? same(trusted, shown.run_id, shown.run_attempt) &&
+              (fork ? same(fork, shown.fork_run_id, shown.fork_run_attempt) : 
!shown.fork_run_id)
+              : same(fork, shown.run_id, shown.run_attempt) && !trusted;
+          if (settled) return;
         }
         await refresh(pr);
       });
@@ -240,14 +191,17 @@ async function update({ github, context, core, sleep = ms 
=> new Promise(resolve
     core.info(`Visited ${processed}/${prs.length} PRs (probed 
${probed}/${recent.length} recently updated); ` +
       `${calls}/${budget} API calls; starting index ${start}.`);
   }
-  const deadline = clock() + LOOP_MS;
+  // Start passes on a fixed PASS_MS cadence: the time a pass spends on API 
calls does not
+  // delay the next one.
+  const started = clock();
   for (let i = 0; i < passes; i++) {
     if (i) {
-      if (clock() + PASS_MS > deadline) break;
-      await sleep(PASS_MS);
+      const next = Math.max(clock(), started + i * PASS_MS);
+      if (next >= started + LOOP_MS) break;
+      await sleep(next - clock());
       calls = 0;
     }
-    await pass(Math.floor(budget / passes), i === 0);
+    await pass(Math.floor(budget / passes));
   }
   if (manual && processed < prs.length) core.setFailed('API budget exhausted; 
dispatch again for a specific PR after the quota resets.');
   if (failures.size) core.setFailed(`Unable to refresh: ${[...failures].map(n 
=> `#${n}`).join(', ')}`);
diff --git a/.github/workflows/asf-allowlist-trusted.yml 
b/.github/workflows/asf-allowlist-trusted.yml
index 7703cc8d0f..e626c7421d 100644
--- a/.github/workflows/asf-allowlist-trusted.yml
+++ b/.github/workflows/asf-allowlist-trusted.yml
@@ -38,14 +38,13 @@ jobs:
     if: >-
       github.repository == 'apache/gravitino' &&
       (github.event_name == 'workflow_dispatch' || 
github.event.workflow_run.event == 'pull_request')
-    # A required check: keep it off the shared ubuntu-latest pool, where small 
jobs can queue for hours.
+    # Keep this quick check off the shared ubuntu-latest pool, where small 
jobs can queue for hours.
     # The allowlist action installs its own Python, so it supports ubuntu-slim.
     runs-on: ubuntu-slim
     timeout-minutes: 10
     permissions:
       contents: read
       pull-requests: read
-      checks: write
       statuses: write
     steps:
       - uses: actions/checkout@v4
diff --git a/.github/workflows/fork-ci-status-update.yml 
b/.github/workflows/fork-ci-status-update.yml
index 9abef0c9e0..39c151c5a2 100644
--- a/.github/workflows/fork-ci-status-update.yml
+++ b/.github/workflows/fork-ci-status-update.yml
@@ -25,7 +25,7 @@ on:
   workflow_dispatch:
     inputs:
       pull-request:
-        description: 'Optional PR number to force-refresh, including settled 
checks'
+        description: 'Optional PR number to force-refresh, including settled 
statuses'
         required: false
         type: string
       sweep:
@@ -37,7 +37,7 @@ permissions: {}
 # Commit statuses are append-only with no compare-and-swap. Signals and 
dispatches share one
 # queue, so a burst of PR events is processed in order and none replaces 
another. Sweeps poll
 # every minute for 11 minutes in their own group, so signals never wait behind 
a sleeping sweep;
-# both re-read the check before writing the status, and the next pass repairs 
any interleaving.
+# both re-read the status before writing it, and the next pass repairs any 
interleaving.
 jobs:
   update:
     if: >-
@@ -55,7 +55,6 @@ jobs:
     timeout-minutes: 14
     permissions:
       actions: read
-      checks: write
       statuses: write
       contents: read
       pull-requests: read
@@ -84,7 +83,6 @@ jobs:
       chain: ${{ steps.sweep.outputs.chain }}
     permissions:
       actions: read
-      checks: write
       statuses: write
       contents: read
       pull-requests: read
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8033898c22..452c6f08ec 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -107,7 +107,7 @@ Pull request tests run with GitHub Actions in your fork, 
not in `apache/gravitin
 * **Re-run the run:** Open the run for your PR's current commit and choose 
**Re-run all jobs**, which also tests the latest base branch, or **Re-run jobs 
→ Re-run failed jobs** to retry only failed and cancelled jobs against the same 
base. A run can be re-run only after it has finished; Fork CI cancels the rest 
of a run as soon as a job fails. See [GitHub's rerun 
instructions](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs).
 * **Push a commit:** Any push to the PR branch starts a new run and cancels 
the previous one. An empty commit (`git commit --allow-empty -m "Trigger Fork 
CI"`) is enough.
 
-The **Fork CI** check on the PR links to the run and to **Run workflow**. Its 
**Re-run** button and the **Update Fork CI Status** workflow only refresh the 
reported result; neither runs tests.
+The **Fork CI** status on the PR links to the exact run attempt it reports, 
where you can re-run it. The **Update Fork CI Status** workflow only refreshes 
the reported result; it does not run tests.
 
 | Action                                                 | Fork CI             
                                      | PR status                               
                  |
 | ------------------------------------------------------ | 
--------------------------------------------------------- | 
--------------------------------------------------------- |
@@ -115,17 +115,17 @@ The **Fork CI** check on the PR links to the run and to 
**Run workflow**. Its **
 | Close the PR                                           | The running fork 
run cancels itself within about a minute | Synchronization stops while the PR 
is closed              |
 | Reopen the PR                                          | Starts nothing      
                                      | Shows the latest fork run's result; run 
CI again as above |
 
-If no fork run starts, enable Actions in your fork, update your branch from 
the latest base branch, and push again. A branch created before Fork CI was 
introduced does not contain `.github/workflows/fork-ci.yml`, so pushing it runs 
no CI; the check then asks you to merge or rebase onto the latest base branch. 
Please fix failures before requesting a review.
+If no fork run starts, enable Actions in your fork, update your branch from 
the latest base branch, and push again. A branch created before Fork CI was 
introduced does not contain `.github/workflows/fork-ci.yml`, so pushing it runs 
no CI; the **Fork CI** status then asks you to merge or rebase onto the latest 
base branch. Please fix failures before requesting a review.
 
-If the check requests trusted verification for CI-definition changes, a 
committer must dispatch the trusted upstream **Fork CI** run described below; 
running CI in the fork does not satisfy that requirement.
+If **Fork CI** requests trusted verification for CI-definition changes, a 
committer must dispatch the trusted upstream **Fork CI** run described below; 
running CI in the fork does not satisfy that requirement.
 
 ### CI status synchronization
 
-Status synchronization closes unfinished checks for confirmed canceled runs 
among the fork branch's ten most recent runs.
+Status synchronization marks the pending status of a previous commit as an 
error once its fork run, among the fork branch's ten most recent runs, is 
confirmed cancelled.
 
-Fork runs cannot notify `apache/gravitino` when they finish, so a sweep polls 
recently updated PRs every minute for 11 minutes and then starts the next 
sweep, which keeps polling continuous; the five-minute schedule restarts the 
chain if it breaks. PR events are processed in order in a separate queue of up 
to 100 runs, so they never wait behind a sweep. Before writing the commit 
status, each publisher re-reads the check and publishes what it records, and 
the next pass repairs any interle [...]
+Fork runs cannot notify `apache/gravitino` when they finish, so a sweep polls 
recently updated PRs every minute for 11 minutes and then starts the next 
sweep, which keeps polling continuous; the five-minute schedule restarts the 
chain if it breaks. PR events are processed in order in a separate queue of up 
to 100 runs, so they never wait behind a sweep. Each publisher reads the 
current status just before writing it and never replaces a newer run attempt, 
or a finished result with a runni [...]
 
-The publishers report **Fork CI** and **ASF Allowlist Check** as commit 
statuses with direct links to the corresponding runs. Additional check runs 
retain diagnostic metadata; GitHub can omit those checks from the PR's 
latest-check view after another signal run. Queued and running CI both have a 
pending status, with the description distinguishing whether jobs have started. 
This also applies to PRs that edit CI definitions: their check explains that 
trusted verification will be needed, wh [...]
+The publishers report **Fork CI** and **ASF Allowlist Check** only as commit 
statuses, each listed once on the PR and linking to the corresponding run; the 
**Fork CI** link names the run attempt, which also records what the status 
reports. Commit statuses do not appear on the PR's **Checks** tab. Queued and 
running CI both have a pending status, with the description distinguishing 
whether jobs have started; this also applies to PRs that edit CI definitions. 
Failed tests report failure an [...]
 
 Known limitations of Fork CI:
 

Reply via email to