Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
8085680
feat(lab): CL-06 routing compatibility policy consumption
Wibias Aug 10, 2026
b96eae8
docs(lab): record CL-06 draft head SHA
Wibias Aug 10, 2026
3dc2762
docs(lab): link CL-06 draft PR #1394
Wibias Aug 10, 2026
f81807c
fix(lab): harden CL-06 compatibility routing
Wibias Aug 10, 2026
524c829
test(lab): cover CL-06 routing boundaries
Wibias Aug 10, 2026
be56c79
fix(lab): align registry auth compatibility identity
Wibias Aug 10, 2026
7309bee
chore(lab): ignore generated compatibility manifest
Wibias Aug 10, 2026
1ce921c
test(lab): cover registry auth compatibility identity
Wibias Aug 10, 2026
d3b4fe8
test(lab): use deterministic compatibility score timestamp
Wibias Aug 10, 2026
70cd775
fix(gui): localize compatibility policy labels
Wibias Aug 10, 2026
e1dddd3
fix(gui): localize compatibility policy labels
Wibias Aug 10, 2026
23c69a1
fix(gui): keep compatibility label diff narrow
Wibias Aug 10, 2026
7e38f10
test(ci): isolate storage API runtime family
Wibias Aug 10, 2026
771c542
fix(ci): isolate storage API runtime test
Wibias Aug 10, 2026
d15d115
merge dev into CL-06 branch
github-actions[bot] Aug 10, 2026
eb1d485
fix(ci): preserve dev isolation with storage API fix
Wibias Aug 10, 2026
f927525
chore(ci): add temporary CL-06 conflict resolver
Wibias Aug 10, 2026
8b80186
chore(ci): fix temporary CL-06 resolver workflow
Wibias Aug 10, 2026
0eab8f9
chore(ci): semantically resolve CL-06 GUI conflicts
Wibias Aug 10, 2026
e4a4d06
chore(ci): run validated CL-06 conflict resolver
Wibias Aug 10, 2026
4984fd7
merge(dev): resolve CL-06 routing conflicts
github-actions[bot] Aug 10, 2026
01080ee
chore(ci): retrigger checks after resolved merge
Wibias Aug 10, 2026
c01efd8
chore(ci): apply CL-06 cursor timeout hotfix
Wibias Aug 10, 2026
53629b4
test(cursor): allow boundary stress test runtime
github-actions[bot] Aug 10, 2026
3647e38
ci: retrigger checks after cursor timeout fix
Wibias Aug 10, 2026
2186e98
fix(oauth): guard expires_in parsing against NaN across token responses
Bruce-Yii Aug 10, 2026
fc5889e
fix(oauth): guard computed token expiry against numeric overflow
Bruce-Yii Aug 10, 2026
355b69e
fix(oauth): reject negative expires_in and assert exact fallback wind…
Bruce-Yii Aug 10, 2026
72395a8
docs(devlog): re-pick the RC and settle the gate record
lidge-jun Aug 10, 2026
08e7e0f
docs(devlog): record the release and the post-release closure sweep
lidge-jun Aug 10, 2026
33dcf46
test(native-profile): publish startup port atomically
Wibias Aug 10, 2026
d8e99a0
chore(test): preserve helper newline
Wibias Aug 10, 2026
2e2c70f
docs: design DeepSeek Responses terminal repair
baileyh8 Aug 6, 2026
e019b14
docs: tighten terminal repair completion predicate
baileyh8 Aug 6, 2026
816b53c
docs: plan DeepSeek Responses terminal repair
baileyh8 Aug 6, 2026
f868862
fix(deepseek): restore Responses upstream streaming
baileyh8 Aug 6, 2026
af1d302
feat(responses): repair complete terminal-less streams
baileyh8 Aug 6, 2026
896943b
fix(responses): fail closed on unsafe terminal repair
baileyh8 Aug 6, 2026
3813c99
fix(responses): preserve terminal repair backpressure
baileyh8 Aug 6, 2026
bf678b1
fix(deepseek): repair terminal-less Responses streams
baileyh8 Aug 6, 2026
2becae4
docs: describe DeepSeek streaming terminal repair
baileyh8 Aug 6, 2026
157c3e4
docs: document DeepSeek Responses streaming
baileyh8 Aug 6, 2026
e7e3877
test(responses): track provider-scoped SSE relay
baileyh8 Aug 6, 2026
243ee6d
docs: design routed computer use and browser support
baileyh8 Aug 9, 2026
c769ef9
docs: clarify routed tool mode scope
baileyh8 Aug 9, 2026
fa17f1b
docs: plan routed computer use and browser support
baileyh8 Aug 9, 2026
30f48a0
test(codex): require code mode for routed models
baileyh8 Aug 9, 2026
f60dd98
fix(codex): enable code mode for routed models
baileyh8 Aug 9, 2026
aa9f11f
test(codex): persist routed code mode policy
baileyh8 Aug 9, 2026
8bb00d3
docs(codex): explain routed local tool access
baileyh8 Aug 9, 2026
e6ad8fb
fix(responses): bridge routed exec custom tools
baileyh8 Aug 9, 2026
f61ed63
fix(responses): address streaming review edge cases
baileyh8 Aug 10, 2026
d20aae4
fix(responses): harden malformed stream repair
baileyh8 Aug 10, 2026
b9b723c
fix(responses): guard late custom tool frames
baileyh8 Aug 10, 2026
da36a30
fix(responses): harden routed custom-tool progressive repair
Wibias Aug 10, 2026
b04ce9f
fix(gui): harden CL-06 CodeRabbit outside-diff findings
Wibias Aug 10, 2026
e7f2cad
fix(gui): allow zero maxEvidenceAgeMs in compatibility editor
Wibias Aug 10, 2026
5ce3198
fix(pr-quality): treat local CI checklist as author attestation
Wibias Aug 10, 2026
aed3262
fix(gui): drop unused parseProfiles binding
Wibias Aug 10, 2026
0968412
fix(pr-quality): address CodeRabbit review on local CI attestation
Wibias Aug 10, 2026
9775e4a
fix(responses): restore DeepSeek streaming and routed code-mode tools…
Wibias Aug 10, 2026
dc56fb4
Merge pull request #1437 from lidge-jun/fix/local-ci-readiness-attest…
Wibias Aug 10, 2026
b66e33c
Merge pull request #1394 from lidge-jun/feat/cl-06-routing-profile-co…
Wibias Aug 10, 2026
831b008
docs(lab): record CL-06 merge via #1394
Wibias Aug 10, 2026
c50bdb5
auth: добавить безопасный импорт аккаунтов Cockpit Tools
agentHits Aug 9, 2026
6f945a5
документация: добавить screenshot импорта Cockpit Tools
agentHits Aug 9, 2026
83c4c5a
auth: укрепить проверку импорта аккаунтов
agentHits Aug 9, 2026
1f2ec70
auth: закрыть замечания ревью импорта
agentHits Aug 9, 2026
af743bc
fix(auth): restore Cockpit import cancel contract after rebase
Wibias Aug 10, 2026
e67532c
fix(auth): address CodeRabbit findings on Cockpit import
Wibias Aug 10, 2026
2d5210c
fix(auth): match import upserts by accountId before email
Wibias Aug 10, 2026
76ca048
fix(auth): upgrade email-only Antigravity rows on Cockpit import
Wibias Aug 10, 2026
c6f0c1c
test(auth): cover CodeRabbit import upsert regressions
Wibias Aug 10, 2026
ed8e079
feat(lab): CL-07 task effectiveness evidence producer
Wibias Aug 10, 2026
5e2ce66
docs(lab): link CL-07 draft PR #1438
Wibias Aug 10, 2026
ae4f4ea
fix(auth): address latest CodeRabbit docs and adapter tests
Wibias Aug 10, 2026
ec275ee
fix(lab): project VERIFIED for fabric task evidence
Wibias Aug 10, 2026
da51af2
Merge pull request #1357 from agentHits/feat/cockpit-tools-account-im…
Wibias Aug 10, 2026
db8e6ab
fix(lab): address CodeRabbit findings for CL-07 fabric producer
Wibias Aug 10, 2026
2f9c151
merge(dev): resolve CL-07 stack-status conflict
Wibias Aug 10, 2026
5dd527c
fix(lab): address second CodeRabbit round for CL-07 fabric producer
Wibias Aug 10, 2026
c420755
test(windows): await proxy teardown before cleanup
luvs01 Aug 10, 2026
bc00433
docs(lab): add JSDoc to CL-07 fabric module for CodeRabbit coverage
Wibias Aug 10, 2026
1689466
fix(lab): address third CodeRabbit round for CL-07 fabric producer
Wibias Aug 10, 2026
fc149b1
test(windows): await proxy teardown before cleanup (#1414)
Wibias Aug 10, 2026
e00a640
fix(lab): address fourth CodeRabbit round for CL-07 fabric producer
Wibias Aug 10, 2026
bdd89e6
Merge pull request #1418 from Bruce-Yii/fix-token-expires-in-guard
Wibias Aug 10, 2026
af11b4e
fix(service): align WSL Codex home ownership
Ingwannu Aug 10, 2026
9edeeaf
fix(lab): address fifth CodeRabbit round for CL-07 fabric producer
Wibias Aug 10, 2026
2416e5e
fix(service): resolve Codex home once in ownership check
Wibias Aug 10, 2026
7b377ce
Merge pull request #1427 from lidge-jun/agent/fix-wsl-service-home
Wibias Aug 10, 2026
006f880
fix(lab): propagate ledger lock metadata write failures immediately
Wibias Aug 10, 2026
9ad1283
feat(providers): add Novita AI preset
olddonkey Aug 8, 2026
f45cefc
fix(lab): reject incomplete ledger lock metadata writes
Wibias Aug 10, 2026
d2cdc68
docs(providers): state Novita model ids must not be rewritten
Wibias Aug 10, 2026
8ab41d3
Merge pull request #1318 from olddonkey/codex/572-novita-model-api
Wibias Aug 10, 2026
34777e6
fix(lab): CL-07 authoritative route execution and terminable producer
Wibias Aug 11, 2026
d17b717
test(lab): expect infrastructure throws only for sandbox verifier cases
Wibias Aug 11, 2026
0a10d0b
fix(lab): close CL-07 producer isolation and persistence gaps
Wibias Aug 11, 2026
e7c6337
test(lab): reproduce infrastructure symlink path alias
Wibias Aug 11, 2026
3596fa5
fix(lab): allow canonical infrastructure aliases above Lab root
Wibias Aug 11, 2026
700303f
test(lab): guard fabric persistence authority boundary
Wibias Aug 11, 2026
26575d0
fix(lab): close fabric persistence authority bypass
Wibias Aug 11, 2026
5607ea5
fix(lab): restore fabric validation error code
Wibias Aug 11, 2026
a060669
fix(lab): scope delayed producer case
Wibias Aug 11, 2026
54e4c4e
fix(lab): simplify exact tree verifier
Wibias Aug 11, 2026
d4defb0
fix(lab): allow default deprecated harness kind
Wibias Aug 11, 2026
24287e7
refactor(lab): derive global secret pattern
Wibias Aug 11, 2026
0efe2c6
fix(lab): surface non-EPIPE producer stdin errors
Wibias Aug 11, 2026
02e62fc
Merge pull request #1438 from lidge-jun/feat/cl-07-task-effectiveness…
Wibias Aug 11, 2026
6be4c23
docs(lab): record CL-07 merge and accepted head from #1438
Wibias Aug 11, 2026
da8ebd3
docs(lab): back up CL-06 merge record and compat-lab tags
Wibias Aug 11, 2026
e4c29f6
fix(ci): reconcile PR from head SHA when the commit-PR index lags
Wibias Aug 11, 2026
793a545
test(ci): cover ambiguous fallback and fail-closed index error
Wibias Aug 11, 2026
1b1d7d9
test(ci): assert the fallback lookup runs in the ambiguous-head case
Wibias Aug 11, 2026
7f4de36
test(ci): prove the ambiguous-head fallback runs pulls.list
Wibias Aug 11, 2026
7779c05
Merge pull request #1445 from Wibias/ci/resolve-pr-fallback
Wibias Aug 11, 2026
593d8c2
fix: recognize Codex Team plans in pool capacity (#1443)
terrytan95 Aug 11, 2026
a4f5321
feat(providers): add Nous Portal (Nous Research) OAuth provider — dev…
Cheurteenyt Aug 11, 2026
dd00784
fix(claude): preserve hosted web search choices (#1428)
Ingwannu Aug 11, 2026
9f545f2
fix: add per-model structured output opt-out (#1424)
Ingwannu Aug 11, 2026
0c17052
fix(collaboration): scope catalog-state guidance to what we can attri…
abhisheksharma2411 Aug 11, 2026
e63de8d
fix(codex): honor split SQLite state homes (#1425)
Ingwannu Aug 11, 2026
e2f7f2b
feat(providers): add the Daybreak alias models to the OpenAI API prov…
lidge-jun Aug 11, 2026
cf44362
fix(catalog): apply providerContextCaps.openai to native OpenAI rows …
Yuxin-Qiao Aug 11, 2026
8716629
docs(providers): table-safe Kiro install pipes in translations; fix l…
Wibias Aug 11, 2026
87e3ff9
refactor(cli): move CLI head dispatch into src/cli/root.ts (#1444)
Wibias Aug 11, 2026
20c5131
Add Traditional Chinese (zh-TW) localization for GUI, README, and doc…
letr1n1ty Aug 11, 2026
38c9b35
refactor(cli): add command registry as single metadata source (#1446)
Wibias Aug 11, 2026
5d8c4fe
refactor(cli): registry-driven command dispatch module (#1451)
Wibias Aug 11, 2026
316f675
refactor(cli): normalize process exit through dispatchCommand (#1455)
Wibias Aug 11, 2026
3759786
refactor(cli): fold internal-dispatch and pin help banner (#1456)
Wibias Aug 11, 2026
9ef7df8
ci: isolate Bun test shards into fresh-process batches (#1469)
Wibias Aug 11, 2026
4e22f98
fix(responses): reject unscoped reasoning replay
luvs01 Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 2 additions & 6 deletions .github/scripts/pr-quality-messages.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -259,14 +259,10 @@ function failureSummary(failures, { pr }) {
}

/** The notice shown when the gate's own claim check disproves a ticked box. */
function buildClaimCheckNotice(violations, liveHeadSha) {
function buildClaimCheckNotice(violations, _liveHeadSha) {
const lines = [];
for (const code of violations) {
if (code === "ci_green") {
lines.push(
`GitHub CI is not green on the current head ${inlineCode(liveHeadSha.slice(0, 7))}; the **CI green** box has been unticked.`
);
} else if (code === "latest_dev") {
if (code === "latest_dev") {
lines.push(
`The PR is more than ${READINESS_LATEST_DEV_BEHIND_MAX} commits behind ${inlineCode("dev")}; the **latest dev** box has been unticked.`
);
Expand Down
20 changes: 9 additions & 11 deletions .github/scripts/pr-quality-messages.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -213,23 +213,21 @@ describe("buildStaleNotice", () => {
});

describe("buildClaimCheckNotice", () => {
it("names each violated claim and the reset action", () => {
it("names the latest-dev violation and the reset action", () => {
const notice = buildClaimCheckNotice(
["ci_green", "latest_dev"],
["latest_dev"],
"3f1c0de0a6a4d0a3f9a1b2c3d4e5f60718293a4b",
);
assert.match(notice[0], /CI is not green on the current head `3f1c0de`/);
assert.match(notice[0], /\*\*CI green\*\* box has been unticked/);
assert.match(notice[1], /more than 10 commits behind `dev`/);
assert.match(notice[1], /\*\*latest dev\*\* box has been unticked/);
assert.match(notice[2], /reset: re-test against the latest code/);
assert.match(notice[0], /more than 10 commits behind `dev`/);
assert.match(notice[0], /\*\*latest dev\*\* box has been unticked/);
assert.match(notice[1], /reset: re-test against the latest code/);
});

it("handles a single violation", () => {
it("ignores a stale ci_green code without inventing GitHub-CI copy", () => {
const notice = buildClaimCheckNotice(["ci_green"], "a".repeat(40));
assert.equal(notice.length, 2);
assert.match(notice[0], /CI is not green/);
assert.match(notice[1], /has been reset/);
assert.equal(notice.length, 1);
assert.match(notice[0], /has been reset/);
assert.doesNotMatch(notice[0], /CI is not green/);
});

it("returns only the reset line for an empty violation list", () => {
Expand Down
18 changes: 8 additions & 10 deletions .github/scripts/pr-quality-state.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -201,23 +201,21 @@ function migrateLegacyGateState(enforcerState, readinessState) {
*/

/**
* Bot-side verification of the two checklist claims the gate can check itself.
* The CI box only holds when the head's `ci` check is green, and the
* latest-dev box only holds while the head is at most
* READINESS_LATEST_DEV_BEHIND_MAX commits behind the base. Unknown state
* (compare or checks lookup failed) fails closed: an unverifiable claim is a
* violation, because an attestation must not ride on missing evidence.
* Bot-side verification of the checklist claim the gate can check itself for
* ancestry. The local-CI box is an author attestation only (fork contributors
* cannot start repository CI; a maintainer has to), so it is never disproved
* here — head-drift still resets every box after a new push. The latest-dev
* box only holds while the head is at most READINESS_LATEST_DEV_BEHIND_MAX
* commits behind the base. Unknown state (compare lookup failed) fails closed:
* an unverifiable claim is a violation, because an attestation must not ride
* on missing evidence.
*/
function readinessClaimViolations({
ciGreen,
behindBase,
behindUnknown = false,
behindMax = READINESS_LATEST_DEV_BEHIND_MAX
}) {
const violations = [];
if (!ciGreen) {
violations.push("ci_green");
}
if (behindUnknown || behindBase > behindMax) {
violations.push("latest_dev");
}
Expand Down
33 changes: 8 additions & 25 deletions .github/scripts/pr-quality-state.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -229,48 +229,31 @@ describe("completionIsStale", () => {
});

describe("readinessClaimViolations", () => {
it("passes when CI is green and the head is current", () => {
assert.deepEqual(
readinessClaimViolations({ ciGreen: true, behindBase: 0 }),
[],
);
assert.deepEqual(
readinessClaimViolations({ ciGreen: true, behindBase: 10 }),
[],
);
it("passes when the head is current enough", () => {
assert.deepEqual(readinessClaimViolations({ behindBase: 0 }), []);
assert.deepEqual(readinessClaimViolations({ behindBase: 10 }), []);
});

it("flags red CI", () => {
it("never treats local CI as a bot-verifiable claim", () => {
// Fork contributors attest local green; repository CI is maintainer-started.
assert.deepEqual(
readinessClaimViolations({ ciGreen: false, behindBase: 0 }),
["ci_green"],
readinessClaimViolations({ behindBase: 0, ciGreen: false }),
[],
);
});

it("flags a head more than the threshold behind the base", () => {
assert.deepEqual(
readinessClaimViolations({
ciGreen: true,
behindBase: READINESS_LATEST_DEV_BEHIND_MAX + 1,
}),
["latest_dev"],
);
});

it("flags both when both claims fail", () => {
assert.deepEqual(
readinessClaimViolations({
ciGreen: false,
behindBase: READINESS_LATEST_DEV_BEHIND_MAX + 20,
}),
["ci_green", "latest_dev"],
);
});

it("fails closed when the behind count is unknown", () => {
assert.deepEqual(
readinessClaimViolations({
ciGreen: true,
behindBase: 0,
behindUnknown: true,
}),
Expand All @@ -280,7 +263,7 @@ describe("readinessClaimViolations", () => {

it("honours a custom threshold", () => {
assert.deepEqual(
readinessClaimViolations({ ciGreen: true, behindBase: 5, behindMax: 4 }),
readinessClaimViolations({ behindBase: 5, behindMax: 4 }),
["latest_dev"],
);
});
Expand Down
7 changes: 4 additions & 3 deletions .github/scripts/pr-quality.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ const REVIEW_READINESS_ITEMS = [

/**
* Which checklist box each bot-verifiable claim maps to. The order must stay
* in sync with REVIEW_READINESS_ITEMS: index 0 is the CI claim, index 1 is
* the latest-dev claim, and index 2 is the Codex/CodeRabbit findings claim.
* in sync with REVIEW_READINESS_ITEMS: index 1 is the latest-dev claim and
* index 2 is the Codex/CodeRabbit findings claim. Index 0 (local CI) is an
* author attestation only — fork contributors cannot start repository CI — so
* the gate never disproves it; head-drift still resets every box.
*/
const REVIEW_READINESS_CLAIM_INDEX = {
ci_green: 0,
latest_dev: 1,
review_findings: 2
};
Expand Down
8 changes: 4 additions & 4 deletions .github/scripts/pr-quality.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -586,16 +586,16 @@ describe("uncheckReviewReadinessBoxes", () => {

it("unchecks only the requested boxes", () => {
const body = uncheckReviewReadinessBoxes(checkedBody, [
REVIEW_READINESS_CLAIM_INDEX.ci_green,
REVIEW_READINESS_CLAIM_INDEX.latest_dev,
]);
assert.ok(body.includes("- [ ] All CI tests are green on my local testing."));
assert.ok(body.includes("- [x] I pushed my PR to the latest dev commit."));
assert.ok(body.includes("- [x] All CI tests are green on my local testing."));
assert.ok(body.includes("- [ ] I pushed my PR to the latest dev commit."));
assert.ok(body.includes("- [x] My PR is ready for review."));
});

it("can uncheck several boxes at once", () => {
const body = uncheckReviewReadinessBoxes(checkedBody, [
REVIEW_READINESS_CLAIM_INDEX.ci_green,
0,
REVIEW_READINESS_CLAIM_INDEX.latest_dev,
]);
assert.ok(body.includes("- [ ] All CI tests are green on my local testing."));
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,10 @@ jobs:

# The suite, split by file across four Linux runners.
#
# `bun test --shard=i/N` sorts test files by path and deals them round-robin,
# so the split is deterministic for the files that remain in this lane.
# `scripts/ci/run-bun-test-batches.sh` mirrors Bun's sorted round-robin shard
# assignment, then runs each shard in small batches so every batch gets a fresh
# Bun process. The helper prints the exact files before each batch and retries
# only a Bun runtime crash once; ordinary test failures are never retried.
# Storage-policy API tests and api-usage are deliberately excluded here and run
# in dedicated jobs below. Bun 1.3.14 can corrupt the Linux isolate/epoll state
# around those Worker-heavy harnesses; keeping them out of the general shards
Expand Down Expand Up @@ -293,11 +295,13 @@ jobs:
cd gui
bun run build

- name: Test
run: bun test --isolate tests --path-ignore-patterns 'tests/api-storage-policy*.test.ts' --path-ignore-patterns 'tests/api-usage.test.ts' --shard=${{ matrix.shard }}/4
- name: Test in fresh-process batches
env:
TEST_SHARD: ${{ matrix.shard }}/4
run: bash scripts/ci/run-bun-test-batches.sh "$TEST_SHARD"

# Bun 1.3.14 has shown a Linux isolate/epoll race around the storage-policy
# harness. Keep the entire five-file family in one fresh process so a runtime
# harness. Keep the entire six-file family in one fresh process so a runtime
# failure is bounded to this job instead of poisoning a general test shard.
storage-policy:
name: storage policy
Expand Down Expand Up @@ -334,7 +338,8 @@ jobs:
./tests/api-storage-policy-mutation-busy.test.ts \
./tests/api-storage-policy-put-race.test.ts \
./tests/api-storage-policy-run.test.ts \
./tests/api-storage-policy.test.ts
./tests/api-storage-policy.test.ts \
./tests/api-storage.test.ts

# Bun 1.3.14 has shown a Linux isolate wedge around startServer() plus the user
# cost overlay reconciler. Keep api-usage in one fresh process so a runtime
Expand Down
124 changes: 60 additions & 64 deletions .github/workflows/enforce-pr-target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,56 @@ jobs:
}

const statusSha = context.payload.sha;
const associatedPrs = await github.paginate(
github.rest.repos.listPullRequestsAssociatedWithCommit,
{ owner, repo, commit_sha: statusSha, per_page: 100 }
);
const candidates = associatedPrs.filter(
candidate =>
candidate.state === "open" &&
candidate.head?.sha === statusSha
);
// Primary authority: GitHub's commit-to-PR index. This read can
// lag a fresh head push, so a non-match is not proof of absence.
let candidates = [];
try {
const associatedPrs = await github.paginate(
github.rest.repos.listPullRequestsAssociatedWithCommit,
{ owner, repo, commit_sha: statusSha, per_page: 100 }
);
candidates = associatedPrs.filter(
candidate =>
candidate.state === "open" &&
candidate.head?.sha === statusSha
);
} catch (error) {
core.warning(
`Could not list PRs associated with commit ${statusSha}: ${error.message}`
);
}

if (candidates.length !== 1) {
// Fallback: reconcile directly against the live head SHA. The
// association index can be stale or empty for a very recent
// head (seen on PR #1441), so an empty/ambiguous index result
// must not silently drop the revalidation. Matching on the
// head SHA is the same authoritative identity the write gate
// uses, and `pulls.list` is a read — compatible with this
// job's `pull-requests: read` permission.
const priorCount = candidates.length;
try {
const openPrs = await github.paginate(github.rest.pulls.list, {
owner,
repo,
state: "open",
per_page: 100
});
candidates = openPrs.filter(
pr =>
pr.state === "open" &&
pr.head?.sha === statusSha
);
core.info(
`Associated-index fallback: ${priorCount} index match(es), ${candidates.length} open PR(s) match head ${statusSha}.`
);
} catch (error) {
core.warning(
`Could not list open PRs for head-${statusSha} fallback: ${error.message}`
);
}
}

if (candidates.length !== 1) {
core.info(
`CodeRabbit status ${statusSha} maps to ${candidates.length} open current-head PRs; skipping ambiguous/stale revalidation.`
Expand All @@ -99,10 +140,8 @@ jobs:
needs: resolve-pr
if: needs.resolve-pr.outputs.pull-number != ''
runs-on: ubuntu-latest
# The write job also reads the current head's aggregate check evidence.
# Job-scoped permissions replace, rather than extend, the workflow default.
permissions:
checks: read
contents: write
pull-requests: write
concurrency:
Expand Down Expand Up @@ -802,14 +841,16 @@ jobs:
checklistComplete = readiness.present && readiness.complete;
}

// The bot verifies the three checklist claims it can check itself.
// The CI box only counts when the head's `ci` check (the repo's
// documented "CI passed" signal) is green; the latest-dev box only
// counts while the head is at most READINESS_LATEST_DEV_BEHIND_MAX
// commits behind the base; the findings box only counts while every
// Codex/CodeRabbit review thread on the PR is resolved. A disproved
// claim unchecks that box and keeps the PR a draft, exactly like a
// head-drift reset.
// The bot verifies the checklist claims it can check itself. The
// local-CI box is an author attestation only — fork contributors
// cannot start repository CI (a maintainer has to) — so the gate
// never disproves it; head-drift still resets every box after a
// new push. The latest-dev box only counts while the head is at
// most READINESS_LATEST_DEV_BEHIND_MAX commits behind the base;
// the findings box only counts while every Codex/CodeRabbit
// review thread on the PR is resolved. A disproved claim unchecks
// that box and keeps the PR a draft, exactly like a head-drift
// reset.
let claimViolations = [];
let claimNotice = [];
if (
Expand All @@ -818,52 +859,7 @@ jobs:
!headDrifted &&
failures.length === 0
) {
let ciGreen = false;
try {
// GitHub Actions' immutable App ID. Name alone is not evidence:
// any installed app can publish a check called `ci`.
const githubActionsAppId = 15368;
const { data: checksData } =
await github.rest.checks.listForRef({
owner,
repo,
ref: pr.head.sha,
app_id: githubActionsAppId,
check_name: "ci",
filter: "latest",
per_page: 100
});
const checkRuns = Array.isArray(checksData.check_runs)
? checksData.check_runs
: [];
const ciChecks = checkRuns.filter(
check =>
check.name === "ci" &&
check.app?.id === githubActionsAppId
);
// The readiness claim requires positive CI evidence. A missing,
// pending, unsuccessful, foreign, or conflicting aggregate
// check must fail closed. The exact app/name/latest query should
// be tiny; if GitHub reports more rows than this response holds,
// treat the truncated evidence as unreadable rather than paging
// through an endpoint whose filters already select the latest run.
ciGreen =
Number.isSafeInteger(checksData.total_count) &&
checksData.total_count === checkRuns.length &&
ciChecks.length > 0 &&
ciChecks.every(
check =>
check.status === "completed" &&
check.conclusion === "success"
);
} catch (error) {
core.warning(
`Could not list checks for the readiness claim check: ${error.message}`
);
ciGreen = false;
}
claimViolations = readinessClaimViolations({
ciGreen,
behindBase,
behindUnknown: ancestryLookupFailed
});
Expand Down
Loading
Loading