From 9af96732bccdbcf2ef4e62797ffe8361bd562e91 Mon Sep 17 00:00:00 2001 From: Remi Antczak <140408771+remigiusz-antczak@users.noreply.github.com> Date: Sat, 31 Oct 2026 20:52:54 +0100 Subject: [PATCH] release: 1.632.0 (stamped at land time) Co-Authored-By: Claude Opus 5.5 --- .claude-plugin/plugin.json | 2 +- .claude/skills/agentic-delivery/SKILL.md | 2 +- .claude/skills/agentic-delivery/VERSION | 2 +- .claude/skills/deep-code-review/SKILL.md | 2 +- .claude/skills/deep-code-review/VERSION | 2 +- .claude/skills/idea-critic/SKILL.md | 2 +- .claude/skills/idea-critic/VERSION | 2 +- .codex-plugin/plugin.json | 2 +- CHANGELOG.md | 18 ++++++++++++++++++ SHA256SUMS | 16 ++++++++-------- changelog.d/handback-followups.md | 7 ------- changelog.d/privacy-prefilter.md | 2 -- changelog.d/semgrep-partial-detail.md | 4 ---- gemini-extension.json | 2 +- 14 files changed, 35 insertions(+), 30 deletions(-) delete mode 100644 changelog.d/handback-followups.md delete mode 100644 changelog.d/privacy-prefilter.md delete mode 100644 changelog.d/semgrep-partial-detail.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index f69d8709a..32803cc7d 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "name": "perun", "description": "Perun: a suite of skills for building with AI agents. Deep code review, token and cost tools (spend reports, auto-compact with handoff, model-tier guidance), gated agentic delivery (merge train, lanes, destructive-command guard, auto-update), an idea critic, and product, growth, positioning, business-ops and output-safety specialists.", "skills": "./.claude/skills", - "version": "1.631.0", + "version": "1.632.0", "author": { "name": "deep-code-review contributors" }, diff --git a/.claude/skills/agentic-delivery/SKILL.md b/.claude/skills/agentic-delivery/SKILL.md index 1d03bc6aa..3fcb8758f 100644 --- a/.claude/skills/agentic-delivery/SKILL.md +++ b/.claude/skills/agentic-delivery/SKILL.md @@ -8,7 +8,7 @@ description: >- license: MIT metadata: author: deep-code-review contributors - version: "1.631.0" + version: "1.632.0" --- # Agentic delivery diff --git a/.claude/skills/agentic-delivery/VERSION b/.claude/skills/agentic-delivery/VERSION index 74e0a6c96..01280b9e0 100644 --- a/.claude/skills/agentic-delivery/VERSION +++ b/.claude/skills/agentic-delivery/VERSION @@ -1 +1 @@ -1.631.0 +1.632.0 diff --git a/.claude/skills/deep-code-review/SKILL.md b/.claude/skills/deep-code-review/SKILL.md index 5c8ce0cf4..0f7a5c7ed 100644 --- a/.claude/skills/deep-code-review/SKILL.md +++ b/.claude/skills/deep-code-review/SKILL.md @@ -8,7 +8,7 @@ description: >- license: MIT metadata: author: deep-code-review contributors - version: "1.631.0" + version: "1.632.0" --- # Deep Code Review diff --git a/.claude/skills/deep-code-review/VERSION b/.claude/skills/deep-code-review/VERSION index 74e0a6c96..01280b9e0 100644 --- a/.claude/skills/deep-code-review/VERSION +++ b/.claude/skills/deep-code-review/VERSION @@ -1 +1 @@ -1.631.0 +1.632.0 diff --git a/.claude/skills/idea-critic/SKILL.md b/.claude/skills/idea-critic/SKILL.md index 87855cf76..79786c155 100644 --- a/.claude/skills/idea-critic/SKILL.md +++ b/.claude/skills/idea-critic/SKILL.md @@ -8,7 +8,7 @@ description: >- license: MIT metadata: author: deep-code-review contributors - version: "1.631.0" + version: "1.632.0" --- # Veles: the evil twin (idea-critic) diff --git a/.claude/skills/idea-critic/VERSION b/.claude/skills/idea-critic/VERSION index 74e0a6c96..01280b9e0 100644 --- a/.claude/skills/idea-critic/VERSION +++ b/.claude/skills/idea-critic/VERSION @@ -1 +1 @@ -1.631.0 +1.632.0 diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index cea16fb17..8ba6a3ca8 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "perun", - "version": "1.631.0", + "version": "1.632.0", "description": "Perun: a skill suite for AI-agent teams: deep code review, token and cost tools, gated delivery, an idea critic and product specialists.", "skills": "./.claude/skills", "interface": { diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c181d110..886aee301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to this repository are documented here. Format loosely follows Keep a Changelog; versioning follows Semantic Versioning. +## [1.632.0] — 2026-10-31 + +### Fixed +- `handback_cap.py`'s background-work block text no longer says "You own it until it exits". The scan matches any test or build whose cwd is in the lane's worktree, and that process may have been started by someone else working in the same worktree. The text now says what the lane can do (wait for the pid with `lane_guard.py wait --pid --timeout `, or stop it if this lane started it) and that the hold ends on its own after `HANDBACK_PUSH_MAX_S` (30 minutes by default) at most, as the push and commit hold text already did. +- A hold's window now restarts once its condition is gone. `_hold` keeps the first block's time as the mtime of the lane's `.push`, `.bg` or `.dirty` state file and nothing removed that file, so after one block that was more than 30 minutes old, a later push or commit, background run or dirty tree in the same lane was released at once instead of being held for a fresh window. `check()` now removes the lane's state file (new `_release`, which ignores `OSError`) for each hold whose check found no such condition, so the next block opens a fresh `HANDBACK_PUSH_MAX_S` window. `check()` also no longer returns at the first hold that blocks: the push or commit, background and dirty-worktree checks are all evaluated before it returns 2, so the reset also happens while a higher hold blocks (for example: a dirty-worktree hold opened more than 30 minutes ago, the tree cleaned while a commit is still running, the commit ending, the tree dirtied again, and the lane is held again for a fresh window). The first hold that blocks still wins in the same order (push or commit, background, dirty) with the same text, a lower hold is still never started on a call where a higher one blocks, and a blind lower check now prints its `COULD_NOT_CHECK` line before that hold's text. A check that could not run (`COULD_NOT_CHECK`) keeps the hold, and a condition that stays live past the window is still released, so a stuck process cannot trap the lane. The dirty-worktree hold goes through the same `_hold` and gets the same reset. + +### Changed +- The `_push_running` docstring and the comment above `PUSH_RE` now state a known limit: `ps` prints argv without quoting, so a space inside a `-c` value or a `-C` path splits it (`git -c user.name=Jane Smith commit`, `git -C /acme/my repo commit`), `PUSH_RE` does not match, and that push or commit is not held (the check fails open and does not print `COULD_NOT_CHECK`). The behaviour is unchanged; it is now documented and pinned. +- Test: `python3 .claude/skills/agentic-delivery/scripts/handback_cap.py --selftest` (already run by CI) goes from 83 to 117 cases. Ten of the new ones fail on the previous code (107 of 117 passed there): each of the push, background and dirty-worktree holds starting a fresh window when the condition clears and returns (old first block, condition gone, condition back, held again); the background and dirty holds doing the same when a higher hold blocks while their own condition is gone, including their state file being removed; and the background hold text naming the way out rather than ownership. The other twenty-four pin behaviour that already held: the first block and the release after the window for each of the three holds, a condition that clears and passes, a hold whose scan could not run keeping its state file, a lower hold opening its first block, the first hold that blocks winning (push or commit, then background, then dirty) with no lower hold started, `_skip_pids` skipping the hook's ancestors and descendants (a synthetic process table, hook then child then a grandchild `git commit`) while an unrelated `git commit` pid is still counted, the same through `_push_running`, and three `known-limit-*` cases (a `-c` value with a space and a `-C` path with a space are not held, a `-c` value without one is). Each of the three keep-on-`None` cases fails when its scan's `None` is treated as empty (`if not running`, `elif not bg`, `elif not dirty`). + +### Changed +- The privacy gate (`scripts/ci-gates.sh privacy`) now runs one prefilter pass before its per-pattern scan: a single `grep -IlE -D skip -f` over every banlist pattern at once, in the same 1000-file batches, lists the only files any pattern can match, and the existing per-pattern greps read just those files. A clean tree is therefore read once instead of once per pattern, which shortens the gate on large trees. The hit set is unchanged: hits are still attributed per pattern with the content withheld, the empty-input ERE probe still runs first so the pattern list holds only valid patterns, the `secret_scan.py` pass is untouched, and a prefilter grep error fails closed (it never reads as "no candidates"). The candidate list is newline-delimited, so a tree holding a path with a newline in its name skips the prefilter and falls back to the full per-pattern scan, which keeps the hit set unchanged there too. The new `scripts/test-privacy-prefilter.sh` pins the unchanged hit set against an independent one-grep-per-pattern oracle, the one-pass cost on a clean tree, that the per-pattern greps see only listed files, both fail-closed paths (an invalid ERE and a prefilter error), and that a hit in a file whose name holds a newline still blocks. + +### Changed +- When semgrep reports errors on some of the files it scanned, the `review_checks.sh` tool hub now names those files instead of only saying the scan was partial. Each file with an error is a `not-checked` row (its path, line 0, and the error type and level), at most 20 per 200-file semgrep call, followed by one row with the path `.` that counts the rest and names the first path left out, so two calls with equal error counts keep one such row each instead of the closing dedup of identical `not-checked` rows merging them into one. An error that carries no path stays counted and gets no row. The `review_checks: partial: semgrep ran but reported errors (...)` line on stderr keeps its text and now ends with the error counts, for example `(3 error(s) on 2 of 40 scanned file(s): PartialParsing (warn) x2, Syntax error (error) x1; see not-checked rows)`. The type is semgrep's `type` string, or the first element when it is a list. A warn-level parse error still makes the scan partial and is never read as clean. Whether a scan is partial or not run is decided on the findings alone, before these rows are added, so the "not run" cases (errors on every scanned file, or an error with no path and no findings) are unchanged and name no file. The header comment of `review_checks.sh` now matches. +- The closing summary on stderr no longer counts `not-checked` rows as findings: `review_checks: N findings; ...` counts every other row, and a separate line, `review_checks: K not-checked row(s) (surface a tool did not cover, not findings)`, gives the number of `not-checked` rows and appears only when there are any. The line that reports how many rows are on lines the diff adds still counts every row. +- Test: `scripts/test-review-checks-semgrep-partial.sh` (registered as `scripts/ci-tests.d/review-checks-semgrep-partial.sh`) runs the hub against a stub semgrep that answers each call with its own fictional JSON. It covers a warn-level `PartialParsing` on 1 of 3 files (one row for that path, the counts on the partial line, the finding row unchanged), 25 errored files (20 rows plus the summary row, counts ordered by count), two semgrep calls (200 and 30 files) with equal error counts (two summary rows and two partial lines), the findings count and the separate `not-checked` line, several errors on one file, errors with no path, the "not run" cases, and odd error shapes (a null or string entry, a missing type or level, a path that is not a string, a control character in a path) that must not void the chunk's findings. + ## [1.631.0] — 2026-10-31 ### Fixed diff --git a/SHA256SUMS b/SHA256SUMS index 453ea1f28..5b9cfdce2 100644 --- a/SHA256SUMS +++ b/SHA256SUMS @@ -20,8 +20,8 @@ ef9e423362b12d0dd73c8e165faf32e9f53c4d4ac215b57c2e34002a88713838 .claude/skills 9521b057ff3db92d1e60923ebd88170713914f7e235ceb45717eb39419daf811 .claude/skills/agentic-ceo/scripts/weekly_receipt.py 7e2179751e9dd2fb371b3e9fb01fca987d69605af1e8e6e609ff9b0d0abb384b .claude/skills/agentic-delivery/INDEX-scripts.md 356b85280ede56adc36aea682ae0a182346892c52f8351df82c8d3225647a473 .claude/skills/agentic-delivery/INDEX.md -6629e6be179ec422847cdd67983b73ee013325e43f922d47bb91846c35d0a596 .claude/skills/agentic-delivery/SKILL.md -6de9ea98cc5c87a700b2d2834fac9153006b3fc5eda5ddb0ac1160907c32a919 .claude/skills/agentic-delivery/VERSION +a2c603b27c07bb8ec324203eda38ac8343b1b0f4d06c0bfb66b31a420fa87815 .claude/skills/agentic-delivery/SKILL.md +a94cbe96efae3b8b3ccbb0d7f5e4d3f37afdce3367e7fcfe34935fba4907e249 .claude/skills/agentic-delivery/VERSION b14f9f9cf466e6886fee63c6563d8a7f40c7a6a02782d44e1f4557f5ccd7fe21 .claude/skills/agentic-delivery/evals/evals.json fba7699a2d0836b51b7c838d019b1f0cd20570522a362e8a32b8dacfb911298e .claude/skills/agentic-delivery/evals/triggers.json 39140ac0b40907dc2279bb3234ce1d8ffb4db56e8658c7f89cc370f777df0592 .claude/skills/agentic-delivery/references/cost-quality-guardrails.md @@ -90,7 +90,7 @@ bd29dd7f6cb2ce16402fbaa741d9abc5b081617bed739b0838054ab071d1780d .claude/skills 06824e47863d8660c084ad6ede05573ae3754029e23c41129030718a622768ea .claude/skills/agentic-delivery/scripts/freeze_hook.py e6cc0913d51d2b761c6a41938840a68425c934e39324f7afaf001cee553be0c6 .claude/skills/agentic-delivery/scripts/gh_rest.py 48a985aafe738fca5e96d30ac36a3f7f7065bd30bbb06cad8f51296be80fc975 .claude/skills/agentic-delivery/scripts/handback.py -0077ba64a487c3a7df4c426a76eaab0691edecbce99d3e1a4b8e8609b1a6aae8 .claude/skills/agentic-delivery/scripts/handback_cap.py +1db498b20a3694f7304012a64381f0478ee2ac5c10c71af1e5e451e164101fde .claude/skills/agentic-delivery/scripts/handback_cap.py 026dfd9c2d90300e54a7ec24a51391e7c8fb2eaa64dfecb61afaf8cced3bbce0 .claude/skills/agentic-delivery/scripts/handoff_inject.py 8cd0c52f1f5ef552677d523021072c8030031a36f96a3c51b9f10bde87ca8f74 .claude/skills/agentic-delivery/scripts/heavy_gate.py 6650d5257e60823c88de1a66b083681f192e316148db35c6ac3265fd11c60fb4 .claude/skills/agentic-delivery/scripts/host_accept.py @@ -206,8 +206,8 @@ d98f3e4380da3496061ba63be7beebe75017ab4ee1734eda9a3e798e19007b0e .claude/skills 18f20db537ab784460ad33cf218f7a01ac0a172fc38413f14c0e19e1ce6821cc .claude/skills/contribution/scripts/share_learning.py 57ab71eae0e846ea4e5e8287da26679a5a010cf576fed89ca37c94e0c900180f .claude/skills/deep-code-review/INDEX-scripts.md bd033973aa245a22749cbd3e6c987813ea1be6352756b20599dc0b700bd5ab21 .claude/skills/deep-code-review/INDEX.md -bb67261ba0ce71153b771f94acc550a296c6e21cded3b41b55c66d59c21f9306 .claude/skills/deep-code-review/SKILL.md -6de9ea98cc5c87a700b2d2834fac9153006b3fc5eda5ddb0ac1160907c32a919 .claude/skills/deep-code-review/VERSION +78e8189ec6a86ea400a3a8f3166880d856c3a10d444487655cd1c509eb77758c .claude/skills/deep-code-review/SKILL.md +a94cbe96efae3b8b3ccbb0d7f5e4d3f37afdce3367e7fcfe34935fba4907e249 .claude/skills/deep-code-review/VERSION b97d95bc93cc23a8bc689e2e23db261a138367bcbc69d2f8a0452d5c2c6dfb68 .claude/skills/deep-code-review/evals/evals.json 13dbb52e4bf61b1093302e094151def167371d26e7cf67a026f3beeb09d34378 .claude/skills/deep-code-review/evals/triggers.json b84e3a2b88dc189f041784e76b97e68ad879915814e00f4b37cd27513746d6f1 .claude/skills/deep-code-review/references/a11y-aria.md @@ -397,7 +397,7 @@ e2903a566deee3423cc377b000475b30d6698ccebd640cb62b86b6d2001c4822 .claude/skills 5d6910164ddf6dfd4ed62dfc365a2f615f49dc07878ed3d1f881aa9518e481c2 .claude/skills/deep-code-review/scripts/post_review.sh b01cae69d80ca560cc414c1c70ef0ddfdbb910da5b68df4e9d46cf0daf3f8b16 .claude/skills/deep-code-review/scripts/provision_tools.sh f1108e2700864195a239744b319b1d04953879589f8a2b83708bc45a080e3d86 .claude/skills/deep-code-review/scripts/reaper_lint.py -9dcf6d7a46890d8f3f269e956bd38599ac92b6badfed9e18193b0a85af1469a9 .claude/skills/deep-code-review/scripts/review_checks.sh +67bde273fae6d8903def8b54a86a3adfc65b4f234f8eddc8172fe370f1b4c6cc .claude/skills/deep-code-review/scripts/review_checks.sh 8c87c02a050a975e453b52ecacbaf01481c7134466a9c67feaf409d22e36d9f7 .claude/skills/deep-code-review/scripts/review_feedback.py 6ca102dffcfbc5ecc4eca7c99977351154bca82ded3e499aa31f26fbd8937892 .claude/skills/deep-code-review/scripts/route_auth_map.py 859c67d6a6a781c873f47d5662d403da2321da53e6994ca3d0ccdbf74afd39ac .claude/skills/deep-code-review/scripts/score_review.py @@ -426,8 +426,8 @@ e951eaa63fd0d1870701d69c89c29ef4fe74dbad9b680ab6ef0a4e993fb8bc20 .claude/skills fd316c63bbf1cc0ea64322d7d923d66692eaf7b545c056367bfecca35146c862 .claude/skills/growth-analytics/references/full-map.md 2f1d7499e9ed7ae59f550b5c00043e465b2a4e885821ad153438e2e33fcccb45 .claude/skills/growth-analytics/scripts/readout_check.py 67e71ec40535ad0b3931c51f3decf323bce809ed4c9586c6d422b7ad5698129f .claude/skills/idea-critic/INDEX.md -d92e6af4b348ea00518a5672c44ebbc6195c16828cbeaa923e524aead4fecccc .claude/skills/idea-critic/SKILL.md -6de9ea98cc5c87a700b2d2834fac9153006b3fc5eda5ddb0ac1160907c32a919 .claude/skills/idea-critic/VERSION +5b646af6cc56d5ebc4711421321dd557cf1c932f12785f6d18cea5cb90035b75 .claude/skills/idea-critic/SKILL.md +a94cbe96efae3b8b3ccbb0d7f5e4d3f37afdce3367e7fcfe34935fba4907e249 .claude/skills/idea-critic/VERSION 9f77d5d6d13c99fd16cd8c398795d8be226d74bae5a5bf65369ed94a59fa56b7 .claude/skills/idea-critic/evals/evals.json 0e1c0db300661a1ab1a427a7157c75e2ed67130ab24d5c6cb02ec3ff9e793f58 .claude/skills/idea-critic/evals/heldout.json d8098c5ced63e8b8608867dd144091049563a0553cf62d27ce05b9d52ac54266 .claude/skills/idea-critic/evals/triggers.json diff --git a/changelog.d/handback-followups.md b/changelog.d/handback-followups.md deleted file mode 100644 index fa5ebe9d9..000000000 --- a/changelog.d/handback-followups.md +++ /dev/null @@ -1,7 +0,0 @@ -### Fixed -- `handback_cap.py`'s background-work block text no longer says "You own it until it exits". The scan matches any test or build whose cwd is in the lane's worktree, and that process may have been started by someone else working in the same worktree. The text now says what the lane can do (wait for the pid with `lane_guard.py wait --pid --timeout `, or stop it if this lane started it) and that the hold ends on its own after `HANDBACK_PUSH_MAX_S` (30 minutes by default) at most, as the push and commit hold text already did. -- A hold's window now restarts once its condition is gone. `_hold` keeps the first block's time as the mtime of the lane's `.push`, `.bg` or `.dirty` state file and nothing removed that file, so after one block that was more than 30 minutes old, a later push or commit, background run or dirty tree in the same lane was released at once instead of being held for a fresh window. `check()` now removes the lane's state file (new `_release`, which ignores `OSError`) for each hold whose check found no such condition, so the next block opens a fresh `HANDBACK_PUSH_MAX_S` window. `check()` also no longer returns at the first hold that blocks: the push or commit, background and dirty-worktree checks are all evaluated before it returns 2, so the reset also happens while a higher hold blocks (for example: a dirty-worktree hold opened more than 30 minutes ago, the tree cleaned while a commit is still running, the commit ending, the tree dirtied again, and the lane is held again for a fresh window). The first hold that blocks still wins in the same order (push or commit, background, dirty) with the same text, a lower hold is still never started on a call where a higher one blocks, and a blind lower check now prints its `COULD_NOT_CHECK` line before that hold's text. A check that could not run (`COULD_NOT_CHECK`) keeps the hold, and a condition that stays live past the window is still released, so a stuck process cannot trap the lane. The dirty-worktree hold goes through the same `_hold` and gets the same reset. - -### Changed -- The `_push_running` docstring and the comment above `PUSH_RE` now state a known limit: `ps` prints argv without quoting, so a space inside a `-c` value or a `-C` path splits it (`git -c user.name=Jane Smith commit`, `git -C /acme/my repo commit`), `PUSH_RE` does not match, and that push or commit is not held (the check fails open and does not print `COULD_NOT_CHECK`). The behaviour is unchanged; it is now documented and pinned. -- Test: `python3 .claude/skills/agentic-delivery/scripts/handback_cap.py --selftest` (already run by CI) goes from 83 to 117 cases. Ten of the new ones fail on the previous code (107 of 117 passed there): each of the push, background and dirty-worktree holds starting a fresh window when the condition clears and returns (old first block, condition gone, condition back, held again); the background and dirty holds doing the same when a higher hold blocks while their own condition is gone, including their state file being removed; and the background hold text naming the way out rather than ownership. The other twenty-four pin behaviour that already held: the first block and the release after the window for each of the three holds, a condition that clears and passes, a hold whose scan could not run keeping its state file, a lower hold opening its first block, the first hold that blocks winning (push or commit, then background, then dirty) with no lower hold started, `_skip_pids` skipping the hook's ancestors and descendants (a synthetic process table, hook then child then a grandchild `git commit`) while an unrelated `git commit` pid is still counted, the same through `_push_running`, and three `known-limit-*` cases (a `-c` value with a space and a `-C` path with a space are not held, a `-c` value without one is). Each of the three keep-on-`None` cases fails when its scan's `None` is treated as empty (`if not running`, `elif not bg`, `elif not dirty`). diff --git a/changelog.d/privacy-prefilter.md b/changelog.d/privacy-prefilter.md deleted file mode 100644 index 3438452e1..000000000 --- a/changelog.d/privacy-prefilter.md +++ /dev/null @@ -1,2 +0,0 @@ -### Changed -- The privacy gate (`scripts/ci-gates.sh privacy`) now runs one prefilter pass before its per-pattern scan: a single `grep -IlE -D skip -f` over every banlist pattern at once, in the same 1000-file batches, lists the only files any pattern can match, and the existing per-pattern greps read just those files. A clean tree is therefore read once instead of once per pattern, which shortens the gate on large trees. The hit set is unchanged: hits are still attributed per pattern with the content withheld, the empty-input ERE probe still runs first so the pattern list holds only valid patterns, the `secret_scan.py` pass is untouched, and a prefilter grep error fails closed (it never reads as "no candidates"). The candidate list is newline-delimited, so a tree holding a path with a newline in its name skips the prefilter and falls back to the full per-pattern scan, which keeps the hit set unchanged there too. The new `scripts/test-privacy-prefilter.sh` pins the unchanged hit set against an independent one-grep-per-pattern oracle, the one-pass cost on a clean tree, that the per-pattern greps see only listed files, both fail-closed paths (an invalid ERE and a prefilter error), and that a hit in a file whose name holds a newline still blocks. diff --git a/changelog.d/semgrep-partial-detail.md b/changelog.d/semgrep-partial-detail.md deleted file mode 100644 index 25d16c368..000000000 --- a/changelog.d/semgrep-partial-detail.md +++ /dev/null @@ -1,4 +0,0 @@ -### Changed -- When semgrep reports errors on some of the files it scanned, the `review_checks.sh` tool hub now names those files instead of only saying the scan was partial. Each file with an error is a `not-checked` row (its path, line 0, and the error type and level), at most 20 per 200-file semgrep call, followed by one row with the path `.` that counts the rest and names the first path left out, so two calls with equal error counts keep one such row each instead of the closing dedup of identical `not-checked` rows merging them into one. An error that carries no path stays counted and gets no row. The `review_checks: partial: semgrep ran but reported errors (...)` line on stderr keeps its text and now ends with the error counts, for example `(3 error(s) on 2 of 40 scanned file(s): PartialParsing (warn) x2, Syntax error (error) x1; see not-checked rows)`. The type is semgrep's `type` string, or the first element when it is a list. A warn-level parse error still makes the scan partial and is never read as clean. Whether a scan is partial or not run is decided on the findings alone, before these rows are added, so the "not run" cases (errors on every scanned file, or an error with no path and no findings) are unchanged and name no file. The header comment of `review_checks.sh` now matches. -- The closing summary on stderr no longer counts `not-checked` rows as findings: `review_checks: N findings; ...` counts every other row, and a separate line, `review_checks: K not-checked row(s) (surface a tool did not cover, not findings)`, gives the number of `not-checked` rows and appears only when there are any. The line that reports how many rows are on lines the diff adds still counts every row. -- Test: `scripts/test-review-checks-semgrep-partial.sh` (registered as `scripts/ci-tests.d/review-checks-semgrep-partial.sh`) runs the hub against a stub semgrep that answers each call with its own fictional JSON. It covers a warn-level `PartialParsing` on 1 of 3 files (one row for that path, the counts on the partial line, the finding row unchanged), 25 errored files (20 rows plus the summary row, counts ordered by count), two semgrep calls (200 and 30 files) with equal error counts (two summary rows and two partial lines), the findings count and the separate `not-checked` line, several errors on one file, errors with no path, the "not run" cases, and odd error shapes (a null or string entry, a missing type or level, a path that is not a string, a control character in a path) that must not void the chunk's findings. diff --git a/gemini-extension.json b/gemini-extension.json index f4738449b..5ff8fb302 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "perun", - "version": "1.631.0", + "version": "1.632.0", "description": "Perun: a skill suite for AI-agent teams: deep code review, token and cost tools, gated delivery, an idea critic and product specialists.", "contextFileName": "AGENTS.md" }