See [docs/prs/2026-10-06-PR#26-dashboard-design.md](docs/prs/2026-10-06-PR%2326-dashboard-design.md).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
ai-review/assessment AI findings; a developer approval after checking them unlocks the merge; review requested from mi; merge scheduled for when the checks succeed
YELLOW files the model cannot review: server/src/main/resources/static/favicon.svg, server/src/main/resources/static/fonts/plex-mono-400.woff2, server/src/main/resources/static/fonts/plex-mono-500.woff2 and 1 more
YELLOW model reports a security concern
hint writing rules violated in the changed docs: docs/prs/2026-10-06-PR#26-dashboard-design.md:97: line longer than 128 characters (129); docs/prs/2026-10-06-PR#26-dashboard-design.md:113: line longer than 128 characters (130)
hint 2 finding(s) of low severity or rated minor by Jev: server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:372-378, server/src/main/resources/static/werkrevisor-dashboard.js:175-182
hint model recommends changes before merge
Findings
[high] Hidden private repositories leak through row order at server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142, ORANGE, as a line comment
[high] Test weakened: pullRequests assertion removed at server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:372-378, hint, as a line comment
[medium] Missing aria state on the toggle button at server/src/main/resources/static/werkrevisor-dashboard.js:175-182, hint, as a line comment
Classifier
10 of 10 units passed all questions (1 PR document(s)).
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60096, calls 1, tokens in 57265 / out 779 (reasoning included in out), duration 13.6 s, cost 0.1223 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8409, cost 0.0004 USD, finding judge `jev-1.13.0` calls 3, tokens in 4907, cost 0.0002 USD, config: defaults + host + repository (.werkrevisor.toml at base 924b279).
Reviewed head `2f9ababd842a67fced870939078ccc24573578ef` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
<!-- werkrevisor:2f9ababd842a67fced870939078ccc24573578ef -->
<!-- werkrevisor-verdict:ORANGE -->
<!-- werkrevisor-folded -->
<details><summary>🟠 werkrevisor ORANGE for <code>2f9abab</code>, superseded by <a href="http://git.javagil.de/mi/werkrevisor/pulls/26#issuecomment-1212">the result for <code>6159c9e</code></a></summary>
## 🟠 werkrevisor: ORANGE / FINDINGS
Change kind: `mixed`.
### Reasons
- **ORANGE** 1 finding(s) that Jev rates as probably real and severe: server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142
- **YELLOW** risky paths changed: server/build.gradle.kts (server/*.gradle.kts)
- **YELLOW** files the model cannot review: server/src/main/resources/static/favicon.svg, server/src/main/resources/static/fonts/plex-mono-400.woff2, server/src/main/resources/static/fonts/plex-mono-500.woff2 and 1 more
- **YELLOW** model reports a security concern
- **hint** writing rules violated in the changed docs: docs/prs/2026-10-06-PR#26-dashboard-design.md:97: line longer than 128 characters (129); docs/prs/2026-10-06-PR#26-dashboard-design.md:113: line longer than 128 characters (130)
- **hint** 2 finding(s) of low severity or rated minor by Jev: server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:372-378, server/src/main/resources/static/werkrevisor-dashboard.js:175-182
- **hint** model recommends changes before merge
### Findings
1. **[high] Hidden private repositories leak through row order** at `server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142`, ORANGE, as a line comment
2. **[high] Test weakened: pullRequests assertion removed** at `server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:372-378`, hint, as a line comment
3. **[medium] Missing aria state on the toggle button** at `server/src/main/resources/static/werkrevisor-dashboard.js:175-182`, hint, as a line comment
### Classifier
10 of 10 units passed all questions (1 PR document(s)).
<sub>
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60096, calls 1, tokens in 57265 / out 779 (reasoning included in out), duration 13.6 s, cost 0.1223 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8409, cost 0.0004 USD, finding judge `jev-1.13.0` calls 3, tokens in 4907, cost 0.0002 USD, config: defaults + host + repository (.werkrevisor.toml at base 924b279).<br>
Reviewed head `2f9ababd842a67fced870939078ccc24573578ef` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
</sub>
</details>
werkrevisor: ORANGE / FINDINGS for 2f9ababd842a67fced870939078ccc24573578ef.
The result comment of werkrevisor holds the details.
werkrevisor: ORANGE / FINDINGS for `2f9ababd842a67fced870939078ccc24573578ef`.
The result comment of werkrevisor holds the details.
<!-- werkrevisor-review:2f9ababd842a67fced870939078ccc24573578ef -->
[high] Hidden private repositories leak through row order (werkrevisor)
ORANGE; Jev: real 0.71, severity 3.0 of 3
groups(lastMonth) sorts by cost and the hidden rows keep that order, so every hidden row sits at the position of its cost rank. The sums also stay per repository. A reader without a token can combine these with other public data, such as the cost per day or window, to infer which private repository a row belongs to. The per-repository sums of private repositories were hidden before, in one aggregated row; this PR changes that. The PR document states the intent, but it does not discuss this disclosure, so confirm that it is accepted.
**[high] Hidden private repositories leak through row order** (werkrevisor)
ORANGE; Jev: real 0.71, severity 3.0 of 3
`groups(lastMonth)` sorts by cost and the hidden rows keep that order, so every hidden row sits at the position of its cost rank. The sums also stay per repository. A reader without a token can combine these with other public data, such as the cost per day or window, to infer which private repository a row belongs to. The per-repository sums of private repositories were hidden before, in one aggregated row; this PR changes that. The PR document states the intent, but it does not discuss this disclosure, so confirm that it is accepted.
[medium] Missing aria state on the toggle button (werkrevisor)
hint; Jev: real 0.94, severity 2.4 of 3
The "Show N more" button only changes a CSS class on the section. It has no aria-expanded, so assistive technology cannot tell whether the rows are open or hidden.
**[medium] Missing aria state on the toggle button** (werkrevisor)
hint; Jev: real 0.94, severity 2.4 of 3
The "Show N more" button only changes a CSS class on the section. It has no `aria-expanded`, so assistive technology cannot tell whether the rows are open or hidden.
[high] Test weakened: pullRequests assertion removed (werkrevisor)
hint; Jev: real 0.62, severity 2.0 of 3
The old test asserted pullRequests shouldBe 6 for the aggregated private row. The new test checks only the review count and the number of hidden rows. A regression in the pull-request count of the hidden rows would no longer be caught. The test also no longer checks that no hidden row carries a name beyond an empty key. Add the pullRequests sum, 6, back to the test.
**[high] Test weakened: pullRequests assertion removed** (werkrevisor)
hint; Jev: real 0.62, severity 2.0 of 3
The old test asserted `pullRequests shouldBe 6` for the aggregated private row. The new test checks only the review count and the number of hidden rows. A regression in the pull-request count of the hidden rows would no longer be caught. The test also no longer checks that no hidden row carries a name beyond an empty key. Add the `pullRequests` sum, 6, back to the test.
ai-reviewer
scheduled this pull request to auto merge when all checks succeed 2026-10-06 12:46:39 +02:00
ai-reviewer
requested review from mi 2026-10-06 12:46:39 +02:00
ai-review/assessment AI findings; a developer approval after checking them unlocks the merge; a human review request is pending; merge already scheduled
YELLOW files the model cannot review: server/src/main/resources/static/favicon.svg, server/src/main/resources/static/fonts/plex-mono-400.woff2, server/src/main/resources/static/fonts/plex-mono-500.woff2 and 1 more
hint 2 finding(s) of low severity or rated minor by Jev: server/src/main/resources/static/werkrevisor-dashboard.js:171-208, docs/prs/2026-10-06-PR#26-dashboard-design.md:104-107
hint model recommends merge with caution
Findings
[medium] Hidden private repos leak per-repo costs and mutable ordering at server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142, ORANGE, still open in an earlier line comment
[medium] Missing test for hidden-row rendering and toggle behavior at server/src/main/resources/static/werkrevisor-dashboard.js:171-208, hint, still open in an earlier line comment
[low] Document says Scenario 26.05 is verified by a renamed test only at docs/prs/2026-10-06-PR#26-dashboard-design.md:104-107, hint, as a line comment
Classifier
10 of 10 units passed all questions (1 PR document(s)).
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60388, calls 1, tokens in 57551 / out 724 (reasoning included in out), duration 13.5 s, cost 0.1223 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8473, cost 0.0004 USD, finding judge `jev-1.13.0` calls 2, tokens in 3542, cost 0.0001 USD, config: defaults + host + repository (.werkrevisor.toml at base 924b279).
Reviewed head `6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
<!-- werkrevisor:6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac -->
<!-- werkrevisor-verdict:ORANGE -->
<!-- werkrevisor-folded -->
<details><summary>🟠 werkrevisor ORANGE for <code>6159c9e</code>, superseded by <a href="http://git.javagil.de/mi/werkrevisor/pulls/26#issuecomment-1217">the result for <code>1512693</code></a></summary>
## 🟠 werkrevisor: ORANGE / FINDINGS
Change kind: `mixed`.
### Reasons
- **ORANGE** 1 finding(s) that Jev rates as probably real and severe: server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142
- **YELLOW** risky paths changed: server/build.gradle.kts (server/*.gradle.kts)
- **YELLOW** files the model cannot review: server/src/main/resources/static/favicon.svg, server/src/main/resources/static/fonts/plex-mono-400.woff2, server/src/main/resources/static/fonts/plex-mono-500.woff2 and 1 more
- **hint** 2 finding(s) of low severity or rated minor by Jev: server/src/main/resources/static/werkrevisor-dashboard.js:171-208, docs/prs/2026-10-06-PR#26-dashboard-design.md:104-107
- **hint** model recommends merge with caution
### Findings
1. **[medium] Hidden private repos leak per-repo costs and mutable ordering** at `server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142`, ORANGE, still open in [an earlier line comment](http://git.javagil.de/mi/werkrevisor/pulls/26#issuecomment-1205)
2. **[medium] Missing test for hidden-row rendering and toggle behavior** at `server/src/main/resources/static/werkrevisor-dashboard.js:171-208`, hint, still open in [an earlier line comment](http://git.javagil.de/mi/werkrevisor/pulls/26#issuecomment-1207)
3. **[low] Document says Scenario 26.05 is verified by a renamed test only** at `docs/prs/2026-10-06-PR#26-dashboard-design.md:104-107`, hint, as a line comment
### Classifier
10 of 10 units passed all questions (1 PR document(s)).
<sub>
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60388, calls 1, tokens in 57551 / out 724 (reasoning included in out), duration 13.5 s, cost 0.1223 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8473, cost 0.0004 USD, finding judge `jev-1.13.0` calls 2, tokens in 3542, cost 0.0001 USD, config: defaults + host + repository (.werkrevisor.toml at base 924b279).<br>
Reviewed head `6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
</sub>
</details>
werkrevisor: ORANGE / FINDINGS for 6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac.
The result comment of werkrevisor holds the details.
werkrevisor: ORANGE / FINDINGS for `6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac`.
The result comment of werkrevisor holds the details.
<!-- werkrevisor-review:6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac -->
[low] Document says Scenario 26.05 is verified by a renamed test only (werkrevisor)
hint
Scenario#26.05 links to the test "private repositories are named only with a read token". That test is titled Scenario#25.03 and covers the API fields (hidden, empty key), not the dashboard's grey italic "private repository" label. The claim of verification by that test is only partly true.
**[low] Document says Scenario 26.05 is verified by a renamed test only** (werkrevisor)
hint
Scenario#26.05 links to the test "private repositories are named only with a read token". That test is titled Scenario#25.03 and covers the API fields (`hidden`, empty key), not the dashboard's grey italic "private repository" label. The claim of verification by that test is only partly true.
Assessment of the werkrevisor findings (as of the last commit):
Fixed:
UsageApiIntegrationTest.kt: the hidden rows are checked for their pull requests too (sum 6).
werkrevisor-dashboard.js: the "Show N more" button carries aria-expanded.
PR doc: lines above 128 characters wrapped; Scenario#26.05 states what the test and what the browser check verify.
Not changed:
Statistics.kt:139-142 (ORANGE), per-repository costs of private repositories without a token: intended.
The developer asked for one row per private repository with its costs, so that the rows add up to the total;
only the name stays hidden. The PR doc states this under Non-Goals, including that a reader with other data may guess which row is which.
werkrevisor-dashboard.js:171-208, no automated test of the rendering: the server has no JavaScript test setup;
the browser check in the Measurement section covers the label, the toggle, the theme and the token button.
YELLOW server/build.gradle.kts: version bump and buildInfo() for the version in the footer.
YELLOW binary files: the IBM Plex fonts are the same files that Werkator serves (SIL Open Font License); favicon.svg is the new logo.
Assessment of the werkrevisor findings (as of the last commit):
Fixed:
- `UsageApiIntegrationTest.kt`: the hidden rows are checked for their pull requests too (sum 6).
- `werkrevisor-dashboard.js`: the "Show N more" button carries `aria-expanded`.
- PR doc: lines above 128 characters wrapped; Scenario#26.05 states what the test and what the browser check verify.
Not changed:
- `Statistics.kt:139-142` (ORANGE), per-repository costs of private repositories without a token: intended.
The developer asked for one row per private repository with its costs, so that the rows add up to the total;
only the name stays hidden. The PR doc states this under Non-Goals, including that a reader with other data may guess which row is which.
- `werkrevisor-dashboard.js:171-208`, no automated test of the rendering: the server has no JavaScript test setup;
the browser check in the Measurement section covers the label, the toggle, the theme and the token button.
- YELLOW `server/build.gradle.kts`: version bump and `buildInfo()` for the version in the footer.
- YELLOW binary files: the IBM Plex fonts are the same files that Werkator serves (SIL Open Font License); `favicon.svg` is the new logo.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
YELLOW files the model cannot review: server/src/main/resources/static/favicon.svg, server/src/main/resources/static/fonts/plex-mono-400.woff2, server/src/main/resources/static/fonts/plex-mono-500.woff2 and 1 more
hint 3 finding(s) of low severity or rated minor by Jev: server/src/main/resources/static/werkrevisor-dashboard.js:298-299, server/src/main/resources/static/index.html:7-8, server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:395-397
hint model recommends merge with caution
Findings
[high] Verdict table renders an element as the row key at server/src/main/resources/static/werkrevisor-dashboard.js:298-299, hint, as a line comment
[medium] Favicon and font files not part of the diff at server/src/main/resources/static/index.html:7-8, hint, as a line comment
[medium] Hidden repository test does not check public-only labelling per row at server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:395-397, hint, as a line comment
Classifier
10 of 10 units passed all questions (1 PR document(s)).
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60430, calls 1, tokens in 57581 / out 794 (reasoning included in out), duration 13.1 s, cost 0.1231 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8473, cost 0.0004 USD, finding judge `jev-1.13.0` calls 3, tokens in 4007, cost 0.0002 USD, config: defaults + host + repository (.werkrevisor.toml at base 924b279).
Reviewed head `1512693c47781948d05afd37b8e8c01575d97a38` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
<!-- werkrevisor:1512693c47781948d05afd37b8e8c01575d97a38 -->
<!-- werkrevisor-verdict:YELLOW -->
## 🟡 werkrevisor: YELLOW / HUMAN_REVIEW
Change kind: `mixed`.
### Reasons
- **YELLOW** risky paths changed: server/build.gradle.kts (server/*.gradle.kts)
- **YELLOW** files the model cannot review: server/src/main/resources/static/favicon.svg, server/src/main/resources/static/fonts/plex-mono-400.woff2, server/src/main/resources/static/fonts/plex-mono-500.woff2 and 1 more
- **hint** 3 finding(s) of low severity or rated minor by Jev: server/src/main/resources/static/werkrevisor-dashboard.js:298-299, server/src/main/resources/static/index.html:7-8, server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:395-397
- **hint** model recommends merge with caution
### Findings
1. **[high] Verdict table renders an element as the row key** at `server/src/main/resources/static/werkrevisor-dashboard.js:298-299`, hint, as a line comment
2. **[medium] Favicon and font files not part of the diff** at `server/src/main/resources/static/index.html:7-8`, hint, as a line comment
3. **[medium] Hidden repository test does not check public-only labelling per row** at `server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:395-397`, hint, as a line comment
### Classifier
10 of 10 units passed all questions (1 PR document(s)).
<sub>
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60430, calls 1, tokens in 57581 / out 794 (reasoning included in out), duration 13.1 s, cost 0.1231 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8473, cost 0.0004 USD, finding judge `jev-1.13.0` calls 3, tokens in 4007, cost 0.0002 USD, config: defaults + host + repository (.werkrevisor.toml at base 924b279).<br>
Reviewed head `1512693c47781948d05afd37b8e8c01575d97a38` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
</sub>
werkrevisor: YELLOW / HUMAN_REVIEW for 1512693c47781948d05afd37b8e8c01575d97a38.
The result comment of werkrevisor holds the details.
werkrevisor: YELLOW / HUMAN_REVIEW for `1512693c47781948d05afd37b8e8c01575d97a38`.
The result comment of werkrevisor holds the details.
<!-- werkrevisor-review:1512693c47781948d05afd37b8e8c01575d97a38 -->
[medium] Favicon and font files not part of the diff (werkrevisor)
hint; Jev: real 0.37, severity 1.4 of 3
index.html links favicon.svg and werkrevisor.css references fonts/plex-sans.woff2, fonts/plex-mono-400.woff2 and fonts/plex-mono-500.woff2. None of these files appear in the diff. If they are not committed, the page gets 404s and falls back to system fonts. Uncertain: binary files may simply be omitted from the diff view.
**[medium] Favicon and font files not part of the diff** (werkrevisor)
hint; Jev: real 0.37, severity 1.4 of 3
`index.html` links `favicon.svg` and `werkrevisor.css` references `fonts/plex-sans.woff2`, `fonts/plex-mono-400.woff2` and `fonts/plex-mono-500.woff2`. None of these files appear in the diff. If they are not committed, the page gets 404s and falls back to system fonts. Uncertain: binary files may simply be omitted from the diff view.
[high] Verdict table renders an element as the row key (werkrevisor)
hint; Jev: real 0.16, severity 0.5 of 3
groupTable is called for the verdict table with verdict as the name function. verdict() returns a DOM element, which el appends correctly as a Node, so this is fine. For the repository table with hidden rows the key is empty, which is handled. However, groupTable receives a DOM element (el("span", ...)) as title, and el("h2", {}, title) appends it, which works. No defect here; but a hidden row in a table whose name is verdict would never occur, so this is uncertain and likely fine.
**[high] Verdict table renders an element as the row key** (werkrevisor)
hint; Jev: real 0.16, severity 0.5 of 3
`groupTable` is called for the verdict table with `verdict` as the `name` function. `verdict()` returns a DOM element, which `el` appends correctly as a Node, so this is fine. For the repository table with `hidden` rows the key is empty, which is handled. However, `groupTable` receives a DOM element (`el("span", ...)`) as `title`, and `el("h2", {}, title)` appends it, which works. No defect here; but a hidden row in a table whose `name` is `verdict` would never occur, so this is uncertain and likely fine.
[medium] Hidden repository test does not check public-only labelling per row (werkrevisor)
hint; Jev: real 0.56, severity 2.0 of 3
The test asserts four hidden rows with empty keys, but no test covers the new werkrevisor-page.js behavior (token state, version display) beyond a string match. The JS-only scenarios 26.01, 26.03 and 26.04 are verified manually only. This is acceptable but leaves token-accepted detection untested.
**[medium] Hidden repository test does not check public-only labelling per row** (werkrevisor)
hint; Jev: real 0.56, severity 2.0 of 3
The test asserts four hidden rows with empty keys, but no test covers the new `werkrevisor-page.js` behavior (token state, version display) beyond a string match. The JS-only scenarios 26.01, 26.03 and 26.04 are verified manually only. This is acceptable but leaves token-accepted detection untested.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
See docs/prs/2026-10-06-PR#26-dashboard-design.md.
🤖 Generated with Claude Code
🟠 werkrevisor ORANGE for
2f9abab, superseded by the result for6159c9e🟠 werkrevisor: ORANGE / FINDINGS
Change kind:
mixed.Reasons
Findings
[high] Hidden private repositories leak through row order at
server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142, ORANGE, as a line comment[high] Test weakened: pullRequests assertion removed at
server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:372-378, hint, as a line comment[medium] Missing aria state on the toggle button at
server/src/main/resources/static/werkrevisor-dashboard.js:175-182, hint, as a line commentClassifier
10 of 10 units passed all questions (1 PR document(s)).
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60096, calls 1, tokens in 57265 / out 779 (reasoning included in out), duration 13.6 s, cost 0.1223 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8409, cost 0.0004 USD, finding judge `jev-1.13.0` calls 3, tokens in 4907, cost 0.0002 USD, config: defaults + host + repository (.werkrevisor.toml at base924b279).Reviewed head `2f9ababd842a67fced870939078ccc24573578ef` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
werkrevisor: ORANGE / FINDINGS for
2f9ababd842a67fced870939078ccc24573578ef.The result comment of werkrevisor holds the details.
@@ -128,3 +137,3 @@details =Details(byRepo = groups(lastMonth) { if (withRecent || it.repo in publicRepos) it.repo else PRIVATE_REPOS },byRepo =[high] Hidden private repositories leak through row order (werkrevisor)
ORANGE; Jev: real 0.71, severity 3.0 of 3
groups(lastMonth)sorts by cost and the hidden rows keep that order, so every hidden row sits at the position of its cost rank. The sums also stay per repository. A reader without a token can combine these with other public data, such as the cost per day or window, to infer which private repository a row belongs to. The per-repository sums of private repositories were hidden before, in one aggregated row; this PR changes that. The PR document states the intent, but it does not discuss this disclosure, so confirm that it is accepted.@@ -143,1 +173,3 @@{},const section = el("section", this.opened.has(title) ? { class: "open" } : {});const rest = periods.length - VISIBLE_PERIODS;const toggle = el("button", { class: "toggle", type: "button" });[medium] Missing aria state on the toggle button (werkrevisor)
hint; Jev: real 0.94, severity 2.4 of 3
The "Show N more" button only changes a CSS class on the section. It has no
aria-expanded, so assistive technology cannot tell whether the rows are open or hidden.@@ -373,3 +372,1 @@with(byRepo.items().first { it["key"].asString() == "private repositories" }["sums"]) {this["reviews"].asInt() shouldBe 6this["pullRequests"].asInt() shouldBe 6byRepo.items().filter { !it["hidden"].asBoolean() }.map { it["key"].asString() } shouldContainExactly listOf("team/app")[high] Test weakened: pullRequests assertion removed (werkrevisor)
hint; Jev: real 0.62, severity 2.0 of 3
The old test asserted
pullRequests shouldBe 6for the aggregated private row. The new test checks only the review count and the number of hidden rows. A regression in the pull-request count of the hidden rows would no longer be caught. The test also no longer checks that no hidden row carries a name beyond an empty key. Add thepullRequestssum, 6, back to the test.🟠 werkrevisor ORANGE for
6159c9e, superseded by the result for1512693🟠 werkrevisor: ORANGE / FINDINGS
Change kind:
mixed.Reasons
Findings
[medium] Hidden private repos leak per-repo costs and mutable ordering at
server/src/main/kotlin/de/hoennig/werkrevisor/server/Statistics.kt:139-142, ORANGE, still open in an earlier line comment[medium] Missing test for hidden-row rendering and toggle behavior at
server/src/main/resources/static/werkrevisor-dashboard.js:171-208, hint, still open in an earlier line comment[low] Document says Scenario 26.05 is verified by a renamed test only at
docs/prs/2026-10-06-PR#26-dashboard-design.md:104-107, hint, as a line commentClassifier
10 of 10 units passed all questions (1 PR document(s)).
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60388, calls 1, tokens in 57551 / out 724 (reasoning included in out), duration 13.5 s, cost 0.1223 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8473, cost 0.0004 USD, finding judge `jev-1.13.0` calls 2, tokens in 3542, cost 0.0001 USD, config: defaults + host + repository (.werkrevisor.toml at base924b279).Reviewed head `6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
werkrevisor: ORANGE / FINDINGS for
6159c9ed2d63f5a8ce32e67ba2e91b5f37a49cac.The result comment of werkrevisor holds the details.
@@ -0,0 +101,4 @@- **and** one row per private repository, named "private repository" in grey italics,with its costs, reviews and pull requests##### Verified by[low] Document says Scenario 26.05 is verified by a renamed test only (werkrevisor)
hint
Scenario#26.05 links to the test "private repositories are named only with a read token". That test is titled Scenario#25.03 and covers the API fields (
hidden, empty key), not the dashboard's grey italic "private repository" label. The claim of verification by that test is only partly true.Assessment of the werkrevisor findings (as of the last commit):
Fixed:
UsageApiIntegrationTest.kt: the hidden rows are checked for their pull requests too (sum 6).werkrevisor-dashboard.js: the "Show N more" button carriesaria-expanded.Not changed:
Statistics.kt:139-142(ORANGE), per-repository costs of private repositories without a token: intended.The developer asked for one row per private repository with its costs, so that the rows add up to the total;
only the name stays hidden. The PR doc states this under Non-Goals, including that a reader with other data may guess which row is which.
werkrevisor-dashboard.js:171-208, no automated test of the rendering: the server has no JavaScript test setup;the browser check in the Measurement section covers the label, the toggle, the theme and the token button.
server/build.gradle.kts: version bump andbuildInfo()for the version in the footer.favicon.svgis the new logo.🤖 Generated with Claude Code
🟡 werkrevisor: YELLOW / HUMAN_REVIEW
Change kind:
mixed.Reasons
Findings
[high] Verdict table renders an element as the row key at
server/src/main/resources/static/werkrevisor-dashboard.js:298-299, hint, as a line comment[medium] Favicon and font files not part of the diff at
server/src/main/resources/static/index.html:7-8, hint, as a line comment[medium] Hidden repository test does not check public-only labelling per row at
server/src/test/kotlin/de/hoennig/werkrevisor/server/UsageApiIntegrationTest.kt:395-397, hint, as a line commentClassifier
10 of 10 units passed all questions (1 PR document(s)).
Usage: model `openrouter/anthropic/claude-sonnet-5.5`, LLM done, tokens counted before the call 60430, calls 1, tokens in 57581 / out 794 (reasoning included in out), duration 13.1 s, cost 0.1231 USD (reported), classifier `jev-1.13.0` calls 10, tokens in 8473, cost 0.0004 USD, finding judge `jev-1.13.0` calls 3, tokens in 4007, cost 0.0002 USD, config: defaults + host + repository (.werkrevisor.toml at base924b279).Reviewed head `1512693c47781948d05afd37b8e8c01575d97a38` against base `924b27916c6c2708f5f3c2ff5d616f7297d9fa28`, werkrevisor 0.18.4.
werkrevisor: YELLOW / HUMAN_REVIEW for
1512693c47781948d05afd37b8e8c01575d97a38.The result comment of werkrevisor holds the details.
@@ -10,3 +7,1 @@h1 { font-size: 20px; margin: 0; }form { display: flex; gap: 6px; }</style><link rel="icon" href="favicon.svg" type="image/svg+xml">[medium] Favicon and font files not part of the diff (werkrevisor)
hint; Jev: real 0.37, severity 1.4 of 3
index.htmllinksfavicon.svgandwerkrevisor.cssreferencesfonts/plex-sans.woff2,fonts/plex-mono-400.woff2andfonts/plex-mono-500.woff2. None of these files appear in the diff. If they are not committed, the page gets 404s and falls back to system fonts. Uncertain: binary files may simply be omitted from the diff view.@@ -243,3 +297,2 @@{ class: "groups" },this.groupTable("Last 30 days by repository", details.byRepo),this.groupTable("by verdict", details.byVerdict),this.groupTable(el("span", {}, "By repository", el("em", {}, "last 30 days")), "Repository", details.byRepo, (key) => key),[high] Verdict table renders an element as the row key (werkrevisor)
hint; Jev: real 0.16, severity 0.5 of 3
groupTableis called for the verdict table withverdictas thenamefunction.verdict()returns a DOM element, whichelappends correctly as a Node, so this is fine. For the repository table withhiddenrows the key is empty, which is handled. However,groupTablereceives a DOM element (el("span", ...)) astitle, andel("h2", {}, title)appends it, which works. No defect here; but a hidden row in a table whosenameisverdictwould never occur, so this is uncertain and likely fine.@@ -389,6 +392,10 @@ class UsageApiIntegrationTest : FunSpec() {recent[0]["prUrl"].asString() shouldBe "https://git.example.org/team/app/pulls/1"}test("the statistics name the version of the service") {[medium] Hidden repository test does not check public-only labelling per row (werkrevisor)
hint; Jev: real 0.56, severity 2.0 of 3
The test asserts four hidden rows with empty keys, but no test covers the new
werkrevisor-page.jsbehavior (token state, version display) beyond a string match. The JS-only scenarios 26.01, 26.03 and 26.04 are verified manually only. This is acceptable but leaves token-accepted detection untested.