Skip to content

chore: merge current dev into vision-reasoning takeover branch - #1242

Closed
Wibias wants to merge 375 commits into
maintainer/vision-reasoning-sidecarfrom
dev
Closed

chore: merge current dev into vision-reasoning takeover branch#1242
Wibias wants to merge 375 commits into
maintainer/vision-reasoning-sidecarfrom
dev

Conversation

@Wibias

@Wibias Wibias commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Temporary maintainer integration PR used to merge the current dev tip into maintainer/vision-reasoning-sidecar, which starts from the contributor head of #1002. This preserves the original implementation while bringing it forward before maintainer fixes are applied.

Wibias and others added 30 commits August 6, 2026 11:19
The numeric requirement spec object has a union shape ({min, step} for
minContextWindow vs {min, max, step} for minQuotaHeadroom), so indexing
[NUMERIC_REQUIREMENT_SPEC[key].max] fails the GUI typecheck. Add
max: undefined to the minContextWindow entry so both members share the
same shape; behavior is unchanged (max={undefined} renders no max
attribute).
… pin

The issue-quality workflow's translate job migrated from the
actions/ai-inference permission (models: read) to the Copilot CLI
permission (copilot-requests: write) in 3a7a72d, but the regression
test still pinned models: read. The test was guarding that the job
stays job-scoped (no top-level issues:write, no actions:write), so it
now accepts either permission name and keeps that guard.
…rmission-test

test(ci): accept the Copilot permission in the issue-quality workflow pin
Thread CodexAccountUsabilityOptions through the tier-aware selection
paths (pickPriorityPreemption and the round-robin/fill-first branches of
pickAlternateCodexAccount), so nativeMainSelectionOnly is honored
consistently with the quota path during main-profile draining.

Close and block an open Select when disabled flips: the dropdown is no
longer rendered and the option buttons are disabled, so a shared
controller flipping priorityUpdatingId cannot leave clickable options
that silently drop the second update.

Strengthen the tests:
- exact-selector regression now configures a live pin alongside the
  priorities and asserts the pin survives, covering the stronger
  pin-ceiling case;
- routing-level regression proves selection options reach the tier and
  alternate paths;
- config-set pin-release test asserts each written order value;
- controller-contract test guards the slice windows instead of slicing
  potentially-empty ranges;
- toast-tone no-op test uses the real feedback selectors.

Docs and copy accuracy:
- switch strings state that existing account-affine threads and
  in-flight requests keep their captured account, and only new/unbound
  requests use the selected account's order tier (en/ja/ko/ru);
- README qualifies lowest-usage as the quota policy and replaces
  unconditional thread-pinning claims;
- web-dashboard adds the Pool/Direct boundary and full pin-release
  conditions across locales;
- CLI current reports priority-aware selection;
- US-English afterward and a split Russian pin-release sentence.
test: replace hardcoded old username with generic user in test fixture
Three findings from react-doctor 0.9.3:

- saveProfile/removeProfile read the fetch Response body before checking
  response.ok, so an HTTP error payload was parsed as success. Route both
  through readJsonIfOk (which checks res.ok before consuming) and read the
  structured error body explicitly on the non-OK branch.
- the candidate card used an index-derived React key. Draft candidates now
  carry a stable client-side key (newDraftCandidate) that is stripped by
  routingProfilePutBody and never reaches the server; add/update keep it.

react-doctor --scope changed --base upstream/dev: No issues found.
Verified: root+GUI typecheck, GUI lint, 610 GUI tests, 128 focused server
tests.
feat(codex): selection order for the account pool
The destination fallback added here lets a canonical preset saved under an
unknown name recover its registry-owned discovery policy by transport. The
existing coverage proved only that a renamed row picks up a path and query; it
never asserted the filter, and it had no negative cases at all.

Adds five tests, each driven red once against a real sabotage:

- recovers path, query AND filter (literal expectations, not a re-read of the
  same registry row \u2014 the first formulation compared the spec against itself
  and stayed green when the filter was replaced)
- refuses a name that matches a registry entry whose transport does not
- refuses OAuth destinations reached by an unknown name
- refuses non-key auth modes, templated base URLs, and overridable destinations
- keeps every fallback-eligible absolute discovery URL same-origin with its own
  base URL

The last one closes a real gap: an absolute spec.url overrides the configured
base, so a cross-origin one on a fallback-eligible row would send a user's key
to an origin they never configured. DeepInfra is the current instance (base
/v1/openai, discovery /v1/models, same origin) and the test pins that invariant.

Also corrects the OAuth narrative in all five locales: it said six presets plus
Copilot while the registry has eight OAuth rows, and the command list omitted
ocx login command-code. Pre-existing on dev, corrected here because this change
rewrites the surrounding preset counts.
CodeRabbit, Codex connector, and owner review items on #1108:

- routing.createProfile key replaces the reused routing.detail on the create
  button; guide synced; localized in all six locales.
- routingProfilePutBody now owns the serialized request contract: mode is
  part of the returned body (not a caller-side spread), and updates carry
  expectedRevision for optimistic concurrency.
- requirementSelect test helper scopes to the Hard requirements fieldset so
  health/cost/quota keys in other fieldsets cannot false-match.
- management regression test covers the mode:update success path (one save,
  one catalog refresh) plus a 409 stale-revision conflict.
- dry-run error fallback and UnknownEvidenceMode option labels are localized.
- parseProfiles validates the complete nested DTO shape so a malformed
  management response cannot crash the load path; GUI regression test added.
- PUT update migrates config references on alias change (disabledModels,
  subagentModels, injectionModel, shadowCallIntercept, claudeCode) and syncs
  Claude agent defs, mirroring the /api/combos pattern.
- delete confirmation and candidate remove aria-label are localized.

react-doctor 0.9.3 --scope changed --base upstream/dev: No issues found.
Verified: root+GUI typecheck, GUI lint+i18n lint, 611 GUI tests, 137 focused
server tests.
…el-apis

feat(providers): add SambaNova and Nebius presets
…s change

CodeRabbit follow-up on cf3d4b5: migrateProfileModelReferences rewrote
subagentModels and claudeCode.modelMap values but missed the sibling
config.subagentModelFallback chain and modelMap keys, which are the inbound
ids matched for reroute in src/claude/inbound.ts. Both now follow an alias
rename, with the migration regression test extended to cover them.
…y-model-apis

feat(providers): add DigitalOcean and Scaleway presets
CodeRabbit follow-up on bcec06d: migrating modelMap keys via
Object.fromEntries silently drops a mapping when the map already contains the
new alias as a key with a different target. Detect that collision before any
mutation and reject the update with 409 alias_reference_conflict so no
mapping is lost; regression test covers both keys with different targets.
fix(providers): replay DeepSeek reasoning for opencode-zen (#994)
feat(routing): add routing profiles dashboard editor
… changes

The maintainer GUI-waiver comment ("not touching gui") never re-ran the
enforce-target gate because pull_request_target types do not include issue
comments. Add an issue_comment trigger so the waiver takes effect when
posted, resolving the PR number from the issue payload and falling the
checkout back to the default branch.

Also stop running lint:gui unconditionally in the local prepush hook: it now
runs only when the push touches gui/, mirroring doctor:gui:if-changed. CI
already gated GUI lint behind the changes filter; the local hook now matches.
…tests

The CJS validator test asserted the exact base-SHA checkout ref and did not
cover the new issue_comment trigger. Update the ref assertion to the
fallback form and add a test pinning that a maintainer GUI-waiver comment
re-runs the gate via the issue_comment event.
feat(providers): add Nscale and Vultr presets
…olidate bot comments

The issue_comment trigger fired for any comment on any issue from any user.
Guard the enforce-target job so only maintainer (OWNER/COLLABORATOR/MEMBER)
comments on actual PRs re-run the write-capable gate; a comment on a plain
issue or from a contributor is skipped, with a defensive in-script re-check
matching the job-level if.

Also consolidate the PR gate and PR hygiene bot messages into the single
opencodex-pr-gate comment. The hygiene workflow now writes its status block
into the gate comment (preserving the gate section) instead of posting a
second standalone message, and the gate rebuild preserves an existing
hygiene block so neither workflow clobbers the other.
…te comment concurrency

Two CodeRabbit findings on the consolidated gate comment:

- The hygiene block delimiters matched anywhere in the comment body. A
  contributor-controlled changed filename could embed delimiter text mid-line
  and corrupt the block boundary on the next rewrite. Anchor both delimiters
  to complete lines via a shared regex used by the existence check and the
  replacement, with a regression test for embedded delimiter text.

- The gate and hygiene workflows each had their own per-PR concurrency group
  while both read-modify-write the same consolidated comment. A concurrent
  gate rebuild and hygiene update could run from stale snapshots and the last
  write would drop the other's section. Share one per-PR concurrency group
  between the two workflows and pin it in the workflow tests.
…rifiable checklists

Codex-bot review findings on the issue_comment trigger:

- The checkout fell back to the repository default branch (main) on
  issue_comment, which can lag the integration branch the gate enforces.
  Fall back to dev (the gate's only allowed base) so comment-triggered runs
  evaluate with the gate's own current scripts.

- issue_comment events carry no pull_request.head.sha, so eventHeadSha
  fell back to the live head and a completed checklist with no recorded
  completion head was accepted as attesting the current head. Pass an empty
  eventHeadSha on issue_comment so completionIsStale resets the checklist
  (fail closed) instead of promoting readiness from an unverifiable
  attestation. Regression tests cover both.
lidge-jun and others added 22 commits August 8, 2026 02:09
…reverting concurrent changes

Adopts #1203 by @estelledc — the first three commits are theirs, cherry-picked
with authorship intact. The approach was right: expose the existing
`providers.<id>.contextWindow` / `modelContextWindows` contract at the
management and UI layers without touching catalog derivation, which already
materializes those values when upstream metadata is absent.

Four corrections, all found by independent audit.

**Only the selected model was saved.** The drafts map held edits for every
model but the PATCH was keyed on `contextModelId`, so a value typed into
model A and then abandoned by switching to B vanished — no error, no warning.
The PR's own test pinned that as correct. It now sends every model the user
typed into.

**But "every model that differs" would have been wrong the other way.** The
10s poll can refresh a field while the modal is open; diffing drafts against
live state would then call an untouched field dirty and revert someone else's
change. Two conditions are required: the user touched it, AND the value
differs from what the modal opened with. Both apply to the provider default
too, which was previously sent unconditionally and would stamp a stale number
over a concurrent update.

The snapshot holds canonical numbers, not the raw text. Retyping 64000 as
"64,000" is not an edit, and treating it as one would resurrect the same
stale-write. When nothing survives the comparison, no PATCH is sent at all
and the feedback says so rather than claiming an update.

**`Number.isInteger(1e100)` is true.** Both the management validator and the
form accepted it; it would persist and serialize into the catalog as an
enormous number that can make Codex reject the file. Both now require a safe
integer. The default is only validated when touched, so a value inherited
from a hand-edited config cannot block an unrelated per-model save.

**An override for a model that left live discovery was unreachable.** It sat
in the drafts map, absent from the picker, impossible to inspect or clear.

Tests: the exact #1073 reproduction is split in two, because a single case
setting `modelContextWindows` keeps passing with the provider-wide fallback
deleted. Ablations were driven red in their real defect shape rather than as
artificially strong mutants — notably, comparing against live `groups` while
keeping the touched guard is only visible when a field is edited, reverted,
and changed server-side, which the suite now covers.

Translated provider docs (ko/ja/ru/zh-cn) described both fields as caps only,
which reads as the opposite of the fix for non-English users.

Co-authored-by: zhouxun <zhouxun.13@bytedance.com>
Closes #1073
Pinning the package NAME to our own still left the VERSION free:
`@bitkyc08/opencodex@99.99.99-JaneDoe` is a valid-looking spec, and a semver
prerelease identifier can encode anything. That is the same lesson the
`/healthz` version taught in round 13 — I applied it there and not here.

There is no trusted resolved version available at this call site, so the spec is
not rendered at all. `code: ETARGET · notarget: no matching version` already
tells a user their requested version does not exist, which is the diagnostic
that matters.

Both attack inputs are regression tests.
Adopted from PR #1171 by @byongshintv, rebuilt on the current stack. Original
closed in favor of this commit.

An unlimited A6API key reports zero finite credit totals. Finite-total
validation then treated that as a terminal failure and returned before the key
could be represented at all, so a perfectly working key looked dead in the
dashboard.

The unlimited branch now runs ahead of that validation and emits the generic
`customWindows` row the GUI and CLI already consume, preserving expiry. It
accepts `true`, `1`, and `"true"` for the upstream flag.

Two known limitations, stated rather than discovered later: `creditsUsd` and
its expiry are not yet surfaced by the GUI — visibility comes from
`customWindows` — and neither changes existing behavior for finite keys.

Confirmed to fail with the unlimited branch disabled.
… plan

Audit found resolveTrustedWindowsPowerShellExe() already resolves and validates
the executable through GetSystemDirectoryW. Writing a third SystemRoot/PATH
lookup would reintroduce the substitution surface the plan exists to close.
…dable

Builds on the contributor fix by luvs01 (#1180), which replaced the
USERDOMAIN\USERNAME ACL principal with the effective token SID. Three
things that fix left open:

The synthetic principal POSIX CI needs lived in windows-secret-acl.ts and
was chosen before the injected runner. That ordering made a lookup
FAILURE unreachable outside Windows, so the two cases that defend the
fail-closed boundary and the timedOutPaths isolation were guarded with
`if (process.platform !== "win32") return;` and never ran on Linux or
macOS. A test that silently returns on two of three CI platforms is not
coverage of a security boundary. The synthetic value moves to the
resolver as its own seam, runner selection becomes explicit > synthetic
> default, and both guards are gone.

sanitizedAclError re-attaches only allow-listed codes, and EACLIDENTITY
was not among them. A required-mode harden therefore threw with the
cause in the message but `error.code === undefined`, so no caller could
branch on "the SID could not be resolved" versus "icacls stalled". The
existing test matched the message and hid this.

The absence of a name-shaped fallback is now stated as the fix rather
than left as an omission. `DOMAIN\User` has a valid shape, but shape is
not evidence of the token's subject, and both variables are writable by
whatever launched us. runIcacls grants the principal Full Control and
then removes inheritance, so a wrong principal either leaves another
account holding the secret or strands the file with no usable ACE. An
independent audit rejected an earlier draft of this change that restored
that fallback for the optional read path.

Coverage now runs the sync and async paths across required and optional
on every platform, and asserts zero icacls invocations when the
environment names a plausible-looking account.

Ablation: reverting the runner ordering makes identityCalls 0 and the
required harden succeed (2 red); dropping EACLIDENTITY from the
allow-list makes both toMatchObject assertions fail (2 red).

Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
Closes #1149
The audit named this the ready gate, and it was right to. Every existing
test proves a piece — admission, the route allowlist, CORS, the bind scope,
the injected port — and none of them prove the thing the feature exists
for: that a real `codex app-server`, spawned the way a third-party host
spawns it, reaches the proxy without a credential. That seam is between two
processes.

Not a `bun test` file. The repository does not depend on `@openai/codex`,
so a test that skips when it is absent would report green on machines that
never ran it. This fails loudly and its output is the evidence.

The oracle is a routed model id generated at run time. Codex caches model
lists and falls back to a bundled catalog when a refresh fails, so "did
model/list succeed" proves nothing — a broken path looks identical to a
working one. A name no bundled catalog can contain can only have arrived
through our listener.

Writing it surfaced two things worth recording. `model/list` reads
`model_catalog_json`; it does not call the provider's `/v1/models`, so the
first version watched Codex return its five bundled ids while never
touching the listener — the exact false-negative shape the unique id exists
to expose, pointed at the harness instead of the feature. And a hand-written
catalog fixture is a liability: Codex rejects the whole file on any schema
mismatch and silently falls back, so the catalog is now built with our own
serializer, which also means the script exercises the bytes `ocx sync`
writes.

Result on Codex 0.146.0, isolated CODEX_HOME with no models_cache.json and
OPENCODEX_API_AUTH_TOKEN stripped from the child environment: 9/9, ending
with POST /v1/responses observed on the loopback listener.

Ablation: pointing base_url at a dead port makes the last check red, so the
harness is watching the hop rather than asserting its own setup.

Refs #1102
react-doctor's prefer-module-scope-pure-function, and it is right: the
function closes over nothing, so rebuilding it on every render is wasted
work. The prepush doctor gate rejected the push over it.
…t_index tables

Final-gate audit found the cross-table fallback could hand a reasoning
content_part the MESSAGE canonical id when both tables held the same
output_index, and an out-of-order part event passed through unrepaired.
Track raw upstream id -> canonical id at item registration and rewrite
part/delta events by exact raw-id match first; the index table remains only
for events without a known raw id. A reused index can no longer borrow the
sibling item's id, and function_call part events stay untouched.
…d drop the positional guess

Final-audit round 2 reproduced two defects in the raw-id rewrite: a flat
raw-id map collapsed items sharing one placeholder id into the last item's
canonical id, and the index fallback could still hand a function_call part
event (or an already-canonical id) the sibling message's identity on a
reused index. The map is now keyed by (output_index, rawId), and events
that carry an item_id are rewritten only on an exact key match — an unknown
id is left alone instead of guessed by position. The index table serves
only item_id-less events behind repairMissingTerminalIds, the pre-existing
contract. Regression tests pin all three reproductions.
…ervision

fix(lifecycle): consolidate identity-bound restart and service install cleanup
@Wibias
Wibias marked this pull request as ready for review August 7, 2026 21:10
@Wibias
Wibias requested a review from lidge-jun as a code owner August 7, 2026 21:10
@github-actions github-actions Bot added the chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). label Aug 7, 2026
@Wibias
Wibias requested a review from Ingwannu as a code owner August 7, 2026 21:10
@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

⚠️ 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/components/AccountPriorityControl.tsx.

@Wibias Wibias closed this Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • ^dev$
  • ^preview$

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d1e794ec-5d37-43cc-94ed-58d40abb5bd6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.