Skip to content

v0.9.2 release candidate integration (umbrella, draft) - #4911

Merged
Hmbown merged 195 commits into
mainfrom
codex/v092-integration-direct-main
Jul 27, 2026
Merged

v0.9.2 release candidate integration (umbrella, draft)#4911
Hmbown merged 195 commits into
mainfrom
codex/v092-integration-direct-main

Conversation

@Hmbown

@Hmbown Hmbown commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Summary

Umbrella draft PR for the v0.9.2 release candidate (codex/v092-integration-direct-main, currently 82 commits ahead of main). Opened to put hosted CI and code review on the combined candidate while integration continues; focused harvest PRs will target this branch for narrow review.

Living disposition: docs/releases/v0.9.2-completion-ledger.md on this branch.

Do not merge — landing on protected main remains maintainer-gated. This PR is a review/CI surface, not a landing request.

No-Issue: umbrella integration candidate; per-issue closure happens with per-issue receipts on the final release SHA, not via this PR's merge.

🤖 Generated with Claude Code

snail-vs and others added 30 commits July 26, 2026 21:33
Represent provider wire selection as either fixed or model-aware. Resolve model-aware protocols from catalog endpoint keys and fail closed when an endpoint does not prove a supported request shape.\n\nExisting providers remain fixed-policy routes, so this creates the Zen routing seam without changing current provider behavior.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Register OpenCode Zen across config, CLI, secrets, and TUI surfaces with provider-scoped API key guidance. Keep its wire policy model-aware and fail closed until a catalog offering proves the selected model protocol.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Route the documented Zen catalog across Responses, Anthropic Messages, and Chat Completions by model. Normalize the official opencode/model selector and reject Gemini or unknown models until their request protocol is supported and proven.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Bind clients to the resolver-proven request protocol and send Zen models through Responses, Anthropic Messages, or Chat Completions as appropriate. Keep Zen on bearer authentication, exclude Codex OAuth headers, and fail closed when a request changes protocol or uses an unproven FIM route.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Document Zen as a separate API-key provider with model-scoped Responses, Messages, and Chat Completions groups. Record the unsupported Gemini boundary and teach the provider registry drift check about the manual model-aware provider implementation.

Signed-off-by: snailoniu <snailoniu@gmail.com>
OpenCode Zen routes Anthropic models through the Messages API, which expects the native x-api-key header. Sending Zen keys as Authorization bearer tokens produced upstream 401 Missing API key errors for Claude models. Refresh the request-shape test to lock the Zen Messages auth dialect while keeping bearer auth for Zen Responses and Chat Completions routes.

Signed-off-by: snailoniu <snailoniu@gmail.com>
The model-aware route guard now reports that the Anthropic-compatible route has no proven FIM wire contract. Keep the local-failure test aligned with that fail-closed behavior and continue asserting that no HTTP request is made.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Align the rebased provider with current route candidate accessors, offering capabilities, registry counts, and Responses URL construction. Rename custom-provider test fixtures now that opencode_zen is a built-in identity, and remove the superseded protocol helper.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Route the opt-in resource-admission test skip notice through tracing so the all-targets Clippy gate respects the TUI module's print_stderr deny policy.

Signed-off-by: snailoniu <snailoniu@gmail.com>
State explicitly that Zen Responses and Chat Completions use Bearer authorization while Anthropic Messages uses x-api-key, matching the request-shape implementation and detailed protocol section.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Align the workflow trigger with the fail-closed deploy preflight so normal pushes and pull requests run validation without creating an impossible deploy job. Pin manual deploys to the dispatched SHA and cover the workflow contract with tests.
Give every direct, nested, sibling, and background worker its own todo list so child updates cannot overwrite the supervisor checklist or parent work graph. Preserve parent progress as immutable fork context and cover the isolation boundaries with focused tests.
Three follow-ups from automated review on #4899.

The real bug: mention_menu_limit = 0 is a documented way to disable the
mention popup, but the @git/@diff tokens were seeded into the entry list
before the limit applied, so typing @g with the popup disabled still
surfaced a one-entry menu. The tokens are menu entries like any other and
now respect the same cap.

Efficiency: one submit resolved each git mention twice — once building the
context-inspector references and once building the model-facing payload.
For @diff that made git compute the entire working-tree diff twice, before
the 32 KB budget applies, to attach it once. Both passes now share a
GitMentionCache scoped to a single submit, so a later message always
re-shells out and can never show a stale working tree.

Reuse: ExternalTool::available() already expressed the git-on-PATH check
without constructing a throwaway Command; this is its first real caller, so
its allow(dead_code) is gone too.

Receipts: file-mention and git-mention suites 28/28, including a zero-limit
regression and a test asserting one submit resolves @diff exactly once;
codewhale-tui 8344/8344; CI's exact clippy invocation, fmt, and diff clean.

Refs #4067.
Only the test build fails on it: CI runs with -D warnings, which promotes
unused_attributes to an error, and the duplicate sat on a cfg(test) item so
an ordinary build never saw it.

Verified with the exact CI shape: RUSTFLAGS="-D warnings" cargo test
-p codewhale-tui --bin codewhale-tui --locked --no-run.
Give each composer chord one stable role: Enter sends or queues, Ctrl+Enter steers, newline chords always add a line, Ctrl+G/Ctrl+S only stash, and Tab never submits text. Empty Enter now promotes the oldest queued follow-up explicitly.

Keep modified Enter chords out of paste-burst suppression, align hints/help/locales/docs, and cover the contract with unit and PTY runtime regressions.
Take the shared environment lock and clear DeepSeek runtime overrides before resolving the Zen route so sibling provider tests cannot leak CODEWHALE_PROVIDER into this assertion. Completes the focused review fix for contributor PR #4467 without changing its implementation.
Preserve @snail-vs's full contributor history from PR #4467 and include the review follow-up that isolates its provider environment test. This local candidate merge is not pushed and remains subject to the combined v0.9.2 release gates.
Stop guessed trailing-newline handling from re-arming the paste window indefinitely, and distinguish a lone IME commit from a paste-speed CJK run. Preserve raw multiline and laggy-link protection while ensuring subsequent human Enter submits.

Cover ASCII paste, CJK IME, and repeated-Enter behavior with unit and real PTY regressions.
Pin the v0.9.2 composer contract: bare Enter queues during any running turn, while Ctrl/Cmd+Enter is the explicit same-turn steer gesture. The previous test still asserted the superseded waiting-state behavior.
Render one bounded authoritative work-state tail for parent turns and sub-agent steps, keep it out of stable history and compaction prefixes, and make fork and relay handoffs consume the same graph-backed snapshot.\n\nAdd regressions for staged graph state, context accounting, per-agent isolation, compaction rehydration, and same-turn relay behavior. Document the exact request boundaries without overstating auxiliary model calls.
Serialize the model-aware provider test with other environment-mutating config tests and clear runtime provider overrides so parallel runs cannot leak a sibling test's provider selection.

Signed-off-by: snailoniu <snailoniu@gmail.com>
Mint an immutable non-secret route authority from the installed client at turn start and require exact provider, model, endpoint, and key generation continuity before launching a DeepSeek prompt suggestion. Injected clients and configured path overrides fail closed, and all debug/display surfaces redact route and credential material.
Merge the updated @snail-vs PR #4467 head so the contributor-authored environment-isolation repair remains in the v0.9.2 candidate ancestry. The only overlap with the prior local review fix was a blank line; the resulting source is unchanged.
Route interactive mode, reasoning, model, and permission changes through one busy-turn lock and a cross-process settings transaction. Atomic no-clobber migration, startup-write shutdown draining, localized failure receipts, and same-live selection outcomes keep the next launch truthful without blocking the TUI event loop.
Keep the public provider facts and source-candidate count aligned with the new ApiProvider variant so the hosted web gate remains truthful.

Verified: npm run check:facts; npm run check:docs; npm test (137/137); npm run lint; npm run build.
Keep the canonical idle-composer wording contiguous so the public-surface contract can verify it without weakening the assertion.

Verified: web check:facts, check:docs, 143/143 tests, lint, and production build.
Publish bounded, agent-addressed WorkState snapshots after real child todo changes and project only matching snapshots onto delegate cards. Keep private ledgers out of transcripts and fanout aggregation while preserving the last truthful snapshot on terminal cards.

Verified: cargo check -p codewhale-tui --locked; focused work-grounding, agent-card, routing, mailbox, and child-work-state filters 89/89; independent static re-review PASS.
Record the live candidate identity, exact CI commands, approval rails, issue dispositions, product decisions, integrated receipts, and unresolved release blockers in one maintained source of truth.
Remove an explicit dereference rejected by Rust 1.97 clippy while preserving the leaked per-path mutex reference used by serialized settings writes.

Verified: settings filter 114/114 (1 child helper ignored); exact codewhale-tui clippy warning policy PASS.
Group configuration rows by their actual scope, identify the saved DeepSeek fallback as a legacy off-route setting, and keep Fleet, Workflow, Lane, Runtime, and future Operation vocabulary distinct across shipped locales and docs.

Closes #4751
Hmbown added 3 commits July 27, 2026 09:48
Update candidate install copy and contributor credits, keep changelog comparisons truthful before the tag exists, and permit an honestly versioned screenshot to lag the source candidate.
Assemble credential-shaped redaction fixtures at runtime so the tests preserve their adversarial coverage without publishing literals that secret scanners classify as live material.
Refresh the living v0.9.2 ledger with the bumped candidate identity, three focused repair commits, and the exact local verification evidence that precedes the hosted rerun.
@Hmbown
Hmbown marked this pull request as ready for review July 27, 2026 16:49
Copilot AI review requested due to automatic review settings July 27, 2026 16:49
@cursor

cursor Bot commented Jul 27, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude Code is reviewing this PR

Todo list

  • Gather context (diff vs origin/main, changed files, custom review focus areas)
  • Review correctness (panics, unwrap/expect, error handling, exhaustive matches)
  • Review provider/model/route safety (v0.8.65 EPIC v0.8.65 EPIC: Separate provider facts, model facts, offerings, and route resolution #2608 invariant)
  • Review reuse/simplification/dead code
  • Review test coverage for new behavior
  • Review security (secrets, exec policy, input validation) — note GitGuardian findings
  • Post final review summary

View job run

Guard nullable screenshot metadata explicitly and compare it with the non-null source-candidate version so the hosted TypeScript check agrees with the runtime public-surface contract.
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 3m 59s —— View job


Claude Code is reviewing this PR

Todo list

  • Gather context (diff vs origin/main, changed files, custom review focus areas)
  • Triage GitGuardian findings (all 5 are redaction/credential test fixtures, not live secrets)
  • Manually review config/pricing, config/user_constitution, agent model registry, secrets provider aliases, TUI command dispatch/session/config files not covered by parallel review
  • Parallel deep review in progress: route/provider resolution, lane control runtime, client/chat plumbing, large new session/debug command files
  • Review test coverage for new behavior
  • Post final review summary

Hmbown added 2 commits July 27, 2026 10:12
Serialize the unknown-mode regression with the shared environment lock and remove ambient MINIMAX_API_KEY so suite order cannot turn an unproven route into a metered or token-plan route.
Advance the living candidate identity and replace the prior flake disposition with the isolated 9,299-test pass plus the hosted TypeScript follow-up evidence.
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 2m 12s —— View job


Claude Code is reviewing this PR

Todo list

  • Gather context (diff vs origin/main, changed files, custom review focus areas)
  • Verify GitGuardian findings (all 5 confirmed test-fixture literals in redaction.rs/safe_label.rs/request_manifest.rs/prompt_suggestion.rs — already de-fanged in current HEAD; flagged commits predate the de-fanging commit)
  • Parallel deep review in progress: route/provider resolution (EPIC v0.8.65 EPIC: Separate provider facts, model facts, offerings, and route resolution #2608 invariant), lane control runtime (new control.rs, 3261 lines), TUI client/chat plumbing, session export/structcopy, debug/core command groups, CLI/agent/secrets/user_constitution
  • Review test coverage for new behavior
  • Post final review summary

CI status: 5 passed (DCO, cargo-deny, Web Frontend, Security audit, closes-issue check), 4 in progress (CI, OpenHarmony, this review, PR check), 0 failed so far.

Hmbown added 2 commits July 27, 2026 10:32
Add an explicit child-start handshake before the parent's atomic-write loop so slower Windows process startup cannot produce a zero-read, non-proving result.
Advance the v0.9.2 candidate ledger to the settings-test repair and record five consecutive strict targeted passes before the definitive hosted run.
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 5m 35s —— View job


Claude Code review — v0.9.2 integration candidate

Todo list

  • Gather context (diff vs origin/main, 381 files changed, +106829/-5847)
  • Verify GitGuardian findings (all 5 confirmed test-fixture literals, already de-fanged)
  • Manually review config/pricing, config/user_constitution, agent model registry, secrets provider aliases, TUI command dispatch/session/config files
  • Deep review: route/provider resolution (EPIC v0.8.65 EPIC: Separate provider facts, model facts, offerings, and route resolution #2608 invariant) — catalog.rs, provider.rs, route/*.rs
  • Deep review: lane control runtime — control.rs (3261 lines, new), registry.rs, runtime.rs
  • Deep review: TUI client/chat plumbing — client.rs, chat.rs, prepared.rs, responses.rs, anthropic.rs
  • Deep review: large new session/debug command files — structcopy.rs (2844 lines), preview_request.rs, core/lane.rs, constitution.rs, hooks.rs, fleet.rs, config.rs
  • Review test coverage for new behavior
  • Post final review summary

EPIC #2608 (provider/model-prefix invariant): no violations found

Checked route resolution, the lane control plane, TUI client/chat/prepared/responses plumbing, and Lane/Fleet control commands. Provider selection consistently comes from explicit_provider/config/Fleet policy before any model-string inspection. Prefix-stripping (opencode/, opencode-zen/) only normalizes a wire id within an already-selected provider's scope, never picks the provider. The new exact-route helpers (is_exact_minimax_*, is_exact_zai_*) gate wire-body shaping on (provider, base_url, model) triples, not prefix inference — actually tightens a prior gap where reasoning-field shaping was gated on provider enum alone.

Findings (posted inline, most important first)

  1. crates/lane/src/control.rs:1929-1938 — Important. lane_one() collapses every registry.load() error (I/O failure, corrupt JSON) into NotFound, discarding the real error. A corrupted-but-present Lane record becomes permanently "not found" instead of a retryable backend failure, unlike LaneRegistry::list() which handles corruption more honestly.
  2. crates/config/src/route/resolver.rs:331-345 — Reuse/simplification. Byte-for-byte duplicated if require_catalog_match { return Err(...) } block in scope_selector; the second copy is unreachable dead code, likely a merge artifact — worth confirming nothing distinct was meant to go there before deleting.
  3. crates/tui/src/client.rs:1208 — Minor/efficiency. bind_request_to_protocol calls RouteResolver::new() per request for OpenCode Zen, re-parsing the bundled catalog JSON and rebuilding the offering list on every turn instead of once at construction. Correct, just wasteful — a OnceLock would avoid the repeated work.
  4. crates/config/src/pricing.rs:233 — Nit. Doc comment on endpoint_fingerprint still says "FNV digest" but base_url_fingerprint was changed to SHA-256 elsewhere in this diff.

Additional minor items not inline (lower priority, no action required):

  • control.rs redact_token's SECRET_KEY_HINTS matches bare "key" via ends_with, so monkey=1/hockey=2-shaped tokens get over-redacted — safe-direction false positive, just cosmetic in debug output.
  • client.rs:1853 unreachable!() (no message) relies on a 1:1 WireFormat/WireDialect mapping holding — fine today, add a message if this is ever restructured.
  • core/constitution.rs:88 matches rest.starts_with("ratify") rather than an exact token, so /constitution ratifyme parses as ratify with id "me" instead of erroring — low impact since ratify still fails closed against the live digest.
  • debug/cache.rs silently clamps u32::try_from(...).unwrap_or(u32::MAX) on overflow rather than surfacing a display error — harmless given realistic token counts.

What's genuinely well done

  • crates/lane/src/control.rs (new, 3261 lines) is thoroughly tested (~40 inline tests) including a real multi-threaded TOCTOU test for the fencing logic (concurrent_interrupts_produce_exactly_one_transition), and correctly closes a lifecycle race by checking the fence under the per-Lane lock rather than before it.
  • crates/tui/src/client/prepared.rs unifies production dispatch and /preview-request behind one seam (prepare_outbound_request), eliminating a real class of preview/production drift; chat.rs's build_chat_wire_body extraction removes ~150 lines of prior streaming/blocking duplication.
  • saturating_u32 replacing as u32 casts and the reasoning_tokens <= output_tokens filter close a real double-billing bug (Pricing: cache-write rates dropped by CurrencyPricing/TokenUsage #4318), with strong regression tests.
  • structcopy.rs (new, 2844 lines) correctly reuses export::redact_json/sanitize_text/is_sensitive_key rather than reimplementing transcript redaction, is fail-closed on ambiguous URLs/paths/over-cap payloads, and is proven absent from the model-visible tool catalog by a dedicated test.
  • hooks.rs fixes a real terminal-escape-injection vector in /hooks list rendering, now sanitized and tested.
  • Secret handling: all 5 GitGuardian hits are redaction-logic test fixtures (crates/workflow/src/redaction.rs, crates/tui/src/safe_label.rs, request_manifest.rs, prompt_suggestion.rs), already de-fanged in current HEAD.

No blocking correctness bugs or EPIC #2608 violations found. This PR is explicitly marked "Do not merge" (umbrella review/CI surface per the description), so the above should feed narrower harvest PRs rather than block this draft.
· Branch: codex/v092-integration-direct-main

Comment thread crates/lane/src/control.rs
Comment thread crates/config/src/route/resolver.rs Outdated
Comment thread crates/tui/src/client.rs Outdated
Comment thread crates/config/src/pricing.rs Outdated
Hmbown added 5 commits July 27, 2026 11:04
Let missing records retain their typed I/O cause, map only true absence to NotFound, and surface corrupt or unreadable records as retryable backend failures with focused coverage.
Drop the byte-identical unreachable require_catalog_match branch left by integration; the surviving guard remains the sole fail-closed protocol proof.
Build the bundled OpenCode Zen route resolver once per process instead of reparsing and rebuilding its offerings on every request, while retaining per-request protocol validation.
Correct the endpoint fingerprint contract after the catalog cache moved away from FNV.
Advance the candidate ledger through all four final-head Claude findings and record the Lane, Zen routing, protocol, clippy, format, and diff receipts.
@claude

claude Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 1m 55s —— View job


Claude Code review — v0.9.2 integration candidate (re-review after push)

Todo list

  • Identify what changed since the last review (5 new commits, diff-stat confirmed: only control.rs/registry.rs, resolver.rs, client.rs, pricing.rs, and the completion ledger touched)
  • Verify fix(lane): preserve registry load failures resolves the lane_one() finding
  • Verify refactor(route): remove duplicate catalog guard resolves the dead-code finding
  • Verify perf(client): cache the Zen route resolver resolves the OnceLock finding
  • Verify docs(pricing): name the SHA-256 route fingerprint resolves the stale doc finding
  • Scan for regressions introduced by the fixes themselves
  • Post final review summary

All four previously flagged findings are resolved

I diffed HEAD~5..HEAD and confirmed the delta since the last review round is exactly these five commits, touching only the files the findings named — no unrelated changes snuck in.

  1. lane_one() swallowing registry errors (crates/lane/src/control.rs) — fixed correctly in 71c7083. The catch-all Err(_) => NotFound is now split: only an io::Error with ErrorKind::NotFound (via downcast_ref) maps to not_found; every other error (corrupt JSON, permission denied, etc.) now returns ControlFailure::backend(...) with the original error text preserved and retryable: true. Correctly paired with removing the redundant if !path.is_file() { bail!(...) } pre-check in registry.rs::load() — that check produced a plain string error that wouldn't have downcast to io::Error, which would have silently defeated the new classification for the "truly absent" case. Backed by a new test, corrupt_lane_records_are_retryable_backend_failures, that asserts on ControlFailureKind::Backend, retryable, and the error message. I checked all other registry.load() call sites (registry.rs:292,394 via ?, runtime.rs, tui/lane_control.rs, tests) — none depend on the removed pre-check's error text, so this is a clean, self-contained fix.
  2. Duplicate require_catalog_match block (crates/config/src/route/resolver.rs) — the unreachable duplicate is removed in 2807007; the surviving guard is untouched. Clean.
  3. RouteResolver::new() rebuilt per request (crates/tui/src/client.rs:1208) — fixed in fb6b1c6 with a static RESOLVER: OnceLock<RouteResolver> initialized via get_or_init, so the bundled catalog is parsed once per process instead of per turn; per-request resolution behavior is unchanged.
  4. Stale "FNV digest" doc comment (crates/config/src/pricing.rs:233) — updated to "SHA-256 digest" in 17f6ae8, matching catalog::base_url_fingerprint.

The final commit (1208642) just advances docs/releases/v0.9.2-completion-ledger.md to record these receipts — no code change.

No new issues found in this delta, and EPIC #2608 provider/route-safety invariants are unaffected by these commits (none of them touch provider-selection logic).

Note: cargo check/cargo test were not permitted to run in this environment (tool approval required and unavailable here), so verification above is a careful manual/static read of the diffs plus a check of all other call sites of the changed functions, rather than a compiled/test-run confirmation. Recommend confirming green CI (cargo test -p lane, cargo test -p config) before treating this as fully verified.

This PR remains marked "Do not merge" (umbrella review/CI surface). Nothing here blocks continued integration.
· Branch: codex/v092-integration-direct-main

@Hmbown
Hmbown merged commit 8fff533 into main Jul 27, 2026
26 of 27 checks passed
@Hmbown
Hmbown deleted the codex/v092-integration-direct-main branch July 27, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants