Skip to content

fix(cost): stop fabricating $0.00 prices for unpriced models - #956

Merged
seonghobae merged 14 commits into
mainfrom
fix/cost-ledger-price-honesty
Sep 1, 2026
Merged

fix(cost): stop fabricating $0.00 prices for unpriced models#956
seonghobae merged 14 commits into
mainfrom
fix/cost-ledger-price-honesty

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Both bugs (adversarial audit confirmed, both real)

Bug 1 — PriceBook.compute_cost() fabricates a $0.00 price for any unpriced provider/model.
contextual_orchestrator/cost_ledger.py. Previously: entry is Nonereturn 0.0, self.default_currency. That flows into CostLedger.record_usage() as UsageRecord.cost_amount, while measurement_status is computed independently — purely from whether token counts were reported (cost_router.py) — so a request with real, provider-reported usage against a model that simply has no price row yet was recorded as cost_amount=0.0, measurement_status="measured": "we measured this and it cost nothing," when the truth is "we don't know the price." This contradicts this repo's own Honest metrics convention (CLAUDE.md) and is inconsistent with two sibling honest-degradation patterns already in this codebase: model_discovery.py leaves Bytez per-token pricing unset rather than invent one ("more honest than a misleading estimate"), and orchestrator.py's commercial-readiness report surfaces unpriced models under a separate unpriced_models key with a null cost instead of a fabricated zero. cost_ledger.py had no equivalent "price unknown" signal anywhere.

The existing test test_unpriced_model_costs_zero_and_still_records confirmed the $0.0-on-unpriced behavior is deliberate (never fail recording on a missing price row) but only asserted cost_amount == 0.0, with no way to tell that zero apart from a real free price.

Bug 2 (downstream of bug 1) — rollup()/.report()/.total() blend measured, estimated, and unavailable-priced rows into one opaque total.
All three summed cost_amount from every stored row with zero regard for measurement_status. The buyer-facing cost_report() API presented one authoritative-looking grand_total/per-dimension total that could silently mix fully measured dollars with rows that are $0 only because the price or the usage was unknown — with nothing in the output surfacing how many records, or how much of the total, fell into each bucket. The data (measurement_status) already existed per-row; it was just discarded during aggregation.

The fix

  1. PriceBook.compute_cost() now returns a (cost_amount, currency_code, price_known) 3-tuple — price_known=False only when there's no price row (entry is None), True otherwise. Updated all 3 call sites (cost_ledger.py::record_usage, model_discovery.py's discovery-ranking cost key, batch_routing.py::cheapest_upstream — the latter two discard the new third element since their existing logic doesn't need it).
  2. UsageRecord gains price_known: bool = True (default True so callers setting cost_amount explicitly, bypassing PriceBook, are unaffected), captured from compute_cost() in record_usage(), included in as_dict().
  3. Persisted via a new usage_price_knowledge satellite table — same pattern this file already uses for measurement_status/usage_measurements (a LEFT JOIN + COALESCE(..., 0) default, not an ALTER TABLE), including in the legacy-flattened-schema migration path, where a migrated row's price-knownness is genuinely unknown and is marked 0/unknown rather than assumed known.
  4. CostLedger.rollup()/.total() (and therefore .report()) add additive, backward-compatible cost_amount_by_status/record_count_by_status breakdowns keyed by measurement_status (measured/estimated/unavailable) alongside the existing flat cost_amount — computed so the flat total is provably the sum of the breakdown (not double-computed and hoped to match). cost_amount's existing meaning and value are unchanged; every previously-passing test that asserts a flat total still passes unmodified.
  5. cost_router.py::cost_report()'s docstring updated to mention the new breakdown (no logic change — it just forwards ledger.report()'s output).

Tests

  • Extended test_unpriced_model_costs_zero_and_still_records with record.price_known is False; added test_priced_model_marks_price_known_true.
  • test_compute_cost_returns_price_known_flag — asserts the 3-tuple shape/values for both priced and unpriced cases directly on PriceBook.
  • test_rollup_report_total_break_down_cost_by_measurement_status — records one measured, one estimated, one unavailable (unpriced) row with distinct costs; asserts cost_amount_by_status/record_count_by_status on total(), rollup(), and report(), and that the flat cost_amount total is unchanged and equals the sum of the breakdown.
  • test_sql_ledger_persists_price_known_flag — round-trips price_known through SqlLedgerStore/sqlite.
  • Extended the existing legacy-migration tests (test_sql_ledger_migrates_flattened_usage_rows, test_orphaned_legacy_generation_is_adopted_and_dropped) to assert migrated rows get price_known=False (unknown, not assumed known).
  • Extended test_ledger_table_names_follow_two_word_snake_case to cover the new (and the previously-untested usage_measurements) table names.
  • Updated the pre-existing compute_cost 2-tuple unpackers in tests/test_cost_ledger_boundaries.py and tests/test_batch_routing_boundaries.py's _StaticPriceBook mock to the new 3-tuple contract.

Validation

  • python -m pytest tests -q: 2835 passed, 1 skipped, 1 pre-existing unrelated failure (test_psychometric_routing.py::test_fast_mlsirm_fit_uses_judge_acceptance_item_for_context_scoreModuleNotFoundError: No module named 'fast_mlsirm'; confirmed identical on unmodified origin/main via git stash, so unrelated to this change).
  • python -m interrogate -c pyproject.toml contextual_orchestrator/: PASSED (100.0%).
  • Coverage spot-check on the touched modules: all new branches exercised; the only uncovered lines in cost_ledger.py are pre-existing, untouched error-handling paths.
  • Rebuilt on current origin/main (merged in 045d17da — Bytez is_free fix, a clean auto-merge with no conflicts in model_discovery.py).
  • No open PR in this repo touches cost_ledger.py's compute_cost/rollup (checked before opening this one).
  • No new dependency (Ponytail gate n/a — everything here is stdlib Decimal/SQL already in use in this file).

Do not merge without the required CI checks (Security workflow, OpenCode review) passing per this repo's governance.


Generated by Claude Code

Summary by CodeRabbit

  • 개선 사항
    • 비용 기록에 가격 산정 여부가 표시됩니다.
    • 가격 정보가 없는 사용량은 비용을 $0.00으로 오인하지 않고 비용을 null로 표시합니다.
    • 비용 보고서에서 측정 상태와 가격 확인 상태별 비용 및 기록 수를 확인할 수 있습니다.
    • 가격이 확인되지 않은 공급자는 최저 비용 후보에서 제외됩니다.
    • 배치 사용량이 유효하지 않은 토큰 값으로 계산되지 않도록 개선했습니다.
    • 중복 기록 재시도 시 기존 비용 정보가 변경되지 않습니다.

claude added 2 commits August 31, 2026 06:25
PriceBook.compute_cost() silently returned a $0.00 price for any
provider/model without a configured price row, and that fabricated zero
was indistinguishable from a real free price once recorded — the ledger
asserted "measured, cost nothing" when the truth was "price unknown".
This contradicted the repo's own honest-metrics convention and the two
sibling honest-degradation patterns already in this codebase
(model_discovery's unset Bytez per-token pricing, and orchestrator's
separate unpriced_models reporting key).

compute_cost() now returns a (cost_amount, currency_code, price_known)
3-tuple. UsageRecord gains a price_known: bool field, persisted through
a new usage_price_knowledge satellite table joined the same way
usage_measurements already is (including the conservative "unknown"
default for rows migrated from the pre-price_known flattened schema).

CostLedger.rollup()/.report()/.total() add an additive
cost_amount_by_status/record_count_by_status breakdown
(measured/estimated/unavailable) alongside the existing flat
cost_amount total, so measured, estimated, and unavailable-priced spend
are no longer opaquely blended into one authoritative-looking number.
cost_amount's existing meaning and value are unchanged.
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 53 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 5e88e007-6115-4b8e-b973-8e6386640995

📥 Commits

Reviewing files that changed from the base of the PR and between 2314341 and 4e239d4.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • contextual_orchestrator/batch_routing.py
  • contextual_orchestrator/cost_ledger.py
  • contextual_orchestrator/cost_router.py
  • contextual_orchestrator/model_discovery.py
  • tests/test_cost_ledger.py
  • tests/test_cost_router.py
  • tests/test_cost_router_boundaries.py
📝 Walkthrough

Walkthrough

PriceBook이 가격 지식 상태를 반환하고, 원장이 이를 저장합니다. 집계 결과는 측정 상태와 가격 상태별로 분류됩니다. 라우팅 결과는 가격 미확정 비용을 null로 표시합니다. 배치 사용량 검증과 중복 저장 동작도 갱신했습니다.

Changes

비용 계약과 원장 저장

Layer / File(s) Summary
비용 계산 및 사용량 상태
contextual_orchestrator/cost_ledger.py
PriceBook.compute_cost()price_known을 반환합니다. UsageRecord와 telemetry가 가격 상태를 포함합니다. 측정 상태와 가격 상태별 집계를 추가했습니다.
SQL 가격 지식 저장과 append 처리
contextual_orchestrator/cost_ledger.py
usage_price_knowledge 위성 테이블을 추가했습니다. 레거시 행은 가격 미확정으로 표시합니다. 중복 parent insert가 거부되면 위성 테이블을 갱신하지 않습니다.

배치 사용량 검증과 upstream 선택

Layer / File(s) Summary
가격 기반 upstream 선택
contextual_orchestrator/batch_routing.py, contextual_orchestrator/model_discovery.py
가격 미확정 후보를 최저가 비교에서 제외합니다. compute_cost()의 새 반환값을 반영했습니다.
배치 토큰 유효성 기록
contextual_orchestrator/batch_routing.py
음수 또는 잘못된 토큰 값은 0으로 저장합니다. 결과에 usage_valid=False를 기록합니다.

라우팅 결과 비용 전파

Layer / File(s) Summary
라우팅 비용 결과
contextual_orchestrator/cost_router.py
sync, provider request, stream, batch, embedding 결과에 price_known을 추가했습니다. 가격 미확정 비용은 cost_amount=None으로 반환합니다.
비용 문서 계약
contextual_orchestrator/cost_router.py
cost_report 문서가 상태별 집계 필드를 설명하도록 갱신되었습니다.

회귀 검증과 변경 문서

Layer / File(s) Summary
원장 및 저장소 검증
tests/test_cost_ledger.py, tests/test_cost_ledger_boundaries.py
가격 지식 반환, 상태별 집계, telemetry, SQL 저장, 레거시 마이그레이션, 중복 append 동작을 검증합니다.
라우팅 및 배치 경계 검증
tests/test_batch_routing_boundaries.py, tests/test_cost_router.py, tests/test_cost_router_boundaries.py
가격 미확정 결과, 0 토큰 결과, mixed currency 결과, embedding 결과를 검증합니다.
캐시 결과와 변경 내역
tests/test_distributed_cache_truth_and_isolation.py, CHANGELOG.md
캐시 적중 결과의 price_known=True를 검증하고 변경 내역을 기록합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🟡 Moderate · up to 23143

When batch usage is marked invalid, cost estimation can omit the original prompt and understate charges for requests with large inputs. This bounded correctness issue should be fixed or explicitly accepted before merging.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CostRoutingCoordinator
  participant CostLedger
  participant PriceBook
  Client->>CostRoutingCoordinator: 요청 완료 또는 사용량 결과
  CostRoutingCoordinator->>CostLedger: 사용량 기록
  CostLedger->>PriceBook: 비용과 price_known 계산
  PriceBook-->>CostLedger: 비용 상태 반환
  CostLedger-->>CostRoutingCoordinator: 원장 기록과 비용 상태
  CostRoutingCoordinator-->>Client: cost_amount와 price_known 반환
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.79% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 63 functions across 10 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 미가격 모델에 대해 인위적인 $0.00 비용을 생성하지 않도록 비용 회계를 수정하는 핵심 변경을 정확하고 간결하게 설명합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.79% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 63 functions across 10 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cost-ledger-price-honesty

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.

Copy link
Copy Markdown
Contributor Author

opencode-review failed on the current head (10dfd1cf) with the same signature as ContextualWisdomLab/.github#1485 (the systemic race between this required check's immediate verdict-lookup and the async OpenCode dispatch, which has no workflow_run "second chance" retry unlike noema-review.yml/pr-review-merge-scheduler.yml): zero reviews exist on this PR yet (get_reviews returns []), and the job failed a few seconds after starting. Not a defect in this PR's diff; no fix for #1485 has landed to port in. Queued one re-run of the failed job.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

@opencode-agent please review this draft PR.


Generated by Claude Code

@seonghobae
seonghobae marked this pull request as ready for review August 31, 2026 17:03
devin-ai-integration[bot]

This comment was marked as resolved.

claude and others added 2 commits August 31, 2026 17:35
Devin review on #956: SqlLedgerStore._append_locked()'s satellite
writes (usage_measurements, usage_price_knowledge, attribution) ran
unconditionally even when the parent llm_usage_records insert was
rejected as a duplicate usage_record_id. A retried append for a parent
row that predates one of these satellite tables (e.g. an
upgrade-migrated row with no usage_price_knowledge child, intentionally
read as price-unknown) silently backfilled that child using the
retry's current price/measurement state instead of what actually
priced the original spend -- relabeling historical unknown-price
provenance from an unrelated later call.

The three satellite inserts now only run when the parent insert is
actually accepted, so append() is a true no-op on a rejected
duplicate.

New regression test appends the same usage_record_id twice with
different measurement_status/price_known values and asserts the
second (rejected) append leaves the original row's provenance
untouched.

Copy link
Copy Markdown
Contributor Author

noema-review failed on 2b0b2f30 — same signature as the recurring orchestrator/free preflight degradation now affecting #955, #957, and #961 (TimeoutError at noema_review_gate.py:656 call_llm()). Not a defect in this PR's diff — the price_known propagation changes don't touch the review gateway or model discovery.

Root cause is fixed in #979 (draft, fully validated), not yet merged so it doesn't help this specific re-run. Re-ran the failed job once (first occurrence of this cause on this PR); watching #979 to landing, which should let this self-heal.


Generated by Claude Code

PriceBook.compute_cost() treated a zero-token record the same as a
missing price row: both returned price_known=False. That's wrong for
zero usage specifically -- zero tokens cost zero regardless of
whether the per-token price is known, since zero times any finite
price is still zero, so there is no unknown quantity left to guess.

This broke the required "Full unit and contract suite" check on
2b0b2f3 ("expose unknown price across usage surfaces"), which
started surfacing price_known on complete()'s cost dict: a cache hit
records its answer via a synthetic ("cache", "response")
provider/model that never has a real price row, so every cache hit
was newly (and wrongly) reported as an unpriced request with
cost_amount=None instead of the honest $0.00 it actually is.

compute_cost() now special-cases prompt_tokens == completion_tokens
== 0 before ever consulting the price book, returning
price_known=True with cost_amount=0.0 (using the price entry's own
currency when one exists, the ledger's default currency otherwise).

Updated the pre-existing cache-hit test to expect the now-exposed
price_known: True field. Full suite: 2868 passed, 1 skipped, 1 known
pre-existing fast_mlsirm gap (Python 3.11 sandbox vs the package's
python_full_version >= 3.12 requirement).

Copy link
Copy Markdown
Contributor Author

Full unit and contract suite failed on 2b0b2f30test_cache_hit_records_zero_provider_usage_instead_of_rebilling_inference broke because PriceBook.compute_cost() treated a zero-token record the same as a missing price row (both returned price_known=False). That's wrong specifically for zero usage: zero tokens cost zero regardless of whether the per-token price is known, since zero times any finite price is still zero — there's no unknown quantity left to guess. A cache hit records its answer via a synthetic ("cache", "response") provider/model that never has a real price row, so once price_known started surfacing on complete()'s cost dict (this PR's own change), every cache hit was newly reported as an unpriced request (cost_amount: None) instead of the honest $0.00 it actually is.

Fixed in c37932f: compute_cost() now special-cases zero token usage before ever consulting the price book, returning price_known=True, cost_amount=0.0. Updated the pre-existing test to expect the now-exposed price_known: True field. Full suite: 2868 passed, 1 skipped, 1 known pre-existing gap.


Generated by Claude Code

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

CodeRabbit review on #956: retrieve_batch's invalid-usage estimation
fallback passed a hardcoded [{"role": "user", "content": ""}]
placeholder into _record_completion instead of the request actually
submitted. When a provider marks a batch item's usage invalid,
_record_completion estimates prompt tokens from that messages
argument -- an empty placeholder always estimates near-zero prompt
tokens regardless of the real prompt's size, silently understating
batch cost for any large-input request whose usage came back invalid.

submit_batch() now keeps the submitted BatchRequest list keyed by
job_id (self._batch_requests, mirroring the existing
self._embedding_requests pattern for embeddings batches).
retrieve_batch() looks the original request up by custom_id and uses
its real messages for estimation whenever usage_valid is False,
falling back to the empty placeholder only when no matching original
request is on record (e.g. a backend that never went through
submit_batch).

New regression test
(test_invalid_batch_usage_estimates_prompt_tokens_from_original_request)
submits a ~500-word prompt through a backend that reports invalid
usage, and asserts the recorded prompt_tokens reflects the real
prompt rather than the near-zero an empty placeholder would give.

Full suite: 2870 passed, 1 skipped, 1 known pre-existing fast_mlsirm
gap (Python 3.11 sandbox vs the package's python_full_version >= 3.12
requirement).
devin-ai-integration[bot]

This comment was marked as resolved.

seonghobae and others added 2 commits September 1, 2026 05:42
Updates the CHANGELOG entry to describe the actual shipped design
from 2bfcaf6 (fix(cost_router): keep batch prompt fallback metadata
safe) rather than the superseded intermediate approach: the prompt-
token estimate lives on the durable BatchJob record itself (one
publication write, no raw prompt content ever persisted), not a
separate registry holding the original BatchRequest list.
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

…trievals

Devin review on #956: _legacy_batch_requests() gated its lookup on
`if job.prompt_token_estimates: return {}` -- meaning any non-empty
dict short-circuited the legacy read, not just a fully-populated one.
A legacy (pre-fix) job's estimates can be filled in incrementally
across multiple retrieve_batch() calls (e.g. polling for still-
processing items); once the first partial retrieval stored even one
custom_id's estimate, every subsequent retrieval for that same job
stopped consulting the legacy registry entirely, silently leaving any
other still-unestimated custom_id's cost understated with no way to
recover it later.

retrieve_batch() now decides whether a legacy lookup is needed from
the current retrieval's own items (does any item still lack a stored
estimate), not from whether the job's dict happens to be non-empty.
_legacy_batch_requests() itself is now a plain, ungated read -- for a
normal post-fix job (fully estimated at submission time), the caller
never invokes it at all, so there is no added cost to the common case.
Extracted the usage-validity check the caller and the pre-scan both
need into _batch_item_usage_valid() rather than duplicating it.

New regression test drives a legacy job through two separate
retrieve_batch() calls, each surfacing one of two legacy custom_ids,
and asserts both get correctly estimated from the real submitted
prompt -- reproducing the exact gap Devin flagged, which the prior
gate would have left the second call's estimate at None.

Targeted: tests/test_cost_router_boundaries.py + test_cost_router.py +
test_batch_routing_boundaries.py + test_cost_ledger.py +
test_cost_ledger_boundaries.py, 133 passed. Ruff passed; interrogate
100%. Full suite validation running in the background.
devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

noema-review failing check: this is a genuine TimeoutError in scripts/ci/noema_review_gate.py's call_llm() (.github repo) talking to the vendored orchestrator/free sidecar, not a defect in this PR's own diff (cost_router.py/tests only).

Root cause (confirmed via job log for this exact run, run 33439328660 / job 99643408237): the sidecar's own preflight found only 2/12 candidate free routes healthy (TimeoutError/HTTP 429/404 on the rest), and the serving ModelClient/TaskOrchestrator in contextual_orchestrator_review_launcher.py has no bounded retry/failover ceiling — noema_review_gate.py's single request carries a fixed 120s socket timeout, but ModelClient defaults (timeout=90, max_retries=2) plus tool_retry_attempts=1 plus unbounded cross-candidate failover can legitimately exceed that many times over. This is already root-caused in detail in contextual-orchestrator#974's PR body, which is adding an opt-in deadline_seconds bound to route_once()/_invoke() for exactly this caller. The .github-side companion (tightening the launcher's serving-client retry/timeout knobs and giving noema_review_gate.py's own timeout some margin) is in progress on ContextualWisdomLab/.github#1415.

Not fixing it here — both fixes are already in flight elsewhere and this PR's own diff doesn't touch the review path. Will keep this PR watched and re-check once #974/#1415 land.


Generated by Claude Code

@seonghobae

Copy link
Copy Markdown
Contributor Author

Cross-PR integration contract: routing identity is provider-neutral model_group only; do not add or preserve a provider-family abstraction. OpenRouter discovery must retain concrete free model IDs, while the aggregate openrouter/free router is not a serving candidate. OpenCode, Noema, and Strix must call contextual-orchestrator. Do not impose fixed wall-clock deadlines on inference, initial ping, readiness/health, provider discovery, or OpenRouter ZDR-list retrieval; use explicit cancellation and evidence-backed transport failure instead. Reconcile this PR with #971 and central .github #1508 before merge.

Copy link
Copy Markdown
Contributor Author

Acknowledged. This PR's diff (cost_router.py price honesty) doesn't touch model routing identity, OpenRouter discovery, or any fixed wall-clock deadline — no changes needed here to satisfy the contract. Its recurring noema-review failure is the separate, already-tracked serving-timeout issue (see earlier comment on this PR); #979 is where the actual model_group/provider-family and #971/#1508 reconciliation work is happening.


Generated by Claude Code

@seonghobae

Copy link
Copy Markdown
Contributor Author

Contextual-Orchestrator와 관계한 것들을 같이 손보든 어쩌든 해결하세요. Bypass merge 필요하면 가능 (chicken and eggs 상황이라면) + NVIDIA NIM 만 쓰는 건 허용하지 않아요. Contextual-Orchestrator를 쓰세요. Timeout은 적어도 3시간으로 잡으세요. 120초 같은 건 당황스럽군요. Opencode와 Noema 는 Coderabbitai 및 Devin 수준으로 실제로 리뷰를 하게 하시오. Strix도 보안 리뷰를 꼼꼼하게 하도록 하시오. 특히 보안 리뷰는 전체 코드로 수행하는 것입니다. Contextual-Orchestrator는 실시간으로 빠르면서 능력이 좋은 모델에 요청을 보내어 시간을 당기시오.

Copy link
Copy Markdown
Contributor Author

opencode-review's failure here is the same class of issue diagnosed on #955's noema-review failure: this run's job log shows the OLD 180-attempt/30s-sleep polling loop (for attempt in $(seq 1 180); do ... sleep 30; done), which .github main no longer has — it was replaced by a fast check-once/dispatch/wake-callback design in #1507/#1532. This run's own content (both the workflow structure and, per #955's confirmed behavior, any job-context values like github.workflow_sha) was pinned at whatever .github commit was current when this specific run was originally created, and — confirmed empirically on #955 — a manual rerun_failed_jobs does not refresh that pinned content; it re-executes the exact same stale definition. Not repeating that attempt here for the same reason. Not a defect in this PR's own diff; the underlying design is already fixed on .github main. This required check will pick up the current design once a genuinely new triggering event creates a fresh run (a new push, or the org's own re-dispatch) — keeping this PR watched.


Generated by Claude Code

@seonghobae
seonghobae merged commit 2919b66 into main Sep 1, 2026
21 of 25 checks passed
@seonghobae
seonghobae deleted the fix/cost-ledger-price-honesty branch September 1, 2026 07:14

@devin-ai-integration devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

Devin Review

Comment on lines +238 to +239
if prompt_tokens == 0 and completion_tokens == 0:
return 0.0, entry.currency_code if entry is not None else self.default_currency, True

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.

🟡 Missing usage falsely confirms prices

When an unpriced call has unavailable usage, compute_cost converts its sentinel zero tokens into price_known=True. Streaming and race results claim known pricing without either input.

Prompt for agents
Distinguish authoritative zero usage from the zero-token sentinel used for measurement_status unavailable. PriceBook.compute_cost cannot infer that distinction from token counts alone. Move or override the zero-usage exception where measurement provenance is available, preserving price_known true for confirmed zero usage and cache hits while leaving unpriced unavailable stream and race records price-unknown. Add tests for both unpriced unavailable paths.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

2 participants