Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
9534c0c
fix(coding-agent): launch native Windows CLIs and refuse empty-arg-dr…
lidge-jun Oct 23, 2026
c4d4bb2
docs(providers): qualify Qoder native executable precedence across PA…
lidge-jun Oct 23, 2026
306a88e
chore(release): open dev at 2.93.0 before releasing 2.92.0 (#7633)
github-actions[bot] Oct 23, 2026
93911e5
fix(deps): pin zod 4.6.6 and body-parser 2.4.0 for audit:high (#7642)
lidge-jun Oct 23, 2026
2494848
fix(deps): bump gui happy-dom to 21.0.4 for GHSA-834v-8h66-3h79 (#7644)
lidge-jun Oct 24, 2026
ceef488
test: settle Windows ACL work and owner locks before fixture removal …
lidge-jun Oct 24, 2026
43f872f
test: make codex-runtime, client-connect and loopback-listener tests …
lidge-jun Oct 24, 2026
bd5c2ea
test: keep cold first-exec and PowerShell start out of two timed case…
lidge-jun Oct 24, 2026
46f23ca
feat(usage): price and seed Kimi K3.1 Pro on Kimi Code and Moonshot (…
lidge-jun Oct 24, 2026
4731614
ci: run docker/keyring smoke and React Doctor on PRs only when their …
lidge-jun Oct 24, 2026
5253164
fix(qoder): provider-only catalog, replay-envelope refusal and isolat…
lidge-jun Oct 24, 2026
8066099
fix(codex): list pool accounts without a native home and expose safe …
lidge-jun Oct 24, 2026
e8ff1b2
docs: align localized Mistral and OpenGateway provider guidance (#7646)
lidge-jun Oct 24, 2026
e01c5a7
fix(command-code): rotate on insufficient-credit refusals (#7558)
lidge-jun Oct 24, 2026
a564487
fix(codex): calibrate Business Premium display capacity (#7557)
lidge-jun Oct 24, 2026
3decf65
fix(fallback): check the first hard-lock profile destination (#7589)
luvs01 Oct 24, 2026
af8cd35
fix(service): bind ownership lease release to its acquisition (#7543)
luvs01 Oct 24, 2026
c5ba1e1
test(server): isolate agent-task-recovery fixtures (#7613) (#7649)
lidge-jun Oct 24, 2026
a033a1a
fix(gui): cancel Remote Link sheet focus work (#7611) (#7650)
lidge-jun Oct 24, 2026
047c5dc
feat(gui): expose JEV session pin in Combo editor (#7664)
lidge-jun Oct 24, 2026
4e2940e
fix(deps): patch Hono and ip-address advisories and align qs (#7647)
lidge-jun Oct 24, 2026
71be051
fix(windows): resolve ACL principal natively without cold PowerShell …
lidge-jun Oct 24, 2026
e9df82c
fix(codex): preserve sync edits with canonical sandbox checks (#7659)
lidge-jun Oct 24, 2026
488d5f1
fix(link): keep a connected client's integrations across ocx stop; st…
lidge-jun Oct 24, 2026
68f2669
docs(getting-started): align Korean installation guide with Bun 1.4.4…
mvanhorn Oct 24, 2026
6426c42
fix(codex): keep a role's model when auto-assign finds an equal-price…
LilMGenius Oct 24, 2026
8aa8206
fix(codex): validate subagent limit boundaries before writes (#7276)
luvs01 Oct 24, 2026
8d7a35f
fix(chat): isolate Anthropic reasoning state from native passthrough …
luvs01 Oct 24, 2026
071b4d9
perf(eventstream): use Bun native CRC32 for Kiro frame validation (#7…
luvs01 Oct 24, 2026
0aeaf0c
fix(i18n): complete Turkish dashboard copy and documentation (#7565)
ardakrt Oct 24, 2026
9d74a73
docs: point ADR-7517 to its Qoder contract owner (#7686)
luvs01 Oct 24, 2026
d0a8443
perf(responses): avoid input Buffer copies in gzip requests (#7671)
luvs01 Oct 24, 2026
26598df
perf(streams): retain a bounded SSE field prefix during fragmented re…
luvs01 Oct 24, 2026
d891cac
fix(ci): wake the PR gate when attribution-approved is applied (#7698)
lidge-jun Oct 24, 2026
f0bf610
feat(providers): seed Kimi K3.1 Pro on the Moonshot API preset (#7695)
lidge-jun Oct 24, 2026
5ab431b
fix(kiro): fail over accounts when overage quota is exhausted (#7687)
martinbcg Oct 24, 2026
0929e6e
chore(test): align Bun runner with the 1.4.4 security baseline (#7627)
luvs01 Oct 25, 2026
79b4964
fix(codex): detect LazyCodex installed from the marketplace (#7692)
LilMGenius Oct 25, 2026
c2bcb52
fix(command-code): answer MODEL_NOT_IN_PLAN once as a model-scoped 40…
lidge-jun Oct 25, 2026
6269f5c
fix(ci): bind exception approval labels to the evaluated head (#7699)
lidge-jun Oct 25, 2026
f87a321
fix(runtime): release detached sweep hooks and preserve replacement t…
luvs01 Oct 25, 2026
5d995c9
perf(usage): bound timeline aggregation scratch memory and avoid argu…
luvs01 Oct 25, 2026
5b71daf
perf(codex): validate audit UTF-8 without round-trip Buffer copies (#…
luvs01 Oct 25, 2026
2296a7b
fix(remote-workspace): observe Pi prompt failures before acknowledgem…
luvs01 Oct 25, 2026
3d4d3e0
perf(eventstream): avoid quadratic copying of fragmented frames (#7673)
luvs01 Oct 25, 2026
323a5e1
perf(responses): coalesce queued thought-signature snapshot writes (#…
luvs01 Oct 25, 2026
ac65aa7
fix(quota): bound snapshot persistence under sustained updates (#7666)
luvs01 Oct 25, 2026
6728882
perf(history): skip unchanged partial-tail reads and SQLite metadata …
luvs01 Oct 25, 2026
c203c86
fix(routing): inspect hard-lock fallback without selecting candidates…
luvs01 Oct 25, 2026
6672cfb
fix(transport): honor backpressure in pinned HTTP responses (#7667)
luvs01 Oct 25, 2026
959a07a
feat(sync): ocx sync --expect-link / --expect-hub-key refuses a diffe…
lidge-jun Oct 25, 2026
a589dde
fix(ci): select Docker smoke for actual image build inputs (#7689)
luvs01 Oct 25, 2026
4049f40
fix(responses): preserve gateway citations during native compact (#7682)
luvs01 Oct 25, 2026
9b56622
perf(adapters): use native SHA-256 for tool identity digests (#7670)
luvs01 Oct 25, 2026
50afcec
perf(socks5): bound upload waiters and release completed read results…
luvs01 Oct 25, 2026
6fc3c88
feat(integrations): connect named Hermes profiles (#7674) (#7700)
lidge-jun Oct 25, 2026
7b0e4ab
fix(socks5): deliver partial response payloads promptly and release t…
luvs01 Oct 25, 2026
8ebe46b
perf(proxy): bound CONNECT header buffering and avoid repeated prefix…
luvs01 Oct 25, 2026
88f7a77
fix(protocols): account for Antigravity direct Chat IR (#7724)
luvs01 Oct 26, 2026
bf0d80c
fix(claude): classify legacy desktop aliases on cold launch (#7721)
luvs01 Oct 26, 2026
ef386eb
fix(scripts): detect diagnostic spawn timeout via exitedDueToTimeout …
luvs01 Oct 26, 2026
d056f84
test(server): isolate port reclaim fixture identity and clock (#7706)
luvs01 Oct 26, 2026
ea48448
fix(management): declare Hermes profile route (#7729)
luvs01 Oct 26, 2026
01ec325
fix(config): preserve disabled sidecars when targets retire (#7420)
luvs01 Oct 26, 2026
14fa422
fix(meta): preserve destinations when refreshing saved model rosters …
luvs01 Oct 26, 2026
0eb8cd0
fix(cursor): use Bun glob matching for native grep (#7630)
luvs01 Oct 26, 2026
8e18e60
test(launcher): copy only Node launcher modules into runtime selectio…
luvs01 Oct 26, 2026
88c17bc
fix(responses): notice a Codex WebSocket that dies after the response…
FredAmartey Oct 26, 2026
c2f3d8b
fix(codex): clamp native efforts to selected model ladder (#7731)
Plamyth Oct 26, 2026
8dd330a
fix(link): preserve literal SSH include names on Bun 1.4.4 (#7629)
luvs01 Oct 26, 2026
2971af8
feat(combos): add opt-in cooldown recovery with configurable interval…
artur-safonov Oct 26, 2026
415078c
test(cli): let the forged sibling-env start bind its own port (#7740)
lidge-jun Oct 26, 2026
833a804
fix(launcher): enforce the pinned Bun patch floor for PATH fallback (…
luvs01 Oct 26, 2026
852bf9d
fix(responses): bound closing handshakes for non-reused upstream WebS…
lidge-jun Oct 26, 2026
bada676
fix(desktop): bind usage trials to fresh package proof (#7709)
luvs01 Oct 26, 2026
1db7b61
fix(chat): fail unmet required client tool completions (#7463)
Ingwannu Oct 26, 2026
66e0892
fix(ci): verify installer signature before administrative extraction …
luvs01 Oct 26, 2026
dc49f32
fix(service): preserve Windows probe support across Node and Bun (#7722)
luvs01 Oct 26, 2026
3b4e04a
fix(test): bind and serialize queue lock ownership (#7508)
luvs01 Oct 26, 2026
2d8463a
fix(usage): retain Kiro prompt estimates in hosted tool paths (#7744)
lidge-jun Oct 26, 2026
820234b
fix(router): support Vercel JEV decisions and thinking model reasonin…
omar391 Oct 26, 2026
48b77ee
fix(update): join the Windows npm tree before stage cleanup (#7751)
lidge-jun Oct 26, 2026
8a3be77
fix(deepseek): restore official V4 Pro availability (#7591)
norths7ar Oct 26, 2026
daec176
fix(live): bound WebSocket close without releasing live ownership (#7…
luvs01 Oct 26, 2026
5c588f2
fix(runtime): bypass proxy environment for local stop requests (#7754)
lidge-jun Oct 26, 2026
9d15527
feat(codex): expose opt-in Flex tier for eligible routed models (#7534)
Transient-Onlooker Oct 26, 2026
162beb3
fix(anthropic): preserve cache prefixes during routed compaction (#7749)
lidge-jun Oct 26, 2026
609ce90
fix(minimax): move to GA MiniMax-M3.1-Flash and rename the retired pr…
lidge-jun Oct 26, 2026
b8ba848
feat(clients): connect Qoder CN and WorkBuddy desktop editions (#7665)
Flowershangfromthebranches Oct 26, 2026
816e84b
fix(combo): reject buffered required-tool false successes (#7741)
lidge-jun Oct 26, 2026
81ce595
fix(update): keep Codex routing for the restarted proxy during an upd…
lidge-jun Oct 26, 2026
a3e2214
fix(codex): renew credit evidence for namespace-bound Direct accounts…
Caledvwlch Oct 26, 2026
d610ccc
fix(reasoning): separate support, thinking toggles and effort control…
norths7ar Oct 26, 2026
9a61bd9
fix(codex): fence uncertain catalog entry identity (#7610)
luvs01 Oct 26, 2026
911ad9f
fix(live): keep sideband admission until the upstream closes after cl…
lidge-jun Oct 26, 2026
0f642c4
fix(codex): preserve credit recovery retry hints and scoped cooldowns…
Caledvwlch Oct 26, 2026
9e48f78
feat(providers): add AI Stupid Level API-key preset (#7623)
StudioPlatforms Oct 26, 2026
4111e93
fix(claude): drain parent ACL flights before intercept secret writes …
lidge-jun Oct 27, 2026
19b7f19
fix(config): skip optional hardening for non-directory homes (#7688)
luvs01 Oct 27, 2026
1de2b71
ci: run import-graph tests on pull requests and verify merged batches…
lidge-jun Oct 27, 2026
2606f6f
feat(models): add GPT-6.1 Terra alongside GPT-5.6 Terra (non-Cursor p…
lidge-jun Oct 27, 2026
6a87fea
release: promote frozen tip 2606f6f922d6c897836f4aafc0910f46293e5786 …
lidge-jun Oct 27, 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
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/actions/setup-project-bun/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ description: >-
# (#6713 run 37631558263: Linux 1/4, macOS 2/2, Windows 9/9). It moved from 1.4.0 to
# 1.4.3 for oven-sh/bun#44581: 1.4.0's Bun.spawnSync could lose a child's exit after
# finalizers ran inside an earlier call and spin past its own timeout (#4956).
# Rejoin only after the upstream runner crash is fixed and a green lane=all
# dispatch proves the unified version; then delete testRunnerBun and this role input.
# Both roles now default to the package's 1.4.4 security transition, retaining role validation.
# Promotion requires a green full cross-platform lane=all run on the exact candidate head.
inputs:
role:
description: Bun role to install (runtime or test-runner).
Expand Down
4 changes: 3 additions & 1 deletion .github/scripts/enforce-pr-target.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ describe("enforce-pr-target workflow", () => {

it("writes exactly one consolidated comment via a single upsert helper", () => {
assert.match(workflow, /GATE_MARKER,/);
assert.match(workflow, /comment\.body\?\.includes\(GATE_MARKER\)/);
// The gate comment is the bot comment that starts with GATE_MARKER; a
// marker echoed inside another comment does not classify it.
assert.match(workflow, /comments\.find\(isGateComment\)/);
assert.match(workflow, /upsertGateComment/);
assert.match(workflow, /buildGateCommentBody/);
// No legacy two-comment write path remains.
Expand Down
110 changes: 110 additions & 0 deletions .github/scripts/pr-hygiene.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,109 @@ const HYGIENE_GATE_LABELS = [
"attribution-approved",
];

/**
* Exception approvals vouch for one revision of the change. Each counts only
* while the head the hygiene workflow last recorded is still the head being
* evaluated and nothing has rewritten the branch since. Sponsorship
* (`maintainer-sponsored`) is about which surfaces change, not about one
* revision, so it is not head-bound.
*/
const HEAD_BOUND_APPROVAL_LABELS = [
"test-exception-approved",
"suppression-approved",
"generated-change-approved",
"dependency-change-approved",
"attribution-approved",
];

/** Issue events after which the head can point at an earlier commit again. */
const HEAD_REWRITE_EVENTS = ["head_ref_force_pushed", "head_ref_restored"];

const APPROVAL_RECORD_TOKEN = "pr-hygiene-approvals";
const APPROVAL_RECORD_LINE = /^<!-- pr-hygiene-approvals (\{.*\}) -->$/;
const FULL_SHA = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;

function isRewriteCount(value) {
return Number.isSafeInteger(value) && value >= 0;
}

/**
* Read the head binding the hygiene workflow wrote as the last line of its
* own section. The token must occur exactly once in `source` and sit on that
* last line, so echoed text (a changed path can contain newlines) can only
* make the record unreadable, never stand in for it.
* @returns {{ head: string, headRewrites: number | null } | null}
*/
function parseApprovalRecord(source) {
if (typeof source !== "string") return null;
if (source.split(APPROVAL_RECORD_TOKEN).length !== 2) return null;
const lines = source.split("\n").map((line) => line.trim()).filter(Boolean);
const match = lines.at(-1)?.match(APPROVAL_RECORD_LINE);
if (!match) return null;
let value;
try {
value = JSON.parse(match[1]);
} catch {
return null;
}
if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
if (Object.keys(value).sort().join(",") !== "head,headRewrites") return null;
if (typeof value.head !== "string" || !FULL_SHA.test(value.head)) return null;
if (value.headRewrites !== null && !isRewriteCount(value.headRewrites)) return null;
return { head: value.head, headRewrites: value.headRewrites };
}

/** `headRewrites` is null when the history read failed: nothing is confirmed. */
function formatApprovalRecord({ head, headRewrites }) {
const value = { head, headRewrites: isRewriteCount(headRewrites) ? headRewrites : null };
return "<!-- " + APPROVAL_RECORD_TOKEN + " " + JSON.stringify(value) + " -->";
}

function countHeadRewrites(events) {
return (events ?? []).filter((entry) => HEAD_REWRITE_EVENTS.includes(entry?.event)).length;
}

function presentHeadBoundApprovals(labels) {
return HEAD_BOUND_APPROVAL_LABELS.filter((label) => labels.includes(label));
}

/** True when a current rewrite count could still confirm an approval. */
function needsHeadRewriteCount({ labels = [], headSha, record = null, eventAction }) {
return (
eventAction !== "synchronize" &&
record !== null &&
record.head === headSha &&
isRewriteCount(record.headRewrites) &&
presentHeadBoundApprovals(labels).length > 0
);
}

/**
* Split the head-bound approvals on the pull request into the ones that still
* describe the evaluated head and the ones that do not. They are kept only
* when the last recorded evaluation saw this same head and the rewrite count,
* read before that evaluation's snapshot and again after this one's, has not
* changed. Without a rewrite, fast-forward pushes cannot bring the recorded
* head back, so the head has not moved since that evaluation, which removed
* every approval it could not confirm. A synchronize event, a missing record,
* or an unknown count confirms nothing.
* @returns {{ kept: string[], stale: string[] }}
*/
function reconcileHeadBoundApprovals({
labels = [],
headSha,
record = null,
eventAction,
headRewriteCount = null,
}) {
const present = presentHeadBoundApprovals(labels);
const current =
needsHeadRewriteCount({ labels, headSha, record, eventAction }) &&
isRewriteCount(headRewriteCount) &&
headRewriteCount === record.headRewrites;
return current ? { kept: present, stale: [] } : { kept: [], stale: present };
}

/**
* Combine patch-hygiene and sponsored-surface failures into one list so the
* hygiene workflow and the PR quality gate cannot disagree about Ready.
Expand Down Expand Up @@ -340,13 +443,20 @@ module.exports = {
addedLines,
assessHygiene,
collectDeterministicHygieneFailures,
countHeadRewrites,
formatApprovalRecord,
HEAD_BOUND_APPROVAL_LABELS,
HEAD_REWRITE_EVENTS,
HYGIENE_FAILURE_HINTS,
HYGIENE_GATE_LABELS,
hasEmptyCatch,
hasDeletions,
isBehaviorPath,
isGeneratedPath,
isTestPath,
needsHeadRewriteCount,
parseApprovalRecord,
reconcileHeadBoundApprovals,
resultLines,
resultLinesByHunk,
};
103 changes: 103 additions & 0 deletions .github/scripts/pr-hygiene.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ const {
addedLines,
assessHygiene,
collectDeterministicHygieneFailures,
countHeadRewrites,
formatApprovalRecord,
HEAD_BOUND_APPROVAL_LABELS,
HYGIENE_FAILURE_HINTS,
HYGIENE_GATE_LABELS,
hasEmptyCatch,
needsHeadRewriteCount,
parseApprovalRecord,
reconcileHeadBoundApprovals,
resultLines,
resultLinesByHunk,
} = require("./pr-hygiene.cjs");
Expand Down Expand Up @@ -391,3 +397,100 @@ describe("pr-hygiene workflow trust boundary", () => {
);
});
});

describe("head-bound approvals", () => {
const HEAD = "c".repeat(40);
const OTHER = "d".repeat(40);
const record = (head, headRewrites) =>
"<!-- pr-hygiene-approvals " + JSON.stringify({ head, headRewrites }) + " -->";

it("covers exactly the exception approvals, not sponsorship", () => {
assert.deepEqual(
[...HEAD_BOUND_APPROVAL_LABELS].sort(),
HYGIENE_GATE_LABELS.filter(
(label) => label !== "intake: hygiene-blocked" && label !== "maintainer-sponsored",
).sort(),
);
});

it("round-trips a record, including an unknown rewrite count", () => {
const line = formatApprovalRecord({ head: HEAD, headRewrites: 2 });
assert.equal(line, record(HEAD, 2));
assert.deepEqual(parseApprovalRecord("status\n\n" + line), { head: HEAD, headRewrites: 2 });
assert.deepEqual(parseApprovalRecord(formatApprovalRecord({ head: HEAD, headRewrites: undefined })), {
head: HEAD,
headRewrites: null,
});
assert.deepEqual(parseApprovalRecord(record("e".repeat(64), 0)), { head: "e".repeat(64), headRewrites: 0 });
});

it("rejects anything but one well-formed record on the last line", () => {
for (const source of [
null,
"",
record(HEAD, 0) + "\nlater line",
record(HEAD, 0) + "\n" + record(HEAD, 0),
"mentions pr-hygiene-approvals elsewhere\n" + record(HEAD, 0),
"<!-- pr-hygiene-approvals {not json} -->",
"<!-- pr-hygiene-approvals " + JSON.stringify({ head: HEAD, headRewrites: 0, approvals: [] }) + " -->",
"<!-- pr-hygiene-approvals " + JSON.stringify({ head: HEAD }) + " -->",
"<!-- pr-hygiene-approvals [1] -->",
record("abc", 0),
record(HEAD.toUpperCase(), 0),
record(HEAD, -1),
record(HEAD, 1.5),
record(HEAD, "1"),
]) {
assert.equal(parseApprovalRecord(source), null, String(source));
}
});

it("counts only head rewrite events", () => {
assert.equal(
countHeadRewrites([
{ event: "head_ref_force_pushed" },
{ event: "labeled" },
{ event: "head_ref_restored" },
null,
]),
2,
);
assert.equal(countHeadRewrites(undefined), 0);
});

it("keeps approvals only under an unchanged head and rewrite count", () => {
const labels = ["test-exception-approved", "maintainer-sponsored"];
const base = { labels, headSha: HEAD, record: { head: HEAD, headRewrites: 1 }, eventAction: "edited" };
const kept = { kept: ["test-exception-approved"], stale: [] };
const stale = { kept: [], stale: ["test-exception-approved"] };
assert.deepEqual(reconcileHeadBoundApprovals({ ...base, headRewriteCount: 1 }), kept);
assert.deepEqual(reconcileHeadBoundApprovals({ ...base, headRewriteCount: 2 }), stale);
assert.deepEqual(reconcileHeadBoundApprovals({ ...base, headRewriteCount: null }), stale);
assert.deepEqual(reconcileHeadBoundApprovals({ ...base, headRewriteCount: 1, eventAction: "synchronize" }), stale);
assert.deepEqual(reconcileHeadBoundApprovals({ ...base, headRewriteCount: 1, headSha: OTHER }), stale);
assert.deepEqual(reconcileHeadBoundApprovals({ ...base, headRewriteCount: 1, record: null }), stale);
assert.deepEqual(
reconcileHeadBoundApprovals({ ...base, headRewriteCount: 1, record: { head: HEAD, headRewrites: null } }),
stale,
);
assert.deepEqual(
reconcileHeadBoundApprovals({ ...base, labels: ["maintainer-sponsored"], headRewriteCount: 1 }),
{ kept: [], stale: [] },
);
});

it("asks for a rewrite count only when one could confirm an approval", () => {
const base = {
labels: ["suppression-approved"],
headSha: HEAD,
record: { head: HEAD, headRewrites: 0 },
eventAction: "labeled",
};
assert.equal(needsHeadRewriteCount(base), true);
assert.equal(needsHeadRewriteCount({ ...base, labels: [] }), false);
assert.equal(needsHeadRewriteCount({ ...base, eventAction: "synchronize" }), false);
assert.equal(needsHeadRewriteCount({ ...base, headSha: OTHER }), false);
assert.equal(needsHeadRewriteCount({ ...base, record: null }), false);
assert.equal(needsHeadRewriteCount({ ...base, record: { head: HEAD, headRewrites: null } }), false);
});
});
Loading
Loading