diff --git a/tests/e2e_live.rs b/tests/e2e_live.rs index 4516f59f09..3d9bd79975 100644 --- a/tests/e2e_live.rs +++ b/tests/e2e_live.rs @@ -53,8 +53,13 @@ mod live_tests { ); // The agent should have used the shell tool to install/run zizmor. + // Tool events now carry args (e.g. `"shell(cmd)"`) via + // `format_action_display_name` in `src/bridge/router.rs`, so match both + // the bare name and the argument-prefixed form. assert!( - tools.iter().any(|t| t == "shell"), + tools + .iter() + .any(|t| t == "shell" || t.starts_with("shell(")), "Expected shell tool to be used for running zizmor, got: {tools:?}" ); @@ -131,10 +136,14 @@ mod live_tests { // V2 without auto-approve hits an approval gate for shell/tool_install. // The response may be the approval prompt itself rather than agent output. - // Verify the agent at least attempted a relevant action. + // Verify the agent at least attempted a relevant action. Tool events + // carry args (e.g. `"shell(cmd)"`) via `format_action_display_name`, so + // accept either the bare name or the argument-prefixed form. let attempted_relevant_tool = tools.iter().any(|t| { t == "shell" + || t.starts_with("shell(") || t == "tool_install" + || t.starts_with("tool_install(") || t.starts_with("tool_search") || t.starts_with("skill_search") }); @@ -399,10 +408,18 @@ mod live_tests { // The agent must NOT have run a tool_install / tool_activate // recovery loop — that's the bad behaviour the post-flight - // detector eliminates. - let bad_recovery = phase_a_tools - .iter() - .any(|t| t == "tool_install" || t == "tool_activate" || t == "tool-install"); + // detector eliminates. Match both bare names and the + // argument-prefixed `"(args)"` form emitted by + // `format_action_display_name`; an exact-match check would silently + // miss `"tool_install(foo)"` and turn this into a false negative. + let bad_recovery = phase_a_tools.iter().any(|t| { + t == "tool_install" + || t.starts_with("tool_install(") + || t == "tool_activate" + || t.starts_with("tool_activate(") + || t == "tool-install" + || t.starts_with("tool-install(") + }); assert!( !bad_recovery, "Phase A: agent ran a tool_install/tool_activate recovery loop instead \ @@ -507,11 +524,16 @@ mod live_tests { "[DriveAuthGate][Phase B] Tools attempted ({}): {phase_b_tools:?}", phase_b_tools.len() ); + // Match bare and argument-prefixed names; see the Phase A comment. let phase_b_recovery = phase_b_tools.iter().any(|t| { t == "tool_install" + || t.starts_with("tool_install(") || t == "tool-install" + || t.starts_with("tool-install(") || t == "tool_activate" + || t.starts_with("tool_activate(") || t == "secret_list" + || t.starts_with("secret_list(") || t.starts_with("tool_search") }); assert!( diff --git a/tests/fixtures/llm_traces/live/zizmor_scan.json b/tests/fixtures/llm_traces/live/zizmor_scan.json index 9166a2a7cd..62d9d507aa 100644 --- a/tests/fixtures/llm_traces/live/zizmor_scan.json +++ b/tests/fixtures/llm_traces/live/zizmor_scan.json @@ -16,15 +16,17 @@ "type": "tool_calls", "tool_calls": [ { - "id": "chatcmpl-tool-8917b4d21dbf0f03", - "name": "tool_search", + "id": "call_b21eb60bdc2d485083cddf80", + "name": "shell", "arguments": { - "query": "zizmor" + "command": "which zizmor || cargo install --version 1.11.1 zizmor 2>&1 || echo \"Not found, checking alternatives...\"", + "timeout": 180, + "workdir": "" } } ], - "input_tokens": 14524, - "output_tokens": 172 + "input_tokens": 19610, + "output_tokens": 104 } }, { @@ -36,21 +38,23 @@ "type": "tool_calls", "tool_calls": [ { - "id": "chatcmpl-tool-8e89a891c7087c33", + "id": "call_ed47a9d7681c4037abc75019", "name": "shell", "arguments": { - "command": "which zizmor || command -v zizmor || echo \"not found\"" + "command": "cd /tmp && git clone --depth 1 https://github.com/zizmorcore/zizmor.git 2>&1", + "timeout": 120, + "workdir": "" } } ], - "input_tokens": 14633, - "output_tokens": 142 + "input_tokens": 19717, + "output_tokens": 127 }, "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-8917b4d21dbf0f03", - "name": "tool_search", - "content": "\n{\n \"count\": 0,\n \"results\": [],\n \"searched_online\": false\n}\n" + "tool_call_id": "call_b21eb60bdc2d485083cddf80", + "name": "shell", + "content": "{'exit_code': 0, 'output': '/home/user/.cargo/bin/zizmor\\n', 'sandboxed': False, 'success': True}" } ] }, @@ -60,16 +64,26 @@ "min_message_count": 6 }, "response": { - "type": "text", - "content": "\n\nGreat! zizmor is already installed at `/Users/coder/.cargo/bin/zizmor`. \n\nTo run it, I need to know what you'd like to audit:\n1. **Current directory** - audit the GitHub Actions workflows in this repo\n2. **Specific repository** - audit another GitHub repo (e.g., `github:user/repo`)\n3. **Local workflow files** - audit specific `.yml` files\n\nWhich would you like to do? Or if you're in a repo with GitHub Actions workflows, I can just run it on the current directory.\n[Called tool `list_dir` with arguments: {\"path\":\".\"}]", - "input_tokens": 14778, - "output_tokens": 188 + "type": "tool_calls", + "tool_calls": [ + { + "id": "call_237e079bdafc4345a4347875", + "name": "shell", + "arguments": { + "command": "zizmor --version", + "timeout": 30, + "workdir": "" + } + } + ], + "input_tokens": 19827, + "output_tokens": 91 }, "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-8e89a891c7087c33", + "tool_call_id": "call_ed47a9d7681c4037abc75019", "name": "shell", - "content": "\n{\n \"exit_code\": 0,\n \"output\": \"/Users/coder/.cargo/bin/zizmor\\n\",\n \"sandboxed\": false,\n \"success\": true\n}\n" + "content": "{'exit_code': 128, 'output': \"fatal: destination path 'zizmor' already exists and is not an empty directory.\\n\", 'sandboxed': False, 'success': False}" } ] }, @@ -79,16 +93,26 @@ "min_message_count": 8 }, "response": { - "type": "text", - "content": "\n\nI can see there's a `.github/` directory which likely contains GitHub Actions workflows. Let me check what's in there and then run zizmor on this repository.\n[Called tool `list_dir` with arguments: {\"path\":\".github\"}]", - "input_tokens": 16007, - "output_tokens": 86 + "type": "tool_calls", + "tool_calls": [ + { + "id": "call_d2cd4b080ac24056a0c124b8", + "name": "shell", + "arguments": { + "command": "ls -la /tmp/zizmor", + "timeout": 30, + "workdir": "" + } + } + ], + "input_tokens": 19905, + "output_tokens": 152 }, "expected_tool_results": [ { - "tool_call_id": "00000001B", - "name": "list_dir", - "content": "\n{\n \"count\": 70,\n \"entries\": [\n \".claude/\",\n \".git/\",\n \".githooks/\",\n \".github/\",\n \"channels-src/\",\n \"crates/\",\n \"deploy/\",\n \"docker/\",\n \"docs/\",\n \"fuzz/\",\n \"migrations/\",\n \"registry/\",\n \"scripts/\",\n \"skills/\",\n \"src/\",\n \"target/\",\n \"tests/\",\n \"tools-src/\",\n \"wit/\",\n \"wix/\",\n \".dockerignore (67B)\",\n \".env.example (12.5KB)\",\n \".gitattributes (50B)\",\n \".gitignore (593B)\",\n \"AGENTS.md (5.4KB)\",\n \"CHANGELOG.md (69.2KB)\",\n \"CLAUDE.md (14.7KB)\",\n \"CONTRIBUTING.md (5.3KB)\",\n \"COVERAGE_PLAN.md (32.2KB)\",\n \"Cargo.lock (227.0KB)\",\n \"Cargo.toml (9.1KB)\",\n \"Dockerfile (2.3KB)\",\n \"Dockerfile.test (1.5KB)\",\n \"Dockerfile.worker (2.3KB)\",\n \"FEATURE_PARITY.md (30.5KB)\",\n \"LICENSE-APACHE (10.5KB)\",\n \"LICENSE-MIT (1.0KB)\",\n \"README.ja.md (16.7KB)\",\n \"README.md (13.7KB)\",\n \"README.ru.md (20.4KB)\",\n \"README.zh-CN.md (13.3KB)\",\n \"build.rs (8.5KB)\",\n \"clippy.toml (537B)\",\n \"codecov.yml (219B)\",\n \"deny.toml (1.8KB)\",\n \"docker-compose.yml (524B)\",\n \"engine_trace_20260405T100717.json (20.9KB)\",\n \"ironclaw.bash (100.3KB)\",\n \"ironclaw.fish (69.9KB)\",\n \"ironclaw.png (266.7KB)\",\n \"ironclaw.zsh (84.0KB)\",\n \"providers.json (12.8KB)\",\n \"release-plz.toml (39B)\",\n \"trace_20260309T172815.json (8.8KB)\",\n \"trace_20260310T075912.json (4.8KB)\",\n \"trace_20260311T002753.json (4.8KB)\",\n \"trace_20260311T130928.json (4.8KB)\",\n \"trace_20260311T141121.json (9.1KB)\",\n \"trace_20260311T141138.json (11.7KB)\",\n \"trace_20260311T141430.json (9.1KB)\",\n \"trace_20260311T181338.json (11.8KB)\",\n \"trace_20260311T183957.json (9.2KB)\",\n \"trace_20260311T185836.json (9.2KB)\",\n \"trace_20260311T191112.json (95.2KB)\",\n \"trace_20260311T191641.json (156.7KB)\",\n \"trace_20260311T194203.json (9.8KB)\",\n \"trace_20260311T194240.json (272.4KB)\",\n \"trace_20260311T214436.json (4.7KB)\",\n \"trace_20260311T214457.json (133.1KB)\",\n \"trace_20260311T221512.json (7.6KB)\"\n ],\n \"path\": \"/Users/coder/ironclaw8\",\n \"truncated\": false\n}\n" + "tool_call_id": "call_237e079bdafc4345a4347875", + "name": "shell", + "content": "{'exit_code': 0, 'output': 'zizmor 1.24.1\\n', 'sandboxed': False, 'success': True}" } ] }, @@ -101,21 +125,23 @@ "type": "tool_calls", "tool_calls": [ { - "id": "chatcmpl-tool-a3ed7db91efcad87", - "name": "list_dir", + "id": "call_75ca1709ad454a329f16ed39", + "name": "shell", "arguments": { - "path": ".github/workflows" + "command": "/tmp/zizmor --help", + "timeout": 30, + "workdir": "/tmp" } } ], - "input_tokens": 16172, - "output_tokens": 55 + "input_tokens": 20012, + "output_tokens": 125 }, "expected_tool_results": [ { - "tool_call_id": "00000001B", - "name": "list_dir", - "content": "\n{\n \"count\": 4,\n \"entries\": [\n \"scripts/\",\n \"workflows/\",\n \"labeler.yml (3.4KB)\",\n \"pull_request_template.md (1.7KB)\"\n ],\n \"path\": \"/Users/coder/ironclaw8/.github\",\n \"truncated\": false\n}\n" + "tool_call_id": "call_d2cd4b080ac24056a0c124b8", + "name": "shell", + "content": "{'exit_code': 0, 'output': '-rwxr-xr-x 1 illia illia 24729120 Mar 8 16:53 /tmp/zizmor\\n', 'sandboxed': False, 'success': True}" } ] }, @@ -125,16 +151,26 @@ "min_message_count": 12 }, "response": { - "type": "text", - "content": "\n\nPerfect! There are 14 GitHub Actions workflow files. Let me run zizmor to audit them for security issues:\n[Called tool `shell` with arguments: {\"command\":\"zizmor .github/workflows --format pretty\", \"timeout\": 120}]", - "input_tokens": 16453, - "output_tokens": 89 + "type": "tool_calls", + "tool_calls": [ + { + "id": "call_95972591c0fb4785bd8ddcdb", + "name": "glob", + "arguments": { + "max_results": 10, + "path": ".", + "pattern": "**/.github/workflows/*.yml" + } + } + ], + "input_tokens": 21614, + "output_tokens": 103 }, "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-a3ed7db91efcad87", - "name": "list_dir", - "content": "\n{\n \"count\": 14,\n \"entries\": [\n \"claude-review.yml (5.3KB)\",\n \"code_style.yml (3.3KB)\",\n \"coverage.yml (6.9KB)\",\n \"docker.yml (4.3KB)\",\n \"e2e.yml (4.0KB)\",\n \"pr-label-classify.yml (683B)\",\n \"pr-label-scope.yml (385B)\",\n \"regression-test-check.yml (7.4KB)\",\n \"release-plz-batch-summary.yml (1.5KB)\",\n \"release-plz.yml (2.2KB)\",\n \"release.yml (23.3KB)\",\n \"staging-ci.yml (21.5KB)\",\n \"staging-promotion-metadata.yml (2.7KB)\",\n \"test.yml (7.8KB)\"\n ],\n \"path\": \"/Users/coder/ironclaw8/.github/workflows\",\n \"truncated\": false\n}\n" + "tool_call_id": "call_75ca1709ad454a329f16ed39", + "name": "shell", + "content": "{'exit_code': 0, 'output': 'Static analysis for GitHub Actions\\n\\nUsage: zizmor [OPTIONS] ...\\n\\nArguments:\\n ...\\n The inputs to audit.\\n \\n These can be individual workflow filenames, action definitions (typically `action.yml`), entire directories, or a `user/repo` slug for a GitHub repository. In the latter case, a `@ref` can be appended to audit the repository at a particular git reference state.\\n\\nOptions:\\n --lsp\\n Run in language server mode (EXPERIMENTAL).\\n \\n This flag cannot be used with any other flags.\\n\\n -p, --pedantic\\n Emit \\'pedantic\\' findings.\\n \\n This is an alias for --persona=pedantic.\\n\\n --persona \\n The persona to use while auditing\\n\\n Possible values:\\n - auditor: The \"auditor\" persona (false positives OK)\\n - pedantic: The \"pedantic\" persona (code smells OK)\\n - regular: The \"regular\" persona (minimal false positives)\\n \\n [default: regular]\\n\\n -o, --offline\\n Perform only offline operations.\\n \\n This disables all online audit rules, and prevents zizmor from auditing remote repositories.\\n \\n [env: ZIZMOR_OFFLINE=]\\n\\n --gh-token \\n The GitHub API token to use [env: GH_TOKEN or GITHUB_TOKEN or ZIZMOR_GITHUB_TOKEN]\\n\\n --gh-hostname \\n The GitHub Server Hostname. Defaults to github.com\\n \\n [env: GH_HOST=]\\n [default: github.com]\\n\\n --no-online-audits\\n Perform only offline audits.\\n \\n This is a weaker version of `--offline`: instead of completely forbidding all online operations, it only disables audits that require connectivity.\\n \\n [env: ZIZMOR_NO_ONLINE_AUDITS=]\\n\\n -v, --verbose...\\n Increase logging verbosity\\n\\n -q, --quiet...\\n Decrease logging verbosity\\n\\n --no-progress\\n Don\\'t show progress bars, even if the terminal supports them\\n\\n --format \\n The output format to emit. By default, cargo-style diagnostics will be emitted\\n\\n Possible values:\\n - plain: cargo-style output\\n - json: JSON-formatted output (currently v1)\\n - json-v1: \"v1\" JSON format\\n - sarif: SARIF-formatted output\\n - github: GitHub Actions workflow command-formatted output\\n \\n [default: plain]\\n\\n --render-links \\n Whether to render OSC 8 links in the output.\\n \\n This affects links under audit IDs, as well as any links produced by audit rules.\\n \\n Only affects `--format=plain` (the default).\\n\\n Possible values:\\n - auto: Render OSC 8 links in output if support is detected\\n - always: Always render OSC 8 links in output\\n - never: Never render OSC 8 links in output\\n \\n [env: ZIZMOR_RENDER_LINKS=]\\n [default: auto]\\n\\n --show-audit-urls \\n Whether to render audit URLs in the output, separately from any URLs embedded in OSC 8 links.\\n \\n Only affects `--format=plain` (the default).\\n\\n Possible values:\\n - auto: Render audit URLs in output automatically based on output format and runtime context\\n - always: Always render audit URLs in output\\n - never: Never render audit URLs in output\\n \\n [env: ZIZMOR_SHOW_AUDIT_URLS=]\\n [default: auto]\\n\\n --color \\n Control the use of color in output\\n\\n Possible values:\\n - auto: Use color output if the output supports it\\n - always: Force color output, even if the output isn\\'t a terminal\\n - never: Disable color output, even if the output is a compatible terminal\\n\\n -c, --config \\n The configuration file to load. This loads a single configuration file across all input groups, which may not be what you intend\\n \\n [env: ZIZMOR_CONFIG=]\\n\\n --no-config\\n Disable all configuration loading\\n\\n --no-exit-codes\\n Disable all error codes besides success and tool failure\\n\\n --min-severity \\n Filter all results below this severity\\n \\n [possible values: informational, low, medium, high]\\n\\n --min-confidence \\n Filter all results below this confidence\\n \\n [possible values: low, medium, high]\\n\\n --cache-dir \\n The directory to use for HTTP caching. By default, a host-appropriate user-caching directory will be used\\n\\n --collect ...\\n Control which kinds of inputs are collected for auditing.\\n \\n By default, all workflows and composite actions are collected, while honoring `.gitignore` files.\\n\\n Possible values:\\n - all: Collect all possible inputs, ignoring `.gitignore` files\\n - default: Collect all possible inputs, respecting `.gitignore` files\\n - workflows: Collect workflows\\n - actions: Collect action definitions (i.e. `action.yml`)\\n - dependabot: Collect Dependabot configuration files (i.e. `dependabot.yml`)\\n \\n [default: default]\\n\\n --strict-collection\\n Fail instead of warning on syntax and schema errors in collected inputs\\n\\n --completions \\n Generate tab completion scripts for the specified shell\\n\\n Possible values:\\n - bash: Bourne Again `SHell` (bash)\\n - elvish: Elvish shell\\n - fish: Friendly Interactive `SHell` (fish)\\n - nushell: Nushell\\n - powershell: `PowerShell`\\n - zsh: Z `SHell` (zsh)\\n\\n --fix[=]\\n Fix findings automatically, when available (EXPERIMENTAL)\\n\\n Possible values:\\n - safe: Apply only safe fixes (the default)\\n - unsafe-only: Apply only unsafe fixes\\n - all: Apply all fixes, both safe and unsafe\\n\\n --thanks\\n Emit thank-you messages for zizmor\\'s sponsors\\n\\n -h, --help\\n Print help (see a summary with \\'-h\\')\\n\\n -V, --version\\n Print version\\n', 'sandboxed': False, 'success': True}" } ] }, @@ -147,22 +183,23 @@ "type": "tool_calls", "tool_calls": [ { - "id": "chatcmpl-tool-90714484a7b01774", + "id": "call_e304703be12b45b2becab403", "name": "shell", "arguments": { - "command": "zizmor .github/workflows --format plain", - "timeout": 120 + "command": "zizmor .github/workflows/ --format json --persona regular", + "timeout": 120, + "workdir": "." } } ], - "input_tokens": 16616, - "output_tokens": 67 + "input_tokens": 21776, + "output_tokens": 92 }, "expected_tool_results": [ { - "tool_call_id": "00000001B", - "name": "shell", - "content": "\n{\n \"exit_code\": 2,\n \"output\": \"error: invalid value 'pretty' for '--format '\\n [possible values: plain, json, json-v1, sarif, github]\\n\\nFor more information, try '--help'.\\n\",\n \"sandboxed\": false,\n \"success\": false\n}\n" + "tool_call_id": "call_95972591c0fb4785bd8ddcdb", + "name": "glob", + "content": "{'count': 10, 'duration_ms': 205, 'files': ['.github/workflows/docker.yml', '.github/workflows/e2e.yml', '.github/workflows/pr-label-classify.yml', '.github/workflows/pr-label-scope.yml', '.github/workflows/rebuild-release-image.yml', '.github/workflows/regression-test-check.yml', '.github/workflows/release.yml', '.github/workflows/replay-gate.yml', '.github/workflows/staging-ci.yml', '.github/workflows/test.yml'], 'truncated': True}" } ] }, @@ -172,16 +209,43 @@ "min_message_count": 16 }, "response": { - "type": "text", - "content": "\n\nDone! I ran zizmor on your GitHub Actions workflows and found **security issues across all 14 workflow files**. Here's the summary:\n\n## 🔴 Critical Issues Found\n\n### 1. **Unpinned Action References** (Most Common)\nEvery workflow uses actions like `actions/checkout@v6` instead of pinned SHA hashes. This is a supply chain risk - the action could change without notice.\n\n**Example fixes needed:**\n```yaml\n# Before\nuses: actions/checkout@v6\n\n# After \nuses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v6\n```\n\n### 2. **Dangerous Triggers**\n- `pr-label-classify.yml`, `pr-label-scope.yml`, `release-plz-batch-summary.yml` use `pull_request_target` which is fundamentally insecure when combined with PR code execution.\n\n### 3. **Template Injection Risks**\nMultiple workflows have code injection vulnerabilities where user-controlled input can be expanded into shell commands:\n- `docker.yml` - workflow inputs directly in run blocks\n- `release.yml` - matrix args and tags in commands\n- `regression-test-check.yml` - PR base ref in git commands\n\n### 4. **Excessive Permissions**\n- `coverage.yml` has `id-token: write` at workflow level (too broad)\n- `release.yml` has `contents: write` at workflow level\n- Most workflows use default permissions instead of explicit least-privilege\n\n### 5. **Secrets Outside Environments**\n`release-plz.yml` and `claude-review.yml` access secrets (API keys, private keys) without using dedicated GitHub Environments for protection.\n\n### 6. **Artipacked (Credential Persistence)**\nNearly all `actions/checkout` steps don't set `persist-credentials: false`, leaving Git credentials in the runner artifact.\n\n## 📊 Severity Breakdown\n- **Errors**: 70+ (unpinned uses, dangerous triggers, template injection)\n- **Warnings**: 20+ (excessive permissions, secrets-outside-env)\n- **Help/Info**: 30+ (artipacked, superfluous-actions, template-injection)\n\nWould you like me to:\n1. Generate a SARIF report for GitHub Security tab integration?\n2. Create specific PRs to fix the highest-priority issues?\n3. Focus on one workflow file at a time?\n\n[\"Generate SARIF report for GitHub\", \"Fix unpinned actions in claude-review.yml\", \"Prioritize template injection fixes\"]", - "input_tokens": 34701, - "output_tokens": 611 + "type": "tool_calls", + "tool_calls": [ + { + "id": "call_b2ad3da87b6a4bb3a2b1c479", + "name": "echo", + "arguments": { + "message": "zizmor successfully ran and found security issues. Let me parse and summarize the findings." + } + } + ], + "input_tokens": 40348, + "output_tokens": 78 }, "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-90714484a7b01774", + "tool_call_id": "call_e304703be12b45b2becab403", "name": "shell", - "content": "\n{\n \"exit_code\": 14,\n \"output\": \"help[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/claude-review.yml:23:9\\n |\\n23 | - uses: actions/checkout@v6\\n | _________^\\n24 | | with:\\n25 | | fetch-depth: 0\\n | |________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/claude-review.yml:23:15\\n |\\n23 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/claude-review.yml:28:15\\n |\\n28 | uses: anthropics/claude-code-action@v1\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/claude-review.yml:30:34\\n |\\n18 | review:\\n | ------ this job\\n...\\n30 | anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/code_style.yml:10:7\\n |\\n10 | - name: Checkout repository\\n | _______^\\n11 | | uses: actions/checkout@v6\\n | |_______________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/code_style.yml:23:7\\n |\\n23 | - name: Checkout repository\\n | _______^\\n24 | | uses: actions/checkout@v6\\n | |_______________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/code_style.yml:42:7\\n |\\n42 | - name: Checkout repository\\n | _______^\\n43 | | uses: actions/checkout@v6\\n | |_______________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/code_style.yml:69:7\\n |\\n69 | - name: Checkout repository\\n | _______^\\n70 | | uses: actions/checkout@v6\\n | |_______________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/code_style.yml:85:7\\n |\\n85 | - name: Checkout repository\\n | _______^\\n86 | | uses: actions/checkout@v6\\n87 | | with:\\n88 | | fetch-depth: 0\\n | |______________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:1:1\\n |\\n 1 | / name: Code Style\\n 2 | | on:\\n 3 | | pull_request:\\n... |\\n112 | | exit 1\\n113 | | fi\\n | |_____________^ default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:6:3\\n |\\n 6 | / format:\\n 7 | | name: Formatting\\n 8 | | runs-on: ubuntu-latest\\n 9 | | steps:\\n... |\\n16 | | - name: Check formatting\\n17 | | run: cargo fmt --all -- --check\\n | | ^\\n | | |\\n | |_____________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:19:3\\n |\\n19 | / deny-check:\\n20 | | name: cargo-deny\\n21 | | runs-on: ubuntu-latest\\n22 | | steps:\\n... |\\n25 | | - name: Run cargo deny\\n26 | | uses: EmbarkStudios/cargo-deny-action@v2\\n | | ^\\n | | |\\n | |______________________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:28:3\\n |\\n28 | / clippy:\\n29 | | name: Clippy (${{ matrix.name }})\\n30 | | runs-on: ubuntu-latest\\n31 | | strategy:\\n... |\\n51 | | - name: Check lints\\n52 | | run: cargo clippy --all --benches --tests --examples ${{ matrix.flags }} -- -D warnings\\n | | ^\\n | | |\\n | |_____________________________________________________________________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:54:3\\n |\\n54 | / clippy-windows:\\n55 | | name: Clippy Windows (${{ matrix.name }})\\n56 | | if: github.base_ref == 'main'\\n57 | | runs-on: windows-latest\\n... |\\n78 | | - name: Check lints\\n79 | | run: cargo clippy --all --benches --tests --examples ${{ matrix.flags }} -- -D warnings\\n | | ^\\n | | |\\n | |_____________________________________________________________________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:81:3\\n |\\n81 | / no-panics:\\n82 | | name: No panics in production code\\n83 | | runs-on: ubuntu-latest\\n84 | | steps:\\n... |\\n97 | | # Roll-up job for branch protection\\n | | ^\\n | | |\\n | |_____________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/code_style.yml:98:3\\n |\\n 98 | / code-style:\\n 99 | | name: Code Style (fmt + clippy + deny)\\n100 | | runs-on: ubuntu-latest\\n101 | | if: always()\\n... |\\n112 | | exit 1\\n113 | | fi\\n | | ^\\n | | |\\n | |_____________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:105:22\\n |\\n104 | - run: |\\n | --- this run block\\n105 | if [[ \\\"${{ needs.format.result }}\\\" != \\\"success\\\" || \\\"${{ needs.clippy.result }}\\\" != \\\"success\\\" || \\\"${{ needs.deny-check.res...\\n | ^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:105:67\\n |\\n104 | - run: |\\n | --- this run block\\n105 | if [[ \\\"${{ needs.format.result }}\\\" != \\\"success\\\" || \\\"${{ needs.clippy.result }}\\\" != \\\"success\\\" || \\\"${{ needs.deny-check.res...\\n | ^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:105:112\\n |\\n104 | ... - run: |\\n | --- this run block\\n105 | ... if [[ \\\"${{ needs.format.result }}\\\" != \\\"success\\\" || \\\"${{ needs.clippy.result }}\\\" != \\\"success\\\" || \\\"${{ needs.deny-check.result }}...\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:105:161\\n |\\n104 | ... - run: |\\n | --- this run block\\n105 | ... if [[ \\\"${{ needs.format.result }}\\\" != \\\"success\\\" || \\\"${{ needs.clippy.result }}\\\" != \\\"success\\\" || \\\"${{ needs.deny-check.result }}\\\" != \\\"success\\\" || \\\"${{ needs.no-panics.result }}...\\n | ^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:110:22\\n |\\n104 | - run: |\\n | --- this run block\\n...\\n110 | if [[ \\\"${{ needs.clippy-windows.result }}\\\" != \\\"success\\\" && \\\"${{ needs.clippy-windows.result }}\\\" != \\\"skipped\\\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:110:22\\n |\\n104 | - run: |\\n | --- this run block\\n...\\n110 | if [[ \\\"${{ needs.clippy-windows.result }}\\\" != \\\"success\\\" && \\\"${{ needs.clippy-windows.result }}\\\" != \\\"skipped\\\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/code_style.yml:111:46\\n |\\n104 | - run: |\\n | --- this run block\\n...\\n111 | echo \\\"Windows clippy failed: ${{ needs.clippy-windows.result }}\\\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:11:13\\n |\\n11 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:13:13\\n |\\n13 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:24:13\\n |\\n24 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:26:13\\n |\\n26 | uses: EmbarkStudios/cargo-deny-action@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:43:13\\n |\\n43 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:45:13\\n |\\n45 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:48:13\\n |\\n48 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:70:13\\n |\\n70 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:72:13\\n |\\n72 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:75:13\\n |\\n75 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:86:13\\n |\\n86 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/code_style.yml:89:13\\n |\\n89 | - uses: actions/setup-python@v5\\n | ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/code_style.yml:13:13\\n |\\n12 | - name: Install Rust\\n | ------------------ this step\\n13 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/code_style.yml:45:13\\n |\\n44 | - name: Install Rust\\n | ------------------ this step\\n45 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/code_style.yml:72:13\\n |\\n71 | - name: Install Rust\\n | ------------------ this step\\n72 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/coverage.yml:70:9\\n |\\n70 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/coverage.yml:129:9\\n |\\n129 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> .github/workflows/coverage.yml:35:3\\n |\\n35 | id-token: write\\n | ^^^^^^^^^^^^^^^ id-token: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/coverage.yml:223:22\\n |\\n222 | - run: |\\n | --- this run block\\n223 | if [[ \\\"${{ needs.coverage.result }}\\\" != \\\"success\\\" || \\\"${{ needs.e2e-coverage.result }}\\\" != \\\"success\\\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/coverage.yml:223:69\\n |\\n222 | - run: |\\n | --- this run block\\n223 | if [[ \\\"${{ needs.coverage.result }}\\\" != \\\"success\\\" || \\\"${{ needs.e2e-coverage.result }}\\\" != \\\"success\\\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:70:15\\n |\\n70 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:72:15\\n |\\n72 | - uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:77:15\\n |\\n77 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:82:15\\n |\\n82 | uses: taiki-e/install-action@cargo-llvm-cov\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:116:15\\n |\\n116 | uses: codecov/codecov-action@v5\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:129:15\\n |\\n129 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:131:15\\n |\\n131 | - uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:136:15\\n |\\n136 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:141:15\\n |\\n141 | uses: taiki-e/install-action@cargo-llvm-cov\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:165:15\\n |\\n165 | - uses: actions/setup-python@v5\\n | ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:200:15\\n |\\n200 | uses: codecov/codecov-action@v5\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/coverage.yml:210:15\\n |\\n210 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/coverage.yml:72:15\\n |\\n72 | - uses: dtolnay/rust-toolchain@stable\\n | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n | _________|\\n | |\\n73 | | with:\\n74 | | components: llvm-tools-preview\\n75 | | targets: wasm32-wasip2\\n | |________________________________- this step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/coverage.yml:131:15\\n |\\n131 | - uses: dtolnay/rust-toolchain@stable\\n | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n | _________|\\n | |\\n132 | | with:\\n133 | | components: llvm-tools-preview\\n134 | | targets: wasm32-wasip2\\n | |________________________________- this step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/docker.yml:37:9\\n |\\n37 | - name: Checkout\\n | _________^\\n38 | | uses: actions/checkout@v4\\n39 | | with:\\n40 | | ref: ${{ github.event_name == 'schedule' && 'staging' || '' }}\\n | |________________________________________________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:52:24\\n |\\n51 | run: |\\n | --- this run block\\n52 | VERSION=\\\"${{ steps.version.outputs.version }}\\\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:77:25\\n |\\n51 | run: |\\n | --- this run block\\n...\\n77 | if [[ -n \\\"${{ inputs.tag }}\\\" ]]; then\\n | ^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:77:25\\n |\\n51 | run: |\\n | --- this run block\\n...\\n77 | if [[ -n \\\"${{ inputs.tag }}\\\" ]]; then\\n | ^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:77:25\\n |\\n51 | run: |\\n | --- this run block\\n...\\n77 | if [[ -n \\\"${{ inputs.tag }}\\\" ]]; then\\n | ^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:121:23\\n |\\n115 | run: |\\n | --- this run block\\n...\\n121 | echo \\\"${{ steps.tags.outputs.tags }}\\\" | tr ',' '\\\\n'\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:126:23\\n |\\n115 | run: |\\n | --- this run block\\n...\\n126 | echo \\\"${{ steps.tags.outputs.worker_tags }}\\\" | tr ',' '\\\\n'\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/docker.yml:129:36\\n |\\n115 | run: |\\n | --- this run block\\n...\\n129 | echo \\\"- version: \\\\`${{ steps.version.outputs.version }}\\\\`\\\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/docker.yml:38:15\\n |\\n38 | uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/docker.yml:85:15\\n |\\n85 | uses: docker/setup-buildx-action@v3\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/docker.yml:88:15\\n |\\n88 | uses: docker/login-action@v3\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/docker.yml:94:15\\n |\\n94 | uses: docker/build-push-action@v6\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/docker.yml:104:15\\n |\\n104 | uses: docke\\n\\n... [truncated 1244 bytes] ...\\n\\nd]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/e2e.yml:68:9\\n |\\n68 | - uses: actions/checkout@v6\\n | _________^\\n69 | | with:\\n70 | | ref: ${{ inputs.ref || github.sha }}\\n | |______________________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/e2e.yml:1:1\\n |\\n 1 | / name: E2E Tests\\n 2 | | on:\\n 3 | | workflow_call:\\n 4 | | inputs:\\n... |\\n112 | | exit 1\\n113 | | fi\\n | |_____________^ default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/e2e.yml:21:3\\n |\\n21 | / build:\\n22 | | name: Build ironclaw (libsql)\\n23 | | runs-on: ubuntu-latest\\n24 | | timeout-minutes: 30\\n... |\\n49 | | # ── Step 2: run test slices in parallel ───────────────────────────────────\\n | | ^\\n | | |\\n | |______________________________________________________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/e2e.yml:50:3\\n |\\n 50 | / test:\\n 51 | | name: E2E (${{ matrix.group }})\\n 52 | | needs: build\\n 53 | | runs-on: ubuntu-latest\\n... |\\n102 | | # ── Roll-up for branch protection ────────────────────────────────────────\\n | | ^\\n | | |\\n | |_____________________________________________________________________________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/e2e.yml:103:3\\n |\\n103 | / e2e:\\n104 | | name: E2E Tests\\n105 | | runs-on: ubuntu-latest\\n106 | | if: always()\\n... |\\n112 | | exit 1\\n113 | | fi\\n | | ^\\n | | |\\n | |_____________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/e2e.yml:110:22\\n |\\n109 | - run: |\\n | --- this run block\\n110 | if [[ \\\"${{ needs.test.result }}\\\" != \\\"success\\\" ]]; then\\n | ^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:26:15\\n |\\n26 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:30:15\\n |\\n30 | - uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:32:15\\n |\\n32 | - uses: actions/cache@v4\\n | ^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:43:15\\n |\\n43 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:68:15\\n |\\n68 | - uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:73:15\\n |\\n73 | uses: actions/download-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:81:15\\n |\\n81 | - uses: actions/setup-python@v5\\n | ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/e2e.yml:96:15\\n |\\n96 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/e2e.yml:30:15\\n |\\n30 | - uses: dtolnay/rust-toolchain@stable\\n | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n | | |\\n | | use `rustup` and/or `cargo` in a script step\\n | this step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/pr-label-classify.yml:16:9\\n |\\n16 | - name: Checkout base branch\\n | _________^\\n17 | | uses: actions/checkout@v4\\n18 | | with:\\n19 | | ref: ${{ github.event.pull_request.base.ref }}\\n | |________________________________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> .github/workflows/pr-label-classify.yml:3:1\\n |\\n3 | / on:\\n4 | | pull_request_target:\\n5 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/pr-label-classify.yml:17:15\\n |\\n17 | uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> .github/workflows/pr-label-scope.yml:3:1\\n |\\n3 | / on:\\n4 | | pull_request_target:\\n5 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/pr-label-scope.yml:15:15\\n |\\n15 | - uses: actions/labeler@v5\\n | ^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/regression-test-check.yml:11:9\\n |\\n11 | - name: Checkout repository\\n | _________^\\n12 | | uses: actions/checkout@v4\\n13 | | with:\\n14 | | fetch-depth: 0\\n | |________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> .github/workflows/regression-test-check.yml:7:3\\n |\\n 7 | / regression-test:\\n 8 | | name: Regression test enforcement\\n 9 | | runs-on: ubuntu-latest\\n 10 | | steps:\\n... |\\n183 | | exit 1\\n184 | |\\n | | ^\\n | | |\\n | |_this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[template-injection]: code injection via template expansion\\n --> .github/workflows/regression-test-check.yml:18:32\\n |\\n17 | run: |\\n | --- this run block\\n18 | git fetch origin ${{ github.event.pull_request.base.ref }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[template-injection]: code injection via template expansion\\n --> .github/workflows/regression-test-check.yml:28:32\\n |\\n25 | run: |\\n | --- this run block\\n...\\n28 | BASE_REF=\\\"origin/${{ github.event.pull_request.base.ref }}\\\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/regression-test-check.yml:12:15\\n |\\n12 | uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nhelp[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/release-plz-batch-summary.yml:31:9\\n |\\n31 | - name: Checkout base branch\\n | _________^\\n32 | | uses: actions/checkout@v6\\n33 | | with:\\n34 | | ref: ${{ github.event_name == 'workflow_dispatch' && 'main' || github.event.pull_request.base.ref }}\\n35 | | fetch-depth: 0\\n36 | | fetch-tags: true\\n | |__________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> .github/workflows/release-plz-batch-summary.yml:3:1\\n |\\n 3 | / on:\\n 4 | | workflow_dispatch:\\n 5 | | inputs:\\n 6 | | pr_number:\\n... |\\n15 | | pull_request_target:\\n16 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz-batch-summary.yml:32:15\\n |\\n32 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:20:15\\n |\\n20 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:26:15\\n |\\n26 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:27:15\\n |\\n27 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:31:15\\n |\\n31 | uses: actions/create-github-app-token@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:39:15\\n |\\n39 | uses: release-plz/action@v0.5\\n | ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:20:15\\n |\\n20 | uses: actions/checkout@v6\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:26:15\\n |\\n26 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:60:15\\n |\\n60 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:62:15\\n |\\n62 | uses: actions/create-github-app-token@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release-plz.yml:68:15\\n |\\n68 | uses: release-plz/action@v0.5\\n | ^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/release-plz.yml:35:23\\n |\\n11 | release-plz-release:\\n | ------------------- this job\\n...\\n35 | app-id: ${{ secrets.GH_RELEASES_MANAGER_APP_ID }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/release-plz.yml:37:28\\n |\\n11 | release-plz-release:\\n | ------------------- this job\\n...\\n37 | private-key: ${{ secrets.GH_RELEASES_MANAGER_APP_PRIVATE_KEY }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/release-plz.yml:44:37\\n |\\n11 | release-plz-release:\\n | ------------------- this job\\n...\\n44 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/release-plz.yml:65:23\\n |\\n47 | release-plz-pr:\\n | -------------- this job\\n...\\n65 | app-id: ${{ secrets.GH_RELEASES_MANAGER_APP_ID }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/release-plz.yml:66:28\\n |\\n47 | release-plz-pr:\\n | -------------- this job\\n...\\n66 | private-key: ${{ secrets.GH_RELEASES_MANAGER_APP_PRIVATE_KEY }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nwarning[secrets-outside-env]: secrets referenced without a dedicated environment\\n --> .github/workflows/release-plz.yml:73:37\\n |\\n47 | release-plz-pr:\\n | -------------- this job\\n...\\n73 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ secret is accessed outside of a dedicated environment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-outside-env\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/release-plz.yml:26:15\\n |\\n25 | name: Install Rust toolchain\\n | ---------------------------- this step\\n26 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nhelp[superfluous-actions]: action functionality is already included by the runner\\n --> .github/workflows/release-plz.yml:26:15\\n |\\n25 | name: Install Rust toolchain\\n | ---------------------------- this step\\n26 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> .github/workflows/release.yml:467:9\\n |\\n467 | - uses: actions/checkout@v4\\n | _________^\\n468 | | with:\\n469 | | ref: main\\n | |___________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> .github/workflows/release.yml:18:3\\n |\\n18 | \\\"contents\\\": \\\"write\\\"\\n | ^^^^^^^^^^^^^^^^^^^ contents: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:79:91\\n |\\n78 | run: |\\n | --- this run block\\n79 | dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-fo...\\n | ^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nwarning[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:136:18\\n |\\n136 | run: ${{ matrix.install_dist.run }}\\n | --- ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n | |\\n | this run block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nwarning[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:181:15\\n |\\n180 | run: |\\n | --- this run block\\n181 | ${{ matrix.packages_install }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:185:26\\n |\\n183 | ... run: |\\n | --- this run block\\n184 | ... # Actually do builds and make zips and whatnot\\n185 | ... dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest....\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nwarning[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:185:98\\n |\\n183 | run: |\\n | --- this run block\\n184 | # Actually do builds and make zips and whatnot\\n185 | dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifes...\\n | ^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:238:26\\n |\\n237 | run: |\\n | --- this run block\\n238 | dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json \\\"--artifacts=global\\\" > dist-manifest.json\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:419:25\\n |\\n418 | run: |\\n | --- this run block\\n419 | dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> .github/workflows/release.yml:450:34\\n |\\n446 | ... run: |\\n | --- this run block\\n...\\n450 | ... gh release create \\\"${{ needs.plan.outputs.tag }}\\\" --target \\\"$RELEASE_COMMIT\\\" $PRERELEASE_FLAG --title \\\"$ANNOUNCEMENT_TITLE\\\"...\\n | ^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:58:15\\n |\\n58 | - uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:68:15\\n |\\n68 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:84:15\\n |\\n84 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:120:15\\n |\\n120 | - uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:131:15\\n |\\n131 | - uses: swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:139:15\\n |\\n139 | uses: actions/download-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:201:15\\n |\\n201 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:218:15\\n |\\n218 | - uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:223:15\\n |\\n223 | uses: actions/download-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:230:15\\n |\\n230 | uses: actions/download-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:248:15\\n |\\n248 | uses: actions/upload-artifact@v4\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:263:15\\n |\\n263 | - uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:271:15\\n |\\n271 | - uses: swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> .github/workflows/release.yml:377:15\\n |\\n377 | uses: actions/upload-artifact@v4\\n \\n\\n--- stderr ---\\n🌈 zizmor v1.23.1\\n INFO audit: zizmor: 🌈 completed .github/workflows/claude-review.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/code_style.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/coverage.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/docker.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/e2e.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/pr-label-classify.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/pr-label-scope.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/regression-test-check.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/release-plz-batch-summary.yml\\n WARN audit: zizmor: one or more inputs contains YAML anchors; you may encounter crashes or unpredictable behavior\\n WARN audit: zizmor: for more information, see: https://docs.zizmor.sh/usage/#yaml-anchors\\n INFO audit: zizmor: 🌈 completed .github/workflows/release-plz.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/release.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/staging-ci.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/staging-promotion-metadata.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/test.yml\\n\",\n \"sandboxed\": false,\n \"success\": false\n}\n" + "content": "{'exit_code': 14, 'output': '[\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"High\",\\n \"severity\": \"High\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/code_style.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"clippy-matrix\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 0\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 75,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 87,\\n \"column\": 12\\n },\\n \"offset_span\": {\\n \"start\": 2750,\\n \"end\": 3471\\n }\\n },\\n \"feature\": \"id: set\\\\n run: |\\\\n FULL=\\'[{\\\\\"name\\\\\":\\\\\"all-features\\\\\",\\\\\"flags\\\\\":\\\\\"--all-features\\\\\"},{\\\\\"name\\\\\":\\\\\"default\\\\\",\\\\\"flags\\\\\":\\\\\"\\\\\"},{\\\\\"name\\\\\":\\\\\"libsql-only\\\\\",\\\\\"flags\\\\\":\\\\\"--no-default-features --features libsql\\\\\"}]\\'\\\\n SLIM=\\'[{\\\\\"name\\\\\":\\\\\"all-features\\\\\",\\\\\"flags\\\\\":\\\\\"--all-features\\\\\"}]\\'\\\\n\\\\n # Full matrix on push (cache-warming + verification across configs)\\\\n # and on PRs targeting main (final promotion gate). Other PRs use\\\\n # SLIM since lint findings are almost never feature-gated.\\\\n if [ \\\\\"${{ github.event_name }}\\\\\" = \\\\\"push\\\\\" ] || [ \\\\\"${{ github.base_ref }}\\\\\" = \\\\\"main\\\\\" ]; then\\\\n echo \\\\\"matrix=${FULL}\\\\\" >> \\\\\"$GITHUB_OUTPUT\\\\\"\\\\n else\\\\n echo \\\\\"matrix=${SLIM}\\\\\" >> \\\\\"$GITHUB_OUTPUT\\\\\"\\\\n fi\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/code_style.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"clippy-matrix\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 0\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 463,\\n \"fragment\": {\\n \"Raw\": \"github.base_ref\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 83,\\n \"column\": 63\\n },\\n \"end_point\": {\\n \"row\": 83,\\n \"column\": 78\\n },\\n \"offset_span\": {\\n \"start\": 3299,\\n \"end\": 3314\\n }\\n },\\n \"feature\": \"|\\\\n FULL=\\'[{\\\\\"name\\\\\":\\\\\"all-features\\\\\",\\\\\"flags\\\\\":\\\\\"--all-features\\\\\"},{\\\\\"name\\\\\":\\\\\"default\\\\\",\\\\\"flags\\\\\":\\\\\"\\\\\"},{\\\\\"name\\\\\":\\\\\"libsql-only\\\\\",\\\\\"flags\\\\\":\\\\\"--no-default-features --features libsql\\\\\"}]\\'\\\\n SLIM=\\'[{\\\\\"name\\\\\":\\\\\"all-features\\\\\",\\\\\"flags\\\\\":\\\\\"--all-features\\\\\"}]\\'\\\\n\\\\n # Full matrix on push (cache-warming + verification across configs)\\\\n # and on PRs targeting main (final promotion gate). Other PRs use\\\\n # SLIM since lint findings are almost never feature-gated.\\\\n if [ \\\\\"${{ github.event_name }}\\\\\" = \\\\\"push\\\\\" ] || [ \\\\\"${{ github.base_ref }}\\\\\" = \\\\\"main\\\\\" ]; then\\\\n echo \\\\\"matrix=${FULL}\\\\\" >> \\\\\"$GITHUB_OUTPUT\\\\\"\\\\n else\\\\n echo \\\\\"matrix=${SLIM}\\\\\" >> \\\\\"$GITHUB_OUTPUT\\\\\"\\\\n fi\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/code_style.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"clippy-matrix\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 0\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 76,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 76,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 2766,\\n \"end\": 2769\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/code_style.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"code-style\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 0\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 269,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 303,\\n \"column\": 0\\n },\\n \"offset_span\": {\\n \"start\": 10691,\\n \"end\": 12078\\n }\\n },\\n \"feature\": \"run: |\\\\n # Docs-only PRs intentionally skip every gated job — that\\'s a pass.\\\\n if [[ \\\\\"${{ needs.changes.outputs.has_code }}\\\\\" == \\\\\"false\\\\\" ]]; then\\\\n echo \\\\\"No code changes — style checks skipped correctly\\\\\"\\\\n exit 0\\\\n fi\\\\n\\\\n # Always-required jobs.\\\\n for job_result in \\\\\\\\\\\\n \\\\\"format=${{ needs.format.result }}\\\\\" \\\\\\\\\\\\n \\\\\"gateway-js-syntax=${{ needs.gateway-js-syntax.result }}\\\\\" \\\\\\\\\\\\n \\\\\"clippy=${{ needs.clippy.result }}\\\\\" \\\\\\\\\\\\n \\\\\"deny-check=${{ needs.deny-check.result }}\\\\\" \\\\\\\\\\\\n \\\\\"gateway-boundaries=${{ needs.gateway-boundaries.result }}\\\\\"; do\\\\n name=\\\\\"${job_result%%=*}\\\\\"\\\\n result=\\\\\"${job_result##*=}\\\\\"\\\\n if [[ \\\\\"$result\\\\\" != \\\\\"success\\\\\" ]]; then\\\\n echo \\\\\"$name failed: $result\\\\\"\\\\n exit 1\\\\n fi\\\\n done\\\\n\\\\n # Conditional jobs: must succeed when run, may be skipped on\\\\n # events where their `if:` filter excludes them.\\\\n for job_result in \\\\\\\\\\\\n \\\\\"no-panics=${{ needs.no-panics.result }}\\\\\" \\\\\\\\\\\\n \\\\\"clippy-windows=${{ needs.clippy-windows.result }}\\\\\"; do\\\\n name=\\\\\"${job_result%%=*}\\\\\"\\\\n result=\\\\\"${job_result##*=}\\\\\"\\\\n if [[ \\\\\"$result\\\\\" != \\\\\"success\\\\\" && \\\\\"$result\\\\\" != \\\\\"skipped\\\\\" ]]; then\\\\n echo \\\\\"$name failed: $result\\\\\"\\\\n exit 1\\\\n fi\\\\n done\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/code_style.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"code-style\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 0\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 78,\\n \"fragment\": {\\n \"Raw\": \"needs.changes.outputs.has_code\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 271,\\n \"column\": 21\\n },\\n \"end_point\": {\\n \"row\": 271,\\n \"column\": 51\\n },\\n \"offset_span\": {\\n \"start\": 10799,\\n \"end\": 10829\\n }\\n },\\n \"feature\": \"|\\\\n # Docs-only PRs intentionally skip every gated job — that\\'s a pass.\\\\n if [[ \\\\\"${{ needs.changes.outputs.has_code }}\\\\\" == \\\\\"false\\\\\" ]]; then\\\\n echo \\\\\"No code changes — style checks skipped correctly\\\\\"\\\\n exit 0\\\\n fi\\\\n\\\\n # Always-required jobs.\\\\n for job_result in \\\\\\\\\\\\n \\\\\"format=${{ needs.format.result }}\\\\\" \\\\\\\\\\\\n \\\\\"gateway-js-syntax=${{ needs.gateway-js-syntax.result }}\\\\\" \\\\\\\\\\\\n \\\\\"clippy=${{ needs.clippy.result }}\\\\\" \\\\\\\\\\\\n \\\\\"deny-check=${{ needs.deny-check.result }}\\\\\" \\\\\\\\\\\\n \\\\\"gateway-boundaries=${{ needs.gateway-boundaries.result }}\\\\\"; do\\\\n name=\\\\\"${job_result%%=*}\\\\\"\\\\n result=\\\\\"${job_result##*=}\\\\\"\\\\n if [[ \\\\\"$result\\\\\" != \\\\\"success\\\\\" ]]; then\\\\n echo \\\\\"$name failed: $result\\\\\"\\\\n exit 1\\\\n fi\\\\n done\\\\n\\\\n # Conditional jobs: must succeed when run, may be skipped on\\\\n # events where their `if:` filter excludes them.\\\\n for job_result in \\\\\\\\\\\\n \\\\\"no-panics=${{ needs.no-panics.result }}\\\\\" \\\\\\\\\\\\n \\\\\"clippy-windows=${{ needs.clippy-windows.result }}\\\\\"; do\\\\n name=\\\\\"${job_result%%=*}\\\\\"\\\\n result=\\\\\"${job_result##*=}\\\\\"\\\\n if [[ \\\\\"$result\\\\\" != \\\\\"success\\\\\" && \\\\\"$result\\\\\" != \\\\\"skipped\\\\\" ]]; then\\\\n echo \\\\\"$name failed: $result\\\\\"\\\\n exit 1\\\\n fi\\\\n done\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/code_style.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"code-style\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 0\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 269,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 269,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 10691,\\n \"end\": 10694\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 199,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 217,\\n \"column\": 37\\n },\\n \"offset_span\": {\\n \"start\": 7741,\\n \"end\": 8399\\n }\\n },\\n \"feature\": \"name: Summary\\\\n if: steps.check.outputs.skip != \\'true\\'\\\\n run: |\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 83,\\n \"fragment\": {\\n \"Raw\": \"steps.tags.outputs.tags\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 207,\\n \"column\": 22\\n },\\n \"end_point\": {\\n \"row\": 207,\\n \"column\": 45\\n },\\n \"offset_span\": {\\n \"start\": 7963,\\n \"end\": 7986\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 201,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 201,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 7810,\\n \"end\": 7813\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 199,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 217,\\n \"column\": 37\\n },\\n \"offset_span\": {\\n \"start\": 7741,\\n \"end\": 8399\\n }\\n },\\n \"feature\": \"name: Summary\\\\n if: steps.check.outputs.skip != \\'true\\'\\\\n run: |\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 203,\\n \"fragment\": {\\n \"Raw\": \"steps.tags.outputs.worker_tags\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 212,\\n \"column\": 22\\n },\\n \"end_point\": {\\n \"row\": 212,\\n \"column\": 52\\n },\\n \"offset_span\": {\\n \"start\": 8133,\\n \"end\": 8163\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 201,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 201,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 7810,\\n \"end\": 7813\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 199,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 217,\\n \"column\": 37\\n },\\n \"offset_span\": {\\n \"start\": 7741,\\n \"end\": 8399\\n }\\n },\\n \"feature\": \"name: Summary\\\\n if: steps.check.outputs.skip != \\'true\\'\\\\n run: |\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 300,\\n \"fragment\": {\\n \"Raw\": \"steps.version.outputs.version\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 215,\\n \"column\": 35\\n },\\n \"end_point\": {\\n \"row\": 215,\\n \"column\": 64\\n },\\n \"offset_span\": {\\n \"start\": 8260,\\n \"end\": 8289\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 201,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 201,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 7810,\\n \"end\": 7813\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 199,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 217,\\n \"column\": 37\\n },\\n \"offset_span\": {\\n \"start\": 7741,\\n \"end\": 8399\\n }\\n },\\n \"feature\": \"name: Summary\\\\n if: steps.check.outputs.skip != \\'true\\'\\\\n run: |\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 357,\\n \"fragment\": {\\n \"Raw\": \"steps.source_sha.outputs.sha\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 216,\\n \"column\": 31\\n },\\n \"end_point\": {\\n \"row\": 216,\\n \"column\": 59\\n },\\n \"offset_span\": {\\n \"start\": 8327,\\n \"end\": 8355\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Docker Images\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"**ironclaw-worker:**\\\\\"\\\\n echo \\'```\\'\\\\n echo \\\\\"${{ steps.tags.outputs.worker_tags }}\\\\\" | tr \\',\\' \\'\\\\\\\\n\\'\\\\n echo \\'```\\'\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 11\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 201,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 201,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 7810,\\n \"end\": 7813\\n }\\n },\\n \"feature\": \"run\",\\n \"comme\\n\\n... [truncated 1324 bytes] ...\\n\\n}\\n },\\n \"feature\": \"name: Summary (skipped)\\\\n if: steps.check.outputs.skip == \\'true\\'\\\\n run: |\\\\n {\\\\n echo \\\\\"## Docker Images — skipped\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"Current commit already built for \\\\\\\\`${IMAGE_NAME}:staging\\\\\\\\`.\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 12\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 137,\\n \"fragment\": {\\n \"Raw\": \"steps.source_sha.outputs.sha\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 226,\\n \"column\": 31\\n },\\n \"end_point\": {\\n \"row\": 226,\\n \"column\": 59\\n },\\n \"offset_span\": {\\n \"start\": 8685,\\n \"end\": 8713\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Docker Images — skipped\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"Current commit already built for \\\\\\\\`${IMAGE_NAME}:staging\\\\\\\\`.\\\\\"\\\\n echo \\\\\"- sha: \\\\\\\\`${{ steps.source_sha.outputs.sha }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/docker.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 12\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 221,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 221,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 8488,\\n \"end\": 8491\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"dangerous-triggers\",\\n \"desc\": \"use of fundamentally insecure workflow trigger\",\\n \"url\": \"https://docs.zizmor.sh/audits/#dangerous-triggers\",\\n \"determinations\": {\\n \"confidence\": \"Medium\",\\n \"severity\": \"High\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/pr-label-classify.yml\"\\n }\\n },\\n \"annotation\": \"pull_request_target is almost always used insecurely\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"on\"\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 2,\\n \"column\": 0\\n },\\n \"end_point\": {\\n \"row\": 4,\\n \"column\": 42\\n },\\n \"offset_span\": {\\n \"start\": 48,\\n \"end\": 117\\n }\\n },\\n \"feature\": \"on:\\\\n pull_request_target:\\\\n types: [opened, synchronize, reopened]\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"dangerous-triggers\",\\n \"desc\": \"use of fundamentally insecure workflow trigger\",\\n \"url\": \"https://docs.zizmor.sh/audits/#dangerous-triggers\",\\n \"determinations\": {\\n \"confidence\": \"Medium\",\\n \"severity\": \"High\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/pr-label-scope.yml\"\\n }\\n },\\n \"annotation\": \"pull_request_target is almost always used insecurely\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"on\"\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 2,\\n \"column\": 0\\n },\\n \"end_point\": {\\n \"row\": 4,\\n \"column\": 42\\n },\\n \"offset_span\": {\\n \"start\": 26,\\n \"end\": 95\\n }\\n },\\n \"feature\": \"on:\\\\n pull_request_target:\\\\n types: [opened, synchronize, reopened]\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"High\",\\n \"severity\": \"High\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 109,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 120,\\n \"column\": 0\\n },\\n \"offset_span\": {\\n \"start\": 3709,\\n \"end\": 4220\\n }\\n },\\n \"feature\": \"name: Summary\\\\n run: |\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 70,\\n \"fragment\": {\\n \"Raw\": \"inputs.source_ref\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 114,\\n \"column\": 38\\n },\\n \"end_point\": {\\n \"row\": 114,\\n \"column\": 55\\n },\\n \"offset_span\": {\\n \"start\": 3851,\\n \"end\": 3868\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 110,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 110,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 3731,\\n \"end\": 3734\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 109,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 120,\\n \"column\": 0\\n },\\n \"offset_span\": {\\n \"start\": 3709,\\n \"end\": 4220\\n }\\n },\\n \"feature\": \"name: Summary\\\\n run: |\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 122,\\n \"fragment\": {\\n \"Raw\": \"steps.source.outputs.sha\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 115,\\n \"column\": 38\\n },\\n \"end_point\": {\\n \"row\": 115,\\n \"column\": 62\\n },\\n \"offset_span\": {\\n \"start\": 3913,\\n \"end\": 3937\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 110,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 110,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 3731,\\n \"end\": 3734\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 109,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 120,\\n \"column\": 0\\n },\\n \"offset_span\": {\\n \"start\": 3709,\\n \"end\": 4220\\n }\\n },\\n \"feature\": \"name: Summary\\\\n run: |\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 178,\\n \"fragment\": {\\n \"Raw\": \"steps.version.outputs.version\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 116,\\n \"column\": 35\\n },\\n \"end_point\": {\\n \"row\": 116,\\n \"column\": 64\\n },\\n \"offset_span\": {\\n \"start\": 3979,\\n \"end\": 4008\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 110,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 110,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 3731,\\n \"end\": 3734\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"Low\",\\n \"severity\": \"Informational\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 109,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 120,\\n \"column\": 0\\n },\\n \"offset_span\": {\\n \"start\": 3709,\\n \"end\": 4220\\n }\\n },\\n \"feature\": \"name: Summary\\\\n run: |\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 254,\\n \"fragment\": {\\n \"Raw\": \"steps.target.outputs.has_runtime_stage\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 117,\\n \"column\": 50\\n },\\n \"end_point\": {\\n \"row\": 117,\\n \"column\": 88\\n },\\n \"offset_span\": {\\n \"start\": 4065,\\n \"end\": 4103\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 110,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 110,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 3731,\\n \"end\": 3734\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"template-injection\",\\n \"desc\": \"code injection via template expansion\",\\n \"url\": \"https://docs.zizmor.sh/audits/#template-injection\",\\n \"determinations\": {\\n \"confidence\": \"High\",\\n \"severity\": \"High\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this step\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Hidden\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 109,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 120,\\n \"column\": 0\\n },\\n \"offset_span\": {\\n \"start\": 3709,\\n \"end\": 4220\\n }\\n },\\n \"feature\": \"name: Summary\\\\n run: |\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"may expand into attacker-controllable code\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": {\\n \"Subfeature\": {\\n \"after\": 344,\\n \"fragment\": {\\n \"Raw\": \"inputs.tag\"\\n }\\n }\\n },\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 118,\\n \"column\": 55\\n },\\n \"end_point\": {\\n \"row\": 118,\\n \"column\": 65\\n },\\n \"offset_span\": {\\n \"start\": 4165,\\n \"end\": 4175\\n }\\n },\\n \"feature\": \"|\\\\n {\\\\n echo \\\\\"## Rebuilt Docker Image\\\\\"\\\\n echo \\\\\"\\\\\"\\\\n echo \\\\\"- source ref: \\\\\\\\`${{ inputs.source_ref }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- source sha: \\\\\\\\`${{ steps.source.outputs.sha }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- version: \\\\\\\\`${{ steps.version.outputs.version }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- runtime stage detected: \\\\\\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\\\\\`\\\\\"\\\\n echo \\\\\"- image: \\\\\\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\\\\\`\\\\\"\\\\n } >> \\\\\"$GITHUB_STEP_SUMMARY\\\\\"\\\\n\",\\n \"comments\": []\\n }\\n },\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/rebuild-release-image.yml\"\\n }\\n },\\n \"annotation\": \"this run block\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"jobs\"\\n },\\n {\\n \"Key\": \"build\"\\n },\\n {\\n \"Key\": \"steps\"\\n },\\n {\\n \"Index\": 9\\n },\\n {\\n \"Key\": \"run\"\\n }\\n ]\\n },\\n \"feature_kind\": \"KeyOnly\",\\n \"kind\": \"Related\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 110,\\n \"column\": 8\\n },\\n \"end_point\": {\\n \"row\": 110,\\n \"column\": 11\\n },\\n \"offset_span\": {\\n \"start\": 3731,\\n \"end\": 3734\\n }\\n },\\n \"feature\": \"run\",\\n \"comments\": []\\n }\\n }\\n ],\\n \"ignored\": false\\n },\\n {\\n \"ident\": \"dangerous-triggers\",\\n \"desc\": \"use of fundamentally insecure workflow trigger\",\\n \"url\": \"https://docs.zizmor.sh/audits/#dangerous-triggers\",\\n \"determinations\": {\\n \"confidence\": \"Medium\",\\n \"severity\": \"High\",\\n \"persona\": \"Regular\"\\n },\\n \"locations\": [\\n {\\n \"symbolic\": {\\n \"key\": {\\n \"Local\": {\\n \"prefix\": \".github/workflows/\",\\n \"given_path\": \".github/workflows/release-plz-batch-summary.yml\"\\n }\\n },\\n \"annotation\": \"pull_request_target is almost always used insecurely\",\\n \"route\": {\\n \"route\": [\\n {\\n \"Key\": \"on\"\\n }\\n ]\\n },\\n \"feature_kind\": \"Normal\",\\n \"kind\": \"Primary\"\\n },\\n \"concrete\": {\\n \"location\": {\\n \"start_point\": {\\n \"row\": 2,\\n \"column\": 0\\n \\n\\n--- stderr ---\\n INFO zizmor: 🌈 zizmor v1.24.1\\n INFO audit: zizmor: 🌈 completed .github/workflows/claude-review.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/code_style.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/coverage.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/docker.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/e2e.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/pr-label-classify.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/pr-label-scope.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/rebuild-release-image.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/regression-test-check.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/release-plz-batch-summary.yml\\n WARN audit: zizmor: one or more inputs contains YAML anchors; see https://docs.zizmor.sh/usage/#yaml-anchors for details\\n INFO audit: zizmor: 🌈 completed .github/workflows/release-plz.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/release.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/replay-gate.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/staging-ci.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/staging-promotion-metadata.yml\\n INFO audit: zizmor: 🌈 completed .github/workflows/test.yml\\n', 'sandboxed': False, 'success': False}" + } + ] + }, + { + "request_hint": { + "last_user_message_contains": "can we run https://github.com/zizmorcore/zizmor", + "min_message_count": 18 + }, + "response": { + "type": "text", + "content": "\n\nYes, zizmor can be run! It's already installed (v1.24.1) and I just ran it on the repository's GitHub workflows. Here's what it found:\n\n## Summary\n\n**Exit code 14** indicates security issues were detected.\n\n### Critical Findings\n\n#### 1. **Dangerous Triggers** (High Severity, Medium Confidence)\n- **`.github/workflows/pr-label-classify.yml`** - Uses `pull_request_target` trigger\n- **`.github/workflows/pr-label-scope.yml`** - Uses `pull_request_target` trigger\n- **`.github/workflows/release-plz-batch-summary.yml`** - Uses `pull_request_target` trigger\n\n`pull_request_target` is fundamentally insecure because it runs in the context of the base branch with write permissions, making it vulnerable to code injection from PRs.\n\n#### 2. **Template Injection** (High Severity, High Confidence)\nMultiple workflows have unsafe template expansions that could allow code injection:\n\n- **`.github/workflows/code_style.yml`** - Lines 83 (`github.base_ref`), 271 (`needs.changes.outputs.has_code`)\n- **`.github/workflows/rebuild-release-image.yml`** - Lines 114-118 (`inputs.source_ref`, `inputs.tag`, `steps.*.outputs.*`)\n\nThese inject user-controllable data directly into shell commands via `${{ }}` expressions.\n\n#### 3. **Template Injection** (Informational Severity, Low Confidence)\nSeveral `GITHUB_STEP_SUMMARY` injections in:\n- `.github/workflows/docker.yml` - Metadata output steps\n- `.github/workflows/rebuild-release-image.yml` - Summary generation\n\n### Recommendation\n\n1. **High Priority**: Replace `pull_request_target` with safer alternatives like `pull_request` + approved checks\n2. **Medium Priority**: Sanitize template injections by using environment variables or avoiding direct expansion of user input\n3. **Consider**: Running zizmor as a CI check on all PRs to catch new issues\n\nWould you like me to analyze specific workflow files in more detail or suggest fixes for these issues?", + "input_tokens": 40414, + "output_tokens": 553 + }, + "expected_tool_results": [ + { + "tool_call_id": "call_b2ad3da87b6a4bb3a2b1c479", + "name": "echo", + "content": "zizmor successfully ran and found security issues. Let me parse and summarize the findings." } ] } diff --git a/tests/fixtures/llm_traces/live/zizmor_scan.log b/tests/fixtures/llm_traces/live/zizmor_scan.log index cad8d83eb6..4db40494f8 100644 --- a/tests/fixtures/llm_traces/live/zizmor_scan.log +++ b/tests/fixtures/llm_traces/live/zizmor_scan.log @@ -1,135 +1,84 @@ # Live Test Session: zizmor_scan -# Mode: Replay -# LLM calls: 8, Input tokens: 143884, Output tokens: 1410 -# Wall time: 0.9s, Cost: $0.0000 +# Mode: Live +# LLM calls: 9, Input tokens: 223223, Output tokens: 1425 +# Wall time: 32.3s, Cost: $0.0000 # ────────────────────────────────────────────────── -› can we run https://github.com/zizmorcore/zizmor - ○ Processing... - ○ Thinking (step 1)... - ○ Running tool_search... - ● tool_search - ✓ tool_search - tool_search → { - "count": 0, - "results": [], - "searched_online": false -} - ○ Thinking (step 2)... - ○ Running command... - ● shell - ✓ shell - shell → { - "exit_code": 0, - "output": "/Users/coder/.cargo/bin/zizmor\n", - "sandboxed": false, - "success": true -} - ○ Thinking (step 3)... - ○ Running list_dir... - ● list_dir - ✓ list_dir - list_dir → { - "count": 70, - "entries": [ - ".claude/", - ".git/", - ".githooks/", - ".github/", - "channels-src/", - "crates/", - "deploy/", - "docker/", - "docs/", - "fuzz/", - "migratio… - ○ Thinking (step 4)... - ○ Running list_dir... - ● list_dir - ✓ list_dir - list_dir → { - "count": 4, - "entries": [ - "scripts/", - "workflows/", - "labeler.yml (3.4KB)", - "pull_request_template.md (1.7KB)" - ], - "path": "/Users/coder/ironclaw8/.github", - "truncated": false… - ○ Thinking (step 5)... - ○ Running list_dir... - ● list_dir - ✓ list_dir - list_dir → { - "count": 14, - "entries": [ - "claude-review.yml (5.3KB)", - "code_style.yml (3.3KB)", - "coverage.yml (6.9KB)", - "docker.yml (4.3KB)", - "e2e.yml (4.0KB)", - "pr-label-classify.yml (… - ○ Thinking (step 6)... - ○ Running command... - ● shell - ✓ shell - shell → { - "exit_code": 2, - "output": "error: invalid value 'pretty' for '--format '\n [possible values: plain, json, json-v1, sarif, github]\n\nFor more information, try '--help'.\n", - "sandboxed… - ○ Thinking (step 7)... - ○ Running command... - ● shell - ✓ shell - shell → { - "exit_code": 14, - "output": "help[artipacked]: credential persistence through GitHub Actions artifacts\n --> .github/workflows/claude-review.yml:23:9\n |\n23 | - uses: actions/checkout… - ○ Thinking (step 8)... - … Done +## Turn 1 +[USER] › can we run https://github.com/zizmorcore/zizmor ──────────────────────────────────────────────────── -Done! I ran zizmor on your GitHub Actions workflows and found **security issues across all 14 workflow files**. Here's the summary: -## 🔴 Critical Issues Found -### 1. **Unpinned Action References** (Most Common) -Every workflow uses actions like `actions/checkout@v6` instead of pinned SHA hashes. This is a supply chain risk - the action could change without notice. +Yes, zizmor can be run! It's already installed (v1.24.1) and I just ran it on the repository's GitHub workflows. Here's what it found: -**Example fixes needed:** -```yaml -# Before -uses: actions/checkout@v6 +## Summary -# After -uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v6 -``` +**Exit code 14** indicates security issues were detected. -### 2. **Dangerous Triggers** -- `pr-label-classify.yml`, `pr-label-scope.yml`, `release-plz-batch-summary.yml` use `pull_request_target` which is fundamentally insecure when combined with PR code execution. +### Critical Findings -### 3. **Template Injection Risks** -Multiple workflows have code injection vulnerabilities where user-controlled input can be expanded into shell commands: -- `docker.yml` - workflow inputs directly in run blocks -- `release.yml` - matrix args and tags in commands -- `regression-test-check.yml` - PR base ref in git commands +#### 1. **Dangerous Triggers** (High Severity, Medium Confidence) +- **`.github/workflows/pr-label-classify.yml`** - Uses `pull_request_target` trigger +- **`.github/workflows/pr-label-scope.yml`** - Uses `pull_request_target` trigger +- **`.github/workflows/release-plz-batch-summary.yml`** - Uses `pull_request_target` trigger -### 4. **Excessive Permissions** -- `coverage.yml` has `id-token: write` at workflow level (too broad) -- `release.yml` has `contents: write` at workflow level -- Most workflows use default permissions instead of explicit least-privilege +`pull_request_target` is fundamentally insecure because it runs in the context of the base branch with write permissions, making it vulnerable to code injection from PRs. -### 5. **Secrets Outside Environments** -`release-plz.yml` and `claude-review.yml` access secrets (API keys, private keys) without using dedicated GitHub Environments for protection. +#### 2. **Template Injection** (High Severity, High Confidence) +Multiple workflows have unsafe template expansions that could allow code injection: -### 6. **Artipacked (Credential Persistence)** -Nearly all `actions/checkout` steps don't set `persist-credentials: false`, leaving Git credentials in the runner artifact. +- **`.github/workflows/code_style.yml`** - Lines 83 (`github.base_ref`), 271 (`needs.changes.outputs.has_code`) +- **`.github/workflows/rebuild-release-image.yml`** - Lines 114-118 (`inputs.source_ref`, `inputs.tag`, `steps.*.outputs.*`) -## 📊 Severity Breakdown -- **Errors**: 70+ (unpinned uses, dangerous triggers, template injection) -- **Warnings**: 20+ (excessive permissions, secrets-outside-env) -- **Help/Info**: 30+ (artipacked, superfluous-actions, template-injection) +These inject user-controllable data directly into shell commands via `${{ }}` expressions. -Would you like me to: -1. Generate a SARIF report for GitHub Security tab integration? -2. Create specific PRs to fix the highest-priority issues? -3. Focus on one workflow file at a time? +#### 3. **Template Injection** (Informational Severity, Low Confidence) +Several `GITHUB_STEP_SUMMARY` injections in: +- `.github/workflows/docker.yml` - Metadata output steps +- `.github/workflows/rebuild-release-image.yml` - Summary generation + +### Recommendation + +1. **High Priority**: Replace `pull_request_target` with safer alternatives like `pull_request` + approved checks +2. **Medium Priority**: Sanitize template injections by using environment variables or avoiding direct expansion of user input +3. **Consider**: Running zizmor as a CI check on all PRs to catch new issues + +Would you like me to analyze specific workflow files in more detail or suggest fixes for these issues? + +## Activity + ○ Processing... + ○ Calling LLM... + ○ Step complete — 19610 in / 104 out tokens + ● shell(which zizmor || cargo install --version 1.11.1 zizmor 2>&1 |...) + ✓ shell(which zizmor || cargo install --version 1.11.1 zizmor 2>&1 |...) + ○ Calling LLM... + ○ Step complete — 19717 in / 127 out tokens + ● shell(cd /tmp && git clone --depth 1 https://github.com/zizmorcore...) + ✓ shell(cd /tmp && git clone --depth 1 https://github.com/zizmorcore...) + ○ Calling LLM... + ○ Step complete — 19827 in / 91 out tokens + ● shell(zizmor --version) + ✓ shell(zizmor --version) + ○ Calling LLM... + ○ Step complete — 19905 in / 152 out tokens + ● shell(ls -la /tmp/zizmor) + ✓ shell(ls -la /tmp/zizmor) + ○ Calling LLM... + ○ Step complete — 20012 in / 125 out tokens + ● shell(/tmp/zizmor --help) + ✓ shell(/tmp/zizmor --help) + ○ Calling LLM... + ○ Step complete — 21614 in / 103 out tokens + ● glob(.) + ✓ glob(.) + ○ Calling LLM... + ○ Step complete — 21776 in / 92 out tokens + ● shell(zizmor .github/workflows/ --format json --persona regular) + ✓ shell(zizmor .github/workflows/ --format json --persona regular) + ○ Calling LLM... + ○ Step complete — 40348 in / 78 out tokens + ● echo(zizmor successfully ran and found security issues....) + ✓ echo(zizmor successfully ran and found security issues....) + ○ Calling LLM... + ○ Step complete — 40414 in / 553 out tokens + … Done diff --git a/tests/fixtures/llm_traces/live/zizmor_scan_v2.json b/tests/fixtures/llm_traces/live/zizmor_scan_v2.json index 267c14e341..74d838bd46 100644 --- a/tests/fixtures/llm_traces/live/zizmor_scan_v2.json +++ b/tests/fixtures/llm_traces/live/zizmor_scan_v2.json @@ -16,61 +16,74 @@ "type": "tool_calls", "tool_calls": [ { - "id": "chatcmpl-tool-af116ddf7d76ffe1", - "name": "tool_search", + "id": "call_56a460d2ec6247e5bd600f5b", + "name": "shell", "arguments": { - "query": "zizmor" - } - }, - { - "id": "chatcmpl-tool-a3b63943e42a0ecb", - "name": "http", - "arguments": { - "method": "GET", - "url": "https://github.com/zizmorcore/zizmor" + "command": "which zizmor || cargo install zizmor 2>&1 | head -20", + "timeout": 120, + "workdir": "." } } ], - "input_tokens": 9624, - "output_tokens": 118 + "input_tokens": 19610, + "output_tokens": 148 } }, { "request_hint": { "last_user_message_contains": "can we run https://github.com/zizmorcore/zizmor", - "min_message_count": 5 + "min_message_count": 4 }, "response": { "type": "tool_calls", "tool_calls": [ { - "id": "chatcmpl-tool-9a7f678f4ab6dafa", - "name": "tool_search", + "id": "call_bb4b5d15db39470c903c084e", + "name": "shell", "arguments": { - "query": "zizmor github actions security" - } - }, - { - "id": "chatcmpl-tool-abde2c362fe68cbe", - "name": "tool_list", - "arguments": { - "include_available": true + "command": "zizmor --help", + "timeout": 30, + "workdir": "." } } ], - "input_tokens": 10895, - "output_tokens": 125 + "input_tokens": 19742, + "output_tokens": 112 }, "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-af116ddf7d76ffe1", - "name": "tool_search", - "content": "{'count': 0, 'results': [], 'searched_online': False}" - }, + "tool_call_id": "call_56a460d2ec6247e5bd600f5b", + "name": "shell", + "content": "{'exit_code': 0, 'output': '/home/user/.cargo/bin/zizmor\\n', 'sandboxed': False, 'success': True}" + } + ] + }, + { + "request_hint": { + "last_user_message_contains": "can we run https://github.com/zizmorcore/zizmor", + "min_message_count": 6 + }, + "response": { + "type": "tool_calls", + "tool_calls": [ + { + "id": "call_4f3c4de7d5a2417fba1f2bac", + "name": "shell", + "arguments": { + "command": "zizmor . --format plain --pedantic 2>&1", + "timeout": 60, + "workdir": "." + } + } + ], + "input_tokens": 21386, + "output_tokens": 110 + }, + "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-a3b63943e42a0ecb", - "name": "http", - "content": "{'body': '# Search code, repositories, users, issues, pull requests...\\n\\n\\n\\n\\n\\n[Sign in](/login?return_to=https%3A%2F%2Fgithub.com%2Fzizmorcore%2Fzizmor)\\n\\n/;ref_cta:Sign up;ref_loc:header logged out\"}\" data-hydro-click=\"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/zizmorcore/zizmor\",\"user_id\":null}}\" data-hydro-click-hmac=\"8caabd8b90225b5d5573f566ac422fd36398eba76666d09587f4d4f6f6450bb2\" href=\"/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E&source=header-repo&source_repo=zizmorcore%2Fzizmor\">\\n Sign up\\n\\nAppearance settings\\n', 'headers': {'accept-ranges': 'bytes', 'cache-control': 'max-age=0, private, must-revalidate', 'content-security-policy': \"default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com github.githubassets.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net productionresultssa1.blob.core.windows.net productionresultssa2.blob.core.windows.net productionresultssa3.blob.core.windows.net productionresultssa4.blob.core.windows.net productionresultssa5.blob.core.windows.net productionresultssa6.blob.core.windows.net productionresultssa7.blob.core.windows.net productionresultssa8.blob.core.windows.net productionresultssa9.blob.core.windows.net productionresultssa10.blob.core.windows.net productionresultssa11.blob.core.windows.net productionresultssa12.blob.core.windows.net productionresultssa13.blob.core.windows.net productionresultssa14.blob.core.windows.net productionresultssa15.blob.core.windows.net productionresultssa16.blob.core.windows.net productionresultssa17.blob.core.windows.net productionresultssa18.blob.core.windows.net productionresultssa19.blob.core.windows.net github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com wss://alive-staging.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com user-images.githubusercontent.com private-user-images.githubusercontent.com opengraph.githubassets.com marketplace-screenshots.githubusercontent.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com secured-user-images.githubusercontent.com private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com github.githubassets.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/\", 'content-type': 'text/html; charset=utf-8', 'date': 'Sun, 05 Apr 2026 11:49:36 GMT', 'etag': 'W/\"f79c89ccf6deeb8bf72f05468daae684\"', 'referrer-policy': 'no-referrer-when-downgrade', 'server': 'github.com', 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload', 'vary': 'X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With, Sec-Fetch-Site,Accept-Encoding, Accept, X-Requested-With', 'x-content-type-options': 'nosniff', 'x-frame-options': 'deny', 'x-github-request-id': '80C1:2E367D:125F734:18F58BA:69D24C4F', 'x-xss-protection': '0'}, 'status': 200}" + "tool_call_id": "call_bb4b5d15db39470c903c084e", + "name": "shell", + "content": "{'exit_code': 0, 'output': 'Static analysis for GitHub Actions\\n\\nUsage: zizmor [OPTIONS] ...\\n\\nInput Options:\\n ...\\n The inputs to audit.\\n \\n These can be individual workflow filenames, action definitions (typically `action.yml`), entire directories, or a `user/repo` slug for a GitHub repository. In the latter case, a `@ref` can be appended to audit the repository at a particular git reference state.\\n \\n Use `-` to read a single input from stdin.\\n\\n --collect ...\\n Control which kinds of inputs are collected for auditing.\\n \\n By default, all workflows and composite actions are collected, while honoring `.gitignore` files.\\n\\n Possible values:\\n - all: Collect all possible inputs, ignoring `.gitignore` files\\n - default: Collect all possible inputs, respecting `.gitignore` files\\n - workflows: Collect workflows\\n - actions: Collect action definitions (i.e. `action.yml`)\\n - dependabot: Collect Dependabot configuration files (i.e. `dependabot.yml`)\\n \\n [default: default]\\n\\n --strict-collection\\n Fail instead of warning on syntax and schema errors in collected inputs\\n\\nAudit Options:\\n --fix[=]\\n Fix findings automatically, when available (EXPERIMENTAL)\\n\\n Possible values:\\n - safe: Apply only safe fixes (the default)\\n - unsafe-only: Apply only unsafe fixes\\n - all: Apply all fixes, both safe and unsafe\\n\\n -p, --pedantic\\n Emit \\'pedantic\\' findings.\\n \\n This is an alias for --persona=pedantic.\\n\\n --persona \\n The persona to use while auditing\\n\\n Possible values:\\n - auditor: The \"auditor\" persona (false positives OK)\\n - pedantic: The \"pedantic\" persona (code smells OK)\\n - regular: The \"regular\" persona (minimal false positives)\\n \\n [default: regular]\\n\\n --min-severity \\n Filter all results below this severity\\n \\n [possible values: informational, low, medium, high]\\n\\n --min-confidence \\n Filter all results below this confidence\\n \\n [possible values: low, medium, high]\\n\\nOutput Options:\\n -v, --verbose...\\n Increase logging verbosity\\n\\n -q, --quiet...\\n Decrease logging verbosity\\n\\n --format \\n The output format to emit. By default, cargo-style diagnostics will be emitted\\n\\n Possible values:\\n - plain: cargo-style output\\n - json: JSON-formatted output (currently v1)\\n - json-v1: \"v1\" JSON format\\n - sarif: SARIF-formatted output\\n - github: GitHub Actions workflow command-formatted output\\n \\n [default: plain]\\n\\n --no-progress\\n Don\\'t show progress bars, even if the terminal supports them\\n\\n --color \\n Control the use of color in output\\n\\n Possible values:\\n - auto: Use color output if the output supports it\\n - always: Force color output, even if the output isn\\'t a terminal\\n - never: Disable color output, even if the output is a compatible terminal\\n\\n --render-links \\n Whether to render OSC 8 links in the output.\\n \\n This affects links under audit IDs, as well as any links produced by audit rules.\\n \\n Only affects `--format=plain` (the default).\\n\\n Possible values:\\n - auto: Render OSC 8 links in output if support is detected\\n - always: Always render OSC 8 links in output\\n - never: Never render OSC 8 links in output\\n \\n [env: ZIZMOR_RENDER_LINKS=]\\n [default: auto]\\n\\n --show-audit-urls \\n Whether to render audit URLs in the output, separately from any URLs embedded in OSC 8 links.\\n \\n Only affects `--format=plain` (the default).\\n\\n Possible values:\\n - auto: Render audit URLs in output automatically based on output format and runtime context\\n - always: Always render audit URLs in output\\n - never: Never render audit URLs in output\\n \\n [env: ZIZMOR_SHOW_AUDIT_URLS=]\\n [default: auto]\\n\\n --no-exit-codes\\n Disable all error codes besides success and tool failure\\n\\nNetwork Options:\\n -o, --offline\\n Perform only offline operations.\\n \\n This disables all online audit rules, and prevents zizmor from auditing remote repositories.\\n \\n [env: ZIZMOR_OFFLINE=]\\n\\n --gh-token \\n The GitHub API token to use [env: GH_TOKEN or GITHUB_TOKEN or ZIZMOR_GITHUB_TOKEN]\\n\\n --gh-hostname \\n The GitHub Server Hostname. Defaults to github.com\\n \\n [env: GH_HOST=]\\n [default: github.com]\\n\\n --no-online-audits\\n Perform only offline audits.\\n \\n This is a weaker version of `--offline`: instead of completely forbidding all online operations, it only disables audits that require connectivity.\\n \\n [env: ZIZMOR_NO_ONLINE_AUDITS=]\\n\\n --cache-dir \\n The directory to use for HTTP caching. By default, a host-appropriate user-caching directory will be used\\n\\nOptions:\\n --lsp\\n Run in language server mode (EXPERIMENTAL).\\n \\n This flag cannot be used with any other flags.\\n\\n -c, --config \\n The configuration file to load. This loads a single configuration file across all input groups, which may not be what you intend\\n \\n [env: ZIZMOR_CONFIG=]\\n\\n --no-config\\n Disable all configuration loading\\n\\n --completions \\n Generate tab completion scripts for the specified shell\\n\\n Possible values:\\n - bash: Bourne Again `SHell` (bash)\\n - elvish: Elvish shell\\n - fish: Friendly Interactive `SHell` (fish)\\n - nushell: Nushell\\n - powershell: `PowerShell`\\n - zsh: Z `SHell` (zsh)\\n\\n --thanks\\n Emit thank-you messages for zizmor\\'s sponsors\\n\\n -h, --help\\n Print help (see a summary with \\'-h\\')\\n\\n -V, --version\\n Print version\\n', 'sandboxed': False, 'success': True}" } ] }, @@ -80,57 +93,16 @@ "min_message_count": 8 }, "response": { - "type": "tool_calls", - "tool_calls": [ - { - "id": "chatcmpl-tool-b29195a794545d6d", - "name": "tool_search", - "arguments": { - "query": "zizmor" - } - } - ], - "input_tokens": 15823, - "output_tokens": 65 + "type": "text", + "content": "\n\nYes! Zizmor ran successfully and found **many security issues** in your GitHub Actions workflows. Here's a summary of the findings:\n\n## 🔴 Critical Security Issues Found\n\n### **Errors (High Severity):**\n1. **Excessive Permissions** - Multiple workflows have overly broad permissions:\n - `claude-review.yml`: pull-requests: write, issues: write, id-token: write\n - `pr-label-classify.yml`: pull-requests: write\n - `pr-label-scope.yml`: issues: write, pull-requests: write\n - `release-plz-batch-summary.yml`: pull-requests: write\n\n2. **Dangerous Triggers** - `pull_request_target` used insecurely:\n - `pr-label-classify.yml`\n - `pr-label-scope.yml`\n - `release-plz-batch-summary.yml`\n - `staging-promotion-metadata.yml`\n\n3. **Template Injection** - Code injection vulnerabilities:\n - Multiple workflows expose `${{ github.* }}` and `${{ inputs.* }}` in run blocks\n - Affected: `code_style.yml`, `rebuild-release-image.yml`, `staging-ci.yml`, `test.yml`\n\n4. **Cache Poisoning** - `release.yml` uses rust-cache without `save-always: false`\n\n5. **Unpinned Actions** - `replay-gate.yml` uses unpinned action references (@v4, @stable, @v2)\n\n6. **Unpinned Images** - `coverage.yml` uses `pgvector/pgvector:pg16` without SHA hash\n\n### **Warnings (Medium Severity):**\n- **Dependabot cooldown** - Missing cooldown configuration in `dependabot.yml`\n- **Artipacked** - `actions/checkout` without `persist-credentials: false` in multiple workflows\n- **Secrets inherit** - `release.yml` uses `secrets: inherit` when calling reusable workflows\n\n### **Help/Info (Low Severity):**\n- **Undocumented permissions** - Many workflows lack explanatory comments for permissions\n- **Missing concurrency limits** - Most workflows lack `concurrency` settings\n- **Superfluous actions** - Using `dtolnay/rust-toolchain` when rustup/cargo is available\n\n## 📊 Statistics:\n- **Total findings**: 100+ issues across 18 workflow files\n- **Errors**: ~15-20 critical issues\n- **Warnings**: ~10-15 medium issues \n- **Help/Info**: 70+ low-priority issues\n\n## ✅ Auto-fixes Available:\nMany findings have auto-fixes that can be applied with `zizmor --fix`\n\nWould you like me to:\n1. Generate a detailed JSON report of all findings?\n2. Apply auto-fixes to safe issues?\n3. Focus on specific high-priority issues?", + "input_tokens": 39477, + "output_tokens": 656 }, "expected_tool_results": [ { - "tool_call_id": "chatcmpl-tool-9a7f678f4ab6dafa", - "name": "tool_search", - "content": "{'count': 1, 'results': [{'auth_hint': {'type': 'capabilities_auth'}, 'description': 'GitHub integration for repositories, issues, pull requests, search, branches, file writes, releases, and workflows', 'display_name': 'GitHub', 'fallback_source': {'build_dir': 'tools-src/github', 'crate_name': 'github-tool', 'source_dir': 'tools-src/github', 'type': 'wasm_buildable'}, 'keywords': ['git', 'code', 'issues', 'pull-requests', 'repositories', 'search', 'releases'], 'kind': 'wasm_tool', 'name': 'github', 'source': 'registry', 'validated': True, 'version': '0.2.2'}], 'searched_online': False}" - }, - { - "tool_call_id": "chatcmpl-tool-abde2c362fe68cbe", - "name": "tool_list", - "content": "{'builtin_count': 40, 'builtins': [{'default_state': 'ask_each_time', 'description': 'List contents of a directory on the LOCAL FILESYSTEM. NOT for workspace memory (use memory_tree for that). Shows files and subdirectories with their sizes.', 'locked': False, 'name': 'list_dir', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Permanently remove an installed extension (channel, tool, or MCP server) from disk. This action cannot be undone — the WASM binary and configuration files will be deleted.', 'locked': True, 'name': 'tool_remove', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Make HTTP requests to external APIs. Supports GET, POST, PUT, DELETE methods. Use save_to to download binary files (images, PDFs, etc.) to a local path, e.g. {\"method\":\"GET\",\"url\":\"https://picsum.photos/800/600\",\"save_to\":\"/tmp/photo.jpg\"}.', 'locked': False, 'name': 'http', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Generate an image from a text prompt using an AI image generation model (e.g., FLUX). Returns the generated image data.', 'locked': False, 'name': 'image_generate', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': \"Write to persistent memory (database-backed, NOT the local filesystem). Use for important facts, decisions, preferences, or lessons learned that should be remembered across sessions. Targets: 'memory' for curated long-term facts, 'daily_log' for timestamped session notes, 'heartbeat' for the periodic checklist (HEARTBEAT.md), 'bootstrap' to clear the first-run ritual file, or provide a custom workspace path for arbitrary file creation. Never pass absolute filesystem paths like '/Users/...' or 'C:\\\\...'.\", 'locked': False, 'name': 'memory_write', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'Show detailed information about an installed extension, including version and WIT version compatibility.', 'locked': False, 'name': 'extension_info', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': 'Get info about any tool: description, parameter names, curated summary guidance, or full discovery schema.', 'locked': False, 'name': 'tool_info', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'Update the plan progress checklist displayed to the user. Call this when creating a plan, starting execution, completing a step, or when the plan fails. The UI renders this as a live checklist. Always send the FULL list of steps (not incremental diffs).', 'locked': False, 'name': 'plan_update', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Activate an installed extension — starts channels, loads tools, or connects to MCP servers.', 'locked': False, 'name': 'tool_activate', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Cancel a running or pending job. The job will be marked as cancelled and stopped.', 'locked': False, 'name': 'cancel_job', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': 'Search past memories, decisions, and context. MUST be called before answering questions about prior work, decisions, dates, people, preferences, or todos. Returns relevant snippets with relevance scores.', 'locked': False, 'name': 'memory_search', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': 'Analyze an image using a vision-capable AI model. Provide a workspace path to the image and an optional analysis question.', 'locked': False, 'name': 'image_analyze', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': 'Check the status and details of a specific job by its ID.', 'locked': False, 'name': 'job_status', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'Initiate authentication for an extension. For OAuth, returns a URL. For manual auth, returns instructions. The user provides their token through a secure channel, never through this tool.', 'locked': False, 'name': 'tool_auth', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': \"Write content to a file on the LOCAL FILESYSTEM. NOT for workspace memory (use memory_write for that). Creates the file if it doesn't exist, overwrites if it does. Parent directories are created automatically. Use apply_patch for targeted edits.\", 'locked': False, 'name': 'write_file', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': 'Parse, query, and transform JSON data. Supports JSONPath-like queries. Use `source_tool_call_id` to reference the full output of a previous tool call (avoids truncation issues with large responses).', 'locked': False, 'name': 'json', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'Install an extension (channel, tool, or MCP server). Use the name from tool_search results, or provide an explicit URL.', 'locked': False, 'name': 'tool_install', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Get or set the permission state for a tool. Use to view current permissions or propose a change (requires user approval). States: always_allow (no prompt), ask_each_time (approval required), disabled (tool hidden from LLM).', 'locked': True, 'name': 'tool_permission_set', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Manually trigger a routine to run immediately, bypassing schedule, trigger type, and cooldown.', 'locked': False, 'name': 'routine_fire', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': 'List extensions and built-in tools with their authentication, activation, and permission status. Set include_available:true to also show registry entries not yet installed. Use kind=\"builtin\" to list only built-in Rust tools.', 'locked': False, 'name': 'tool_list', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': 'Read the event log for a sandbox job. Shows messages, tool calls, results, and status changes from the container. Use this to check what Claude Code or a worker sub-agent has been doing.', 'locked': False, 'name': 'job_events', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'View the execution history of a routine. Shows recent runs with status, duration, and results.', 'locked': False, 'name': 'routine_history', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Create a new routine (scheduled or event-driven task). Supports cron schedules, event pattern matching, system events, and manual triggers. Use this when the user wants something to happen periodically or reactively. Creation saves the routine, but does not verify that it will execute successfully.', 'locked': False, 'name': 'routine_create', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Emit a structured system event to routines with a system_event trigger. Use this to trigger routines from tool workflows without waiting for cron.', 'locked': False, 'name': 'event_emit', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Execute shell commands. Use for running builds, tests, git operations, and other CLI tasks. Commands run in a subprocess with captured output. Long-running commands have a timeout. When Docker sandbox is enabled, commands run in isolated containers for security.', 'locked': False, 'name': 'shell', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': 'Get current time, parse or format timestamps, convert timezones, or calculate time differences.', 'locked': False, 'name': 'time', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': 'Search for available extensions to add new capabilities. Extensions include channels (Telegram, Slack, Discord — connect messaging platforms so IronClaw can receive and reply there), tools, and MCP servers. Use `tool_install` and `tool_activate` to install and enable channels; use the `message` tool for proactive outbound sends. Use discover:true to search online if the built-in registry has no results.', 'locked': False, 'name': 'tool_search', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': 'View the workspace memory structure as a tree (database-backed storage). Use memory_read to read files shown here, NOT read_file. The workspace is separate from the local filesystem.', 'locked': False, 'name': 'memory_tree', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': \"Read a file from the workspace memory (database-backed storage). Use this to read files shown by memory_tree. NOT for local filesystem files (use read_file for those). Do not pass absolute paths like '/Users/...' or 'C:\\\\...'. Works with identity files, heartbeat checklist, memory, daily logs, or any custom workspace path.\", 'locked': False, 'name': 'memory_read', 'permission_state': 'always_allow'}, {'default_state': 'always_allow', 'description': 'Echoes back the input message. Useful for testing tool execution.', 'locked': False, 'name': 'echo', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'Edit an existing image using an AI model. Provide the workspace path to the source image and a text prompt describing the desired edits.', 'locked': False, 'name': 'image_edit', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Read a file from the LOCAL FILESYSTEM. NOT for workspace memory paths (use memory_read for those). Returns file content as text. For large files, you can specify offset and limit to read a portion.', 'locked': False, 'name': 'read_file', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': \"Apply targeted edits to a file using search/replace. Finds the exact 'old_string' and replaces it with 'new_string'. Use for surgical code changes without rewriting entire files. The old_string must match exactly (including whitespace and indentation).\", 'locked': False, 'name': 'apply_patch', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Create a new job or task for the agent to work on. Use this when the user wants you to do something substantial that should be tracked as a separate job.', 'locked': False, 'name': 'create_job', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': 'List all jobs or filter by status. Shows job IDs, titles, and current status.', 'locked': False, 'name': 'list_jobs', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'Delete a routine permanently. This also removes all run history.', 'locked': False, 'name': 'routine_delete', 'permission_state': 'ask_each_time'}, {'default_state': 'always_allow', 'description': \"Send a proactive message to a channel. Use normal assistant output to reply in the active conversation; use this tool for proactive notifications, routine/background follow-ups, attachments, or sending to a different channel/recipient. If channel/target are omitted, reuses the current conversation's channel and sender/group when available. If you provide `target` without `channel` and no scoped channel can be resolved, the message may be broadcast across connected channels instead of sent to just one. Supports file attachments: first download the file with the http tool using save_to (e.g., http GET https://picsum.photos/800/600 save_to=/tmp/photo.jpg), then pass the file path in the attachments array. Images are sent as photos on Telegram. - Signal: target accepts E.164 (+1234567890) or group ID - Telegram: target accepts username or chat ID - Slack: target accepts channel (#general) or user ID\", 'locked': False, 'name': 'message', 'permission_state': 'always_allow'}, {'default_state': 'ask_each_time', 'description': 'List all routines with their status, trigger info, and next fire time.', 'locked': False, 'name': 'routine_list', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Upgrade installed WASM extensions (channels and tools) to match the current host WIT version. If name is omitted, checks and upgrades all installed WASM extensions. Authentication and secrets are preserved.', 'locked': False, 'name': 'tool_upgrade', 'permission_state': 'ask_each_time'}, {'default_state': 'ask_each_time', 'description': 'Update an existing routine. Can change prompt, description, enabled state, cron schedule/timezone, Pass the routine name and only the fields you want to change. This does not convert trigger types. Behavior-changing edits should leave the routine marked unverified until it is tested again.', 'locked': False, 'name': 'routine_update', 'permission_state': 'ask_each_time'}], 'count': 23, 'extensions': [{'active': True, 'authenticated': False, 'display_name': 'GitHub', 'has_auth': True, 'installed': True, 'kind': 'wasm_tool', 'name': 'github', 'needs_setup': True, 'tools': ['github'], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Connect to Asana for task management, projects, and team coordination', 'display_name': 'Asana', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'asana', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Connect to Cloudflare for DNS, Workers, KV, and infrastructure management', 'display_name': 'Cloudflare', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'cloudflare', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Talk to your agent in Discord', 'display_name': 'Discord Channel', 'has_auth': False, 'installed': False, 'kind': 'wasm_channel', 'name': 'discord', 'needs_setup': False, 'tools': [], 'version': '0.2.2'}, {'active': False, 'authenticated': False, 'description': 'Talk to your agent through a Feishu or Lark bot', 'display_name': 'Feishu / Lark Channel', 'has_auth': False, 'installed': False, 'kind': 'wasm_channel', 'name': 'feishu', 'needs_setup': False, 'tools': [], 'version': '0.1.4'}, {'active': False, 'authenticated': False, 'description': 'Read, send, and manage Gmail messages and threads', 'display_name': 'Gmail', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'gmail', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Create, read, update, and delete Google Calendar events', 'display_name': 'Google Calendar', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'google_calendar', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Create and edit Google Docs documents', 'display_name': 'Google Docs', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'google_docs', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Upload, download, search, and manage Google Drive files and folders', 'display_name': 'Google Drive', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'google_drive', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Read and write Google Sheets spreadsheet data', 'display_name': 'Google Sheets', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'google_sheets', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Create and edit Google Slides presentations', 'display_name': 'Google Slides', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'google_slides', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Connect to Intercom for customer messaging, support, and engagement', 'display_name': 'Intercom', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'intercom', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Connect to Linear for issue tracking, project management, and team workflows', 'display_name': 'Linear', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'linear', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Fetch pre-extracted web content from Brave Search for grounding LLM answers (RAG, fact-checking)', 'display_name': 'LLM Context', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'llm_context', 'needs_setup': False, 'tools': [], 'version': '0.1.1'}, {'active': False, 'authenticated': False, 'description': 'Connect to Notion for reading and writing pages, databases, and comments', 'display_name': 'Notion', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'notion', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Connect to Sentry for error tracking, performance monitoring, and debugging', 'display_name': 'Sentry', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'sentry', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Talk to your agent in Slack', 'display_name': 'Slack Channel', 'has_auth': False, 'installed': False, 'kind': 'wasm_channel', 'name': 'slack', 'needs_setup': False, 'tools': [], 'version': '0.2.2'}, {'active': False, 'authenticated': False, 'description': 'Your agent uses Slack to post and read messages in your workspace', 'display_name': 'Slack Tool', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'slack_tool', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Connect to Stripe for payment processing, subscriptions, and financial data', 'display_name': 'Stripe', 'has_auth': False, 'installed': False, 'kind': 'mcp_server', 'name': 'stripe', 'needs_setup': False, 'tools': []}, {'active': False, 'authenticated': False, 'description': 'Talk to your agent through a Telegram bot', 'display_name': 'Telegram Channel', 'has_auth': False, 'installed': False, 'kind': 'wasm_channel', 'name': 'telegram', 'needs_setup': False, 'tools': [], 'version': '0.2.6'}, {'active': False, 'authenticated': False, 'description': 'Your agent uses your Telegram account to read and send messages', 'display_name': 'Telegram Tool', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'telegram_mtproto', 'needs_setup': False, 'tools': [], 'version': '0.2.1'}, {'active': False, 'authenticated': False, 'description': 'Search the web using Brave Search API', 'display_name': 'Web Search', 'has_auth': False, 'installed': False, 'kind': 'wasm_tool', 'name': 'web_search', 'needs_setup': False, 'tools': [], 'version': '0.2.2'}, {'active': False, 'authenticated': False, 'description': 'Talk to your agent through WhatsApp', 'display_name': 'WhatsApp Channel', 'has_auth': False, 'installed': False, 'kind': 'wasm_channel', 'name': 'whatsapp', 'needs_setup': False, 'tools': [], 'version': '0.2.0'}]}" - } - ] - }, - { - "request_hint": { - "last_user_message_contains": "can we run https://github.com/zizmorcore/zizmor", - "min_message_count": 10 - }, - "response": { - "type": "tool_calls", - "tool_calls": [ - { - "id": "chatcmpl-tool-b275a8bc3e470620", - "name": "shell", - "arguments": { - "command": "pip install zizmor 2>&1 || echo \"pip install failed\"", - "timeout": 60 - } - } - ], - "input_tokens": 15858, - "output_tokens": 169 - }, - "expected_tool_results": [ - { - "tool_call_id": "chatcmpl-tool-b29195a794545d6d", - "name": "tool_search", - "content": "{'count': 0, 'results': [], 'searched_online': False}" + "tool_call_id": "call_4f3c4de7d5a2417fba1f2bac", + "name": "shell", + "content": "{'exit_code': 14, 'output': ' INFO zizmor: 🌈 zizmor v1.24.1\\n INFO audit: zizmor: 🌈 completed ./.github/actions/install-cargo-component/action.yml\\n INFO audit: zizmor: 🌈 completed ./.github/dependabot.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/claude-review.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/code_style.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/coverage.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/docker.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/e2e.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/pr-label-classify.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/pr-label-scope.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/rebuild-release-image.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/regression-test-check.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/release-plz-batch-summary.yml\\n WARN audit: zizmor: one or more inputs contains YAML anchors; see https://docs.zizmor.sh/usage/#yaml-anchors for details\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/release-plz.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/release.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/replay-gate.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/staging-ci.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/staging-promotion-metadata.yml\\n INFO audit: zizmor: 🌈 completed ./.github/workflows/test.yml\\nwarning[dependabot-cooldown]: insufficient cooldown in Dependabot updates\\n --> ./.github/dependabot.yml:3:5\\n |\\n3 | - package-ecosystem: cargo\\n | ^^^^^^^^^^^^^^^^^^^^^^^^ missing cooldown configuration\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dependabot-cooldown\\n\\nwarning[dependabot-cooldown]: insufficient cooldown in Dependabot updates\\n --> ./.github/dependabot.yml:40:5\\n |\\n40 | - package-ecosystem: github-actions\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing cooldown configuration\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dependabot-cooldown\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/claude-review.yml:9:3\\n |\\n9 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ pull-requests: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/claude-review.yml:10:3\\n |\\n10 | issues: write\\n | ^^^^^^^^^^^^^ issues: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/claude-review.yml:11:3\\n |\\n11 | id-token: write\\n | ^^^^^^^^^^^^^^^ id-token: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/claude-review.yml:9:3\\n |\\n 9 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n10 | issues: write\\n | ^^^^^^^^^^^^^ needs an explanatory comment\\n11 | id-token: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:84:21\\n |\\n77 | run: |\\n | --- this run block\\n...\\n84 | if [ \"${{ github.event_name }}\" = \"push\" ] || [ \"${{ github.base_ref }}\" = \"main\" ]; then\\n | ^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:84:64\\n |\\n77 | run: |\\n | --- this run block\\n...\\n84 | if [ \"${{ github.event_name }}\" = \"push\" ] || [ \"${{ github.base_ref }}\" = \"main\" ]; then\\n | ^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:174:54\\n |\\n174 | run: cargo clippy --all --tests --examples ${{ matrix.flags }} -- -D warnings\\n | --- this run block ^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:208:54\\n |\\n208 | run: cargo clippy --all --tests --examples ${{ matrix.flags }} -- -D warnings\\n | --- this run block ^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:228:19\\n |\\n227 | run: |\\n | --- this run block\\n228 | BASE=\"${{ github.event.pull_request.base.sha }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:272:22\\n |\\n270 | - run: |\\n | --- this run block\\n271 | # Docs-only PRs intentionally skip every gated job — that\\'s a pass.\\n272 | if [[ \"${{ needs.changes.outputs.has_code }}\" == \"false\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:279:25\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n279 | \"format=${{ needs.format.result }}\" \\\\\\n | ^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:280:36\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n280 | \"gateway-js-syntax=${{ needs.gateway-js-syntax.result }}\" \\\\\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:281:25\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n281 | \"clippy=${{ needs.clippy.result }}\" \\\\\\n | ^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:282:29\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n282 | \"deny-check=${{ needs.deny-check.result }}\" \\\\\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:283:37\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n283 | \"gateway-boundaries=${{ needs.gateway-boundaries.result }}\"; do\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:295:28\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n295 | \"no-panics=${{ needs.no-panics.result }}\" \\\\\\n | ^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/code_style.yml:296:33\\n |\\n270 | - run: |\\n | --- this run block\\n...\\n296 | \"clippy-windows=${{ needs.clippy-windows.result }}\"; do\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/code_style.yml:101:13\\n |\\n100 | - name: Install Rust\\n | ------------------ this step\\n101 | uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/code_style.yml:158:13\\n |\\n157 | - name: Install Rust\\n | ------------------ this step\\n158 | uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/code_style.yml:196:13\\n |\\n195 | - name: Install Rust\\n | ------------------ this step\\n196 | uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/coverage.yml:114:33\\n |\\n114 | run: cargo llvm-cov ${{ matrix.flags }} --workspace --lcov --output-path lcov.info\\n | --- this run block ^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/coverage.yml:226:22\\n |\\n225 | - run: |\\n | --- this run block\\n226 | if [[ \"${{ needs.coverage.result }}\" != \"success\" || \"${{ needs.e2e-coverage.result }}\" != \"success\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/coverage.yml:226:69\\n |\\n225 | - run: |\\n | --- this run block\\n226 | if [[ \"${{ needs.coverage.result }}\" != \"success\" || \"${{ needs.e2e-coverage.result }}\" != \"success\" ]]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/coverage.yml:42:7\\n |\\n42 | id-token: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/coverage.yml:130:7\\n |\\n130 | id-token: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nerror[unpinned-images]: unpinned image references\\n --> ./.github/workflows/coverage.yml:59:9\\n |\\n59 | image: pgvector/pgvector:pg16\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ container image is not pinned to a SHA256 hash\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-images\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/coverage.yml:30:1\\n |\\n 30 | / on:\\n 31 | | push:\\n 32 | | branches: [main]\\n | |____________________^ workflow is missing concurrency setting\\n...\\n 39 | name: Coverage (${{ matrix.name }})\\n | ----------------------------------- job affected by missing workflow concurrency\\n...\\n126 | name: E2E Coverage\\n | ------------------ job affected by missing workflow concurrency\\n...\\n220 | name: Coverage\\n | -------------- job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/coverage.yml:76:15\\n |\\n76 | - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n | _________|\\n | |\\n77 | | with:\\n78 | | components: llvm-tools-preview\\n79 | | targets: wasm32-wasip2\\n | |________________________________- this step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/coverage.yml:137:15\\n |\\n137 | - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n | _________|\\n | |\\n138 | | with:\\n139 | | components: llvm-tools-preview\\n140 | | targets: wasm32-wasip2\\n | |________________________________- this step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/docker.yml:1:1\\n |\\n 1 | / name: Docker Image\\n 2 | |\\n 3 | | on:\\n 4 | | # Called by release.yml or other workflows\\n... |\\n227 | | echo \"- sha: \\\\`${{ steps.source_sha.outputs.sha }}\\\\`\"\\n228 | | } >> \"$GITHUB_STEP_SUMMARY\"\\n | |______________________________________^ default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/docker.yml:208:23\\n |\\n202 | run: |\\n | --- this run block\\n...\\n208 | echo \"${{ steps.tags.outputs.tags }}\" | tr \\',\\' \\'\\\\n\\'\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/docker.yml:213:23\\n |\\n202 | run: |\\n | --- this run block\\n...\\n213 | echo \"${{ steps.tags.outputs.worker_tags }}\" | tr \\',\\' \\'\\\\n\\'\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/docker.yml:216:36\\n |\\n202 | run: |\\n | --- this run block\\n...\\n216 | echo \"- version: \\\\`${{ steps.version.outputs.version }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/docker.yml:217:32\\n |\\n202 | run: |\\n | --- this run block\\n...\\n217 | echo \"- sha: \\\\`${{ steps.source_sha.outputs.sha }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/docker.yml:227:32\\n |\\n222 | run: |\\n | --- this run block\\n...\\n227 | echo \"- sha: \\\\`${{ steps.source_sha.outputs.sha }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/docker.yml:34:7\\n |\\n34 | packages: read\\n | ^^^^^^^^^^^^^^ needs an explanatory comment\\n35 | actions: write\\n | ^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/docker.yml:3:1\\n |\\n 3 | / on:\\n 4 | | # Called by release.yml or other workflows\\n 5 | | workflow_call:\\n 6 | | inputs:\\n... |\\n21 | | schedule:\\n22 | | - cron: \\'0 * * * *\\'\\n | |_______________________^ workflow is missing concurrency setting\\n...\\n30 | name: Build & Push\\n | ------------------ job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/e2e.yml:101:25\\n |\\n101 | run: pytest ${{ matrix.files }} -v --timeout=120\\n | --- ^^^^^^^^^^^^ may expand into attacker-controllable code\\n | |\\n | this run block\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/e2e.yml:119:22\\n |\\n118 | - run: |\\n | --- this run block\\n119 | if [[ \"${{ needs.test.result }}\" != \"success\" ]]; then\\n | ^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/e2e.yml:38:15\\n |\\n38 | - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------\\n | | |\\n | | use `rustup` and/or `cargo` in a script step\\n | this step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/pr-label-classify.yml:9:3\\n |\\n9 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ pull-requests: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> ./.github/workflows/pr-label-classify.yml:3:1\\n |\\n3 | / on:\\n4 | | pull_request_target:\\n5 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/pr-label-classify.yml:9:3\\n |\\n9 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/pr-label-classify.yml:17:3\\n |\\n17 | classify:\\n | ^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/pr-label-scope.yml:9:3\\n |\\n9 | issues: write\\n | ^^^^^^^^^^^^^ issues: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/pr-label-scope.yml:10:3\\n |\\n10 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ pull-requests: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> ./.github/workflows/pr-label-scope.yml:3:1\\n |\\n3 | / on:\\n4 | | pull_request_target:\\n5 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/pr-label-scope.yml:9:3\\n |\\n 9 | issues: write\\n | ^^^^^^^^^^^^^ needs an explanatory comment\\n10 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/pr-label-scope.yml:17:3\\n |\\n17 | scope:\\n | ^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/rebuild-release-image.yml:1:1\\n |\\n 1 | / name: Rebuild Release Image\\n 2 | |\\n 3 | | on:\\n 4 | | workflow_dispatch:\\n... |\\n119 | | echo \"- image: \\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\`\"\\n120 | | } >> \"$GITHUB_STEP_SUMMARY\"\\n | |______________________________________^ default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[template-injection]: code injection via template expansion\\n --> ./.github/workflows/rebuild-release-image.yml:115:39\\n |\\n111 | run: |\\n | --- this run block\\n...\\n115 | echo \"- source ref: \\\\`${{ inputs.source_ref }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/rebuild-release-image.yml:116:39\\n |\\n111 | run: |\\n | --- this run block\\n...\\n116 | echo \"- source sha: \\\\`${{ steps.source.outputs.sha }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/rebuild-release-image.yml:117:36\\n |\\n111 | run: |\\n | --- this run block\\n...\\n117 | echo \"- version: \\\\`${{ steps.version.outputs.version }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/rebuild-release-image.yml:118:51\\n |\\n111 | run: |\\n | --- this run block\\n...\\n118 | echo \"- runtime stage detected: \\\\`${{ steps.target.outputs.has_runtime_stage }}\\\\`\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/rebuild-release-image.yml:119:34\\n |\\n111 | run: |\\n | --- this run block\\n...\\n119 | echo \"- image: \\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\`\"\\n | ^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nerror[template-injection]: code injection via template expansion\\n --> ./.github/workflows/rebuild-release-image.yml:119:56\\n |\\n111 | run: |\\n | --- this run block\\n...\\n119 | echo \"- image: \\\\`${{ env.IMAGE_NAME }}:${{ inputs.tag }}\\\\`\"\\n | ^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/rebuild-release-image.yml:23:7\\n |\\n23 | actions: write\\n | ^^^^^^^^^^^^^^ needs an explanatory comment\\n24 | contents: read\\n25 | packages: read\\n | ^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/rebuild-release-image.yml:3:1\\n |\\n 3 | / on:\\n 4 | | workflow_dispatch:\\n 5 | | inputs:\\n 6 | | source_ref:\\n... |\\n12 | | required: true\\n13 | | type: string\\n | |____________________^ workflow is missing concurrency setting\\n...\\n20 | name: Rebuild Historical Image\\n | ------------------------------ job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\nerror[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/release-plz-batch-summary.yml:20:3\\n |\\n20 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ pull-requests: write is overly broad at the workflow level\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> ./.github/workflows/release-plz-batch-summary.yml:3:1\\n |\\n 3 | / on:\\n 4 | | workflow_dispatch:\\n 5 | | inputs:\\n 6 | | pr_number:\\n... |\\n15 | | pull_request_target:\\n16 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/release-plz-batch-summary.yml:20:3\\n |\\n20 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release-plz-batch-summary.yml:23:3\\n |\\n23 | update-release-pr:\\n | ^^^^^^^^^^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/release-plz-batch-summary.yml:3:1\\n |\\n 3 | / on:\\n 4 | | workflow_dispatch:\\n 5 | | inputs:\\n 6 | | pr_number:\\n... |\\n15 | | pull_request_target:\\n16 | | types: [opened, synchronize, reopened]\\n | |__________________________________________^ workflow is missing concurrency setting\\n...\\n23 | update-release-pr:\\n | ----------------- job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/release-plz.yml:1:1\\n |\\n 1 | / name: Release-plz\\n 2 | |\\n 3 | | on:\\n 4 | | push:\\n... |\\n72 | | GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}\\n73 | | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}\\n | |____________________________________________________________________^ default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/release-plz.yml:16:7\\n |\\n16 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/release-plz.yml:52:7\\n |\\n52 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n53 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/release-plz.yml:3:1\\n |\\n 3 | / on:\\n 4 | | push:\\n 5 | | branches:\\n 6 | | - main\\n | |____________^ workflow is missing concurrency setting\\n...\\n13 | name: Release-plz release\\n | ------------------------- job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/release-plz.yml:26:15\\n |\\n25 | name: Install Rust toolchain\\n | ---------------------------- this step\\n26 | uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/release-plz.yml:26:15\\n |\\n25 | name: Install Rust toolchain\\n | ---------------------------- this step\\n26 | uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> ./.github/workflows/release.yml:499:9\\n |\\n499 | - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4\\n | _________^\\n500 | | with:\\n501 | | ref: main\\n502 | | # persist-credentials kept enabled — job pushes a checksum-update branch.\\n | |___________________________________________________________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nwarning[template-injection]: code injection via template expansion\\n --> ./.github/workflows/release.yml:143:18\\n |\\n143 | run: ${{ matrix.install_dist.run }}\\n | --- ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n | |\\n | this run block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nwarning[template-injection]: code injection via template expansion\\n --> ./.github/workflows/release.yml:188:15\\n |\\n187 | run: |\\n | --- this run block\\n188 | ${{ matrix.packages_install }}\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/release.yml:408:7\\n |\\n408 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/release.yml:479:7\\n |\\n479 | packages: read\\n | ^^^^^^^^^^^^^^ needs an explanatory comment\\n480 | actions: write\\n | ^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/release.yml:494:7\\n |\\n494 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n495 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nerror[cache-poisoning]: runtime artifacts potentially vulnerable to a cache poisoning attack\\n --> ./.github/workflows/release.yml:138:9\\n |\\n 41 | / on:\\n 42 | | push:\\n 43 | | tags:\\n 44 | | - \\'ironclaw-v[0-9]+.[0-9]+.[0-9]+*\\'\\n | |_________________________________________- generally used when publishing artifacts generated at runtime\\n...\\n138 | - uses: swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ enables caching by default\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#cache-poisoning\\n\\nerror[cache-poisoning]: runtime artifacts potentially vulnerable to a cache poisoning attack\\n --> ./.github/workflows/release.yml:285:9\\n |\\n 41 | / on:\\n 42 | | push:\\n 43 | | tags:\\n 44 | | - \\'ironclaw-v[0-9]+.[0-9]+.[0-9]+*\\'\\n | |_________________________________________- generally used when publishing artifacts generated at runtime\\n...\\n285 | - uses: swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ enables caching by default\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#cache-poisoning\\n\\nwarning[secrets-inherit]: secrets unconditionally inherited by called workflow\\n --> ./.github/workflows/release.yml:481:11\\n |\\n481 | uses: ./.github/workflows/docker.yml\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this reusable workflow\\n482 | secrets: inherit\\n | ---------------- inherits all parent secrets\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#secrets-inherit\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release.yml:48:3\\n |\\n48 | plan:\\n | ^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release.yml:220:3\\n |\\n220 | build-global-artifacts:\\n | ^^^^^^^^^^^^^^^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release.yml:269:3\\n |\\n269 | build-wasm-extensions:\\n | ^^^^^^^^^^^^^^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release.yml:399:3\\n |\\n399 | host:\\n | ^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release.yml:486:3\\n |\\n486 | update-registry-checksums:\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/release.yml:561:3\\n |\\n561 | announce:\\n | ^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/release.yml:41:1\\n |\\n 41 | / on:\\n 42 | | push:\\n 43 | | tags:\\n 44 | | - \\'ironclaw-v[0-9]+.[0-9]+.[0-9]+*\\'\\n | |_________________________________________^ workflow is missing concurrency setting\\n...\\n 48 | plan:\\n | ---- job affected by missing workflow concurrency\\n...\\n 98 | name: build-local-artifacts (${{ join(matrix.targets, \\', \\') }})\\n | --------------------------------------------------------------- job affected by missing workflow concurrency\\n...\\n220 | build-global-artifacts:\\n | ---------------------- job affected by missing workflow concurrency\\n...\\n269 | build-wasm-extensions:\\n | --------------------- job affected by missing workflow concurrency\\n...\\n399 | host:\\n | ---- job affected by missing workflow concurrency\\n...\\n486 | update-registry-checksums:\\n | ------------------------- job affected by missing workflow concurrency\\n...\\n561 | announce:\\n | -------- job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> ./.github/workflows/replay-gate.yml:46:9\\n |\\n46 | - name: Checkout repository\\n | _________^\\n47 | | uses: actions/checkout@v4\\n | |_________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/replay-gate.yml:1:1\\n |\\n 1 | / name: Replay Snapshot Gate\\n 2 | |\\n 3 | | # Runs `cargo insta test --check` over the committed replay fixtures so any\\n 4 | | # change to engine dispatch, agent loop, or tool execution has to come with\\n... |\\n101 | | exit 1\\n102 | | fi\\n | |_____________^ default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nwarning[excessive-permissions]: overly broad permissions\\n --> ./.github/workflows/replay-gate.yml:41:3\\n |\\n 41 | / replay-snapshots:\\n 42 | | name: Replay snapshot gate\\n 43 | | runs-on: ubuntu-latest\\n 44 | | timeout-minutes: 25\\n... |\\n101 | | exit 1\\n102 | | fi\\n | | ^\\n | | |\\n | |_____________this job\\n | default permissions used due to no permissions: block\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#excessive-permissions\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> ./.github/workflows/replay-gate.yml:47:15\\n |\\n47 | uses: actions/checkout@v4\\n | ^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> ./.github/workflows/replay-gate.yml:50:15\\n |\\n50 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> ./.github/workflows/replay-gate.yml:56:15\\n |\\n56 | - uses: Swatinem/rust-cache@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nerror[unpinned-uses]: unpinned action reference\\n --> ./.github/workflows/replay-gate.yml:65:15\\n |\\n65 | uses: taiki-e/install-action@v2\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^ action is not pinned to a hash (required by blanket policy)\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#unpinned-uses\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/replay-gate.yml:16:1\\n |\\n16 | / on:\\n17 | | pull_request:\\n18 | | paths:\\n19 | | - \\'crates/ironclaw_engine/**\\'\\n... |\\n37 | | - staging\\n38 | | - main\\n | |____________^ workflow is missing concurrency setting\\n...\\n42 | name: Replay snapshot gate\\n | -------------------------- job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\ninfo[superfluous-actions]: action functionality is already included by the runner\\n --> ./.github/workflows/replay-gate.yml:50:15\\n |\\n49 | - name: Install Rust\\n | ------------------ this step\\n50 | uses: dtolnay/rust-toolchain@stable\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use `rustup` and/or `cargo` in a script step\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#superfluous-actions\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> ./.github/workflows/staging-ci.yml:155:9\\n |\\n155 | - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\\n | _________^\\n156 | | with:\\n157 | | ref: ${{ needs.check-changes.outputs.current_head }}\\n158 | | fetch-depth: 0\\n159 | | token: ${{ steps.app-token.outputs.token }}\\n | |_____________________________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\nwarning[artipacked]: credential persistence through GitHub Actions artifacts\\n --> ./.github/workflows/staging-ci.yml:512:9\\n |\\n512 | - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6\\n | _________^\\n513 | | with:\\n514 | | ref: staging\\n515 | | fetch-depth: 0\\n516 | | # persist-credentials kept enabled — job pushes the staging-tested tag.\\n | |_________________________________________________________________________________^ does not set persist-credentials: false\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#artipacked\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:164:24\\n |\\n163 | run: |\\n | --- this run block\\n164 | if [ -n \"${{ steps.app-token.outputs.token }}\" ]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:165:29\\n |\\n163 | run: |\\n | --- this run block\\n164 | if [ -n \"${{ steps.app-token.outputs.token }}\" ]; then\\n165 | echo \"token=${{ steps.app-token.outputs.token }}\" >> \"$GITHUB_OUTPUT\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:167:29\\n |\\n163 | run: |\\n | --- this run block\\n...\\n167 | echo \"token=${{ github.token }}\" >> \"$GITHUB_OUTPUT\"\\n | ^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:189:33\\n |\\n188 | run: |\\n | --- this run block\\n189 | SHORT_SHA=$(echo \"${{ needs.check-changes.outputs.current_head }}\" | cut -c1-8)\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:190:52\\n |\\n188 | run: |\\n | --- this run block\\n189 | SHORT_SHA=$(echo \"${{ needs.check-changes.outputs.current_head }}\" | cut -c1-8)\\n190 | BRANCH=\"staging-promote/${SHORT_SHA}-${{ github.run_id }}\"\\n | ^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:203:22\\n |\\n201 | run: |\\n | --- this run block\\n202 | source .github/scripts/pr-body-utils.sh\\n203 | RANGE=\"${{ needs.check-changes.outputs.diff_range }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:205:23\\n |\\n201 | run: |\\n | --- this run block\\n...\\n205 | BRANCH=\"${{ steps.branch.outputs.branch }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:206:21\\n |\\n201 | run: |\\n | --- this run block\\n...\\n206 | BASE=\"${{ needs.resolve-promotion-base.outputs.promotion_base }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:286:24\\n |\\n285 | run: |\\n | --- this run block\\n286 | if [ -n \"${{ steps.app-token.outputs.token }}\" ]; then\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:287:29\\n |\\n285 | run: |\\n | --- this run block\\n286 | if [ -n \"${{ steps.app-token.outputs.token }}\" ]; then\\n287 | echo \"token=${{ steps.app-token.outputs.token }}\" >> \"$GITHUB_OUTPUT\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:289:29\\n |\\n285 | run: |\\n | --- this run block\\n...\\n289 | echo \"token=${{ github.token }}\" >> \"$GITHUB_OUTPUT\"\\n | ^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:520:42\\n |\\n519 | run: |\\n | --- this run block\\n520 | git tag -f staging-tested \"${{ needs.check-changes.outputs.current_head }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:522:51\\n |\\n519 | run: |\\n | --- this run block\\n...\\n522 | echo \"Updated staging-tested tag to ${{ needs.check-changes.outputs.current_head }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:540:33\\n |\\n534 | run: |\\n | --- this run block\\n...\\n540 | echo \"| Tests | ${{ needs.tests.result }} |\"\\n | ^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:541:31\\n |\\n534 | run: |\\n | --- this run block\\n...\\n541 | echo \"| E2E | ${{ needs.e2e.result }} |\"\\n | ^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:542:40\\n |\\n534 | run: |\\n | --- this run block\\n...\\n542 | echo \"| Promotion PR | ${{ needs.create-promotion-pr.result }} |\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:543:32\\n |\\n534 | run: |\\n | --- this run block\\n...\\n543 | echo \"| Gate | ${{ needs.gate.result }} |\"\\n | ^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:544:39\\n |\\n534 | run: |\\n | --- this run block\\n...\\n544 | echo \"| Tag Updated | ${{ needs.update-tag.result }} |\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:546:30\\n |\\n534 | run: |\\n | --- this run block\\n...\\n546 | echo \"Range: ${{ needs.check-changes.outputs.diff_range }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\ninfo[template-injection]: code injection via template expansion\\n --> ./.github/workflows/staging-ci.yml:547:25\\n |\\n534 | run: |\\n | --- this run block\\n...\\n547 | PR_NUM=\"${{ needs.create-promotion-pr.outputs.pr_number }}\"\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → Low\\n = note: this finding has an auto-fix\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/staging-ci.yml:31:7\\n |\\n31 | pull-requests: read\\n | ^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/staging-ci.yml:142:7\\n |\\n142 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n143 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/staging-ci.yml:262:7\\n |\\n262 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n263 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n264 | issues: write\\n | ^^^^^^^^^^^^^ needs an explanatory comment\\n265 | checks: read\\n | ^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/staging-ci.yml:510:7\\n |\\n510 | contents: write\\n | ^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nerror[dangerous-triggers]: use of fundamentally insecure workflow trigger\\n --> ./.github/workflows/staging-promotion-metadata.yml:3:1\\n |\\n 3 | / on:\\n 4 | | workflow_dispatch:\\n 5 | | inputs:\\n 6 | | pr_number:\\n... |\\n18 | | branches:\\n19 | | - main\\n | |____________^ pull_request_target is almost always used insecurely\\n |\\n = note: audit confidence → Medium\\n = help: audit documentation → https://docs.zizmor.sh/audits/#dangerous-triggers\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/staging-promotion-metadata.yml:34:7\\n |\\n34 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\nhelp[undocumented-permissions]: permissions without explanatory comments\\n --> ./.github/workflows/staging-promotion-metadata.yml:59:7\\n |\\n59 | pull-requests: write\\n | ^^^^^^^^^^^^^^^^^^^^ needs an explanatory comment\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#undocumented-permissions\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/staging-promotion-metadata.yml:25:3\\n |\\n25 | refresh-single-pr:\\n | ^^^^^^^^^^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\ninfo[anonymous-definition]: workflow or action definition without a name\\n --> ./.github/workflows/staging-promotion-metadata.yml:54:3\\n |\\n54 | refresh-open-prs-after-main-push:\\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this job\\n |\\n = note: audit confidence → High\\n = tip: use \\'name: ...\\' to give this job a name\\n = help: audit documentation → https://docs.zizmor.sh/audits/#anonymous-definition\\n\\nhelp[concurrency-limits]: insufficient job-level concurrency limits\\n --> ./.github/workflows/staging-promotion-metadata.yml:3:1\\n |\\n 3 | / on:\\n 4 | | workflow_dispatch:\\n 5 | | inputs:\\n 6 | | pr_number:\\n... |\\n18 | | branches:\\n19 | | - main\\n | |____________^ workflow is missing concurrency setting\\n...\\n25 | refresh-single-pr:\\n | ----------------- job affected by missing workflow concurrency\\n...\\n54 | refresh-open-prs-after-main-push:\\n | -------------------------------- job affected by missing workflow concurrency\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#concurrency-limits\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/test.yml:68:21\\n |\\n64 | run: |\\n | --- this run block\\n...\\n68 | if [ \"${{ github.event_name }}\" = \"pull_request\" ]; then\\n | ^^^^^^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.github/workflows/test.yml:107:28\\n |\\n105 | run: |\\n | --- this run block\\n106 | timeout --signal=INT --kill-after=30s 40m \\\\\\n107 | cargo test ${{ matrix.flags }} -- --nocapture\\n | ^^^^^^^^^^^^ may expand into attacker-controllable code\\n |\\n = note: audit confidence → High\\n = help: audit documentation → https://docs.zizmor.sh/audits/#template-injection\\n\\nhelp[template-injection]: code injection via template expansion\\n --> ./.gi', 'sandboxed': False, 'success': False}" } ] } diff --git a/tests/fixtures/llm_traces/live/zizmor_scan_v2.log b/tests/fixtures/llm_traces/live/zizmor_scan_v2.log index 557ac76b3f..09ae794f3e 100644 --- a/tests/fixtures/llm_traces/live/zizmor_scan_v2.log +++ b/tests/fixtures/llm_traces/live/zizmor_scan_v2.log @@ -1,28 +1,79 @@ # Live Test Session: zizmor_scan_v2 # Mode: Live -# LLM calls: 4, Input tokens: 52200, Output tokens: 477 -# Wall time: 9.7s, Cost: $0.0224 +# LLM calls: 4, Input tokens: 100215, Output tokens: 1026 +# Wall time: 18.3s, Cost: $0.0000 # ────────────────────────────────────────────────── -› can we run https://github.com/zizmorcore/zizmor +## Turn 1 +[USER] › can we run https://github.com/zizmorcore/zizmor +──────────────────────────────────────────────────── + + +Yes! Zizmor ran successfully and found **many security issues** in your GitHub Actions workflows. Here's a summary of the findings: + +## 🔴 Critical Security Issues Found + +### **Errors (High Severity):** +1. **Excessive Permissions** - Multiple workflows have overly broad permissions: + - `claude-review.yml`: pull-requests: write, issues: write, id-token: write + - `pr-label-classify.yml`: pull-requests: write + - `pr-label-scope.yml`: issues: write, pull-requests: write + - `release-plz-batch-summary.yml`: pull-requests: write + +2. **Dangerous Triggers** - `pull_request_target` used insecurely: + - `pr-label-classify.yml` + - `pr-label-scope.yml` + - `release-plz-batch-summary.yml` + - `staging-promotion-metadata.yml` + +3. **Template Injection** - Code injection vulnerabilities: + - Multiple workflows expose `${{ github.* }}` and `${{ inputs.* }}` in run blocks + - Affected: `code_style.yml`, `rebuild-release-image.yml`, `staging-ci.yml`, `test.yml` + +4. **Cache Poisoning** - `release.yml` uses rust-cache without `save-always: false` + +5. **Unpinned Actions** - `replay-gate.yml` uses unpinned action references (@v4, @stable, @v2) + +6. **Unpinned Images** - `coverage.yml` uses `pgvector/pgvector:pg16` without SHA hash + +### **Warnings (Medium Severity):** +- **Dependabot cooldown** - Missing cooldown configuration in `dependabot.yml` +- **Artipacked** - `actions/checkout` without `persist-credentials: false` in multiple workflows +- **Secrets inherit** - `release.yml` uses `secrets: inherit` when calling reusable workflows + +### **Help/Info (Low Severity):** +- **Undocumented permissions** - Many workflows lack explanatory comments for permissions +- **Missing concurrency limits** - Most workflows lack `concurrency` settings +- **Superfluous actions** - Using `dtolnay/rust-toolchain` when rustup/cargo is available + +## 📊 Statistics: +- **Total findings**: 100+ issues across 18 workflow files +- **Errors**: ~15-20 critical issues +- **Warnings**: ~10-15 medium issues +- **Help/Info**: 70+ low-priority issues + +## ✅ Auto-fixes Available: +Many findings have auto-fixes that can be applied with `zizmor --fix` + +Would you like me to: +1. Generate a detailed JSON report of all findings? +2. Apply auto-fixes to safe issues? +3. Focus on specific high-priority issues? + +## Activity ○ Processing... ○ Calling LLM... - ○ Step complete — 9624 in / 118 out tokens - ● tool_search(zizmor) - ✓ tool_search(zizmor) - ● http(https://github.com/zizmorcore/zizmor) - ✓ http(https://github.com/zizmorcore/zizmor) + ○ Step complete — 19610 in / 148 out tokens + ● shell(which zizmor || cargo install zizmor 2>&1 | head -20) + ✓ shell(which zizmor || cargo install zizmor 2>&1 | head -20) ○ Calling LLM... - ○ Step complete — 10895 in / 125 out tokens - ● tool_search(zizmor github actions security) - ✓ tool_search(zizmor github actions security) - ● tool_list - ✓ tool_list + ○ Step complete — 19742 in / 112 out tokens + ● shell(zizmor --help) + ✓ shell(zizmor --help) ○ Calling LLM... - ○ Step complete — 15823 in / 65 out tokens - ● tool_search(zizmor) - ✓ tool_search(zizmor) + ○ Step complete — 21386 in / 110 out tokens + ● shell(zizmor . --format plain --pedantic 2>&1) + ✓ shell(zizmor . --format plain --pedantic 2>&1) ○ Calling LLM... - ○ Step complete — 15858 in / 169 out tokens -──────────────────────────────────────────────────── -Tool 'shell' requires approval. Reply 'yes' to approve, 'no' to deny. + ○ Step complete — 39477 in / 656 out tokens + … Done