From 0201fd01775fbdbcbf9857674eeb33fb0ad290f2 Mon Sep 17 00:00:00 2001 From: Remi Antczak <140408771+remigiusz-antczak@users.noreply.github.com> Date: Sat, 31 Oct 2026 23:13:51 +0100 Subject: [PATCH] release: 1.633.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 | 15 +++++++++++++++ SHA256SUMS | 20 ++++++++++---------- changelog.d/handback-wait-block.md | 5 ----- changelog.d/semgrep-js-gap-rules.md | 6 ------ docs/INDEX.md | 2 +- gemini-extension.json | 2 +- 14 files changed, 35 insertions(+), 31 deletions(-) delete mode 100644 changelog.d/handback-wait-block.md delete mode 100644 changelog.d/semgrep-js-gap-rules.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 32803cc7d..119ddaf83 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.632.0", + "version": "1.633.0", "author": { "name": "deep-code-review contributors" }, diff --git a/.claude/skills/agentic-delivery/SKILL.md b/.claude/skills/agentic-delivery/SKILL.md index 3fcb8758f..544c3e47a 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.632.0" + version: "1.633.0" --- # Agentic delivery diff --git a/.claude/skills/agentic-delivery/VERSION b/.claude/skills/agentic-delivery/VERSION index 01280b9e0..d25645c21 100644 --- a/.claude/skills/agentic-delivery/VERSION +++ b/.claude/skills/agentic-delivery/VERSION @@ -1 +1 @@ -1.632.0 +1.633.0 diff --git a/.claude/skills/deep-code-review/SKILL.md b/.claude/skills/deep-code-review/SKILL.md index 0f7a5c7ed..74b25654e 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.632.0" + version: "1.633.0" --- # Deep Code Review diff --git a/.claude/skills/deep-code-review/VERSION b/.claude/skills/deep-code-review/VERSION index 01280b9e0..d25645c21 100644 --- a/.claude/skills/deep-code-review/VERSION +++ b/.claude/skills/deep-code-review/VERSION @@ -1 +1 @@ -1.632.0 +1.633.0 diff --git a/.claude/skills/idea-critic/SKILL.md b/.claude/skills/idea-critic/SKILL.md index 79786c155..ee2e7fb2f 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.632.0" + version: "1.633.0" --- # Veles: the evil twin (idea-critic) diff --git a/.claude/skills/idea-critic/VERSION b/.claude/skills/idea-critic/VERSION index 01280b9e0..d25645c21 100644 --- a/.claude/skills/idea-critic/VERSION +++ b/.claude/skills/idea-critic/VERSION @@ -1 +1 @@ -1.632.0 +1.633.0 diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 8ba6a3ca8..9b4cbdd26 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -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": { diff --git a/CHANGELOG.md b/CHANGELOG.md index 886aee301..794254bfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 --timeout `) 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 `.cookie`, `.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 `.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 diff --git a/SHA256SUMS b/SHA256SUMS index 5b9cfdce2..40f47d833 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 -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/changelog.d/handback-wait-block.md b/changelog.d/handback-wait-block.md deleted file mode 100644 index 9d1be00c2..000000000 --- a/changelog.d/handback-wait-block.md +++ /dev/null @@ -1,5 +0,0 @@ -### 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 --timeout `) 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. diff --git a/changelog.d/semgrep-js-gap-rules.md b/changelog.d/semgrep-js-gap-rules.md deleted file mode 100644 index 2fb4e5501..000000000 --- a/changelog.d/semgrep-js-gap-rules.md +++ /dev/null @@ -1,6 +0,0 @@ -### 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 `.cookie`, `.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 `.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. diff --git a/docs/INDEX.md b/docs/INDEX.md index d86ec0f36..4faa73cdf 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -23,7 +23,7 @@ Generated by `python3 .claude/skills/agentic-delivery/scripts/focus_kit.py docs- | `docs/scoreboard.md` | Perun scoreboard: Generated by scripts/scoreboard.py from committed results | 5143 | | `docs/security-heldout-table-1026/table.md` | Security held-out table, 2026-10-26: Generated by results.py (offline, $0, byte-identical on rerun). | 1847 | | `docs/self-improvement.md` | How Perun improves itself: Perun is improved by running Perun on Perun: its own review skill (deep-code-review), idea attack (idea-critic),… | 1268 | -| `docs/standards-index.md` | Standards index: Every standard the skill relies on, split into what was verified by direct fetch for this release and what is referenced b… | 101855 | +| `docs/standards-index.md` | Standards index: Every standard the skill relies on, split into what was verified by direct fetch for this release and what is referenced b… | 102167 | | `docs/team-install.md` | Team-wide install through a Claude Code plugin marketplace: This repository is its own marketplace (.claude-plugin/marketplace.json, name p… | 478 | | `docs/technical-overview.md` | Technical overview: you want the engineering detail that used to sit in the top-level README.md: the mechanisms table, the full "what you g… | 2288 | | `docs/token-cost-tips.md` | Token cost tips for teams: the biggest savings come from sending less context, using the cheapest model tier that clears its own gate, and… | 2127 | diff --git a/gemini-extension.json b/gemini-extension.json index 5ff8fb302..adb6112b8 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -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.", "contextFileName": "AGENTS.md" }