From 1006405c513aa49ed02703caa54ee6b269223587 Mon Sep 17 00:00:00 2001 From: Apurv Kumaria Date: Fri, 7 Aug 2026 14:24:54 -0700 Subject: [PATCH 1/2] fix(maintainer): authenticate fork Advisor runs Signed-off-by: Apurv Kumaria --- .../scripts/check-gates.ts | 55 +++++++++-------- .../check-gates-actions-evidence.test.ts | 61 +++++++++++++++++++ 2 files changed, 91 insertions(+), 25 deletions(-) diff --git a/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts b/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts index 900aef405db..a6e6c83c69a 100644 --- a/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts +++ b/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts @@ -1865,6 +1865,29 @@ function currentCheckRollup( return { runId: segments[4], jobId: segments[6] }; }; + const associationLessHeadBinding = ( + metadata: ActionRunMetadata, + ): "current" | "other" | "unknown" => { + if ( + metadata.hasPullRequests !== false || + (metadata.event !== "pull_request" && metadata.event !== "pull_request_target") + ) { + return "unknown"; + } + if ( + metadata.headShaMatches === false || + metadata.headRefNameMatches === false || + metadata.headRepositoryMatches === false + ) { + return "other"; + } + return metadata.headShaMatches === true && + metadata.headRefNameMatches === true && + metadata.headRepositoryMatches === true + ? "current" + : "unknown"; + }; + const isAuthenticatedAdvisoryPrReviewCheck = (check: StatusCheck): boolean => { const checkName = check.name ?? ""; if ( @@ -1880,13 +1903,18 @@ function currentCheckRollup( const job = latestAttemptJobs(identity.runId)?.get(identity.jobId); const checkStatus = check.status?.toUpperCase() ?? null; const checkConclusion = check.conclusion?.toUpperCase() ?? null; + const currentPrBinding = + run?.hasPullRequests === true && run.exactDiff === true + ? true + : exactDiff.headRepository !== repo && + run !== null && + associationLessHeadBinding(run) === "current"; return Boolean( run && job && run.event === "pull_request_target" && run.path === PR_REVIEW_ADVISOR_WORKFLOW_PATH && - run.hasPullRequests === true && - run.exactDiff === true && + currentPrBinding && job.name === checkName && job.status === checkStatus && job.conclusion === checkConclusion, @@ -1899,29 +1927,6 @@ function currentCheckRollup( check.detailsUrl?.match(/\/runs\/(\d+)(?:[/?#]|$)/u)?.[1] === String(e2eCoordinationEvidence.trustedCustomCheckId); - const associationLessHeadBinding = ( - metadata: ActionRunMetadata, - ): "current" | "other" | "unknown" => { - if ( - metadata.hasPullRequests !== false || - (metadata.event !== "pull_request" && metadata.event !== "pull_request_target") - ) { - return "unknown"; - } - if ( - metadata.headShaMatches === false || - metadata.headRefNameMatches === false || - metadata.headRepositoryMatches === false - ) { - return "other"; - } - return metadata.headShaMatches === true && - metadata.headRefNameMatches === true && - metadata.headRepositoryMatches === true - ? "current" - : "unknown"; - }; - function runIdentityEvidence( runId: string, requiresExactDiff: boolean, diff --git a/test/skills/check-gates-actions-evidence.test.ts b/test/skills/check-gates-actions-evidence.test.ts index 2bc3b508d9d..040d1fd7c88 100644 --- a/test/skills/check-gates-actions-evidence.test.ts +++ b/test/skills/check-gates-actions-evidence.test.ts @@ -35,6 +35,9 @@ interface AdvisorRunOptions { jobName?: string; path?: string; event?: string; + headSha?: string; + headBranch?: string; + headRepository?: string; pullRequests?: unknown[]; status?: string; conclusion?: string | null; @@ -165,6 +168,64 @@ describe("maintainer merge-gate contributor compliance", () => { }); }); + it("keeps a current fork Advisor lane advisory without a REST PR association", () => { + const runId = 9003; + const jobId = 9103; + const forkRepository = "contributor/NemoClaw"; + const result = runGate({ + body: "Signed-off-by: Example User ", + verified: true, + headRepository: forkRepository, + statusChecks: [...successfulRequiredChecks(), advisorCheck(runId, jobId)], + actionRunAttempts: { + [String(runId)]: advisorRun(jobId, { + headSha: HEAD_SHA, + headBranch: "feature-branch", + headRepository: forkRepository, + pullRequests: [], + }), + }, + }); + + expect(JSON.parse(result.stdout)).toMatchObject({ + allPass: true, + gates: { ci: { pass: true } }, + }); + }); + + it.each([ + { evidence: "the head SHA differs", run: { headSha: BASE_SHA } }, + { evidence: "the head ref differs", run: { headBranch: "other-branch" } }, + { + evidence: "the head repository differs", + run: { headRepository: "attacker/NemoClaw" }, + }, + ])("keeps an association-less fork Advisor lane merge-relevant when $evidence", ({ run }) => { + const runId = 9004; + const jobId = 9104; + const forkRepository = "contributor/NemoClaw"; + const result = runGate({ + body: "Signed-off-by: Example User ", + verified: true, + headRepository: forkRepository, + statusChecks: [...successfulRequiredChecks(), advisorCheck(runId, jobId)], + actionRunAttempts: { + [String(runId)]: advisorRun(jobId, { + headSha: HEAD_SHA, + headBranch: "feature-branch", + headRepository: forkRepository, + pullRequests: [], + ...run, + }), + }, + }); + + expect(JSON.parse(result.stdout)).toMatchObject({ + allPass: false, + gates: { ci: { pass: false } }, + }); + }); + it.each([ { evidence: "the REST job has another name", run: { jobName: "unrelated job" } }, { From 7a04b67d85d85fffd542488aa1eedd473d3a2f46 Mon Sep 17 00:00:00 2001 From: Apurv Kumaria Date: Fri, 7 Aug 2026 14:59:12 -0700 Subject: [PATCH 2/2] fix(maintainer): require terminal fork Advisor runs Signed-off-by: Apurv Kumaria --- .../scripts/check-gates.ts | 2 + .../check-gates-actions-evidence.test.ts | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts b/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts index a6e6c83c69a..7a9f8f14f4f 100644 --- a/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts +++ b/.agents/skills/nemoclaw-maintainer-day/scripts/check-gates.ts @@ -1908,6 +1908,8 @@ function currentCheckRollup( ? true : exactDiff.headRepository !== repo && run !== null && + run.status === "COMPLETED" && + run.conclusion !== null && associationLessHeadBinding(run) === "current"; return Boolean( run && diff --git a/test/skills/check-gates-actions-evidence.test.ts b/test/skills/check-gates-actions-evidence.test.ts index 040d1fd7c88..cbce16d0c8a 100644 --- a/test/skills/check-gates-actions-evidence.test.ts +++ b/test/skills/check-gates-actions-evidence.test.ts @@ -183,6 +183,8 @@ describe("maintainer merge-gate contributor compliance", () => { headBranch: "feature-branch", headRepository: forkRepository, pullRequests: [], + status: "completed", + conclusion: "failure", }), }, }); @@ -193,6 +195,41 @@ describe("maintainer merge-gate contributor compliance", () => { }); }); + it.each([ + { + evidence: "the workflow run is in progress", + run: { status: "in_progress", conclusion: "failure" }, + }, + { + evidence: "the completed workflow run has no conclusion", + run: { status: "completed", conclusion: null }, + }, + ])("keeps an association-less fork Advisor lane merge-relevant when $evidence", ({ run }) => { + const runId = 9005; + const jobId = 9105; + const forkRepository = "contributor/NemoClaw"; + const result = runGate({ + body: "Signed-off-by: Example User ", + verified: true, + headRepository: forkRepository, + statusChecks: [...successfulRequiredChecks(), advisorCheck(runId, jobId)], + actionRunAttempts: { + [String(runId)]: advisorRun(jobId, { + headSha: HEAD_SHA, + headBranch: "feature-branch", + headRepository: forkRepository, + pullRequests: [], + ...run, + }), + }, + }); + + expect(JSON.parse(result.stdout)).toMatchObject({ + allPass: false, + gates: { ci: { pass: false } }, + }); + }); + it.each([ { evidence: "the head SHA differs", run: { headSha: BASE_SHA } }, { evidence: "the head ref differs", run: { headBranch: "other-branch" } },