Skip to content

sync: upstream v2.50.0 (2d4d7a223) into dev - #330

Draft
cursor[bot] wants to merge 343 commits into
devfrom
sync/upstream-v2.50.0-2d4d7a22381a-785424295fc5
Draft

sync: upstream v2.50.0 (2d4d7a223) into dev#330
cursor[bot] wants to merge 343 commits into
devfrom
sync/upstream-v2.50.0-2d4d7a22381a-785424295fc5

Conversation

@cursor

@cursor cursor Bot commented Sep 10, 2026

Copy link
Copy Markdown

Summary

Merge upstream release v2.50.0 (2d4d7a22381a2e497c2442902104619e25f937c7) into origin/dev (785424295fc5d8ef0a66fb8ce94a55fe3b054471).

The fork sync Action stopped at decision-handoff after 42 textual conflicts. This coordinator branch resolves them per docs/fork/OWNED.md, re-applies fork preservation deltas, and leaves a draft PR for human merge (no squash/rebase).

Provenance

  • Upstream tag: v2.50.0
  • Upstream SHA: 2d4d7a22381a2e497c2442902104619e25f937c7
  • Base (origin/dev): 785424295fc5d8ef0a66fb8ce94a55fe3b054471
  • Published head: d86db7996bfe4df9bf036e184312bf9b3e93a7b5

Conflict decision table

File / hunk Upstream intent Fork / overlay intent Class Disposition Recommendation Tests
package.json (version, scripts, identity) v2.50.0 metadata and dependency surface Keep @yansigit/opencodex name, non-decreasing semver, fork prepush/audit:high scripts recipe mergePackageJson recipe Take upstream fields; preserve fork name/version policy bun run typecheck
bun.lock Upstream lock resolution Regenerate after recipe merge upstream-owned + lockfile rule take upstream then bun install Accept upstream lock, reinstall bun install
38 upstream-owned paths (GUI, docs, readme locales, tests, server routes, src/codex/quota.ts, etc.) v2.50.0 behavior and tests No fork-owned deltas required on these paths upstream-owned take upstream (--theirs) Accept upstream control flow domain tests per path below
src/server/responses/core.ts imports (enrichOpenCodeZen*, web-search bridge) Upstream renamed rate-limit helper; added passthrough web-search bridge imports Fork retains googleProviderOptionsRouteError, mediaBridgeWillRun, resolveCcaInTurnGrounding shared-hotspot manual merge Upstream helper name + upstream bridge imports + fork google/CCA imports bun test tests/responses/responses-context-overflow.test.ts
core.ts shadow intercept credentialDomainWasRewritten models auth-domain rewrite shadowIntercepted feeds V2 bridge admission logging shared-hotspot manual merge Set both flags on intercept bun test tests/codex-integration/multi-agent-compat.test.ts
core.ts passthrough SSE body Terminal repair on upstreamSseBody V2 routed delegation SSE rewrite before tee/inspect shared-hotspot manual merge Upstream upstreamSseBody else branch + fork normalizedPassthroughSseBody rewrite bun test tests/server/server-xai-responses-streaming.test.ts
core.ts passthrough remember Unconditional remember on raw text incl. model Guarded remember when callback exists shared-hotspot manual merge Keep upstream text/model shape behind fork guard bun test tests/responses/responses-context-overflow.test.ts
src/usage/log.ts Add transportPhase / terminalSource persistence Fork cursor recovery kinds, agentKind, v2-bridge telemetry upstream-owned + preserve take upstream base, re-apply fork exports + upstream transport fields Merge both telemetry models bun test tests/ci-workflows/test-home-guard.test.ts
src/server/responses/fetch-helpers.ts Upstream Codex WS options object Fork UpstreamRedirectError, TLS/test fetch chain upstream-owned + preserve take fork file Required by core.ts redirect handling bun test tests/server/server-xai-responses-streaming.test.ts
src/server/responses/collaboration.ts Upstream proactive guidance text/tags Fork syncCodexSubagentDefaults / nativeDefaultState placeholders upstream-owned + preserve upstream base + minimal fork fields Do not replace upstream guidance prose bun test tests/codex-integration/multi-agent-compat.test.ts
src/codex/routing.ts pin release Immediate saveConfigPreservingClaudeCode on pin drain Deferred pin save compatible with fork config repair gate upstream-owned + preserve upstream routing + fork persist=false try/finally Avoid repair-gate throws mid-selection bun test tests/codex-integration/codex-routing.test.ts
src/codex/inject.ts Upstream #3978 client compaction provider Fork publicOrigin TLS injection upstream-owned + preserve take fork inject.ts (blocker: compaction test still red) Human: merge clientCompaction from upstream into fork inject bun test tests/codex-integration/codex-inject.test.ts
src/claude/inbound.ts #3922 explicit strict: false on tools Fork had alternate tool translation upstream-owned take upstream Required by upstream claude tests bun test tests/claude-integration/claude-inbound.test.ts
tests/codex-integration/codex-routing.test.ts Upstream WHAM/3029 expectations Fork config repair gate + fiveHour aliases fork test alignment take origin/dev test file Upstream test file incompatible with fork config gate bun test tests/codex-integration/codex-routing.test.ts
tests/responses/responses-context-overflow.test.ts Upstream overflow/status contract Fork googleProviderOptionsRouteError may 400 early fork test alignment take origin/dev test file One upstream-only case still failing (413 non-stream) bun test tests/responses/responses-context-overflow.test.ts

Verification

# identity
git rev-parse v2.50.0^{commit}   # 2d4d7a22381a2e497c2442902104619e25f937c7
git rev-parse origin/dev         # 785424295fc5d8ef0a66fb8ce94a55fe3b054471

# compile
cd /workspace && export PATH="$HOME/.bun/bin:$PATH"
bun run typecheck
# -> exit 0

# focused conflict domains (438 pass / 3 fail as of head d86db7996)
bun test tests/responses/responses-context-overflow.test.ts \
  tests/server/server-xai-responses-streaming.test.ts \
  tests/codex-integration/codex-routing.test.ts \
  tests/codex-integration/codex-models-cache-invalidate.test.ts \
  tests/codex-integration/codex-retained-root-serialization.test.ts \
  tests/codex-integration/multi-agent-compat.test.ts \
  tests/claude-integration/claude-inbound.test.ts \
  tests/ci-workflows/test-home-guard.test.ts \
  tests/images/loop.test.ts \
  tests/lib/process-control-graceful.test.ts \
  tests/codex-integration/codex-inject.test.ts \
  gui/tests/subagents-ultra-mode.test.tsx \
  gui/tests/usage-custom-range.test.tsx

# shared runtime gate attempted
bun run test
# -> worker SIGSEGV cascade in this container (1079 aborted); treat full-suite as BLOCKED pending clean runner

Remaining focused failures (human)

  1. tests/responses/responses-context-overflow.test.tsnon-streaming callers retain the upstream 413 status and body
  2. tests/codex-integration/codex-inject.test.tsCodex client compaction opt-in (#3978) (needs upstream clientCompaction merged into fork inject.ts)
  3. tests/codex-integration/codex-routing.test.tsWHAM preserves the 5h, weekly, and Spark weekly windows (needs fiveHour* quota fields without breaking upstream core.ts signatures)

Checklist

  • Scope stays focused on upstream v2.50.0 sync and fork preservation.
  • Added/updated tests for behavior changes under src/ or gui/src/3 focused regressions remain; see blockers above.
  • Docs or release notes were updated when needed — not required for sync branch.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults — no new secret surfaces.
  1. Merge vendor/main v2.50.0 / 2d4d7a223 — done
  2. Resolve shared hotspot src/server/responses/core.ts per OWNED.md — done (manual)
  3. Rebase onto origin/dev — pending gh pr view --json mergeable
  4. CI ci / enforce-target / hygiene — pending exact-head runs

Draft for human merge — do not squash/rebase.

Open in Web View Automation 

lidge-jun and others added 30 commits September 8, 2026 16:59
…6-recovery

fix(codex): reconcile manual reset cooldowns with owned fresh usage
…close

docs: archive six-item bug stack delivery proof
[WRONG BRANCH] release: promote 2.48.0 to main
chore(release): open dev at 2.49.0 before releasing 2.48.0
…cord

docs(devlog): archive the 2.48.0 release train record
The carried CodeBuddy commits predate the tests/ modularization, so their
two test files landed at the tests/ root where the layout guard rejects
them. Move them under tests/providers and register both in layout.json
and the expected-layout fixture.
Same drift as the CodeBuddy layer: the carried Qoder commit predates the
tests/ modularization. Move both files under tests/providers and register
them in layout.json and the expected-layout fixture.
…rors

The Qoder catalog branch was written against the pre-lidge-jun#3601 shape of
provider-fetch.ts, so it merged cleanly while dropping captured.effectiveAlias
from all four hint applications; a Qoder row would carry whatever alias the
cached row already held instead of the decision captured at flight admission.

The shared coding-agent result classifier matched the bare word
authentication anywhere in vendor text, turning transient upstream wording
into a 401 credential verdict that drives reauth messaging and key-pool
rotation. Anchor it to credential phrasing; the existing 'Not logged in;
invalid token' fixture still classifies as 401.
…idge-jun#3989)

Configure `sourcePreservingYaml: { path: ["providers", "opencodex"] }` for
Hermes Agent in `INTEGRATION_CLIENTS`.

Hermes Agent is a multi-provider autonomous agent whose configuration
(`~/.hermes/config.yaml`) typically hosts multiple providers, vision models,
and comments. Previously, Hermes was registered without source preservation,
causing `classifyIntegration` to fail-closed (`state: "conflict", reason: "foreign-edit"`)
whenever a user modified sibling providers or comments. In the dashboard UI,
this locked the toggle and threatened a destructive full-file restore ("Replace").

By giving Hermes source-preserving YAML semantics (joining OMP and DSH):
- OpenCodex mutates only `providers.opencodex` in-place.
- Sibling provider configurations, user comments, and formatting remain untouched.
- Unit and invariant test suites updated with dedicated regression coverage.
- Public documentation in `guides/integrations.md` updated accordingly.

Closes lidge-jun#3989

(cherry picked from commit a1fe9ca)
…ss Gemini and CCA

Google Gemini (via Cloud Code Assist / Antigravity, Vertex AI, and AI Studio)
rejects requests whose conversation history ends on a model turn with HTTP 400
INVALID_ARGUMENT ("Requests ending with a model turn are not supported.").

Previously, the continue nudge was only attached for Claude-on-Antigravity under
the assumption that Gemini natively accepts model-tail histories. In practice,
autonomous multi-turn loops (such as subagent orchestration and continuation turns
in Codex CLI) produce histories ending in an assistant message, triggering the 400.

This patch:
- Injects a synthetic user `(continue)` nudge in `messagesToGeminiFormat` whenever
  the reconstructed `contents` ends with `role: "model"` or is empty.
- Broadens the post-replay Antigravity tail check to cover all Google models.
- Updates unit tests to verify that Gemini 3.7 Flash, Gemini 3.8 Flash, and
  AI Studio endpoints all receive the continue nudge on model-tail contexts.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
(cherry picked from commit 1837b8f)
qoder and qoder-cn landed without an icon alias or display name, so the
dashboard drew them as an initial tile with a raw config id underneath;
codebuddy and codebuddy-cn had the same gap. Every other first-class provider
carries both.

Qoder ships its own square symbol as the declared site icon, byte-identical
across qoder.com, qoder.cn, qoder.com.cn and the schema.org Organization
logo, and neither terms document restricts its use; it is committed
verbatim and wired to both ids. CodeBuddy keeps the initials tile on purpose:
section 9.3 of the Tencent service agreement forbids using Tencent brand
features under any circumstances without written consent. Both decisions,
with sources and clauses, are recorded in the provider-icons README so the
refusal is not silently re-litigated.

Also publishes the Qoder Global/CN section in the docs-site providers guide
(the repo-level docs/qoder-cli-provider.md is not built) and lists the
qoder adapter in the configuration reference.
…ervation

The English guide now lists Hermes with OMP and DSH as source-preserving
YAML writers; the French and Traditional Chinese pages still named it among
the clients whose switch locks on sibling edits, contradicting runtime
behaviour.
The carried change added the nudge to messagesToGeminiFormat for every
Google mode and also widened the post-replay Antigravity check from
Claude-only to all models, leaving two injection sites on one request. The
second is only a no-op while nothing between them reshapes the tail; the
signature sanitizer can. Drop the post-replay copy so the formatter owns the
invariant.
feat(provider): add official CodeBuddy Global and CN providers (carry lidge-jun#3340)
…lobal

feat(provider): add Qoder Global PAT provider (carry lidge-jun#3349)
feat(gui): give Qoder its brand mark and name the CLI providers
…yaml

feat(integrations): support source-preserving YAML for Hermes Agent (carry lidge-jun#3990)
…tail

fix(google): guard model-tail histories with user continue nudge across Gemini and CCA (carry lidge-jun#3988)
lidge-jun and others added 26 commits September 10, 2026 09:02
…hput

Logs reported one rate. tokensPerSecond() never subtracted TTFT, tokPerSecondResult
passed the full duration, and the MetricSource Pick did not even include
firstOutputMs, so a decode-rate metric could not be computed at all -- even
though TTFT is already recorded per request and per combo attempt. It was never
a calculation bug: the end-to-end metric is documented as end-to-end. It is a
missing metric.

The history is why this is not a straight re-land. Contributor PR lidge-jun#4040
implemented the same metric and was closed unmerged by the reporter, on the
grounds that proxy TTFT and the provider's own generation window do not line up
and that a small post-TTFT remainder makes the estimate explode. The issue
stayed open, so the repository held both an acceptance criterion and a rejection
of the same feature.

MIN_DECODE_WINDOW_MS answers the rejection directly. Below one second the window
is dominated by TTFT jitter, proxy buffering and timestamp granularity, so a
window under the floor yields NO value instead of a four-digit number. The
second half of the answer is honesty rather than arithmetic: the value is always
marked estimated, because proxy TTFT is when the first byte reached the proxy
and no window length makes that the provider's generation start.

Strictly additive. tokensPerSecond, tokPerSecondResult, filterLogs,
RequestLogEntry and usage.jsonl are untouched, the end-to-end rate keeps its
meaning, the speed filter still sorts on it, and this stays out of
/api/request-history. The parent uses the request's own TTFT and each attempt
uses its own attempt-relative one; a combo parent never borrows a child's.

Closes lidge-jun#4038.
Maintainer integration on dev under the MAINTAINERS.md policy that lets a maintainer
with maintain or admin access land a PR on dev without a second approval, recording
the decision and the exact-head CI evidence. Lane A item 3 of the round-2 stack,
planned in devlog/_plan/260910_post249_round2/040_4141_launchctl_bootout.md.

The decision this carries, stated plainly rather than buried: bootout kills the live
gui job. That is the repair the issue asks for, and it is also why the existing code
only printed the command instead of running it. It is scoped so a healthy job is never
touched - it runs inside installLaunchd only, never in ocx service start, and only
after load -w has already failed. launchctlLoadFailed itself is unchanged, because
that regex is the silent-success guard and the fix is to recover from the condition
rather than stop detecting it.

Sequenced deliberately after PR lidge-jun#4152, which landed as 9ba04b6 and rewrote the same
runLaunchctl runner. This adopts the seam that PR established instead of introducing a
second one.

Exact-head CI at ae057c4, verified by exit code:

  gh run view 34418986812 --exit-status  ->  0   Cross-platform CI
  gh run view 34418986816 --exit-status  ->  0   Service lifecycle
  gh run view 34418986897 --exit-status  ->  0   React Doctor
  gh run view 34419067873 --exit-status  ->  0   Enforce PR target branch

Latest conclusion per check name at that SHA: twenty-six success, none failed, none
cancelled, none pending.

NOT RUN, and worth naming for this change in particular: no launchctl, no ocx service,
no ocx start/stop/restart was executed anywhere while producing it. A live proxy is
running on this machine and a separate task owns it, so the behaviour is proven by
stderr fixtures against the injection seam and by remote CI. Also NOT RUN: bun run
test, bun run typecheck, bun run build, bun run lint:gui, bun run privacy:scan,
bun install.
… path too

deriveEntry builds a served entry twice over: once by cloning a cached template
and once from scratch when none is available. The inactive-reason stamp landed
only on the templated path, so whether a quota-exhausted row carried the field
depended on whether a template happened to be cached -- the same row would be
marked or unmarked across rebuilds.

The regression test caught it because it passed template: null, which is the
fallback path. It now runs both paths explicitly rather than one, so a stamp
added to one branch and not the other fails here instead of shipping.
…d pin the built entry

Two gaps in the same field.

listManagementModelRows REBUILDS custom rows from config.customModels instead of
spreading the CatalogModel, and the slug dedup then drops the gather-derived row
it replaces. So a custom model whose provider is out of credit was the one row on
the page that could never show as inactive, while routed and combo rows beside it
did. The reason gather already computed for that slug is now carried across.

The regression test covered the predicate and deriveEntry, but nothing built a
catalog. Every one of those cases would stay green if a refactor moved the stamp
out of the entry builder. The new case seeds the routing cache, lets the
predicate read it, and builds through buildCatalogEntries -- asserting the
exhausted row is present, still visibility "list", and marked, while a funded
provider's row beside it carries no field at all.
…est history

Two gaps.

The attempt table still showed only the end-to-end rate, while the parent detail
and the list stacked both. The DTO already carried a per-attempt decode rate
measured on that attempt's own TTFT, so this was a rendering gap rather than a
data one.

/api/request-history shares requestLogDto but not its contract, and the field
was riding along. requestLogDto now takes includeDecodeRate, defaulting to true
so /api/logs is unchanged, and both history call sites opt out.

Worth stating plainly: the value would have been MEANINGFUL there, not noise --
firstOutputMs does survive into a persisted-usage row, so history entries would
have carried real numbers. The exclusion is therefore a scope decision rather
than a correctness one. The decode rate is a Logs-page metric, and widening a
separate endpoint's response shape is not this change's business. Flipping it on
later is one argument.

Both halves are asserted: the DTO omits the field on parent and attempts under
the opt-out while keeping tok/s and cost, the default still includes it, and a
source check pins that the route passes the flag at every call site -- otherwise
a correct flag and a route that never set it would both look fine.
Typecheck failure at b19fa9e. /api/logs built its rows with
.map(requestLogDto), which is fine for a one-parameter function and a type error
the moment a second one exists: Array.map passes (value, index, array), so the
element INDEX was being handed to the new options object.

  Type 'number' has no properties in common with
  type '{ includeDecodeRate?: boolean }'

An explicit arrow fixes it and keeps the default, which is what /api/logs wants.
The two request-history call sites were already explicit because they pass the
opt-out.

This is the whole cost of the flag -- one call site that happened to be
point-free -- so the exclusion stays rather than being traded for a documented
deviation.
Lane A is complete. lidge-jun#4141 landed as 95a3f6a, joining lidge-jun#4129 and lidge-jun#4148, and
with lidge-jun#4147 and lidge-jun#3859 that is five issues delivered and closed.

The remaining four are code-complete and audited PASS, and each sits at
twenty-three green checks with enforce-target as the only failure. Its
message is literally "missing UI screenshot". Satisfying it needs a GUI
build, which this round forbids, so the choice is the maintainer's: allow a
build for screenshots, integrate past the gate with admin rights, or carry
these four forward.

It is not a false positive. PR lidge-jun#4162 changed nothing but documentation and
tripped the same gate merely by quoting the trigger token in its
description; rewording made it pass. On four PRs that do change the
dashboard, the requirement is real.

Records the second-round audit and its four findings, all since fixed, and
the answer to the question worth asking about lidge-jun#4165's earlier CI failure:
the repair filled a missing stamp on the deriveEntry fallback and extended
the new test to both derivation paths, rather than relaxing an existing
catalog equality to go green.

Also records a direct cost of this round's constraints. Fixing the last
finding broke the typecheck, and with local typecheck forbidden that was
only discoverable from the remote gates job, whose failing step has to be
read out of the workflow rather than seen locally.

NOT RUN: local test suite, typecheck, build, lint. Remote CI is the gate.
…close

Maintainer integration on dev under the MAINTAINERS.md policy that lets a maintainer
with maintain or admin access land a PR on dev without a second approval, recording
the decision and the exact-head CI evidence.

Documentation only: confined to devlog/_plan/260910_post249_round2/, and nothing in
the build, typecheck or test path reads from devlog/.

Exact-head CI at 7945635, verified by exit code:

  gh run view 34423303084 --exit-status  ->  0   Cross-platform CI
  gh run view 34423303095 --exit-status  ->  0   React Doctor
  gh run view 34423303033 --exit-status  ->  0   Enforce PR target branch
  gh run view 34423302981 --exit-status  ->  0   PR hygiene

Latest conclusion per check name at that SHA: eight success, ten skipped, none
failed, none cancelled, none pending.

NOT RUN: bun run test, bun run typecheck, bun run build, bun run lint:gui,
bun run privacy:scan, bun install. The maintainer set a no-local-suite constraint
for this round and remote CI is the only gate.
The Free switch is offered only where discovery returned per-token prices, but
the operator's choice is component state that outlives the rows it was made
against. When the evidence goes away -- a refresh that comes back without
pricing, a re-auth, a discovery fallback to a static catalog -- pricingKnown
goes false and the control disappears, while the stale true keeps filtering.
Every row is then unclassified, filterFreeModelRows keeps none of them, and the
list empties under a switch that is no longer drawn. The empty-state copy makes
it worse: models.noFreeMatch tells the user to turn off Free only, naming a
control that is not on screen.

Gate the filter on the same condition that renders the switch. freeOnlyInForce
lives beside the predicate in models-shared so the Models page group and the
provider workspace inventory cannot drift, and both surfaces bind their
empty-state message to the derived flag rather than the raw state.

Local checks: NOT RUN, per this round's constraint. Exact-head remote CI gates.
feat(catalog): classify discovered model pricing and filter free models
fix(models): explain the discovery dependency when model sync fails
feat(logs): show an estimated decode rate alongside end-to-end throughput
lidge-jun#4156 and lidge-jun#4158 landed on dev while this branch was open, and both touch the
same catalog surfaces. Every conflict was additive -- the same declaration list,
the same locale catalog, the same row type -- so each one keeps both sides:
quotaInactiveReason (lidge-jun#1711) beside pricingStatus (lidge-jun#3666) on ModelRow and on the
parsed catalog row, and models.inactiveNoCredit beside
models.discoveryFailedDependency in all nine locales.

Two of those hunks shared a single JSDoc opener, so keeping both bodies left the
second block without its /** in models-shared.ts and parsing.ts. Restored.

Local checks: NOT RUN, per this round's constraint. Exact-head remote CI gates.
feat(catalog): mark quota-exhausted models and combos inactive
Round 2 closed with Lane B dammed by the enforce-target screenshot gate. This
records how it was cleared, what an independent audit changed before the merge,
and the disposition of every finding that was not fixed.
…lane-b-landing

docs(devlog): record the Lane B landing and the screenshot-gate waiver
…e-jun#4186)

* docs(devlog): record the Cursor ACP -> OpenCodex feasibility investigation

Answers whether cli-jaw's Cursor ACP integration can be attached to OpenCodex.
Transport yes, provider no: ProviderAdapter is a model port and ACP delivers an
agent. Cursor-the-model is already integrated over HTTP.

Corrects a stale finding: 800_agent-fabric/110_protocol_boundaries.md defers ACP
on the grounds it merged into A2A, but that is IBM/BeeAI's Agent Communication
Protocol. Cursor speaks Zed's Agent Client Protocol, a separate spec still at v1.

Records that the unit's original central premise -- that ACP gives a client no
way to constrain the agent -- was falsified during audit by Cursor's documented
read-only plan/ask modes, and that the conclusion survived while its premise did
not. Three audit rounds, 16 findings, zero rebutted.

Docs only; no src/, gui/ or docs-site/ change.

* docs(devlog): close the Cursor ACP residuals with a live trace

Runs the cursor-agent acp handshake the unit could not run earlier, on
2026.09.08-6caf4ff in a scratch directory.

ask mode held: an explicit "do it now" write instruction produced no
modification. agent mode did not: the same prompt edited the file after
issuing zero session/request_permission and zero fs/write_text_file calls,
against a client instrumented to deny everything.

That reverses a retraction. Cycle 1 withdrew the claim that Cursor mutates
without offering a refusal point because it could not be demonstrated; it
can now. The reviewer was right about the ACP specification and wrong about
Cursor's implementation of it.

Also records a measured model roster (38 rows, context 200k/272k/300k,
no advertised 1M, no Max Mode) replacing an earlier unproven claim.

Four reviewer blockers folded, all scoping conclusions to what two runs
support. Docs only.

* docs(devlog): correct the ACP model-surface measurement and add ACP-D5

The earlier trace omitted the client capability both existing ACP
implementations send, and measured a degraded model surface as a result.

t3code (CursorProvider.ts:71-75) and cli-jaw (cursor-session.ts:64) both set
_meta.parameterizedModelPicker at initialize. With it, Cursor returns clean
base model ids instead of 38 bracketed ones, branded display names, and
per-model config options carrying the legal effort and context values -
including 1m context on claude-opus-5 and gpt-5.6-sol.

Three claims are withdrawn: "no advertised 1M-context variant", "no observed
way to vary effort or context", and "one fixed configuration per listed
model". Neither the ACP spec nor Cursor's docs mention the flag; reading
t3code is what surfaced it.

Adds ACP-D5: run cursor-agent acp as a metadata discovery probe for the
existing HTTP provider rather than as an inference path. No turn crosses the
ACP boundary, so tool ownership, missing usage and unsupervised writes never
arise, and it replaces hand-maintained effort/context tables with values the
vendor advertises.

Docs only.

* docs(devlog): record the workspace constraint and tidy the unit for review

Marks the superseded model-surface section in 070 instead of leaving it to
contradict the correction below it, and records the constraint that actually
decides an ACP inference path: OpenCodex has no workspace to give the agent.

ACP requires a cwd at session/new. OcxParsedRequest has no working-directory
field, IncomingMeta carries none, and coding-agent/turn.ts passes no cwd when
it spawns, so a child inherits the proxy's directory rather than the caller's
project. That also explains why the coding-agent precedent needs no cwd: with
--tools "" the child never touches the filesystem.

Adds a 060 addendum as the current entry point, since two later passes changed
conclusions after that summary was written.
Promotes the audited freeze SHA 12c248f unchanged. The resulting tree is byte-identical to that commit's tree, d8f5a71, so what ships is exactly what the six-lane regression audit read.
…in-01a08a81

[WRONG BRANCH] release: promote verified 2.50.0 product tree to main
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
Co-authored-by: SB Yoon <yansigit@users.noreply.github.com>
@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Sep 10, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Deterministic hygiene checks failed.

  • new_suppression — A new TypeScript, lint, formatter, or similar suppression was added. Fix the underlying issue or obtain suppression-approved. Paths: gui/src/pages/Models.tsx.
  • empty_catch — An empty catch block was added. Handle, report, or deliberately propagate the error. Paths: tests/codex-integration/codex-retained-root-serialization.test.ts.
  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: .github/workflows/cleanup-orphaned-workflows.yml, bun.lock, package.json, scripts/release-notes.ts, src/cli/account-auth.ts, src/codex/auth-api.ts, src/codex/auth-collision.ts, src/codex/auth-context.ts, src/oauth/chatgpt.ts, src/oauth/health.ts, src/oauth/index.ts, src/oauth/token-guardian.ts, src/oauth/xai.ts, src/server/auth-cors.ts, src/server/management-api.ts, src/server/management/oauth-account-routes.ts.

@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown

PR automation (bot-owned)

  • Class: draft (draft)
  • Base: 785424295fc5d8ef0a66fb8ce94a55fe3b054471
  • Head: d86db7996bfe4df9bf036e184312bf9b3e93a7b5
  • Action: observed
  • Exact-head gate: BLOCKED (not-mergeable, check-not-success)
  • Sensitive paths: .github/workflows/cleanup-orphaned-workflows.yml, bun.lock, package.json, scripts/release-notes.ts, src/adapters/anthropic.ts, src/adapters/codebuddy/adapter.ts, src/adapters/codebuddy/profiles.ts, src/adapters/coding-agent/profile.ts, src/
  • Maintainer auto-merge approval: NO
  • Bot merge evidence: NO
  • Next action: human review required

@github-actions

Copy link
Copy Markdown

⏳ DRAFT

  • hygiene: new_suppression. hygiene: empty_catch. hygiene: unsponsored_surface. sync_baseline

What to do

  • Wait for successful exact-head ci, enforce-target, and hygiene checks.
  • Fix new_suppression — A new TypeScript, lint, formatter, or similar suppression was added. Fix the underlying issue or obtain suppression-approved. Paths: gui/src/pages/Models.tsx.
  • Fix empty_catch — An empty catch block was added. Handle, report, or deliberately propagate the error. Paths: tests/codex-integration/codex-retained-root-serialization.test.ts.
  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: .github/workflows/cleanup-orphaned-workflows.yml, bun.lock, package.json, scripts/release-notes.ts, src/cli/account-auth.ts, src/codex/auth-api.ts, src/codex/auth-collision.ts, src/codex/auth-context.ts, src/oauth/chatgpt.ts, src/oauth/health.ts, src/oauth/index.ts, src/oauth/token-guardian.ts, src/oauth/xai.ts, src/server/auth-cors.ts, src/server/management-api.ts, src/server/management/oauth-account-routes.ts.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants