Skip to content

chore: release v0.1.0 - #27

Merged
ancelin-code merged 13 commits into
mainfrom
develop
Oct 23, 2026
Merged

ancelin-code merged 13 commits into
mainfrom
develop

Conversation

@ancelin-code

Copy link
Copy Markdown
Owner

Merges develop into main for the first release, v0.1.0. The changelog is closed at 0.1.0 (2026-10-23), skill and pyproject.toml versions already match, and check-release v0.1.0 passes. Merge with a merge commit, not a squash. The v0.1.0 tag is cut on main afterwards.

dependabot Bot and others added 13 commits October 22, 2026 12:01
Bumps the actions group with 2 updates:
[jdx/mise-action](https://github.com/jdx/mise-action) and
[actions/upload-artifact](https://github.com/actions/upload-artifact).

Updates `jdx/mise-action` from 5.0.1 to 5.1.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jdx/mise-action/releases">jdx/mise-action's
releases</a>.</em></p>
<blockquote>
<h2>v5.1.1: GitHub token is no longer exported to later steps by
default</h2>
<p>mise-action no longer exports its GitHub token as
<code>MISE_GITHUB_TOKEN</code> to every later step in the job. A new
<code>persist_github_token</code> input lets you turn that back on, or
pass a different token to later steps. <strong>This changes the default
behavior.</strong> If later steps need the token, see Breaking Changes
below.</p>
<h2>Fixed</h2>
<ul>
<li><strong>The GitHub token now stays inside the action by
default.</strong> Before this release, the <code>github_token</code>
input (which defaults to <code>${{ github.token }}</code>) was written
to <code>GITHUB_ENV</code> as <code>MISE_GITHUB_TOKEN</code>. That let
any later step read the token and call the GitHub API with the job's
permissions, even if the step never asked for a credential. Now the
token is set only for the mise-action step and the processes it starts.
The action masks the token in logs. (<a
href="https://redirect.github.com/jdx/mise-action/pull/658">#658</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>, reported in <a
href="https://redirect.github.com/jdx/mise-action/issues/657">#657</a>)</li>
</ul>
<h2>Added</h2>
<ul>
<li>
<p><strong><code>persist_github_token</code> input (default
<code>false</code>).</strong> It takes one of three values:</p>
<ul>
<li><code>false</code>: the token stays inside the action.</li>
<li><code>true</code>: the token the action used is exported to later
steps. If <code>env.MISE_GITHUB_TOKEN</code> is already set, it takes
precedence over <code>github_token</code>.</li>
<li>A token value: that token is exported to later steps instead, for
example a read-only token. The action still installs tools with
<code>github_token</code>, or with <code>MISE_GITHUB_TOKEN</code> if
it's already set.</li>
</ul>
<p>Setting <code>false</code> doesn't clear a
<code>MISE_GITHUB_TOKEN</code> that was already set at the job level or
exported by an earlier step. (<a
href="https://redirect.github.com/jdx/mise-action/pull/658">#658</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)</p>
</li>
</ul>
<h2>Breaking Changes</h2>
<p>Check your workflow if a later step needs
<code>MISE_GITHUB_TOKEN</code>, such as mise shims, <code>mise
exec</code>, <code>mise run</code> or lazy tool installs that call the
GitHub API. Those steps no longer get the token automatically and may
hit GitHub API rate limits. To get the old behavior back, opt in:</p>
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
  with:
    persist_github_token: true
</code></pre>
<p>Or give later steps a separate token:</p>
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
  with:
    persist_github_token: ${{ secrets.READ_ONLY_TOKEN }}
</code></pre>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jdx/mise-action/compare/v5.1.0...v5.1.1">https://github.com/jdx/mise-action/compare/v5.1.0...v5.1.1</a></p>
<h2>v5.1.0: Tool version outputs, plugins input, and cached mise
reuse</h2>
<p>mise-action now reports the tool versions it installed as step
outputs, can install mise plugins before tools, and can save the cache
at the end of the job. Several caching fixes stop the action from
downloading mise again on every run.</p>
<h2>Added</h2>
<ul>
<li><strong>Tool versions as step outputs.</strong> After install, the
action runs <code>mise ls --json --current</code> and sets a
<code>versions</code> output. This is a JSON object of the active,
installed tools. Each tool maps to a list of <code>{version,
requested_version, install_path, source}</code> entries. Each tool also
gets its own output with its resolved version, such as
<code>steps.mise.outputs.node</code>. A tool only gets its own output if
its name is a valid output name and isn't <code>cache-hit</code> or
<code>versions</code>. Names like <code>npm:@scope/pkg</code> appear
only in <code>versions</code>. If the action can't read the versions, it
prints a warning and the step still succeeds. (<a
href="https://redirect.github.com/jdx/mise-action/pull/655">#655</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
  id: mise
- run: echo &quot;node ${{ steps.mise.outputs.node }}&quot;
</code></pre>
</li>
<li><strong><code>plugins</code> input.</strong> List plugins one per
line as <code>name</code> or <code>name url</code>. Blank lines and
<code>#</code> comments are ignored. The action runs <code>mise plugins
install -y</code> for each one before <code>mise install</code>. Plugins
that are already installed, for example restored from the cache, are
left as they are. An unknown plugin fails the step. When
<code>plugins</code> is set, its hash is added to the default cache key.
Custom <code>cache_key</code> templates can use it as
<code>{{plugins_hash}}</code>. If <code>plugins</code> is unset,
existing cache keys don't change. (<a
href="https://redirect.github.com/jdx/mise-action/pull/656">#656</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
</code></pre>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jdx/mise-action/blob/main/CHANGELOG.md">jdx/mise-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<hr />
<h2><a
href="https://github.com/jdx/mise-action/compare/v5.1.1..v5.1.2">5.1.2</a>
- 2026-10-10</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>continue with the existing mise when auto-update cannot replace it
(<a
href="https://redirect.github.com/jdx/mise-action/issues/665">#665</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/665">#665</a></li>
<li>export mise_dir as MISE_DATA_DIR so mise installs tools there (<a
href="https://redirect.github.com/jdx/mise-action/issues/672">#672</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/672">#672</a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>explain MISE_ENABLE_TOOLS in GitHub Actions (<a
href="https://redirect.github.com/jdx/mise-action/issues/667">#667</a>)
by <a href="https://github.com/zeitlinger"><code>@​zeitlinger</code></a>
in <a
href="https://redirect.github.com/jdx/mise-action/pull/667">#667</a></li>
<li>update the Rust cache section for mise 2026.9.2 (<a
href="https://redirect.github.com/jdx/mise-action/issues/670">#670</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/670">#670</a></li>
</ul>
<h3>⚙️ Miscellaneous Tasks</h3>
<ul>
<li><strong>(ci)</strong> update pr-closer to v1.3.0 by <a
href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://github.com/jdx/mise-action/commit/076ebfb79b60ee1ddabb50019a55a03b1dbd1ec9">076ebfb</a></li>
<li><strong>(ci)</strong> lint workflows with jactionlint (<a
href="https://redirect.github.com/jdx/mise-action/issues/673">#673</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/673">#673</a></li>
<li><strong>(ci)</strong> switch to jactionlint v2 and drop zizmor (<a
href="https://redirect.github.com/jdx/mise-action/issues/674">#674</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/674">#674</a></li>
<li>update pr-closer policy by <a
href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://github.com/jdx/mise-action/commit/88f13e0475d8b553967dd3816a34b6dcd3344c35">88f13e0</a></li>
<li>fix the upload-artifact version comment (<a
href="https://redirect.github.com/jdx/mise-action/issues/671">#671</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/671">#671</a></li>
</ul>
<hr />
<h2><a
href="https://github.com/jdx/mise-action/compare/v5.1.0..v5.1.1">5.1.1</a>
- 2026-10-04</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>make GitHub token persistence opt-in (<a
href="https://redirect.github.com/jdx/mise-action/issues/658">#658</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/658">#658</a></li>
</ul>
<hr />
<h2><a
href="https://github.com/jdx/mise-action/compare/v5.0.1..v5.1.0">5.1.0</a>
- 2026-10-04</h2>
<h3>🚀 Features</h3>
<ul>
<li>output active tool versions (<a
href="https://redirect.github.com/jdx/mise-action/issues/655">#655</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/655">#655</a></li>
<li>add opt-in cache_save_post input (<a
href="https://redirect.github.com/jdx/mise-action/issues/649">#649</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/649">#649</a></li>
<li>add plugins input (<a
href="https://redirect.github.com/jdx/mise-action/issues/656">#656</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/656">#656</a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li><strong>(cache)</strong> keep a cached mise instead of
re-downloading when version is unset (<a
href="https://redirect.github.com/jdx/mise-action/issues/642">#642</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/642">#642</a></li>
<li>save cache after inexact cache restore (<a
href="https://redirect.github.com/jdx/mise-action/issues/646">#646</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/646">#646</a></li>
<li>extract mise zip with PowerShell instead of unzip on Windows (<a
href="https://redirect.github.com/jdx/mise-action/issues/650">#650</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/650">#650</a></li>
<li>cache mise binary for caches saved without a version record (<a
href="https://redirect.github.com/jdx/mise-action/issues/648">#648</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/648">#648</a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>explain the Rust cache caveat and workarounds (<a
href="https://redirect.github.com/jdx/mise-action/issues/651">#651</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/651">#651</a></li>
<li>add matrix and external cache guides; warn on shadowed mise_toml (<a
href="https://redirect.github.com/jdx/mise-action/issues/654">#654</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/654">#654</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jdx/mise-action/commit/2d8d4cafcbd33be2ea37d2b6f5ad595363d1f1ca"><code>2d8d4ca</code></a>
chore: release v5.1.1 (<a
href="https://redirect.github.com/jdx/mise-action/issues/659">#659</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/3eb43e379b25fd45020fb54a44f614b26633539b"><code>3eb43e3</code></a>
fix: make GitHub token persistence opt-in (<a
href="https://redirect.github.com/jdx/mise-action/issues/658">#658</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/94c60b39bc2d90ab2f9bab27f38d3cc4812c1834"><code>94c60b3</code></a>
chore: release v5.1.0 (<a
href="https://redirect.github.com/jdx/mise-action/issues/640">#640</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/4fff0c68d1b8eeba9e098abf19bac6e9a7667bc9"><code>4fff0c6</code></a>
feat: add plugins input (<a
href="https://redirect.github.com/jdx/mise-action/issues/656">#656</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/893fc72eb5ddabde653fb4a9ad7e5dd87bb764c9"><code>893fc72</code></a>
docs: add matrix and external cache guides; warn on shadowed mise_toml
(<a
href="https://redirect.github.com/jdx/mise-action/issues/654">#654</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/41f58680993595594a9a1c8fdde5a4999ebf9b51"><code>41f5868</code></a>
feat: add opt-in cache_save_post input (<a
href="https://redirect.github.com/jdx/mise-action/issues/649">#649</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/2fe229b3b630af74ad27e5a7662e6fb159a770d3"><code>2fe229b</code></a>
fix: cache mise binary for caches saved without a version record (<a
href="https://redirect.github.com/jdx/mise-action/issues/648">#648</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/abd75d9c106e776b2cb9a0787eb5a8633351ab56"><code>abd75d9</code></a>
fix: extract mise zip with PowerShell instead of unzip on Windows (<a
href="https://redirect.github.com/jdx/mise-action/issues/650">#650</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/4b9c2959b29c99b787f2172608561dd0ce3df9e6"><code>4b9c295</code></a>
docs: explain the Rust cache caveat and workarounds (<a
href="https://redirect.github.com/jdx/mise-action/issues/651">#651</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/7927c6f5a53b3b75be6b7c4f2d1f53d9d9f05ffc"><code>7927c6f</code></a>
feat: output active tool versions (<a
href="https://redirect.github.com/jdx/mise-action/issues/655">#655</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jdx/mise-action/compare/7a4e45a543138629540c9a1616d08632b893e492...2d8d4cafcbd33be2ea37d2b6f5ad595363d1f1ca">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/upload-artifact` from 7.0.1 to 7.0.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Improves artifact download retries when the service returns HTTP 429
(rate limiting), including honoring valid Retry-After headers.</li>
<li>Updates <code>@​actions/artifact</code> to v6.3.1.</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/tunc-d"><code>@​tunc-d</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/821">actions/upload-artifact#821</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v7.0.1...v7.0.2">https://github.com/actions/upload-artifact/compare/v7.0.1...v7.0.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/upload-artifact/commit/cf430e030ddbb5b0abf93d22962f4752f3646cd9"><code>cf430e0</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/822">#822</a>
from actions/tunc-d-prepare-upload-v7-0-2</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/c2acdedd35a8824a1552c7137f8c18288c3ea469"><code>c2acded</code></a>
chore: prepare v7.0.2 release</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/4687c1bbaa0a58abb517d90b4bbade6754c80c1a"><code>4687c1b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/821">#821</a>
from actions/tunc-d-upload-artifact-package-bump</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/8cbe1bebdb858105d8fdd88f81404d4de4595719"><code>8cbe1be</code></a>
Bump <code>@​actions/artifact</code> to 6.3.1</li>
<li>See full diff in <a
href="https://github.com/actions/upload-artifact/compare/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a...cf430e030ddbb5b0abf93d22962f4752f3646cd9">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…he python group (#15)

Bumps the python group with 1 update:
[cisco-ai-skill-scanner](https://github.com/cisco-ai-defense/skill-scanner).

Updates `cisco-ai-skill-scanner` from 2.1.0 to 2.2.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cisco-ai-defense/skill-scanner/releases">cisco-ai-skill-scanner's
releases</a>.</em></p>
<blockquote>
<h2>Skill Scanner 2.2.2</h2>
<p>This release improves static detection while keeping the measured
false-positive rate steady on the pull-request development corpus.</p>
<h3>Changes</h3>
<ul>
<li>Detect whole process-environment value dumps in Python,
JavaScript/TypeScript, and shell code. Targeted reads, keys-only
enumeration, literal examples, and comments stay below the HIGH rule
boundary.</li>
<li>Avoid quadratic regex work on scripts padded with long runs of blank
lines.</li>
<li>Stop <code>PG_PII_CREDIT_CARD</code> from treating digits in decimal
fractions as card numbers.</li>
<li>Disable reasoning by default for short adjudicator verdicts and
allow a separate output-token limit through
<code>SKILL_SCANNER_ADJUDICATOR_LLM_MAX_TOKENS</code>.</li>
<li>Update locked fsspec and multidict versions to resolve the two
dependency audit findings.</li>
</ul>
<h3>Behavior notes</h3>
<p>A shell prompt marker by itself no longer captures a command on the
next line; prompt and command must share a line. The adjudicator's
reasoning default is now disabled and can be overridden with
<code>SKILL_SCANNER_ADJUDICATOR_LLM_REASONING_EFFORT</code>.</p>
<h3>Validation</h3>
<p>The PR detection-impact gate compares base and head on the same
labelled development records and fixed real-skill sample, enforcing a
0.5 percentage point FPR-rise limit. On the combined change, benign
flags stayed at 14/1,338 (1.05%) and real-skill flags at 130/2,000. The
<a
href="https://github.com/cisco-ai-defense/skill-scanner/actions/runs/37870135229">exact-SHA
release evidence</a> and <a
href="https://github.com/cisco-ai-defense/skill-scanner/actions/runs/37870615081">mandatory
release gate</a> passed 3,551 checks. The release holdout compares
CEL-off and active modes of this revision; both flagged 23/545 benign
samples (4.22%).</p>
<h2>2.2.1</h2>
<p>A patch release with a security fix for untrusted archives and
Markdown, report-format fixes, and a working Homebrew formula. Upgrading
from 2.2.0 is recommended.</p>
<h2>Security</h2>
<ul>
<li><strong>Bounded TAR extraction and linear-time Markdown
parsing</strong> (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/246">#246</a>,
by <a href="https://github.com/ihabler"><code>@​ihabler</code></a>;
reported by Koh Jun Sheng).
<ul>
<li><strong>TAR archives</strong> used to be expanded with no
compression-ratio, size or member-count limit; only ZIP archives had
decompression-bomb checks. A 20 KB <code>.tar.gz</code> could expand to
20 MB with no finding. The scanner now copies the TAR payload through a
bounded buffer and checks every member before it writes anything. The
checks cover member count, declared size, compression ratio, path
traversal and links. An archive over a limit raises
<code>ARCHIVE_ZIP_BOMB</code> (CRITICAL) and nothing is extracted.</li>
<li><strong>Markdown link discovery and inline-pipeline
extraction</strong> used overlapping greedy regular expressions that ran
in quadratic time on crafted input. Both now run in linear time.</li>
</ul>
</li>
</ul>
<h2>Fixes</h2>
<ul>
<li><strong>SARIF artifact URIs are valid URI references</strong> (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/242">#242</a>,
by <a
href="https://github.com/xujiantop-crypto"><code>@​xujiantop-crypto</code></a>).
Paths are percent-encoded, so <code>#</code>, <code>?</code>,
<code>%</code>, spaces and non-ASCII file names no longer become
fragments, queries or the wrong file. Absolute paths are emitted as
<code>file:</code> URIs without <code>uriBaseId</code>, as SARIF §3.4.4
requires.</li>
<li><strong>Markdown reports contain incomplete code fences</strong> (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/245">#245</a>,
by <a
href="https://github.com/xujiantop-crypto"><code>@​xujiantop-crypto</code></a>).
A snippet with literal or truncated backtick fences could make renderers
treat the remediation text and the findings after it as part of the
snippet. Snippets with complete fences are kept as they are; any other
snippet is wrapped in a fence longer than its longest backtick run.</li>
<li><strong>Homebrew</strong> (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/243">#243</a>,
<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/244">#244</a>).
The formula installs with current Homebrew again: <code>brew tap
cisco-ai-defense/skill-scanner
https://github.com/cisco-ai-defense/skill-scanner &amp;&amp; brew
install cisco-ai-defense/skill-scanner/skill-scanner</code>. Each
release now gets a reproducible formula, and the unused
<code>rust</code> build dependency, about 2.3 GB with <code>llvm</code>,
is gone.</li>
</ul>
<h2>Behavior changes</h2>
<ul>
<li>A TAR archive over the size, ratio or member-count limit is reported
as <code>ARCHIVE_ZIP_BOMB</code> (CRITICAL) and is not extracted.
Previously it was expanded silently.</li>
<li>SARIF <code>artifactLocation.uri</code> values for paths with
reserved or non-ASCII characters are now percent-encoded, and absolute
paths are <code>file:</code> URIs without <code>uriBaseId</code>. Tools
that match SARIF paths as raw strings should decode them.</li>
</ul>
<p>Detection impact on the development split and a 2,000-skill
real-skill sample was unchanged: recall 31.45% to 31.43%, FPR unchanged
at 1.05%, and real-skill flag rate unchanged at 6.50%.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cisco-ai-defense/skill-scanner/compare/2.2.0...2.2.1">https://github.com/cisco-ai-defense/skill-scanner/compare/2.2.0...2.2.1</a></p>
<h2>2.2.0</h2>
<h2>Highlights</h2>
<ul>
<li>
<p><strong>A setup guide built from measurements.</strong> <a
href="https://cisco-ai-defense.github.io/docs/skill-scanner/recommended-settings">Recommended
Settings</a> lists setups by goal. Every recommended setup runs the LLM
judge. Results on MaliciousSkillBench's held-out split (839 malicious,
545 benign), judge on Gemma 4 26B-A4B:</p>
<p>| Goal | Setup | Recall | FPR | F1 |</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/ef5cfee8d15fe207e09d808ccb5be4b9ae6d321a"><code>ef5cfee</code></a>
Transfer release corpus through exact-run cache (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/260">#260</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/c5254dce50adeff0e25b5caaedd1929e40f05ce4"><code>c5254dc</code></a>
fix: download release snapshot through GitHub CLI (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/259">#259</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/4431d85c57b40d5b0d97f8cb33c48e986c8c1b25"><code>4431d85</code></a>
fix: install scanner runtime for release corpus validation (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/258">#258</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/587dd8ba12c28abfde4983d22641fea74d50333e"><code>587dd8b</code></a>
docs: pin examples to 2.2.2 (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/257">#257</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/5b2e3d6241fc6a63f1994813b3de7f34a2275217"><code>5b2e3d6</code></a>
fix(adjudicator): turn off reasoning so the 200-token verdict is not cut
off ...</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/d0c85a06f378e19edf1746663a52783c57d18d2b"><code>d0c85a0</code></a>
fix(promptguard): PG_PII_CREDIT_CARD matches digits inside decimal
fractions ...</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/c8d33bd2894d8c251d4e4474a85a5003035178c3"><code>c8d33bd</code></a>
feat(rules): add DATA_EXFIL_ENV_DUMP whole-environment dump rule (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/251">#251</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/bfd59869ce61a09851d816184e99d0b4c0f72469"><code>bfd5986</code></a>
perf(pipeline): stop quadratic backtracking on blank-line runs in
shell-promp...</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/253cb776c7a37143afd6a3ec13a1db632f1c308a"><code>253cb77</code></a>
fix(deps): update audited fsspec and multidict locks (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/256">#256</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/c3d7fd9fee50cf2ea45f0b381eb61f857360f825"><code>c3d7fd9</code></a>
ci(homebrew): least-privilege workflow token and a pull-requests write
guard ...</li>
<li>Additional commits viewable in <a
href="https://github.com/cisco-ai-defense/skill-scanner/compare/2.1.0...2.2.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cisco-ai-skill-scanner&package-manager=uv&previous-version=2.1.0&new-version=2.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.14.3 to
3.14.4.

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=aiohttp&package-manager=uv&previous-version=3.14.3&new-version=3.14.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ancelin-code/delivery-kit/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [certifi](https://github.com/certifi/python-certifi) from
2026.7.22 to 2026.10.19.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/certifi/python-certifi/commit/662df63d7906df66f1f07c0751a3dfe9da14d914"><code>662df63</code></a>
Restore unaffected emSign roots (<a
href="https://redirect.github.com/certifi/python-certifi/issues/439">#439</a>)
(<a
href="https://redirect.github.com/certifi/python-certifi/issues/440">#440</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/5cb238caeeb6c30ec1a7309ad3e16a5aa7b10ce8"><code>5cb238c</code></a>
Remove emsign (<a
href="https://redirect.github.com/certifi/python-certifi/issues/437">#437</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/69494a764d0a08f90838d53d4b0fefd3e84045d6"><code>69494a7</code></a>
Bump actions/download-artifact from 8.0.1 to 8.0.2 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/436">#436</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/029c7b0913d79e2efb73a216fc5c5e13ef958536"><code>029c7b0</code></a>
Bump actions/upload-artifact from 7.0.1 to 7.0.2 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/435">#435</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/9d0a8f1f3a0d6b2e38d5773db7afe1a37e4527b6"><code>9d0a8f1</code></a>
Add support for Python 3.15 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/432">#432</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/db472abf0a37067cb4488f036f4c19adf6b6ec3c"><code>db472ab</code></a>
Bump pypa/gh-action-pypi-publish from 1.14.1 to 1.14.2 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/431">#431</a>)</li>
<li>See full diff in <a
href="https://github.com/certifi/python-certifi/compare/2026.07.22...2026.10.19">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=certifi&package-manager=uv&previous-version=2026.7.22&new-version=2026.10.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ancelin-code/delivery-kit/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…18)

## What and why

A large project can now be delivered in **milestones**, ordered
end-to-end
slices, with a reviewed stop after each. Requirements now carry **ids**,
and
coverage of each requirement is derived from them. This came from the
`tiroir`
pilot, whose ~90 approved requirements are meant to land as a walking
skeleton
first, then retrieval, team features and the rest. Before this change,
the kit
cut the whole scope at once, had no checkpoint between slices, and no
task
could say that it covered only part of a requirement.

- **Plan:** a `## Milestones` section in `delivery/decomposition.md`.
Each
  milestone has an `**Exit:**` line, a `**Requirements:**` line and an
  `**Epics:**` line. Only the current milestone is cut into tasks.
- **Gate:** `delivery/milestones/<slug>.md` records whether the exit
criterion
held, the coverage, what was learned, and whether to continue or revise.
  Approving it closes the milestone.
- **Coverage:** tasks list requirement ids under `## Covers`, as `- A4`
or
`- A4 (part): <note>`. The new `coverage.sh` reports each requirement as
  covered, partly, planned or not started.
- **Scripts:**
  - `status.sh` prints `MILESTONE` rows.
  - `where.sh` adds `review-milestone`, `approve-milestone-review` and
    `decompose-milestone`.
  - `follow.sh` stops with `MILESTONE` instead of `COMPLETE`.
- `validate-tasks.sh` checks ids, the plan, and that the current
milestone's
    tasks cover its targets.
  - `snapshot.sh` exports milestones and coverage.

Design, alternatives and consequences:
[ADR-010](docs/decisions/ADR-010-milestones.md).

## How to review

- Start with ADR-010, then the Milestones and Requirement ids sections
of
  `conventions.md`: they are the contract the scripts implement.
- Closest look:
- The milestone state derivation in `status.sh`. It is the single source
for
    `where.sh`, `follow.sh`, `coverage.sh` and `snapshot.sh`.
- The milestone checks in the validator's awk pass. The validator keeps
its
    own parser because it runs offline, without `gh`.
- An empty list in a tab-separated row is written `-`. `read` treats tab
as
  whitespace and would otherwise shift the fields after it.
- Left out on purpose:
  - a `milestone:` field on tasks
  - decomposing a milestone ahead while the previous one is unreviewed
  - a machine check of exit criteria
- a check that every requirement is targeted in full by some milestone.
Should
    items may slip to a later release, which that check would reject.

## How to try it

Against a copy of tiroir's approved PRD, with a four-milestone plan and
the
eight skeleton tasks all merged:

```text
$ sh .agents/skills/delivery-orchestrator/scripts/where.sh
MILESTONE  skeleton   merged   server auth store search  A1 A4 A5 M1 M3 S1 W1 W4 R2 R6 U1 U4 Y1 Y2 Y5 D1
MILESTONE  retrieval  planned  -                         R1 R2 R3 R4 R4a …
…
NEXT  review-milestone  every task of skeleton is merged: check its exit criterion, then write
      delivery/milestones/skeleton.md with delivery-decompose
      (coverage: sh .agents/skills/delivery-status/scripts/coverage.sh --milestone skeleton)

$ sh .agents/skills/delivery-status/scripts/coverage.sh --milestone skeleton
REQ   A4  partly   skeleton,team  auth-002  -
PART  A4  auth-002 done  a member signs in through the browser to connect a host; revoking
          access and removing a member come with the team milestone
REQ   A5  covered  skeleton       server-001  -
…
COVERAGE  covered=8  partly=8  planned=0  not-started=0

$ sh .agents/skills/delivery-orchestrator/scripts/follow.sh
MILESTONE  skeleton  merged
```

On that example, coverage showed a gap in the plan: U1 was targeted only
in
part, by the skeleton, and by no later milestone.

## Does it earn its place?

- Without the review note, what a milestone taught dies with its
session,
although the next cut starts in a fresh one. And `where.sh` could not
tell a
  reviewed milestone from a skipped one.
- Without `## Covers`, nobody can say what is left of a requirement
split
  across milestones.
- Projects that use neither take exactly the old code paths. Every
existing
test passes unchanged, apart from the helper count in
`test_posix_sh.py`. 38
new tests cover the changes, and the validator was also run under
BusyBox.
- Additive for connectors: `snapshot.sh` gains fields, and its schema
stays 1.
  Recorded in CHANGELOG.md.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## What and why

The repository is public, so released and unreleased work are now
separate
branches:

- `develop` is the default branch and the integration branch. Pull
requests
  target it and are squash-merged.
- `main` holds released work only. It moves by merging `develop`, and
release
tags are cut on it. `release.yaml` already refuses a tag that is not on
  `main`.
- CI now also runs on pushes to `develop`.
- The README pins the install to `main`, with `.../tree/main`. Since the
default
branch is now `develop`, a plain repository URL would install unreleased
  work.
- The README also adds CI and licence badges, a pre-release status note,
and a
  Contributing section with the branch model.
- AGENTS.md records the same branch model for agents.

The branch rulesets, the release-tag ruleset, the topics and the
security
settings are repository settings, applied alongside this pull request
rather
than in it.

## How to review

- `ci.yaml` changes one line, the push trigger.
- The README changes are the badges and status note at the top, the
install
  command, and the new Contributing section under Develop.
- Check that the pre-release note says what you want public users to
read: it
  says breaking changes are called out in CHANGELOG.md, not migrated.

## How to try it

```sh
npx skills add https://github.com/ancelin-code/delivery-kit/tree/main --skill '*' -a claude-code -y
```

Run that in an empty git repository. It installs the five skills from
`main`,
and `skills-lock.json` records `"ref": "main"`.

## Does it earn its place?

Without the pinned install, every user of the README command would
install
`develop` from now on. Nothing in the skills or scripts changes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…20)

## What and why

Feedback from the `tiroir` pilot, reproduced with `skills` 1.7.4:

- Installed with `-a claude-code` alone, the CLI copies each skill into
  `.claude/skills/` and creates no `.agents/`.
- A later `npx skills update` moves the skills it updates to
`.agents/skills/`
  behind links, and leaves the ones it finds up to date as copies.

The kit's scripts find each other as siblings (`../../<skill>`). In that
split
layout, `delivery-implement` resolves to
`.agents/skills/delivery-implement`,
which does not exist, whichever path the script was reached by. The
launcher
passed that path to every lane without checking it.

- `where.sh` checks that the other four skills are beside the
orchestrator. It
reports `NEXT repair-install`, alone, when one is missing, and names the
  directory and the missing skills.
- `launch-lanes.sh` refuses to start without `delivery-implement`.
- The README tells you to keep an agent that reads `.agents/skills/` in
the
  install command, explains the trap, and gives the repair: remove every
`delivery-*` directory under both paths, then install with both agents.
- `docs/harness-validation.md` records the reproduction as test 11.

## How to review

- The check is the first block of `where.sh` and one guard in
  `launch-lanes.sh`. Both name the directory with `cd -P`, because `..`
  resolves through the link into `.agents/skills/`, not back through
  `.claude/skills/`.
- The check is harness-neutral: it tests siblings, not `.claude/` or
`.agents/` paths. Only the README and the record name those directories.
- Not detected: the stale `.agents/skills/` copies that a re-run of
`add` with
  `-a claude-code` alone leaves behind. Every skill is still beside its
  siblings there; the README warns against that re-run instead.

## How to try it

```sh
mkdir split && cd split && git init -q
npx skills add https://github.com/ancelin-code/delivery-kit/tree/main --skill '*' -a claude-code -y
sed -i 's/"ref": "main"/"ref": "develop"/' skills-lock.json && npx skills update -p -y
ls -l .claude/skills   # four links, delivery-implement a plain directory
```

On that layout, `where.sh` from this branch prints:

```text
NEXT  repair-install  not beside delivery-orchestrator in …/split/.agents/skills: delivery-implement. The kit installs whole: …
```

## Does it earn its place?

Without the check, a split install fails silently: lanes run without the
skill
that holds their workflow, and nothing says why. The check costs four
file
tests per `where.sh` call. The pilot hit this on its first update.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## What and why

Feedback from the `tiroir` pilot: in the worktree of `foundation-001`,
the
branch was set to push to `develop`. A plain `git push` was refused, and
the
task had to be pushed explicitly to `task/foundation-001`.

Cause: `launch-lanes.sh` creates the branch with
`git worktree add -b task/<id> <path> origin/<default>`. Starting from a
remote-tracking branch, git makes it the upstream. With
`push.default=simple`
the push is refused, because the names differ. With
`push.default=upstream` it
would push the task's work to the default branch.

- `launch-lanes.sh` creates the branch with `--no-track`.
- `claim.sh` sets `<remote>/task/<id>` as the upstream of the branch it
was run
from, when that branch is `task/<id>`, and prints `UPSTREAM`. This also
covers a developer who claims by hand on a branch started from the
default
  branch.
- `conventions.md`, the `delivery-status` skill and the changelog say
so.

## How to review

- `claim.sh` writes `branch.<name>.remote` and `branch.<name>.merge`
directly,
  so it does not depend on a remote-tracking ref existing yet.
- It does so even with `--no-advance`: that option keeps the branch
where it
  is, and the upstream does not move it.

## How to try it

The two new tests fail without the change, and reproduce the pilot's
report:

```text
test_the_lane_branch_pushes_to_itself:   assert 'origin/main' == 'origin/task/a-001'
test_a_plain_push_goes_to_the_claimed_branch:   assert None == 'origin/task/ingestion-003'
```

With it, a lane's branch tracks `origin/task/<id>`, and a plain `git
push`
after a commit updates `task/<id>` and leaves the default branch
untouched.

## Does it earn its place?

Without it, every lane worktree has a branch that pushes to the default
branch.
Today that is refused or protected by a ruleset, but on a repository
with
`push.default=upstream` and no protection, it would put unreviewed work
on the
default branch.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…group (#23)

Bumps the actions group with 1 update:
[jdx/mise-action](https://github.com/jdx/mise-action).

Updates `jdx/mise-action` from 5.1.1 to 5.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/jdx/mise-action/releases">jdx/mise-action's
releases</a>.</em></p>
<blockquote>
<h2>v5.2.0: Periodic cache rebuilds, signed packslip verification, and
monorepo installs</h2>
<p>The default cache key now rolls over every 30 days, so long-lived
caches pick up newer mise releases. The action also checks the
downloaded mise binary against the release's signed packslip, and it
runs <code>mise install --monorepo</code> automatically in monorepos.
<strong>Existing caches miss once after you upgrade</strong>, because
the default cache key format has changed.</p>
<h2>Added</h2>
<ul>
<li><strong>The cache is rebuilt every 30 days by default.</strong>
GitHub never evicts a cache that keeps getting hits. Before this
release, an active repo could keep the same mise binary and tools for
months, until a config file changed. The default cache key now includes
a period suffix (<code>-p&lt;N&gt;</code>), so the cache is rebuilt from
scratch at least once per period. All repos roll over on the same
calendar boundary. Use the new <code>cache_max_age_days</code> input to
change the period, or set it to <code>0</code> to keep the old key that
never expires. Custom <code>cache_key</code> templates can use the new
<code>{{cache_period}}</code> variable, which <code>{{default}}</code>
already includes. A custom key that doesn't use it behaves as before. On
self-hosted runners that keep mise data between runs, you may also need
<code>auto_update: true</code> to pick up a newer mise. (<a
href="https://redirect.github.com/jdx/mise-action/pull/689">#689</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>, fixes <a
href="https://redirect.github.com/jdx/mise-action/issues/688">#688</a>)
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
  with:
    cache_max_age_days: 14 # default 30; 0 disables periodic rebuilds
</code></pre>
</li>
<li><strong>Throttled cache restores and saves can be retried.</strong>
Before this release, when GitHub's cache service returned HTTP 429, the
action gave up right away: a restore counted as a miss and a save was
skipped. The new <code>cache_restore_retry_budget</code> and
<code>cache_save_retry_budget</code> inputs set how long the action may
wait. Each retry waits for the <code>Retry-After</code> value plus some
random jitter. Once the budget runs out, the action falls back to the
old behavior. Retries apply to the main cache, the post-step save and
the binary cache. Real cache misses and reservation conflicts are never
retried. Both budgets default to <code>0s</code> (no retries).
<code>@actions/cache</code> doesn't report 429 errors directly, so the
action detects throttling from its warning messages. If those messages
change in a future <code>@actions/cache</code> release, throttling won't
be detected and nothing will be retried. (<a
href="https://redirect.github.com/jdx/mise-action/pull/692">#692</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>, fixes <a
href="https://redirect.github.com/jdx/mise-action/issues/691">#691</a>)
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
  with:
    cache_restore_retry_budget: 60s
    cache_save_retry_budget: 120s
</code></pre>
</li>
<li><strong>The latest mise binary can fall back to a second download
source.</strong> When the action downloads the latest mise version, it
can fall back between GitHub and mise.jdx.dev if the first source fails.
The <code>fetch_from_github</code> setting decides which source it tries
first. Pinned versions and <code>minimum_release_age</code> installs are
only downloaded from GitHub. The binary is still checked against the
signed checksums for the resolved version, whichever source it came
from. (<a
href="https://redirect.github.com/jdx/mise-action/pull/692">#692</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)</li>
<li><strong>The mise binary is checked against its signed
packslip.</strong> If a mise release includes
<code>packslip.sigstore.json</code>, the action checks the downloaded
binary against it. The bundle must be signed by mise's release workflow
for that exact tag. After a successful check, the log shows
<code>Verified &lt;asset&gt; against the signed packslip</code>. If the
check fails, the install stops instead of falling back to a weaker
check. Releases without a packslip use the existing minisign and
<code>SHASUMS256</code> check. An explicit <code>sha256</code> input
still takes precedence. (<a
href="https://redirect.github.com/jdx/mise-action/pull/693">#693</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)</li>
<li><strong>Monorepo-aware installs.</strong> If your mise config sets
<code>[monorepo].config_roots</code>, the action now adds
<code>--monorepo</code> to <code>mise install</code>, so tools
configured anywhere in the monorepo get installed. Repos without that
setting aren't affected. To opt out, set <code>monorepo: false</code>.
(<a href="https://redirect.github.com/jdx/mise-action/pull/679">#679</a>
by <a
href="https://github.com/zeitlinger"><code>@​zeitlinger</code></a>)</li>
</ul>
<h2>Fixed</h2>
<ul>
<li><strong>Tool directories that mise moves to the front of
<code>PATH</code> are now exported.</strong> The action used to find
mise's <code>PATH</code> changes by comparing mise's <code>PATH</code>
with the runner's. If a tool's bin directory was already on the runner's
<code>PATH</code>, such as <code>~/.cargo/bin</code>, mise only moved it
to the front, so the action didn't export it. Later steps then found the
mise shim first. For example, <code>rustup</code> resolved to the shim
instead of <code>~/.cargo/bin/rustup</code>. The action now asks mise
for its entries with <code>mise env --paths</code> and exports them in
the order mise reports. This fix needs a mise version that supports
<code>--paths</code>. With older versions, the action uses the old
comparison. (<a
href="https://redirect.github.com/jdx/mise-action/pull/685">#685</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)</li>
</ul>
<h2>Documentation</h2>
<ul>
<li>The new &quot;Release workflows&quot; section of the README says
that jobs that publish releases shouldn't restore caches. A lower-trust
workflow that can write to default-branch caches could otherwise slip
files into a release. In those jobs, use <code>cache: false</code> or
GitHub's <code>cache-mode: none</code>. (<a
href="https://redirect.github.com/jdx/mise-action/pull/682">#682</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>)</li>
<li>The README explains how to cache mise's downloads, keyed on
<code>mise.lock</code>, instead of installed tools. It includes a
Windows example that sets <code>MISE_CACHE_DIR</code> from <code>${{
runner.temp }}</code>, because <code>actions/cache</code> doesn't expand
<code>%TEMP%</code>. (<a
href="https://redirect.github.com/jdx/mise-action/pull/686">#686</a>, <a
href="https://redirect.github.com/jdx/mise-action/pull/690">#690</a> by
<a
href="https://github.com/zeitlinger"><code>@​zeitlinger</code></a>)</li>
</ul>
<h2>Breaking Changes</h2>
<ul>
<li>The default cache key has a new format, so the first run after
upgrading is a cache miss and saves a fresh cache. After that, the cache
is rebuilt every 30 days by default. To keep the old cache key that
never expires, set <code>cache_max_age_days: 0</code>. Workflows that
set a custom <code>cache_key</code> without <code>{{default}}</code> or
<code>{{cache_period}}</code> aren't affected.</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/jdx/mise-action/compare/v5.1.2...v5.2.0">https://github.com/jdx/mise-action/compare/v5.1.2...v5.2.0</a></p>
<h2>v5.1.2: mise_dir now sets MISE_DATA_DIR; auto_update handles a
locked mise binary</h2>
<p>The <code>mise_dir</code> input now also sets where mise installs
tools, so those tools end up in the cache. With <code>auto_update:
true</code>, the action no longer crashes on Windows when the mise
binary is still in use.</p>
<h2>Fixed</h2>
<ul>
<li><strong><code>mise_dir</code> now exports
<code>MISE_DATA_DIR</code>.</strong> Before this release,
<code>mise_dir</code> moved the mise binary and the cache path, but mise
kept installing tools to <code>~/.local/share/mise</code>. The saved
cache didn't include the tools. On runners where <code>~/.local</code>
isn't writable, the step failed with <code>EACCES: permission
denied</code>. When <code>mise_dir</code> is set, the action now exports
<code>MISE_DATA_DIR=&lt;mise_dir&gt;</code>, so tools are installed into
the directory that gets cached. If your workflow sets a different
<code>MISE_DATA_DIR</code>, the <code>mise_dir</code> input overrides
it. If <code>mise_dir</code> isn't set, nothing changes. mise's state
directory (<code>~/.local/state/mise</code>) stays where it is. If that
path also can't be written, set <code>MISE_STATE_DIR</code> yourself.
(<a href="https://redirect.github.com/jdx/mise-action/pull/672">#672</a>
by <a href="https://github.com/jdx"><code>@​jdx</code></a>, fixes <a
href="https://redirect.github.com/jdx/mise-action/issues/668">#668</a>)
<pre lang="yaml"><code>- uses: jdx/mise-action@v5
  with:
    mise_dir: ${{ runner.tool_cache }}/mise/data
</code></pre>
</li>
<li><strong><code>auto_update</code> no longer crashes when it can't
replace <code>mise.exe</code>.</strong> On Windows, the step used to
fail with a bare <code>EPERM: operation not permitted, unlink
'…\mise.exe'</code> if another process was still using the binary. Now,
if <code>version</code> isn't pinned and the existing binary passes
verification against its recorded version, the action prints a warning
and continues with that version. In any other case, the step fails with
a message that says the file is in use and how to fix it. A pinned
<code>version</code> never quietly keeps an older binary. (<a
href="https://redirect.github.com/jdx/mise-action/pull/665">#665</a> by
<a href="https://github.com/jdx"><code>@​jdx</code></a>, fixes <a
href="https://redirect.github.com/jdx/mise-action/issues/664">#664</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jdx/mise-action/blob/main/CHANGELOG.md">jdx/mise-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<hr />
<h2><a
href="https://github.com/jdx/mise-action/compare/v5.2.1..v5.2.2">5.2.2</a>
- 2026-10-21</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>hash conf.d config fragments in cache key (<a
href="https://redirect.github.com/jdx/mise-action/issues/698">#698</a>)
by <a
href="https://github.com/rileymichael"><code>@​rileymichael</code></a>
in <a
href="https://redirect.github.com/jdx/mise-action/pull/698">#698</a></li>
</ul>
<h3>New Contributors</h3>
<ul>
<li><a
href="https://github.com/rileymichael"><code>@​rileymichael</code></a>
made their first contribution in <a
href="https://redirect.github.com/jdx/mise-action/pull/698">#698</a></li>
</ul>
<hr />
<h2><a
href="https://github.com/jdx/mise-action/compare/v5.2.0..v5.2.1">5.2.1</a>
- 2026-10-19</h2>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>require the signed packslip for mise 2026.9.3 and later (<a
href="https://redirect.github.com/jdx/mise-action/issues/695">#695</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/695">#695</a></li>
</ul>
<hr />
<h2><a
href="https://github.com/jdx/mise-action/compare/v5.1.2..v5.2.0">5.2.0</a>
- 2026-10-16</h2>
<h3>🚀 Features</h3>
<ul>
<li><strong>(cache)</strong> rebuild the cache every 30 days by default
(<a
href="https://redirect.github.com/jdx/mise-action/issues/689">#689</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/689">#689</a></li>
<li><strong>(cache)</strong> retry throttled cache restores and saves
(<a
href="https://redirect.github.com/jdx/mise-action/issues/692">#692</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/692">#692</a></li>
<li>verify the mise binary against its signed packslip (<a
href="https://redirect.github.com/jdx/mise-action/issues/693">#693</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/693">#693</a></li>
</ul>
<h3>🐛 Bug Fixes</h3>
<ul>
<li>export the PATH entries mise reports with mise env --paths (<a
href="https://redirect.github.com/jdx/mise-action/issues/685">#685</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/685">#685</a></li>
</ul>
<h3>🔍 Other Changes</h3>
<ul>
<li>Use monorepo install when configured (<a
href="https://redirect.github.com/jdx/mise-action/issues/679">#679</a>)
by <a href="https://github.com/zeitlinger"><code>@​zeitlinger</code></a>
in <a
href="https://redirect.github.com/jdx/mise-action/pull/679">#679</a></li>
<li>Change minimum age for auto-merging release PRs by <a
href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://github.com/jdx/mise-action/commit/b511e8dec14aeeaeeac996371d336fcc5d0a6bed">b511e8d</a></li>
</ul>
<h3>📚 Documentation</h3>
<ul>
<li>tell release workflows not to use the cache (<a
href="https://redirect.github.com/jdx/mise-action/issues/682">#682</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/682">#682</a></li>
<li>explain caching mise downloads instead of installs (<a
href="https://redirect.github.com/jdx/mise-action/issues/686">#686</a>)
by <a href="https://github.com/zeitlinger"><code>@​zeitlinger</code></a>
in <a
href="https://redirect.github.com/jdx/mise-action/pull/686">#686</a></li>
<li>use resolved Windows downloads cache path (<a
href="https://redirect.github.com/jdx/mise-action/issues/690">#690</a>)
by <a href="https://github.com/zeitlinger"><code>@​zeitlinger</code></a>
in <a
href="https://redirect.github.com/jdx/mise-action/pull/690">#690</a></li>
</ul>
<h3>⚙️ Miscellaneous Tasks</h3>
<ul>
<li>stop restoring caches in release jobs (<a
href="https://redirect.github.com/jdx/mise-action/issues/683">#683</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/683">#683</a></li>
<li>replace prettier with oxfmt (<a
href="https://redirect.github.com/jdx/mise-action/issues/694">#694</a>)
by <a href="https://github.com/jdx"><code>@​jdx</code></a> in <a
href="https://redirect.github.com/jdx/mise-action/pull/694">#694</a></li>
</ul>
<hr />
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/jdx/mise-action/commit/9b200bcecbfd6303e69a4a261b2e09e3757440a7"><code>9b200bc</code></a>
chore: release v5.2.0 (<a
href="https://redirect.github.com/jdx/mise-action/issues/680">#680</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/b511e8dec14aeeaeeac996371d336fcc5d0a6bed"><code>b511e8d</code></a>
Change minimum age for auto-merging release PRs</li>
<li><a
href="https://github.com/jdx/mise-action/commit/887d1f43266da23235f0fb82165ac68fcac39839"><code>887d1f4</code></a>
docs: use resolved Windows downloads cache path (<a
href="https://redirect.github.com/jdx/mise-action/issues/690">#690</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/93c62ad75cd417c639763e02ab55eda7edb57426"><code>93c62ad</code></a>
chore: replace prettier with oxfmt (<a
href="https://redirect.github.com/jdx/mise-action/issues/694">#694</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/04716d413ce8af3906480132625053e79b3db941"><code>04716d4</code></a>
feat: verify the mise binary against its signed packslip (<a
href="https://redirect.github.com/jdx/mise-action/issues/693">#693</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/510810497dfec59c6eda542df1c57c8105721fda"><code>5108104</code></a>
feat(cache): retry throttled cache restores and saves (<a
href="https://redirect.github.com/jdx/mise-action/issues/692">#692</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/d401260ed8e20397c037bb3fd3fd90ba141f679d"><code>d401260</code></a>
docs: explain caching mise downloads instead of installs (<a
href="https://redirect.github.com/jdx/mise-action/issues/686">#686</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/e7cf35fa5b82d93868f3b60864cfc31b99dcb8ba"><code>e7cf35f</code></a>
feat(cache): rebuild the cache every 30 days by default (<a
href="https://redirect.github.com/jdx/mise-action/issues/689">#689</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/cd026961d0601d9b47ccd076fe308efae012af8d"><code>cd02696</code></a>
fix: export the PATH entries mise reports with mise env --paths (<a
href="https://redirect.github.com/jdx/mise-action/issues/685">#685</a>)</li>
<li><a
href="https://github.com/jdx/mise-action/commit/6784481815ab51eb368de1c2294d9fa396be732a"><code>6784481</code></a>
docs: tell release workflows not to use the cache (<a
href="https://redirect.github.com/jdx/mise-action/issues/682">#682</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/jdx/mise-action/compare/2d8d4cafcbd33be2ea37d2b6f5ad595363d1f1ca...9b200bcecbfd6303e69a4a261b2e09e3757440a7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=jdx/mise-action&package-manager=github_actions&previous-version=5.1.1&new-version=5.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…he python group (#24)

Bumps the python group with 1 update:
[cisco-ai-skill-scanner](https://github.com/cisco-ai-defense/skill-scanner).

Updates `cisco-ai-skill-scanner` from 2.2.2 to 2.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cisco-ai-defense/skill-scanner/releases">cisco-ai-skill-scanner's
releases</a>.</em></p>
<blockquote>
<h2>Skill Scanner 2.3.0</h2>
<p>This release maps every finding to the Cisco AI Security and Safety
Taxonomy, closes several ways to hide text from the frontmatter scan,
and stops silently skipping symlinks and unloadable skills, while
keeping the measured false-positive rate steady on the pull-request
development corpus.</p>
<h3>Changes</h3>
<ul>
<li>Attach a Cisco AI taxonomy code to findings: an AITech code and,
where one fits, an AISubtech code, with names and OWASP, MITRE ATLAS and
NIST AML crosswalks, from a hash-pinned taxonomy 2.0.0 snapshot bundled
with the scanner. Every bundled rule declares its code, operational
findings are <code>not_applicable</code>, and a code that cannot be
resolved is <code>unmapped</code> rather than guessed. New finding
metadata: <code>aitech</code>, <code>aitech_name</code>,
<code>aisubtech</code>, <code>aisubtech_name</code>,
<code>aitech_mappings</code>, <code>aisubtech_mappings</code>,
<code>framework_mappings</code>, <code>taxonomy_status</code> and
<code>taxonomy_source</code>, plus scan-level counts in
<code>scan_metadata.taxonomy</code> and SARIF result properties. (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/267">#267</a>)</li>
<li>Scan every <code>SKILL.md</code> frontmatter value and comment
except <code>allowed-tools</code>, as the loader parses it. Quoted and
complex keys, YAML aliases and merge keys, escape sequences,
<code>!!binary</code> values and values folded over several lines no
longer hide text from the static rules. (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/265">#265</a>,
<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/268">#268</a>)</li>
<li>Detect plain-language instructions to read a local credential file
and send it to a remote host in
<code>ACTIVE_SENSITIVE_EXFILTRATION</code>. (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/264">#264</a>)</li>
<li>Report symlinks among a skill's files, which are not followed, as
<code>SYMLINK_NOT_SCANNED</code> (HIGH when the target leaves the skill
root), and skills that fail to load as <code>SKILL_LOAD_FAILED</code>
findings in <code>scan-all</code>. (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/265">#265</a>)</li>
<li>Avoid quadratic regex work in two rules on long lines. (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/265">#265</a>)</li>
</ul>
<h3>Behavior notes</h3>
<p>Taxonomy codes follow taxonomy 2.0.0, so some change: jailbreak rules
move from <code>AITech-2.1</code> to <code>AITech-1.1</code> /
<code>AISubtech-1.1.5</code>, and hardcoded secrets from
<code>AISubtech-8.2.2</code> to <code>AISubtech-14.1.1</code>. The
<code>AITech-99.9</code> / <code>AISubtech-99.9.9</code> placeholders
are no longer emitted. Update any filters on 1.x codes.
<code>scan-all</code> now reports folders with unloadable skills or
symlinks as findings instead of skipping them, so SARIF, markdown output
and <code>--fail-on-severity</code> exit codes include them.</p>
<h3>Validation</h3>
<p>The PR detection-impact gate compares base and head on the same
labelled development records and fixed real-skill sample, enforcing a
0.5 percentage point FPR-rise limit. Across this release, benign flags
stayed at 14/1,338 (1.05%) and real-skill flags at 130/2,000, while
development-split recall rose from 31.43% to 31.94%. The <a
href="https://github.com/cisco-ai-defense/skill-scanner/actions/runs/38696111205">exact-SHA
release evidence</a> and <a
href="https://github.com/cisco-ai-defense/skill-scanner/actions/runs/38696761973">mandatory
release gate</a> passed 3,551 checks. The release holdout compares
CEL-off and active modes of this revision; both flagged 23/545 benign
samples (4.22%), and holdout recall (7.75%) and macro-F1 (35.41%) are
unchanged from 2.2.2.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/e4e334f03a673015a088febc0e2c566087aeb327"><code>e4e334f</code></a>
docs: pin examples to 2.3.0 and describe the 2.3.0 scanning changes (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/269">#269</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/5b0eda6ecdc27d924a942ee18eaffe4bf0300a43"><code>5b0eda6</code></a>
feat: detect plain-language instructions to send local secrets to a
remote ho...</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/55bd732b22d35b495478412f476344d14ddccdf2"><code>55bd732</code></a>
feat: map every finding to a Cisco AI taxonomy code (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/267">#267</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/010ae2cd4c994cb5341c4af07469235e292e6cc1"><code>010ae2c</code></a>
fix: scan SKILL.md frontmatter values as the loader parses them (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/268">#268</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/64101c558c1163dd1b97cc2206fb77d02c8c0d40"><code>64101c5</code></a>
fix: close silent-skip paths in the scanner and two quadratic rules (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/265">#265</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/f18074a50d4f1973d52fd443a7acd547a45bd07e"><code>f18074a</code></a>
docs: pin site examples to skill-scanner 2.2.2 (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/262">#262</a>)</li>
<li><a
href="https://github.com/cisco-ai-defense/skill-scanner/commit/e5a3d3e22dc51e2496e7b580bae24b99873d06bd"><code>e5a3d3e</code></a>
chore: update Homebrew formula to 2.2.2 (<a
href="https://redirect.github.com/cisco-ai-defense/skill-scanner/issues/261">#261</a>)</li>
<li>See full diff in <a
href="https://github.com/cisco-ai-defense/skill-scanner/compare/2.2.2...2.3.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cisco-ai-skill-scanner&package-manager=uv&previous-version=2.2.2&new-version=2.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## What and why

A lane went straight from `delivery-implement` to a draft pull request.
The
human at the merge gate was the first to review the change, and nothing
simplified it, although that human is the bottleneck the kit is built
around.

A sixth skill, `delivery-refine`, runs as the lane's second session. It
works
in one pass:

1. Review the change against the task's acceptance criteria and the
edge-case
   and verification-gap lenses.
2. Fix the findings that name a concrete failure.
3. Simplify only the lines the change added, without altering their
behaviour.
4. Re-run validation.
5. Add a **Refinement** section to the report that becomes the pull
request
   body.

Design and evidence:
[ADR-011](docs/decisions/ADR-011-lane-refinement.md).

- **A stronger reviewer:**
- By default the review runs one tier up: `chore` is reviewed as
`build`,
`build` as `plan`, `plan` as `plan`, on that tier's harness and model.
  - A tier can name its own `reviewer` in `tiers.conf` instead.
- A cross-model review study found same-model fresh-context review no
better
    than self-review, and a stronger reviewer best.
- **The implementation is never lost:** a failed refinement is logged as
`REFINE-FAILED`, noted in the report, and the change is published as it
  was. `--no-refine` skips the session.
- **Every harness:** the launcher starts the session through
`harness.sh`, so it
  works on every adapter, rather than on one harness's subagents.
  `harness_prompt` now takes the skill's name from its path.

## How to review

- Start with `delivery-refine/SKILL.md`. The order is deliberate: fixing
before
simplifying means no effort goes into code about to change. The list of
simplifications to make and to avoid draws on Anthropic's
`code-simplifier`,
  Claude Code's `/simplify`, EveryInc's `ce-simplify-code` and
  `addyosmani/agent-skills`.
- Then `launch-lanes.sh`:
  - `refine_for` picks the review harness and model.
- The lane's inner shell runs implement, refine when a change exists,
then
    publish.
- **Breaking:** `LAUNCHED` and `WOULD-LAUNCH` gain two columns, the
review
harness and model, after the lane's model. The worktree and repository
stay
  last. `follow.sh` reads only the id.
- **Merge order:** this branch and #21 both add to the top of
CHANGELOG's
Unreleased list. The code merges cleanly; whichever lands second needs a
  one-line rebase.
- **Not validated on a real harness yet:** the tests drive the launcher
with a
fake harness. The first real lanes, on tiroir, will be the first real
runs.

## How to try it

```sh
sh .agents/skills/delivery-orchestrator/scripts/launch-lanes.sh --dry-run a-001
# WOULD-LAUNCH  a-001  claude  sonnet  claude  opus  ../lanes/repo/a-001  repo
```

That output assumes `build` maps to `sonnet` and `plan` to `opus`. A
real lane's
log shows `REFINE claude opus` between the implementation and
`PUBLISHED`.

## Does it earn its place?

It has not been measured yet, and the kit's rule says it must be. It is
on by
default on the strength of the maintainer's practice and of the
cross-model
review literature. The phase 6 evaluation adds a `--no-refine` arm and
compares
four things: hidden tests passing, human review findings per pull
request,
diff size, and cost per lane. If refinement does not reduce human
findings or
raise the number of hidden tests passing, it gets turned off by default.

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## Summary

Every behavioural test in `tests/unit/` now marks its steps with `#
Given`, `# When` and `# Then` comments, each followed by a short phrase
saying what the step sets up, does or checks. This is the style
`test_delivery_implement_scripts.py` already used; it is now applied
across the suite.

- `# Given` is left out when there is nothing to set up.
- A few tests that check a progression (for example a milestone going
merged → reviewing → closed) have several When/Then pairs.
- About fifteen tests called a script and asserted on the same line
(`assert launch(...).returncode == OK`). They are split into `result =
...` then `assert`, so the action and the check stand apart. No
assertion changed.
- `AGENTS.md` records the convention for new tests.

## Validation

- `mise run lint`: clean
- `mise run test`: 355 passed

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Closes the changelog at `0.1.0` dated 2026-10-23, folding the unreleased
entries into the first release and counting six skills. The README's
pre-release banner now says `v0.1.0` is the first release. Skill and
`pyproject.toml` versions were already `0.1.0`; `check-release v0.1.0`
passes. After this merges, `develop` goes to `main` through a merge pull
request, and the `v0.1.0` tag is cut on `main`.

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
@ancelin-code ancelin-code added the ai-assisted AI agents worked on this change label Oct 23, 2026
@ancelin-code
ancelin-code merged commit 97c969e into main Oct 23, 2026
9 checks passed
ancelin-code added a commit that referenced this pull request Oct 23, 2026
`main` holds the merge commit of #27, which `develop` lacks. This brings
it back so the two branches share history again. Merge with a merge
commit, not a squash.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted AI agents worked on this change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant