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.632.0",
"version": "1.633.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.632.0"
version: "1.633.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.632.0
1.633.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.632.0"
version: "1.633.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.632.0
1.633.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.632.0"
version: "1.633.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.632.0
1.633.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.632.0",
"version": "1.633.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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
All notable changes to this repository are documented here. Format loosely
follows Keep a Changelog; versioning follows Semantic Versioning.

## [1.633.0] — 2026-10-31

### Fixed
- A handback that says the lane is waiting on its background tests now blocks the stop (exit 2) in every mode but `off`, including the default `warn`, instead of only adding a `systemMessage` and letting the lane end with its work unverified. The reason on stderr tells the lane to wait in this turn (a local process: `lane_guard.py wait --pid <pid> --timeout <s>`) and hand back the result, or to hand back `status=UNVERIFIED` naming what is still pending (for example a remote check). The text is a claim, not evidence, so the block is bounded: it does not fire when the hook input has no `agent_id` (the counter has nothing to key on, so the note stays), when it has `stop_hook_active` true, or when the first status line of the handback reads UNVERIFIED (so the way out above cannot loop; a later `UNVERIFIED:` line or `- unverified:` field does not exempt a handback whose first status line is VERIFIED); otherwise it fires at most `MAX_BLOCKS` (3) times per agent id, counted in a `.wait` file beside the lane's other state files, and a state file that cannot be written means no block. Where no block applies the `systemMessage` stays and the stop goes through. The push, commit, background and dirty-worktree holds still run first and win. The `background_guard` policy text, the `handback_cap.py` docstring and the lane preamble now say so.

### Changed
- Tests: `python3 .claude/skills/agentic-delivery/scripts/handback_cap.py --selftest` (already run by CI) goes from 117 to 130 cases. Two of the new cases pin the first-status-line rule: a wait claim after a VERIFIED first status line is still blocked when a later line reads `UNVERIFIED: ...` or `- unverified: ...`. The rest pin the block text, the bound, the no-`agent_id`, `stop_hook_active`, UNVERIFIED-first, mode `off` and verified-handback paths. `scripts/test_bg_wait_claim.py` now runs its flag cases with `stop_hook_active` true, the bound past which a waiting claim is only flagged.

### Added
- Three bundled semgrep rules in `.claude/skills/deep-code-review/templates/semgrep-taint/js.yml` for defect classes the taint rules leave unflagged. Each carries the same test-path exclusions as `hardcoded-credential-compare`.
- `perun.js.fetch-no-timeout` (INFO): `fetch(url)` or `fetch(url, {...})` with no `signal` key inside a Next.js route handler (`export async function GET|POST|PUT|PATCH|DELETE`), a pages API `export default async function handler`, or an `app.get|post|put|patch|delete|all("/path", ..., fn)` callback. Any `signal:` value, an options spread, a fetch outside a handler and a `cache.get("key", fn)` callback stay clean. Ceiling: handlers are matched by shape, so a const-arrow export or a handler passed by name is not seen.
- `perun.js.auth-cookie-flags` (WARNING): a cookie whose literal name has session, sess, sessid, sessionid, phpsessid, sid, token, auth, authtoken or jwt as a whole word (split at punctuation and camelCase boundaries, so `authToken`, `connect.sid` and `next-auth.session-token` match and `authorized`, `tokenizer_mode` and `assessment` do not; names holding csrf or xsrf are skipped), set positionally or as one options object through `<x>.cookie`, `<x>.setCookie`, `cookies().set`, `(await cookies()).set`, a variable bound by `X = await cookies()` or `X = cookies()` in an enclosing block (`const jar = await cookies(); jar.set(...)`) or `<x>.cookies.set` on any receiver not named below, with `httpOnly` missing or the literal `false`, or `secure` missing or the literal `false`. `ctx.cookies.set`, `context.cookies.set`, `event.cookies.set`, `this.cookies.set` and a bare `cookies.set` are reported only for a literal `httpOnly: false` or `secure: false`: the cookies library behind Koa's `ctx.cookies` documents `httpOnly` as true by default and `secure` as true by default over HTTPS, and SvelteKit documents both as true by default (`secure` false in development). Any other `httpOnly` or `secure` value passes, and a clear (an empty value, `maxAge: 0` or `expires: new Date(0)`) and a `req.cookies.set` or `request.cookies.set` call are skipped. Ceiling: options must be an object literal, and a bare `cookies.set` also covers other frameworks whose defaults were not checked, so their missing flags are not reported.
- `perun.js.cors-credentials-any-origin` (WARNING): `cors({...})` or `register(cors, {...})` with `credentials: true` and `origin: true`, `origin: /.*/` or a callback that always allows (`cb(null, true)`, `cb(null, origin)` or `cb(null, !!origin)`), or a function that copies `req.get|header("origin")` or `headers.get("origin")` (directly or through a variable) into `Access-Control-Allow-Origin` while it sets `Access-Control-Allow-Credentials` to `"true"` or `true`, unless an `if` on a `.has`, `.includes` or `.test` call encloses or precedes the set call. A literal `origin: "*"` is not reported, because the cors packages send a literal `*` and browsers refuse it on credentialed requests. The `req.headers.origin` handler shape is left to the default pack's express `cors-misconfiguration` rule, which already flags it. Ceiling: any such `if` counts as an allowlist check whatever it tests.
- Test: `scripts/test_semgrep_js_gaps.py`, registered in `scripts/ci-tests.d/semgrep-js-gaps.sh`, runs annotated fictional fixtures (a `ruleid` or `ok` comment marks the next line) through semgrep with the bundled rules only, plus copies under test paths that must stay clean. Offline checks of severity, exclusions and the key regexes run where semgrep is absent.

## [1.632.0] — 2026-10-31

### Fixed
Expand Down
20 changes: 10 additions & 10 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
a2c603b27c07bb8ec324203eda38ac8343b1b0f4d06c0bfb66b31a420fa87815 .claude/skills/agentic-delivery/SKILL.md
a94cbe96efae3b8b3ccbb0d7f5e4d3f37afdce3367e7fcfe34935fba4907e249 .claude/skills/agentic-delivery/VERSION
1eab38488c896a54404601f7a3aaa1add59dc48314f3d228339c19a6a3ee63f2 .claude/skills/agentic-delivery/SKILL.md
42576118230106f7ac254454003551bfebcfd2373a8c4e3fd020d301ed8e9160 .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
1db498b20a3694f7304012a64381f0478ee2ac5c10c71af1e5e451e164101fde .claude/skills/agentic-delivery/scripts/handback_cap.py
bc6cbe754241459320b4b7c5b23f5edfe212da2c053d9df15648358916745087 .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 All @@ -115,7 +115,7 @@ cdcb175e41eecbfe0be0c8d406d520d8c9713460b21d460645afccdb06e1813a .claude/skills
bd5b655445d1dca330de9023c925adb0fe582f6219e45ecb5ae8eb206eb4ce1c .claude/skills/agentic-delivery/scripts/partial_pass.py
cf3176b7983d6ce2ebac93b31c44ed65e3883299f7c38d6731b882d12826fde4 .claude/skills/agentic-delivery/scripts/peer_ack.py
b79368e5d6d041d639e4a64ba6c04b5f153d695ed7ae9b508c8a8c2067201ca1 .claude/skills/agentic-delivery/scripts/perun_auto_update.py
d6577a194d16d945cd59b2b62dd105092c0cdb068747ccfe513f721a48eb9464 .claude/skills/agentic-delivery/scripts/perun_policy.py
f9f81949f896ca0c8ac84e5274bc1345acb0350ff34bf9af97f095f2efb2538a .claude/skills/agentic-delivery/scripts/perun_policy.py
aa1c7b7790ae1eedfbd42033e18877887dc24a5df060fad4c6ec86f480427404 .claude/skills/agentic-delivery/scripts/pipe_mask_guard.py
a208e71ad99d0eb5d195aa18a105a8e2db5b21310dee885115f33be54f9f6f7c .claude/skills/agentic-delivery/scripts/pipeline_hub.py
f829b4e68baa5237bf03d2de6f736c01fb1ede33bba7952ca3dda6e2e5cdfac6 .claude/skills/agentic-delivery/scripts/pipeline_profile.py
Expand Down Expand Up @@ -166,7 +166,7 @@ b759691e776aff3bcc2c92b422179bce1f24522728c472155b8bc227ff094686 .claude/skills
bbbcec171d247196c9859105239149c8d02627918b50a2b3c52775d14eed668e .claude/skills/agentic-delivery/templates/global-rules.settings.json
98ec99b865d0ebf249960be4722e16af57489a1c78af06adc4afcd5a37de9223 .claude/skills/agentic-delivery/templates/handoff.md
46a4e52954370bb53db6ebf78b7365b2c4ef790ea6e2e73f4f4c09c823c8e219 .claude/skills/agentic-delivery/templates/host-safety.tsv
ed6ed58c13a18082dbe2268bad472d218701df176e37d43a0a7a0826967315dc .claude/skills/agentic-delivery/templates/lane-preamble.md
8676e3b89fd18e6ebefd50409a8f745d70fcb766ce73886dfcbe789bd2ca0e93 .claude/skills/agentic-delivery/templates/lane-preamble.md
c3ef87aa65dec1f63df5f6b1aadc3a1e5c322ed7288a5dbd3b7617d56c12adbb .claude/skills/agentic-delivery/templates/loops/cleanup.md
b956a4767c55179e732c5e34581abfd07b285dd73aa030ad9119005cb8e2d0a2 .claude/skills/agentic-delivery/templates/loops/coordinator.md
7f5e043836dca83534623994d97de0da88caec290e434d0c7a1a52cf2345f05b .claude/skills/agentic-delivery/templates/loops/peer.md
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
78e8189ec6a86ea400a3a8f3166880d856c3a10d444487655cd1c509eb77758c .claude/skills/deep-code-review/SKILL.md
a94cbe96efae3b8b3ccbb0d7f5e4d3f37afdce3367e7fcfe34935fba4907e249 .claude/skills/deep-code-review/VERSION
088c26180b0ebe3697102143830de727d85e1ab367e7a530d2430e8529be1df1 .claude/skills/deep-code-review/SKILL.md
42576118230106f7ac254454003551bfebcfd2373a8c4e3fd020d301ed8e9160 .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 @@ -416,7 +416,7 @@ f31e66a322ee172e4b9621c3b70717a6e896ee64178f0e8ea77ac2088b6d0cb6 .claude/skills
d84df8bbfb7e87be95446e91151f1badcc85797c07d3cb574be00c66b4f6b7c4 .claude/skills/deep-code-review/templates/perun-review.yml
429b66e715e660931543b71e346f60df85dfa8df70d6caa409f51958f4202acd .claude/skills/deep-code-review/templates/pre-push-verify.sh
a82701e4893739b8451bcfab0fe6df01e130f1659cd9b4c3780f1461c874d698 .claude/skills/deep-code-review/templates/semgrep-taint/gha.yml
1470877bc6329921c1eebcd763201f9198e47b6f97670a9d42eb8dc281b99cd8 .claude/skills/deep-code-review/templates/semgrep-taint/js.yml
80fe56c980ce2aba92e67b3f284efc28729362ca9b2c1da2be5e1b46ccfa0d85 .claude/skills/deep-code-review/templates/semgrep-taint/js.yml
7bdab757847b5a5ce2323e4fb06905e4446919196f5417c25511ac279b4a1e0e .claude/skills/deep-code-review/templates/semgrep-taint/py.yml
29ee3a47eb7973011cdfe1fb4321aac89fc0fe8f98776505df70a6d6a45cbf0f .claude/skills/growth-analytics/INDEX.md
4fe9fb6176818c279ddce11bde1aa97157800190075ba79604c174a5d9a7c59c .claude/skills/growth-analytics/SKILL.md
Expand All @@ -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
5b646af6cc56d5ebc4711421321dd557cf1c932f12785f6d18cea5cb90035b75 .claude/skills/idea-critic/SKILL.md
a94cbe96efae3b8b3ccbb0d7f5e4d3f37afdce3367e7fcfe34935fba4907e249 .claude/skills/idea-critic/VERSION
883ac83dda222187d7f32da9d1e272cb82017cf51c3307ccf955cbda32724419 .claude/skills/idea-critic/SKILL.md
42576118230106f7ac254454003551bfebcfd2373a8c4e3fd020d301ed8e9160 .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
5 changes: 0 additions & 5 deletions changelog.d/handback-wait-block.md

This file was deleted.

Loading
Loading