Repository navigation
fix(consolidation): an unreported provider cost is unknown, not a free 0.0 (#733, slice 2) - #962
Conversation
…e 0.0 (#733, slice 2) _parse_invoke_response returned cost_usd=0.0 when `claude --print` exited non-zero, printed nothing, printed non-JSON or omitted total_cost_usd, and _claude_invoke did the same on a timeout. CycleBudget summed those zeros, so a cycle whose calls reported no cost read as a free cycle in the consolidate response and the groomer journal. InvokeResult.cost_usd is now float | None: None when the CLI reported no cost (a reported 0.0 stays 0.0; a spawn failure, where no child ran, stays a known 0.0). cycle_budget_charge counts a None as an unpriced call instead of adding it, and CycleSummary, DistillCycleSummary and the consolidate `headless_authoring` block report `unpriced_calls` beside `usd_spent`, which is a lower bound whenever unpriced_calls > 0. Refs #733 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018kyZYq7srjBjYA18eWLVgL
Codex Review Summary: ✅ CompletedThis 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. |
|
Claude finished @cdeust's task in 2m 19s —— View job Review 1 of 3: PR #962
No Blockers. Three Notes are in the review comment: the Verdict: approve |
Review 1 of 3: PR #962I ran five reviews (quality, security, performance, test coverage, docs accuracy). None found a Blocker. Every consumer of Not verified here: I could not run pytest, ruff or the craftsmanship gate in this runner because the commands need approval. CI (Pipeline) was still running when I posted this. Notes, no action before merge
Verdict: approve |
|
Merci pour la revue 1 sur 3. Aucun Blocker, donc pas de push (ADR-1119). Voici ce que je fais des trois Notes :
Generated by Claude Code |
The mutation gate of check `unit` (run 42758075984) selects a module's tests by the dotted import (scripts/ci_mutation_diff.py select_tests). The #733 test reached cycle_types only through headless_authoring's re-export, so cycle_budget_charge's mutants ran against the throttle test alone and survived; no test imported cycle_orchestration; nothing called _claude_invoke's early returns; and no test read the headless_authoring stanza's unpriced_calls key. The budget test now imports cycle_types itself, and a new file pins the no-child (known 0.0) and killed-child (unknown) returns of _claude_invoke, the _summarize_cycle roll-up, and run_wiki_maintenance's unpriced_calls key. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018kyZYtAKnComJzh2PytToW
|
CI autopilot, tentative 1 : la gate de mutation de Diagnostic : la gate choisit les tests d'un module par leur import pointé ( Commit poussé : 5111e02 Reçus locaux :
Non vérifié : la suite complète, parce que Generated by Claude Code |
|
Échec J'avais préparé le même correctif, mais une autre session a poussé Non vérifié ici : le reste du check Generated by Claude Code |
|
Claude finished @cdeust's task in 2m 17s —— View job Review 2 of 3: PR #962
No Blockers. Three Notes are in the review comment: two tests share the value 2 across fields, one docstring phrase is too narrow, and Verdict: approve |
Review 2 of 3: PR #962Scope: commit I ran five reviews (quality, security, performance, test coverage, docs accuracy). None found a Blocker. The patched names and call signatures match the production code. No test starts a real Not verified here: I could not run pytest, ruff or the craftsmanship gate in this runner because the commands need approval. Pipeline was still queued when I posted this. Notes, no action before merge
Verdict: approve |
|
Revue 2 sur 3 : approuvée, sans Blocker, donc pas de push (ADR-1119). Ses trois Notes partent dans la tranche 3 de #733 :
Generated by Claude Code |
Summary
Slice 2 of #733 (slice 1: #895). An unknown provider cost was reported as
0.0, so a headless-authoring or distillation cycle whoseclaude --printcalls reported no cost read as a free cycle.Root cause.
_parse_invoke_response(mcp_server/handlers/consolidation/claude_invoke.py) returnedcost_usd=0.0on a non-zero exit, empty stdout, non-JSON stdout or an absent/nulltotal_cost_usd;_claude_invokedid the same after a timeout.cycle_budget_chargesummed those zeros intousd_spent(probe reproduced indocs/audits/operation-consumption-inventory-2026-11-05.md).Change.
InvokeResult.cost_usdisfloat | None:Nonewhen the CLI reported no cost. A reported0.0stays0.0; a spawn failure (no child process ran) stays a known0.0.cycle_budget_charge(budget, None)incrementsCycleBudget.unpriced_callsinstead of adding tousd_spent.CycleSummary,DistillCycleSummaryand theconsolidateresponse'sheadless_authoringblock reportunpriced_callsbesideusd_spent(usd_spentis a lower bound wheneverunpriced_calls > 0).scripts/groomer.pyserialises the summaries withasdict, so its journal carries the field without a change.docs/groomer-scheduling.mdstates the meaning of the two fields.Refs #733 (the issue stays open: slices 3–5 remain, listed in the issue comment).
Type of change
Test plan
tests_py/handlers/consolidation/test_unknown_cost_733.py(9 tests): the five unreported-cost outputs giveNone; a reported0.0stays0.0; a reported cost is read; an unpriced charge is counted, not summed, and does not exhaust the USD cap; a distillation cycle of three unpriced calls reportsunpriced_calls == 3,usd_spent == 0.0. Mutation caught: restoringor 0.0fails the five parametrised cases.pytest tests_py/handlers tests_py/hooks --deselect tests_py/hooks/test_entry_auto_dispatch.py: 2868 passed, 113 skipped (PostgreSQL), 0 failed.tests_py/hooks/test_entry_auto_dispatch.py: 2 failures that reproduce identically onorigin/main(7b81ab1) in this container (torch not installed: the PyTorch index is unreachable here); not caused by this diff.ruff check/ruff format --check(0.17.3, fromuv.lock) on the changed files: clean.python scripts/check_craftsmanship.py: OK.Audit notes
claude --printrun (no CLI call made here), the PostgreSQL-backed tests (skipped), pyright (not run locally; CI runs it).Breaking changes
InvokeResult.cost_usdandDistillDrainResult.cost_usdcan now beNone. Every in-repo consumer goes throughcycle_budget_charge, which accepts it; the JSON outputs gain theunpriced_callskey.Generated by Claude Code