Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/agentic-delivery/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: >-
license: MIT
metadata:
author: deep-code-review contributors
version: "1.631.0"
version: "1.632.0"
---

# Agentic delivery
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/agentic-delivery/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.631.0
1.632.0
2 changes: 1 addition & 1 deletion .claude/skills/deep-code-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: >-
license: MIT
metadata:
author: deep-code-review contributors
version: "1.631.0"
version: "1.632.0"
---

# Deep Code Review
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/deep-code-review/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.631.0
1.632.0
2 changes: 1 addition & 1 deletion .claude/skills/idea-critic/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/idea-critic/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.631.0
1.632.0
2 changes: 1 addition & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <pid> --timeout <s>`, 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
Expand Down
16 changes: 8 additions & 8 deletions SHA256SUMS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 0 additions & 7 deletions changelog.d/handback-followups.md

This file was deleted.

Loading
Loading