Repository navigation
0.10.2 slices: fail-closed tier pricing (#6396), build-lock bypass fix, then Windows owner recovery (#6915) - #6965
Conversation
…-pricing
A live models.dev row can publish context tiers (`tiers` or the legacy
`context_over_200k`). The catalog audit path priced every turn on such a
row at its base rate, so a turn above the first tier was undercharged
silently. `refused_catalog_pricing_audit` (was
`invalid_catalog_pricing_audit`) now also returns
`UnpricedReason::UnrepresentedTier` ("pricing tier unavailable") when the
turn's total prompt input (`Usage::input_tokens`, cache read and write
included) is at or above a context tier's size, and for any tier kind
other than "context". It runs at both catalog call sites: the
provider/catalog route and the OpenRouter bundled-only path.
This is the first consumer of `ModelsDevCost::context_tiers()`, which
already folds `tiers` and `context_over_200k` into one sorted list and had
no caller until now. No new reason, string or locale key: the existing
reason and its 15 translations are reused.
Frozen quotes are untouched because they cannot carry tiers: provider-live
costs are built from the four base fields (client.rs, two sites),
cloud-facts patches replace the whole cost block (catalog_patch.rs), and
custom_models accepts only the four keys (catalog/configured.rs). Tier
rates themselves are still not applied; the 0.10.2 Known limits line now
says so, and crates/tui/CHANGELOG.md is regenerated by
scripts/sync-changelog.sh.
Not model-visible: cost audits never reach a request, so no session event
and no KV-cache effect. Pure computation, so #6149 does not apply.
Evidence:
- cargo test -p codewhale-tui --lib --locked -- pricing:: cost_status::
test result: ok. 130 passed; 0 failed (86 pricing::, 44 cost_status::),
including malformed_catalog_row_has_an_explicit_runtime_reason and
models_dev_live_rates_price_the_published_estimate (live refresh path,
untiered row, still priced)
- cargo fmt --all -- --check: clean
- scripts/sync-changelog.sh --check: up to date
- the tier edge itself is not exercised by a test (no new tests without
founder request); the bundled catalog has no tiered rows
Refs #6396
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
…D itself The script's docstring says nested invocations see CODEWHALE_BUILD_LOCK_HELD and run unlocked, and its wait message tells the user to "set CODEWHALE_BUILD_LOCK=0 to skip". Neither was true: only scripts/dev-cache.sh checked the two variables before calling it. Every direct caller (CI's self-hosted lock holder, agents wrapping npm or cargo in build-lock.py) ignored both, and a nested direct call deadlocked on the lock its own parent held. The script now runs the command unlocked when CODEWHALE_BUILD_LOCK_HELD is non-empty or CODEWHALE_BUILD_LOCK is one of dev-cache.sh's falsey values (0, false, no, off, never, disabled), with the same exit-status mapping as the locked path. The locked path is unchanged. Evidence, scratch lock files only (never the real build.lock): - committed script, lock held by `-- sleep 8`: CODEWHALE_BUILD_LOCK=0 call -> timeout (exit 124), CODEWHALE_BUILD_LOCK_HELD=1 call -> timeout (124), `build-lock.py L -- python3 build-lock.py L -- echo` -> deadlock (124) - fixed script, same setups: all three exit 0 immediately; each of false/no/off/never/disabled exits 0 - still locks: CODEWHALE_BUILD_LOCK=1, yes, on, unset, and an empty CODEWHALE_BUILD_LOCK_HELD all wait while held (124 under a 2 s timeout) and run after release (exit 0); the locked child still sees CODEWHALE_BUILD_LOCK_HELD=1 - exit status: `sh -c 'exit 7'` -> 7 locked and bypassed; SIGTERM -> 143 locked and bypassed; bad usage -> 2 - python3 -m py_compile and ruff check: clean Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
UNVERIFIED WORK IN PROGRESS, pushed so it survives a move off the cloud session. Do not merge as is. Implements the Q4 plan for #6915 (founder: blocks the 0.10.2 tag; proof is the hosted Test (windows-latest) leg). Windows startup used connect_if_published and failed hard with "opening selected Windows owner; refusing fallback ... (os error 2)" once the owner died; the "stale-owner recovery is not qualified" guard in app-server lib.rs was unreachable. This joins Windows to the lease-first admission and the Unix recovery from a8cdccc: - config/windows_identity.rs: windows_process_status(pid) -> Running/Exited/Absent from OpenProcess + creation time + WaitForSingleObject - config/private_directory.rs: POSIX-semantics handle deletion with the legacy fallback (same order as std::fs::remove_file) - app-server daemon_client.rs: require_dead_process / revalidate_* on Windows; require_same_selection shared with Unix; a NotFound pipe open maps to Unavailable - app-server daemon_windows.rs: bind takes `recovery`, retires the captured receipt by handle before creating the first pipe instance - app-server daemon_socket.rs: Unix bind uses require_same_selection - app-server lib.rs: the Windows-only ensure is gone; one bind call - tui runtime_api.rs / runtime_threads.rs: RuntimeHostAdmission, admit_runtime_host, try_acquire_for_host are cfg(any(unix, windows)); the Windows connect_if_published branch is deleted - cli/tests/owner_crash_reentry.rs: the founder-requested two-process test (spawn A, kill+reap, receipt still names dead A, spawn B, B owns it and serves A's thread) Verified so far (Linux only): - clippy -p codewhale-config -p codewhale-app-server -p codewhale-tui -p codewhale-cli --all-targets --all-features --locked -- -D warnings: exit 0, no warnings - cargo fmt --all -- --check: clean NOT yet run: owner_crash_reentry (Linux), app-server daemon_socket owner_bootstrap tests, tui runtime_api::tests::owner_bootstrap, any Windows compile (x86_64-pc-windows-gnu cross-check or hosted windows-latest), the three-lens review, the CHANGELOG change (drop the 0.10.2 Windows known-limit bullet, add the fix line, run scripts/sync-changelog.sh). Refs #6915 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
A turn at or above a catalog row's first context tier now reports pricing tier unavailable rather than silently using its base rate. Unknown tier kinds also fail closed. Both catalog consumers reuse context_tiers() and the existing localized UnrepresentedTier reason; no new prompt bytes or session events are introduced. Continues verified cloud slice 2cb33c4 from PR #6965. This is S8 only; the founder kept the remaining #6396 scope in v0.10.2. Verification on canonical main 506cdf3 plus the recovered source: - macOS focused pricing/cost_status nextest: Summary: 130 tests run: 130 passed, 15203 skipped (0 failed). - npm test: 1312 passed; 0 failed; 7 skipped. - npm run check:web: exit 0 (facts, docs, lint, types and build). - cargo fmt --all -- --check and changelog synchronization: exit 0. - No new tests. The bundled catalog has no tiered row; the new boundary remains source-reviewed rather than directly exercised by a fixture. Refs #6396 Refs CW-6787 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
Direct callers now honor CODEWHALE_BUILD_LOCK_HELD and the same six falsey CODEWHALE_BUILD_LOCK values as dev-cache.sh. This prevents nested calls from waiting forever on their parent's lock and preserves child exit statuses. The locked path is unchanged. Continues cloud slice e43d86e from PR #6965. Local disposable-lock probes: 8 passed; 0 failed (six falsey bypasses, held-lock bypass, and a real nested invocation). Exit 7 is preserved. The normal machine lock serialized the macOS tests and Windows checks. Shared unchanged-source gate: npm test 1312 passed; 0 failed; 7 skipped; npm run check:web exited 0. No new tests or comments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
Windows now uses the existing lease-first owner admission/recovery path. A captured owner publication is replaced only after matching the selected principal, store, scope, config and endpoint and proving its recorded process is dead. Access-denied or uncertain liveness refuses recovery; creation time rejects a reused PID. Exact-handle POSIX deletion retires the old receipt while readers retain their handles. Preserve the Unix selection rule exactly. Windows blocking mutations and receipt cleanup retain the actual Runtime manager across cancellation. The founder-requested crash/reentry test kills owner A, preserves its publication, and proves owner B serves A's saved thread while a CLI attaches to B. Keep Windows system variables and fixture temp paths, drain stdout after readiness, and reuse the shared TLS client builder. Register the test in nextest's spawns-binaries group. Update both Runtime API docs and synchronize the 0.10.2 changelog. Completes and consolidates cloud WIP ec242fe from PR #6965 with the lease-custody and harness fixes above. Source was frozen throughout the checks; retained SHA-256 inventory shows no source changes. Local macOS receipts (exit 0): - owner_crash_reentry: Summary ... 1 tests run: 1 passed, 0 skipped. - daemon_socket owner_bootstrap: 6 passed; 0 failed; 9 skipped. - existing cancellation helper test: 1 passed; 0 failed; 172 skipped. - TUI owner_bootstrap: 7 passed; 0 failed; 15326 skipped. - First harness run failed (0 passed; 1 failed) because it bypassed the shared TLS provider initializer; corrected run above passed. - Native linking emitted one existing oversized __eh_frame warning; these are passing tests, not a zero-warning native build claim. Windows GNU cross-checks with RUSTFLAGS=-Dwarnings, all features: - config + app-server check and clippy -- -D warnings: exit 0. - TUI + CLI check --all-targets: exit 0, 8m 04s. - brew mingw-w64 could not install because of a pre-existing invalid llvm@21 keg. Used installed Zig0.16 wrappers. The first TUI/CLI check failed in dependency SIMD C++; the passing retry disabled only its ICELAKE implementation through target-specific CXXFLAGS. No dependency or Engine source was modified for that tooling workaround. Shared unchanged-source gate: npm test 1312 passed; 0 failed; 7 skipped; npm run check:web exit 0. fmt, blocking-call budget (538 sites), dead-code budget (221 suppressions) and changelog synchronization passed. The hosted Test (windows-latest) / Run tests PASS for codewhale-cli::owner_crash_reentry on the candidate SHA is still required before tagging. Linux execution and native Windows app qualification remain separate receipts. No tag, release or deployment is authorized. Refs #6915 Refs CW-7079 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
The original tier-pricing, build-lock bypass and Windows owner recovery work is carried by1490dd8900,2a4c1f02b1 and35498ef68b. Resolve daemon_windows, owner_crash_reentry and runtime_api conflicts with current main to preserve completed crash recovery, TLS and owner-state custody fixes. Every other path auto-merges. The resolved complete tree is exactly89d1b981df62ff3f625fb9fa685821f5b90a9136, equal to main68f4dd3406. No original product hunk is missing; retain all three original authored commits through the first parent and current main through the second. The old draft head failed native CI; this reconciliation needs fresh resulting-head checks before merging. Full original source/review audit and exact full-tree equality passed. No canonical checkout or peer build input changed. Refs #6965 Signed-off-by: CodeWhale Bot <bot@codewhale.net>
There was a problem hiding this comment.
If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.
Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request. Check if the Files changed in this pull request are included in default exclusions.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
The original context-tier pricing, build-lock bypass and Windows owner-recovery slices are carried by 1490dd8900, 2a4c1f02b1, and 35498ef68b. Current owner-state custody, secured lifecycle lock, selected-store socket and TLS fixes are preserved. All original product hunks are accounted for; five original files remain byte-identical.
The original PR commits remain ancestors of the updated source branch. Reconciliation head
2710efe40248d520b163fc3b07cc59844539ff82merges main68f4dd34065eac930565b7e87dfb71d134fe646ewithout changing its product source: the complete resulting tree is exactly89d1b981df62ff3f625fb9fa685821f5b90a9136, identical to that main commit. This lets the original PR land with its authored history and current implementations intact.Verification: full original diff and review-thread audit, carrying ancestry, field/control-path comparison, and exact complete-tree equality pass. All exact-head checks completed successfully, including CodeQL. Older failed CI remains failed; it is not evidence for this head. A successful native job that skips work for an empty source diff is not a new native test run. Merged as this original PR in
601009c8b9f6838683b599083542d0feb5149404; source branch and authored history are preserved. Resulting-main checks remain separate.0.10.2 has not been published. Source branches are preserved.
Refs #6968