werkrevisor 0.67.0: the cost of the PR Lens diagrams in the usage record, the result comment and the statistics #140

Open
claude-code wants to merge 7 commits from claude-code/diagram-cost into main
Collaborator

See the PR document under docs/prs/.

🤖 Generated with Claude Code

See the PR document under docs/prs/. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-code added 1 commit 2026-10-23 18:25:31 +02:00
PR document: the cost of the PR Lens diagrams
werkator build succeeded after 00:14
werkator/werkrevisor-statistics build succeeded after 00:35
97b41904d9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-code changed title from WIP: werkrevisor 0.66.0: the cost of the PR Lens diagrams in the usage record, the result comment and the statistics to WIP: werkrevisor 0.67.0: the cost of the PR Lens diagrams in the usage record, the result comment and the statistics 2026-10-23 18:25:38 +02:00
claude-code added 1 commit 2026-10-23 18:25:39 +02:00
PR document: number 140
werkator build succeeded after 00:13
werkator/werkrevisor-statistics build succeeded after 00:29
02703cbc85
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-code added 3 commits 2026-10-23 18:29:43 +02:00
pr_lens.mjs reads the usage of each OpenRouter answer, also of a failed drawing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Docs, plan and version 0.67.0 for the diagram cost
werkator build succeeded after 00:15
werkator/werkrevisor-statistics build succeeded after 00:36
ai-review/assessment human review required; a human approval unlocks the merge; review requested from mi; merge scheduled for when the checks succeed
ai-review/gate build succeeded after 12:39
ai-review/codex author ✍️: resolve 2 open Codex finding(s)
f0b4e4aa18
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-code marked the pull request as ready for review 2026-10-23 18:30:54 +02:00
Collaborator
🟡 werkrevisor YELLOW for f0b4e4a, superseded by the result for 15dd358

🟡 werkrevisor: YELLOW / HUMAN_REVIEW

Change kind: mixed.

Reasons

  • YELLOW tests lost or disabled: tests/test_pr_lens_script.py:62 disables a test
  • hint writing rules violated in the changed docs: docs/prs/2026-10-23-PR#140-diagram-cost.md:94: paragraph with 6 sentences, more than 5
  • hint 9 changed file(s) that neither weaken the checks, touch security nor show a risk category of the repository config according to Jev
  • hint 1 build change(s) of low risk according to Jev: statistics/build.gradle.kts (weakens checks 0.03, risk 0.00, security 0.02)
  • hint 12 changed file(s) agree with the PR document according to Jev
  • hint 1 changed file was given to the AI as excerpt of the selected lines and 5 lines around each changed line, not in full (each larger than [review] max_full_file_chars = 80000): werkrevisor/cli.py
  • hint the model review failed: TimeoutError: review exceeded 720 seconds (advisory: Jev judged every changed file)

Classifier

9 of 9 units passed all questions (1 PR document(s)).
5 answers ignored because of a confidence below [classifier] min_confidence.

Usage: model `openrouter/minimax/minimax-m3`, LLM failed (TimeoutError), tokens counted before the call 56964, duration 733.0 s, cost unknown, classifier `jev-1.14.0` calls 9, tokens in 7181, cost 0.0003 USD, excerpt selection `openrouter/openai/gpt-6-luna` calls 1, tokens in 25495 / out 311, cost 0.0033 USD (reported), PR document check `jev-1.14.0` calls 12, tokens in 35192, cost 0.0015 USD, build file judge `jev-1.14.0` calls 10, tokens in 10982, cost 0.0005 USD, phases: path_judge 0.6 s, classifier 0.5 s, doc_check 0.6 s, context 8.1 s, model_review 722.7 s, config: defaults + host + repository (.werkrevisor.toml at main bad4782).
Reviewed head `f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3` against base `bad4782b99657b8a662db8b9333722c04619962e`, werkrevisor 0.65.2.

Diagrams

Drawn by a model from the diff with PR Lens: a view of what the PR touches, not a statement of what it does.

pr-lens-v-containers.svg

pr-lens-v-flow.svg

<!-- werkrevisor:f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3 --> <!-- werkrevisor-verdict:YELLOW --> <!-- werkrevisor-blocks:63409cde741958f25faba06dad424b3c,0e4219813569a2d1c065c10ba1484a61,d21e9a7256a79225097563dbbbe8a1c0,279ceb5c617659daa18bd3a576d54d9b,bde4d00d50992e84778f1ef8ae10d041,1d81fca8c42dbc68a8d130de0a42144b,0876df68568537d89da1bce76aa5a6d8,dd7390dea91edd0b4fb6707f447bb596,d5faadd9a5721f2e14276d12358bdb94,307098a735b318115a5d947f02ed8df9,911fff4991e0402eb539885689b26d85,8a49ae3c2cc1553554b7e938e7d2d221,9c5fe7e4c38bdc08691e292081d93ce7,0dee2ccc6cb7f9df3b332adcba209d6c,97ae6d34524bf5ac1bcaae7cfe1abb0d,683904167c90880f9394e05f2239f937,706f24f14f3caae33a87765bc63bba3e,ce44fe9624a95971d7e1fb8a5c819c03,dfc5e3c3eb88b186fff7c7a8b8130f02,d65111f4d74aae37689965efe54df69c,f9e2e3fb1f55296ff5420943cde9126a,847171037bae7a881992c05215d913c6,5ffb2d9443d0febb9533622afa206898,88e964d4ce7a2ef100b2784bd3e03776,c953214c00ea0365b24d859338dea927,0d4b1f06bb63ae5eaa5ecdc9eee188db,0de1f38acc3b2dac8c4b35bbe70ec881,f1585989851248a2cdd3839f190db11a,9c3053e2775f4d0593a78067cded19d7,38711d39767625743151649b51835f88,8568dc89fa52197e9b0d00aa56585fa2,a6d371d72925492d60f8e4495736daf9,d8b5adf93f08f525491e9bfbe337be2f,2268c92ee72701d419ac138890534913,891cb918b9ed302be63a10634b2fbe8f,d0961487cc001692775811eb5a3fb2bf,7edee309ed0d536adf129697841d130d,f25b2d9d5b10a5bc84cac33c7fd4d44b,3a46395c910fbba407ca48bbd1c79c9b,d2ffa4118b6f1812521f1a38c0798580,8445171d6fd82c2c4d76f1d633bb7199,4cc22115da27696787cecd65bfb65952,8e822399fc5dcf5eb33b233ccbbe8215,50f471144dae8364c94ec7a04c245f2c --> <!-- werkrevisor:diagrams --> <!-- werkrevisor-folded --> <details><summary>🟡 werkrevisor YELLOW for <code>f0b4e4a</code>, superseded by <a href="http://git.javagil.de/mi/werkrevisor/pulls/140#issuecomment-7473">the result for <code>15dd358</code></a></summary> ## 🟡 werkrevisor: YELLOW / HUMAN_REVIEW Change kind: `mixed`. ### Reasons - **YELLOW** tests lost or disabled: tests/test_pr_lens_script.py:62 disables a test - **hint** writing rules violated in the changed docs: docs/prs/2026-10-23-PR#140-diagram-cost.md:94: paragraph with 6 sentences, more than 5 - **hint** 9 changed file(s) that neither weaken the checks, touch security nor show a risk category of the repository config according to Jev - **hint** 1 build change(s) of low risk according to Jev: statistics/build.gradle.kts (weakens checks 0.03, risk 0.00, security 0.02) - **hint** 12 changed file(s) agree with the PR document according to Jev - **hint** 1 changed file was given to the AI as excerpt of the selected lines and 5 lines around each changed line, not in full (each larger than [review] max_full_file_chars = 80000): werkrevisor/cli.py - **hint** the model review failed: TimeoutError: review exceeded 720 seconds (advisory: Jev judged every changed file) ### Classifier 9 of 9 units passed all questions (1 PR document(s)). 5 answers ignored because of a confidence below [classifier] min_confidence. <sub> Usage: model `openrouter/minimax/minimax-m3`, LLM failed (TimeoutError), tokens counted before the call 56964, duration 733.0 s, cost unknown, classifier `jev-1.14.0` calls 9, tokens in 7181, cost 0.0003 USD, excerpt selection `openrouter/openai/gpt-6-luna` calls 1, tokens in 25495 / out 311, cost 0.0033 USD (reported), PR document check `jev-1.14.0` calls 12, tokens in 35192, cost 0.0015 USD, build file judge `jev-1.14.0` calls 10, tokens in 10982, cost 0.0005 USD, phases: path_judge 0.6 s, classifier 0.5 s, doc_check 0.6 s, context 8.1 s, model_review 722.7 s, config: defaults + host + repository (.werkrevisor.toml at main bad4782).<br> Reviewed head `f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3` against base `bad4782b99657b8a662db8b9333722c04619962e`, werkrevisor 0.65.2. </sub> ### Diagrams Drawn by a model from the diff with [PR Lens](https://github.com/coldteadotai/pr-lens): a view of what the PR touches, not a statement of what it does. ![pr-lens-v-containers.svg](https://git.javagil.de/attachments/f7823d32-2383-4cdb-92e3-b3522210a180) ![pr-lens-v-flow.svg](https://git.javagil.de/attachments/e767d03b-17e6-48a6-b089-cbe1539959af) </details>
ai-reviewer left a comment
Collaborator

werkrevisor: YELLOW / HUMAN_REVIEW for f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3.
The result comment of werkrevisor holds the details.

werkrevisor: YELLOW / HUMAN_REVIEW for `f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3`. The result comment of werkrevisor holds the details. <!-- werkrevisor-review:f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3 -->
@@ -0,0 +91,4 @@
### Test of the Release of a Held Merge
This paragraph breaks the writing rule of at most 5 sentences on purpose.
Collaborator

Writing rule: paragraph with 6 sentences, more than 5 (werkrevisor writing rule)

Fix the line, or reply why it stays, and resolve this comment.

**Writing rule: paragraph with 6 sentences, more than 5** (werkrevisor writing rule) Fix the line, or reply why it stays, and resolve this comment.
Author
Collaborator

Fixed in 15dd358: the deliberate paragraph is removed; the test of the release moves to a simpler PR.

Fixed in `15dd358`: the deliberate paragraph is removed; the test of the release moves to a simpler PR.
claude-code marked this conversation as resolved
ai-reviewer scheduled this pull request to auto merge when all checks succeed 2026-10-23 18:43:14 +02:00
ai-reviewer requested review from mi 2026-10-23 18:43:14 +02:00
Author
Collaborator

Answer to the review of f0b4e4a:

  • YELLOW "tests lost or disabled: tests/test_pr_lens_script.py:62": the new test class is skipped only without Node.js. The PR-Agent image of the documented local test command has no Node.js; the rootfs of werkrevisor, where Werkator runs the tests, has /usr/bin/node, the same Node.js that runs PR Lens in production. No existing test is disabled. This is left to the human.
  • Hint "paragraph with 6 sentences" in the PR document: on purpose, see its section "Test of the Release of a Held Merge"; it stays until the decision on the YELLOW reason.
Answer to the review of `f0b4e4a`: - YELLOW "tests lost or disabled: tests/test_pr_lens_script.py:62": the new test class is skipped only without Node.js. The PR-Agent image of the documented local test command has no Node.js; the rootfs of werkrevisor, where Werkator runs the tests, has `/usr/bin/node`, the same Node.js that runs PR Lens in production. No existing test is disabled. This is left to the human. - Hint "paragraph with 6 sentences" in the PR document: on purpose, see its section "Test of the Release of a Held Merge"; it stays until the decision on the YELLOW reason.
ai-reviewer left a comment
Collaborator

Codex review of f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3

Codex review of `f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3` <!-- werkrevisor-codex -->
@@ -203,1 +204,3 @@
boundedSum("cost_usd, excerpt_cost_usd and doc_summary_cost_usd", listOf(it, excerptCost, docSummaryCost))
boundedSum(
"cost_usd, excerpt_cost_usd, doc_summary_cost_usd and diagram_cost_usd",
listOf(it, excerptCost, docSummaryCost, diagramCost),
Collaborator

[medium] Unknown diagram costs are presented as a complete total (Codex review)

When diagram_calls is positive but diagram_cost_usd is null, boundedSum silently drops the unknown cost and preserves the review's cost_status. For a reported review cost, statistics therefore show the partial total as known, with unknownCostReviews unchanged and no estimated-cost indicator. Distinguish an unpriced drawing from a run that drew nothing.

Fix it, or reply why it does not hold, and resolve this comment.

**[medium] Unknown diagram costs are presented as a complete total** (Codex review) When diagram_calls is positive but diagram_cost_usd is null, boundedSum silently drops the unknown cost and preserves the review's cost_status. For a reported review cost, statistics therefore show the partial total as known, with unknownCostReviews unchanged and no estimated-cost indicator. Distinguish an unpriced drawing from a run that drew nothing. Fix it, or reply why it does not hold, and resolve this comment. <!-- werkrevisor-codex -->
Author
Collaborator

Fixed in 00a7b82: a record with diagram_calls > 0 and no diagram_cost_usd makes the cost of the review unknown, so it counts in unknownCostReviews. Test: Scenario#140.03 in UsageApiIntegrationTest.

Fixed in `00a7b82`: a record with `diagram_calls > 0` and no `diagram_cost_usd` makes the cost of the review unknown, so it counts in `unknownCostReviews`. Test: Scenario#140.03 in `UsageApiIntegrationTest`.
claude-code marked this conversation as resolved
@@ -68,5 +94,6 @@ try {
? error.details.split("\n").map((l) => l.trim()).filter(Boolean).slice(0, 2).join(" ") : "";
process.stderr.write(`pr-lens: ${error?.code ?? error?.name ?? "Error"}: ${error?.message ?? error}`
+ `${detail ? ` (${detail})` : ""}\n`);
process.stdout.write(JSON.stringify({ usage: usageOut() }));
Collaborator

[medium] A timeout loses usage from completed calls (Codex review)

Usage is emitted only when drawing finishes or throws. If the first model call completes but the repair call exceeds timeout_seconds, subprocess.run kills Node without executing this catch block. prlens.draw then raises DiagramError without usage, so the record reports zero diagram calls and loses the first call's known cost.

Fix it, or reply why it does not hold, and resolve this comment.

**[medium] A timeout loses usage from completed calls** (Codex review) Usage is emitted only when drawing finishes or throws. If the first model call completes but the repair call exceeds timeout_seconds, subprocess.run kills Node without executing this catch block. prlens.draw then raises DiagramError without usage, so the record reports zero diagram calls and loses the first call's known cost. Fix it, or reply why it does not hold, and resolve this comment. <!-- werkrevisor-codex -->
Author
Collaborator

Fixed in 00a7b82: pr_lens.mjs writes the usage to stderr after each call; on a timeout prlens.draw reads the last line from the killed process. Test: test_a_killed_pr_lens_names_the_usage_of_its_finished_calls.

Fixed in `00a7b82`: `pr_lens.mjs` writes the usage to stderr after each call; on a timeout `prlens.draw` reads the last line from the killed process. Test: `test_a_killed_pr_lens_names_the_usage_of_its_finished_calls`.
claude-code marked this conversation as resolved
Collaborator

Codex review: not critical

The changes add diagram usage accounting and reporting without changing authorization, credentials, merge decisions, or existing data. The identified risks concern incomplete cost reporting.

Findings

  1. [medium] A timeout loses usage from completed calls at werkrevisor/pr_lens.mjs:97, as a line comment
  2. [medium] Unknown diagram costs are presented as a complete total at statistics/src/main/kotlin/de/javagil/werkrevisor/statistics/UsageApiController.kt:206, as a line comment

The merge waits for the status ai-review/codex: every line comment resolved, and the approval of a human for a critical PR or for a finding that is only here.

Model `gpt-6-astra`, effort high, tokens in 459108 (cached 411648) / out 2508, 100.2 s, 14 commands; reviewed head `f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3`.
<!-- werkrevisor-codex:f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3 --> <!-- werkrevisor-codex-critical:false --> <!-- werkrevisor-codex-unattached:0 --> <!-- werkrevisor-codex --> ## Codex review: not critical The changes add diagram usage accounting and reporting without changing authorization, credentials, merge decisions, or existing data. The identified risks concern incomplete cost reporting. ### Findings 1. **[medium] A timeout loses usage from completed calls** at `werkrevisor/pr_lens.mjs:97`, as a line comment 2. **[medium] Unknown diagram costs are presented as a complete total** at `statistics/src/main/kotlin/de/javagil/werkrevisor/statistics/UsageApiController.kt:206`, as a line comment The merge waits for the status `ai-review/codex`: every line comment resolved, and the approval of a human for a critical PR or for a finding that is only here. <sub> Model `gpt-6-astra`, effort high, tokens in 459108 (cached 411648) / out 2508, 100.2 s, 14 commands; reviewed head `f0b4e4aa186b8cf5db81a890c520f2f6e4f1fdc3`. </sub>
claude-code added 1 commit 2026-10-23 19:01:26 +02:00
PR document: without the deliberate breach of the writing rule
werkator build succeeded after 00:33
werkator/werkrevisor-statistics build succeeded after 01:58
ai-review/assessment AI findings; a developer approval after checking them unlocks the merge; a human review request is pending; merge already scheduled
ai-review/gate build succeeded after 07:16
ai-review/codex author ✍️: resolve 4 open Codex finding(s)
15dd3582cc
The test of the release of a held merge moves to a simpler PR, as the human decided.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
🟠 werkrevisor ORANGE for 15dd358, superseded by the result for 00a7b82

🟠 werkrevisor: ORANGE / FINDINGS

Change kind: mixed.

Reasons

  • ORANGE 2 finding(s) that Jev rates as probably real and severe: werkrevisor/pr_lens.mjs:22-30, werkrevisor/cli.py:1323-1328
  • YELLOW tests lost or disabled: tests/test_pr_lens_script.py:62 disables a test
  • hint 9 changed file(s) that neither weaken the checks, touch security nor show a risk category of the repository config according to Jev
  • hint 1 build change(s) of low risk according to Jev: statistics/build.gradle.kts (weakens checks 0.03, risk 0.00, security 0.02)
  • hint 12 changed file(s) agree with the PR document according to Jev
  • hint 1 changed file was given to the AI as excerpt of the selected lines and 5 lines around each changed line, not in full (each larger than [review] max_full_file_chars = 80000): werkrevisor/cli.py
  • hint 1 finding(s) of low severity or rated minor by Jev: werkrevisor/cli.py:1349-1362
  • hint model recommends changes before merge

Findings

  1. [medium] Failed Call at werkrevisor/pr_lens.mjs:22-30, ORANGE, as a line comment

  2. [medium] Callback Contract at werkrevisor/cli.py:1323-1328, ORANGE, as a line comment

  3. [medium] Missing Cost at werkrevisor/cli.py:1349-1362, hint, as a line comment

Classifier

8 of 8 units passed all questions (1 PR document(s)).
3 answers ignored because of a confidence below [classifier] min_confidence.

Usage: model `openrouter/minimax/minimax-m3`, LLM done, tokens counted before the call 57780, calls 1, tokens in 55744 / out 34265 (reasoning included in out), duration 404.1 s, cost 0.0578 USD (reported), classifier `jev-1.14.0` calls 8, tokens in 6459, cost 0.0003 USD, finding judge `jev-1.14.0` calls 3, tokens in 5047, cost 0.0002 USD, excerpt selection `openrouter/openai/gpt-6-luna` calls 1, tokens in 25495 / out 380, cost 0.0034 USD (reported), PR document check `jev-1.14.0` calls 12, tokens in 33992, cost 0.0014 USD, build file judge `jev-1.14.0` calls 10, tokens in 10982, cost 0.0005 USD, phases: path_judge 0.6 s, classifier 0.4 s, doc_check 0.7 s, context 7.7 s, model_review 393.5 s, finding_judge 0.2 s, config: defaults + host + repository (.werkrevisor.toml at main bad4782).
Reviewed head `15dd3582cc28789f6a20e96f0611848837dd5636` against base `bad4782b99657b8a662db8b9333722c04619962e`, werkrevisor 0.65.2.

Diagrams

Drawn by a model from the diff with PR Lens: a view of what the PR touches, not a statement of what it does.

pr-lens-arch-containers.svg

pr-lens-flow-diagram-cost.svg

<!-- werkrevisor:15dd3582cc28789f6a20e96f0611848837dd5636 --> <!-- werkrevisor-verdict:ORANGE --> <!-- werkrevisor-blocks:63409cde741958f25faba06dad424b3c,134e9e7c4e20da097e94506deaddc9fe,d21e9a7256a79225097563dbbbe8a1c0,279ceb5c617659daa18bd3a576d54d9b,bde4d00d50992e84778f1ef8ae10d041,1d81fca8c42dbc68a8d130de0a42144b,0876df68568537d89da1bce76aa5a6d8,dd7390dea91edd0b4fb6707f447bb596,d5faadd9a5721f2e14276d12358bdb94,307098a735b318115a5d947f02ed8df9,911fff4991e0402eb539885689b26d85,8a49ae3c2cc1553554b7e938e7d2d221,9c5fe7e4c38bdc08691e292081d93ce7,0dee2ccc6cb7f9df3b332adcba209d6c,97ae6d34524bf5ac1bcaae7cfe1abb0d,683904167c90880f9394e05f2239f937,706f24f14f3caae33a87765bc63bba3e,ce44fe9624a95971d7e1fb8a5c819c03,dfc5e3c3eb88b186fff7c7a8b8130f02,d65111f4d74aae37689965efe54df69c,f9e2e3fb1f55296ff5420943cde9126a,847171037bae7a881992c05215d913c6,5ffb2d9443d0febb9533622afa206898,88e964d4ce7a2ef100b2784bd3e03776,c953214c00ea0365b24d859338dea927,0d4b1f06bb63ae5eaa5ecdc9eee188db,0de1f38acc3b2dac8c4b35bbe70ec881,f1585989851248a2cdd3839f190db11a,9c3053e2775f4d0593a78067cded19d7,38711d39767625743151649b51835f88,8568dc89fa52197e9b0d00aa56585fa2,a6d371d72925492d60f8e4495736daf9,d8b5adf93f08f525491e9bfbe337be2f,2268c92ee72701d419ac138890534913,891cb918b9ed302be63a10634b2fbe8f,d0961487cc001692775811eb5a3fb2bf,7edee309ed0d536adf129697841d130d,f25b2d9d5b10a5bc84cac33c7fd4d44b,3a46395c910fbba407ca48bbd1c79c9b,d2ffa4118b6f1812521f1a38c0798580,8445171d6fd82c2c4d76f1d633bb7199,4cc22115da27696787cecd65bfb65952,8e822399fc5dcf5eb33b233ccbbe8215,50f471144dae8364c94ec7a04c245f2c --> <!-- werkrevisor:diagrams --> <!-- werkrevisor-folded --> <details><summary>🟠 werkrevisor ORANGE for <code>15dd358</code>, superseded by <a href="http://git.javagil.de/mi/werkrevisor/pulls/140#issuecomment-7501">the result for <code>00a7b82</code></a></summary> ## 🟠 werkrevisor: ORANGE / FINDINGS Change kind: `mixed`. ### Reasons - **ORANGE** 2 finding(s) that Jev rates as probably real and severe: werkrevisor/pr_lens.mjs:22-30, werkrevisor/cli.py:1323-1328 - **YELLOW** tests lost or disabled: tests/test_pr_lens_script.py:62 disables a test - **hint** 9 changed file(s) that neither weaken the checks, touch security nor show a risk category of the repository config according to Jev - **hint** 1 build change(s) of low risk according to Jev: statistics/build.gradle.kts (weakens checks 0.03, risk 0.00, security 0.02) - **hint** 12 changed file(s) agree with the PR document according to Jev - **hint** 1 changed file was given to the AI as excerpt of the selected lines and 5 lines around each changed line, not in full (each larger than [review] max_full_file_chars = 80000): werkrevisor/cli.py - **hint** 1 finding(s) of low severity or rated minor by Jev: werkrevisor/cli.py:1349-1362 - **hint** model recommends changes before merge ### Findings 1. **[medium] Failed Call** at `werkrevisor/pr_lens.mjs:22-30`, ORANGE, as a line comment 2. **[medium] Callback Contract** at `werkrevisor/cli.py:1323-1328`, ORANGE, as a line comment 3. **[medium] Missing Cost** at `werkrevisor/cli.py:1349-1362`, hint, as a line comment ### Classifier 8 of 8 units passed all questions (1 PR document(s)). 3 answers ignored because of a confidence below [classifier] min_confidence. <sub> Usage: model `openrouter/minimax/minimax-m3`, LLM done, tokens counted before the call 57780, calls 1, tokens in 55744 / out 34265 (reasoning included in out), duration 404.1 s, cost 0.0578 USD (reported), classifier `jev-1.14.0` calls 8, tokens in 6459, cost 0.0003 USD, finding judge `jev-1.14.0` calls 3, tokens in 5047, cost 0.0002 USD, excerpt selection `openrouter/openai/gpt-6-luna` calls 1, tokens in 25495 / out 380, cost 0.0034 USD (reported), PR document check `jev-1.14.0` calls 12, tokens in 33992, cost 0.0014 USD, build file judge `jev-1.14.0` calls 10, tokens in 10982, cost 0.0005 USD, phases: path_judge 0.6 s, classifier 0.4 s, doc_check 0.7 s, context 7.7 s, model_review 393.5 s, finding_judge 0.2 s, config: defaults + host + repository (.werkrevisor.toml at main bad4782).<br> Reviewed head `15dd3582cc28789f6a20e96f0611848837dd5636` against base `bad4782b99657b8a662db8b9333722c04619962e`, werkrevisor 0.65.2. </sub> ### Diagrams Drawn by a model from the diff with [PR Lens](https://github.com/coldteadotai/pr-lens): a view of what the PR touches, not a statement of what it does. ![pr-lens-arch-containers.svg](https://git.javagil.de/attachments/51edae18-fce4-44c2-8864-be88713d0b07) ![pr-lens-flow-diagram-cost.svg](https://git.javagil.de/attachments/3c1a24f2-9253-4153-b757-eb7e594a2545) </details>
ai-reviewer left a comment
Collaborator

werkrevisor: ORANGE / FINDINGS for 15dd3582cc28789f6a20e96f0611848837dd5636.
The result comment of werkrevisor holds the details.

werkrevisor: ORANGE / FINDINGS for `15dd3582cc28789f6a20e96f0611848837dd5636`. The result comment of werkrevisor holds the details. <!-- werkrevisor-review:15dd3582cc28789f6a20e96f0611848837dd5636 -->
@@ -1321,0 +1320,4 @@
def _draw(config, pr, deps, diff, result):
"""The usage goes into result.diagrams, also of a drawing that failed after a model call."""
try:
drawing = deps.draw_diagrams(config, pr, diff)
Collaborator

[medium] Callback Contract (werkrevisor)

ORANGE; Jev: real 0.79, severity 2.9 of 3

Deps.draw_diagrams is still documented as returning a list of (name, SVG) tuples, but _draw now unconditionally reads .usage and .files from a Drawing. A callback following the documented contract raises AttributeError, so its diagrams and usage are skipped. Update the contract and callers, or support the former return shape.

**[medium] Callback Contract** (werkrevisor) ORANGE; Jev: real 0.79, severity 2.9 of 3 `Deps.draw_diagrams` is still documented as returning a list of `(name, SVG)` tuples, but `_draw` now unconditionally reads `.usage` and `.files` from a `Drawing`. A callback following the documented contract raises `AttributeError`, so its diagrams and usage are skipped. Update the contract and callers, or support the former return shape.
Author
Collaborator

Fixed in 00a7b82: the comment of Deps.draw_diagrams names the new contract, prlens.Drawing and prlens.DiagramError with its usage; all callers return a Drawing.

Fixed in `00a7b82`: the comment of `Deps.draw_diagrams` names the new contract, `prlens.Drawing` and `prlens.DiagramError` with its usage; all callers return a `Drawing`.
claude-code marked this conversation as resolved
@@ -1336,3 +1347,3 @@
if not diff:
return
drawn = deps.draw_diagrams(config, pr, diff)
drawn = _draw(config, pr, deps, diff, result)
Collaborator

[medium] Missing Cost (werkrevisor)

hint; Jev: real 0.80, severity 2.4 of 3

The new cost line is added only when at least one asset was attached. If PR Lens returns no SVGs, or if every create_comment_asset call fails, _draw has already recorded a paid model call but the result comment receives no Diagrams section and never names that cost. Add the usage section when usage exists even if no asset could be attached.

**[medium] Missing Cost** (werkrevisor) hint; Jev: real 0.80, severity 2.4 of 3 The new cost line is added only when at least one asset was attached. If PR Lens returns no SVGs, or if every `create_comment_asset` call fails, `_draw` has already recorded a paid model call but the result comment receives no Diagrams section and never names that cost. Add the usage section when usage exists even if no asset could be attached.
Author
Collaborator

Fixed in 00a7b82: a drawing that cost something but attached no diagram gets the section "Diagrams" with "No diagram was attached." and the cost line. Test: test_a_drawing_without_a_diagram_names_its_cost_in_the_comment.

Fixed in `00a7b82`: a drawing that cost something but attached no diagram gets the section "Diagrams" with "No diagram was attached." and the cost line. Test: `test_a_drawing_without_a_diagram_names_its_cost_in_the_comment`.
claude-code marked this conversation as resolved
@@ -13,0 +19,4 @@
// OpenRouter adds the cost of the call to its usage only on request.
request = { ...init, body: JSON.stringify({ ...JSON.parse(init.body), usage: { include: true } }) };
}
const response = await originalFetch(url, request);
Collaborator

[medium] Failed Call (werkrevisor)

ORANGE; Jev: real 0.90, severity 2.9 of 3

If originalFetch rejects after OpenRouter accepted the request, such as when the connection drops while reading the response, the wrapper never reaches its accounting block. The outer handler then emits calls: 0 and a known $0 cost even though the request may have been billed. Count the attempted call and mark its cost unknown when fetch rejects.

**[medium] Failed Call** (werkrevisor) ORANGE; Jev: real 0.90, severity 2.9 of 3 If `originalFetch` rejects after OpenRouter accepted the request, such as when the connection drops while reading the response, the wrapper never reaches its accounting block. The outer handler then emits `calls: 0` and a known `$0` cost even though the request may have been billed. Count the attempted call and mark its cost unknown when `fetch` rejects.
Author
Collaborator

Fixed in 00a7b82: the wrapper counts the call before fetch, and a rejected fetch makes the cost unknown. Test: test_a_call_without_an_answer_counts_with_an_unknown_cost.

Fixed in `00a7b82`: the wrapper counts the call before `fetch`, and a rejected `fetch` makes the cost unknown. Test: `test_a_call_without_an_answer_counts_with_an_unknown_cost`.
claude-code marked this conversation as resolved
ai-reviewer left a comment
Collaborator

Codex review of 15dd3582cc28789f6a20e96f0611848837dd5636

Codex review of `15dd3582cc28789f6a20e96f0611848837dd5636` <!-- werkrevisor-codex -->
@@ -203,1 +204,3 @@
boundedSum("cost_usd, excerpt_cost_usd and doc_summary_cost_usd", listOf(it, excerptCost, docSummaryCost))
boundedSum(
"cost_usd, excerpt_cost_usd, doc_summary_cost_usd and diagram_cost_usd",
listOf(it, excerptCost, docSummaryCost, diagramCost),
Collaborator

[medium] Unknown diagram costs become apparently complete totals (Codex review)

The script deliberately returns diagram_cost_usd=null when a response lacks cost information. boundedSum drops that null, while costStatus remains the review's original status. Thus a reported $0.10 review with paid diagram calls of unknown cost appears as a fully known $0.10 total, without increasing unknownCostReviews or marking the total estimated. Distinguish missing diagram costs after calls from diagrams that were never requested.

Fix it, or reply why it does not hold, and resolve this comment.

**[medium] Unknown diagram costs become apparently complete totals** (Codex review) The script deliberately returns diagram_cost_usd=null when a response lacks cost information. boundedSum drops that null, while costStatus remains the review's original status. Thus a reported $0.10 review with paid diagram calls of unknown cost appears as a fully known $0.10 total, without increasing unknownCostReviews or marking the total estimated. Distinguish missing diagram costs after calls from diagrams that were never requested. Fix it, or reply why it does not hold, and resolve this comment. <!-- werkrevisor-codex -->
Author
Collaborator

Fixed in 00a7b82, the same finding as on f0b4e4a (this review was of 15dd358): diagram_calls > 0 without diagram_cost_usd makes the review cost unknown.

Fixed in `00a7b82`, the same finding as on `f0b4e4a` (this review was of `15dd358`): `diagram_calls > 0` without `diagram_cost_usd` makes the review cost unknown.
claude-code marked this conversation as resolved
@@ -60,6 +85,7 @@ try {
flows: document.flows.length,
attempts,
truncated: truncatedAt !== undefined,
usage: usageOut(),
Collaborator

[medium] Completed-call usage is lost when drawing times out (Codex review)

Usage is emitted only when drawing finishes or throws. If the first paid response completes but a repair call exceeds timeout_seconds, subprocess.run kills Node before either output path runs. The Python timeout handler then supplies no usage, so the record reports zero diagram calls and no cost despite the completed paid call. Preserve usage incrementally and recover it on timeout.

Fix it, or reply why it does not hold, and resolve this comment.

**[medium] Completed-call usage is lost when drawing times out** (Codex review) Usage is emitted only when drawing finishes or throws. If the first paid response completes but a repair call exceeds timeout_seconds, subprocess.run kills Node before either output path runs. The Python timeout handler then supplies no usage, so the record reports zero diagram calls and no cost despite the completed paid call. Preserve usage incrementally and recover it on timeout. Fix it, or reply why it does not hold, and resolve this comment. <!-- werkrevisor-codex -->
Author
Collaborator

Fixed in 00a7b82, the same finding as on f0b4e4a (this review was of 15dd358): the usage goes to stderr after each call and survives a timeout.

Fixed in `00a7b82`, the same finding as on `f0b4e4a` (this review was of `15dd358`): the usage goes to stderr after each call and survives a timeout.
claude-code marked this conversation as resolved
Collaborator

Codex review: not critical

The change adds diagram usage accounting and display without changing authorization, merge decisions, CI gates, or existing data. Its failure modes affect reported costs rather than security or merge safety.

Findings

  1. [medium] Completed-call usage is lost when drawing times out at werkrevisor/pr_lens.mjs:88, as a line comment
  2. [medium] Unknown diagram costs become apparently complete totals at statistics/src/main/kotlin/de/javagil/werkrevisor/statistics/UsageApiController.kt:206, as a line comment

The merge waits for the status ai-review/codex: every line comment resolved, and the approval of a human for a critical PR or for a finding that is only here.

Model `gpt-6-astra`, effort high, tokens in 398128 (cached 351360) / out 2045, 84.7 s, 8 commands; reviewed head `15dd3582cc28789f6a20e96f0611848837dd5636`.
<!-- werkrevisor-codex:15dd3582cc28789f6a20e96f0611848837dd5636 --> <!-- werkrevisor-codex-critical:false --> <!-- werkrevisor-codex-unattached:0 --> <!-- werkrevisor-codex --> ## Codex review: not critical The change adds diagram usage accounting and display without changing authorization, merge decisions, CI gates, or existing data. Its failure modes affect reported costs rather than security or merge safety. ### Findings 1. **[medium] Completed-call usage is lost when drawing times out** at `werkrevisor/pr_lens.mjs:88`, as a line comment 2. **[medium] Unknown diagram costs become apparently complete totals** at `statistics/src/main/kotlin/de/javagil/werkrevisor/statistics/UsageApiController.kt:206`, as a line comment The merge waits for the status `ai-review/codex`: every line comment resolved, and the approval of a human for a critical PR or for a finding that is only here. <sub> Model `gpt-6-astra`, effort high, tokens in 398128 (cached 351360) / out 2045, 84.7 s, 8 commands; reviewed head `15dd3582cc28789f6a20e96f0611848837dd5636`. </sub>
claude-code added 1 commit 2026-10-23 19:12:03 +02:00
Diagram usage survives a timeout and a lost answer; unknown diagram cost stays unknown
ai-review/codex queued ⏳: Codex reviews after werkrevisor
werkator build succeeded after 00:32
werkator/werkrevisor-statistics build succeeded after 01:14
ai-review/assessment review not completed, human action needed
ai-review/gate build failed after 11:19
00a7b8264a
Review findings of round 1 (werkrevisor and Codex).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator

⚠️ werkrevisor: ERROR / review not completed, human action needed

Change kind: mixed.

Reasons

  • ERROR the model answer reached the output token limit [model] max_output_tokens = 64000
  • YELLOW tests lost or disabled: tests/test_pr_lens_script.py:62 disables a test
  • hint 9 changed file(s) that neither weaken the checks, touch security nor show a risk category of the repository config according to Jev
  • hint 1 build change(s) of low risk according to Jev: statistics/build.gradle.kts (weakens checks 0.03, risk 0.00, security 0.02)
  • hint 12 changed file(s) agree with the PR document according to Jev
  • hint 1 changed file was given to the AI as excerpt of the selected lines and 5 lines around each changed line, not in full (each larger than [review] max_full_file_chars = 80000): werkrevisor/cli.py
  • hint 1 finding(s) of low severity or rated minor by Jev: werkrevisor/pr_lens.mjs
  • hint model recommends changes before merge
  • hint model rates the risk as high (advisory: Jev judged every changed file)

Findings

  1. Issue at werkrevisor/pr_lens.mjs, severity unknown, counted as medium

    hint; Jev: real 0.15, severity 0.5 of 3

Classifier

8 of 8 units passed all questions (1 PR document(s)).
3 answers ignored because of a confidence below [classifier] min_confidence.

Usage: model `openrouter/minimax/minimax-m3`, LLM done, tokens counted before the call 60003, calls 1, tokens in 57881 / out 64000 (reasoning included in out), duration 676.1 s, cost 0.0941 USD (reported), classifier `jev-1.14.0` calls 8, tokens in 6576, cost 0.0003 USD, finding judge `jev-1.14.0` calls 1, tokens in 576, cost 0.0000 USD, excerpt selection `openrouter/openai/gpt-6-luna` calls 1, tokens in 25869 / out 380, cost 0.0034 USD (reported), PR document check `jev-1.14.0` calls 12, tokens in 36682, cost 0.0015 USD, build file judge `jev-1.14.0` calls 10, tokens in 12224, cost 0.0005 USD, phases: path_judge 0.5 s, classifier 0.4 s, doc_check 0.5 s, context 6.5 s, model_review 667.3 s, finding_judge 0.2 s, config: defaults + host + repository (.werkrevisor.toml at main bad4782).
Reviewed head `00a7b8264a859317fcf75eb1a0e83443f0e5b48a` against base `bad4782b99657b8a662db8b9333722c04619962e`, werkrevisor 0.65.2.
<!-- werkrevisor-error:00a7b8264a859317fcf75eb1a0e83443f0e5b48a --> ## ⚠️ werkrevisor: ERROR / review not completed, human action needed Change kind: `mixed`. ### Reasons - **ERROR** the model answer reached the output token limit [model] max_output_tokens = 64000 - **YELLOW** tests lost or disabled: tests/test_pr_lens_script.py:62 disables a test - **hint** 9 changed file(s) that neither weaken the checks, touch security nor show a risk category of the repository config according to Jev - **hint** 1 build change(s) of low risk according to Jev: statistics/build.gradle.kts (weakens checks 0.03, risk 0.00, security 0.02) - **hint** 12 changed file(s) agree with the PR document according to Jev - **hint** 1 changed file was given to the AI as excerpt of the selected lines and 5 lines around each changed line, not in full (each larger than [review] max_full_file_chars = 80000): werkrevisor/cli.py - **hint** 1 finding(s) of low severity or rated minor by Jev: werkrevisor/pr_lens.mjs - **hint** model recommends changes before merge - **hint** model rates the risk as high (advisory: Jev judged every changed file) ### Findings 1. **Issue** at `werkrevisor/pr_lens.mjs`, severity unknown, counted as medium hint; Jev: real 0.15, severity 0.5 of 3 ### Classifier 8 of 8 units passed all questions (1 PR document(s)). 3 answers ignored because of a confidence below [classifier] min_confidence. <sub> Usage: model `openrouter/minimax/minimax-m3`, LLM done, tokens counted before the call 60003, calls 1, tokens in 57881 / out 64000 (reasoning included in out), duration 676.1 s, cost 0.0941 USD (reported), classifier `jev-1.14.0` calls 8, tokens in 6576, cost 0.0003 USD, finding judge `jev-1.14.0` calls 1, tokens in 576, cost 0.0000 USD, excerpt selection `openrouter/openai/gpt-6-luna` calls 1, tokens in 25869 / out 380, cost 0.0034 USD (reported), PR document check `jev-1.14.0` calls 12, tokens in 36682, cost 0.0015 USD, build file judge `jev-1.14.0` calls 10, tokens in 12224, cost 0.0005 USD, phases: path_judge 0.5 s, classifier 0.4 s, doc_check 0.5 s, context 6.5 s, model_review 667.3 s, finding_judge 0.2 s, config: defaults + host + repository (.werkrevisor.toml at main bad4782).<br> Reviewed head `00a7b8264a859317fcf75eb1a0e83443f0e5b48a` against base `bad4782b99657b8a662db8b9333722c04619962e`, werkrevisor 0.65.2. </sub>
Some required checks failed
ai-review/codex queued ⏳: Codex reviews after werkrevisor
Required
werkator build succeeded after 00:32
Required
Details
werkator/werkrevisor-statistics build succeeded after 01:14
ai-review/assessment review not completed, human action needed
ai-review/gate build failed after 11:19
Required
Details
This pull request has changes conflicting with the target branch.
  • docs/werkrevisor.werkbaum
  • statistics/build.gradle.kts
  • werkrevisor/__init__.py
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude-code/diagram-cost:claude-code/diagram-cost
git checkout claude-code/diagram-cost
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mi/werkrevisor#140