{"data":{"skill":{"slug":"kochetkov-ma-brewpage-publish","name":"brewpage-publish","icon":"📦","repo":"https://github.com/kochetkov-ma/claude-brewcode/tree/d2d42282fecec988447f9c9547959b31a8012644/skills/brewpage-publish","status":"approved","author":"kochetkov-ma","authorVersion":null,"skillstoreRevision":2},"audit":{"id":"0624628a-6ca4-4845-bb1d-7aba69d9848e","skill_id":"4bf85c8e-ddad-4143-9c98-4b5fde9536c8","version":5,"content_hash":"v3:98e33e143b9d10591d1a0a45cf7515e6a50429e6:c8abc29f3e57aefe8ab9b8dd5742dc6c9d7ba66affe74c1464a12bd61a2bddfc:1707afcafed0ce833cb8e64e59ee92d637707d17f72af438dd7009da6580f5e8:736b696c6c732f6b6f636865746b6f762d6d612f62726577706167652d7075626c697368:3c48a5a7d1f12f1973644ebc9150dd25","risk_level":"high","is_blocked":false,"safe_to_publish":false,"analysis_status":"ok","agent_auto_install_policy":"confirmation_required","manual_install_policy":"allowed","summary":"The static alerts match documentation, defensive exclusions, and expected publishing operations rather than demonstrated malicious behavior. Context review found unsafe history destinations, conflicting token-disclosure instructions, unattended privacy defaults, and unbounded ZIP inspection. No evidence found of deliberate credential theft or encoded executable payloads.","remediation":[{"issue":"The old-publication recovery guidance contradicts the prohibition on printing owner tokens.","severity":"high","suggestion":"Remove the instruction to report the owner token; require recovery replies to contain only the URL and local history location."},{"issue":"Token-history destinations can follow symlinks and permission failures do not stop publication.","severity":"high","suggestion":"Reject symlinked history paths and parents, create history atomically with mode 0600, and abort if ownership or permission checks fail."},{"issue":"Adding a gitignore entry does not protect history that is already tracked.","severity":"medium","suggestion":"Detect tracked history with git ls-files and refuse token storage until the file is removed from the index."},{"issue":"Missing answers permit publication without password protection.","severity":"medium","suggestion":"Require explicit access-policy approval before upload; allow unattended publication only through a separately supplied, deliberate authorization flag."},{"issue":"ZIP integrity testing can consume unbounded local processing time.","severity":"medium","suggestion":"Reject oversized archives before testing, enforce entry and expansion budgets with a structured ZIP parser, and apply child-process timeouts."}],"risk_factor_evidence":[{"factor":"network","evidence":[{"file":"LICENSE","line_end":3,"line_start":3},{"file":"README.md","line_end":113,"line_start":113},{"file":"README.md","line_end":123,"line_start":123},{"file":"scripts/brewpage-lib.sh","line_end":52,"line_start":52},{"file":"scripts/brewpage-run.sh","line_end":64,"line_start":64},{"file":"scripts/brewpage-run.sh","line_end":169,"line_start":169},{"file":"scripts/brewpage-run.sh","line_end":175,"line_start":175},{"file":"scripts/brewpage-run.sh","line_end":180,"line_start":180},{"file":"scripts/brewpage-run.sh","line_end":195,"line_start":195},{"file":"SKILL.md","line_end":84,"line_start":84},{"file":"SKILL.md","line_end":196,"line_start":196},{"file":"SKILL.md","line_end":204,"line_start":204},{"file":"SKILL.md","line_end":257,"line_start":257},{"file":"SKILL.md","line_end":258,"line_start":258}]},{"factor":"external_commands","evidence":[{"file":"scripts/brewpage-lib.sh","line_end":52,"line_start":52},{"file":"scripts/brewpage-lib.sh","line_end":53,"line_start":53},{"file":"scripts/brewpage-lib.sh","line_end":65,"line_start":65},{"file":"scripts/brewpage-lib.sh","line_end":66,"line_start":66},{"file":"scripts/brewpage-lib.sh","line_end":77,"line_start":77},{"file":"scripts/brewpage-lib.sh","line_end":80,"line_start":80},{"file":"scripts/brewpage-lib.sh","line_end":181,"line_start":181},{"file":"scripts/brewpage-lib.sh","line_end":202,"line_start":202},{"file":"scripts/brewpage-lib.sh","line_end":8,"line_start":8},{"file":"scripts/brewpage-lib.sh","line_end":9,"line_start":9},{"file":"scripts/brewpage-lib.sh","line_end":10,"line_start":10},{"file":"scripts/brewpage-lib.sh","line_end":21,"line_start":21},{"file":"scripts/brewpage-lib.sh","line_end":32,"line_start":32},{"file":"scripts/brewpage-lib.sh","line_end":37,"line_start":37},{"file":"scripts/brewpage-lib.sh","line_end":46,"line_start":46},{"file":"scripts/brewpage-lib.sh","line_end":78,"line_start":78},{"file":"scripts/brewpage-lib.sh","line_end":81,"line_start":81},{"file":"scripts/brewpage-lib.sh","line_end":120,"line_start":120},{"file":"scripts/brewpage-lib.sh","line_end":205,"line_start":205},{"file":"scripts/brewpage-lib.sh","line_end":207,"line_start":207},{"file":"scripts/brewpage-lib.sh","line_end":211,"line_start":211},{"file":"scripts/brewpage-lib.sh","line_end":212,"line_start":212},{"file":"scripts/brewpage-lib.sh","line_end":213,"line_start":213},{"file":"scripts/brewpage-lib.sh","line_end":215,"line_start":215},{"file":"scripts/brewpage-lib.sh","line_end":239,"line_start":239},{"file":"scripts/brewpage-lib.sh","line_end":80,"line_start":77},{"file":"scripts/brewpage-lib.sh","line_end":181,"line_start":80},{"file":"scripts/brewpage-run.sh","line_end":6,"line_start":6},{"file":"scripts/brewpage-run.sh","line_end":17,"line_start":17},{"file":"scripts/brewpage-run.sh","line_end":38,"line_start":38},{"file":"scripts/brewpage-run.sh","line_end":40,"line_start":40},{"file":"scripts/brewpage-run.sh","line_end":43,"line_start":43},{"file":"scripts/brewpage-run.sh","line_end":46,"line_start":46},{"file":"scripts/brewpage-run.sh","line_end":47,"line_start":47},{"file":"scripts/brewpage-run.sh","line_end":49,"line_start":49},{"file":"scripts/brewpage-run.sh","line_end":52,"line_start":52},{"file":"scripts/brewpage-run.sh","line_end":53,"line_start":53},{"file":"scripts/brewpage-run.sh","line_end":64,"line_start":64},{"file":"scripts/brewpage-run.sh","line_end":94,"line_start":94},{"file":"scripts/brewpage-run.sh","line_end":117,"line_start":117},{"file":"scripts/brewpage-run.sh","line_end":118,"line_start":118},{"file":"scripts/brewpage-run.sh","line_end":119,"line_start":119},{"file":"scripts/brewpage-run.sh","line_end":170,"line_start":169},{"file":"scripts/brewpage-run.sh","line_end":176,"line_start":175},{"file":"scripts/brewpage-run.sh","line_end":180,"line_start":180},{"file":"scripts/brewpage-run.sh","line_end":186,"line_start":186},{"file":"scripts/brewpage-run.sh","line_end":191,"line_start":191},{"file":"scripts/brewpage-run.sh","line_end":195,"line_start":195},{"file":"scripts/publish.mjs","line_end":4,"line_start":4},{"file":"scripts/publish.mjs","line_end":123,"line_start":123}]},{"factor":"filesystem","evidence":[{"file":"scripts/brewpage-lib.sh","line_end":99,"line_start":99},{"file":"scripts/brewpage-lib.sh","line_end":10,"line_start":10},{"file":"scripts/brewpage-lib.sh","line_end":14,"line_start":14},{"file":"scripts/brewpage-lib.sh","line_end":28,"line_start":28},{"file":"scripts/brewpage-lib.sh","line_end":38,"line_start":38},{"file":"scripts/brewpage-lib.sh","line_end":64,"line_start":64},{"file":"scripts/brewpage-lib.sh","line_end":8,"line_start":8},{"file":"scripts/brewpage-lib.sh","line_end":9,"line_start":9},{"file":"scripts/brewpage-lib.sh","line_end":10,"line_start":10},{"file":"scripts/brewpage-lib.sh","line_end":21,"line_start":21},{"file":"scripts/brewpage-lib.sh","line_end":59,"line_start":59},{"file":"scripts/brewpage-lib.sh","line_end":67,"line_start":67},{"file":"scripts/brewpage-lib.sh","line_end":147,"line_start":147},{"file":"scripts/brewpage-lib.sh","line_end":148,"line_start":148},{"file":"scripts/brewpage-lib.sh","line_end":163,"line_start":163},{"file":"scripts/brewpage-lib.sh","line_end":175,"line_start":175},{"file":"scripts/brewpage-lib.sh","line_end":198,"line_start":198},{"file":"scripts/brewpage-lib.sh","line_end":222,"line_start":222},{"file":"scripts/brewpage-lib.sh","line_end":108,"line_start":108},{"file":"scripts/brewpage-run.sh","line_end":53,"line_start":53},{"file":"scripts/brewpage-run.sh","line_end":62,"line_start":62},{"file":"scripts/brewpage-run.sh","line_end":68,"line_start":68},{"file":"scripts/brewpage-run.sh","line_end":174,"line_start":174},{"file":"scripts/publish.mjs","line_end":80,"line_start":80},{"file":"scripts/publish.mjs","line_end":169,"line_start":169},{"file":"SKILL.md","line_end":195,"line_start":195},{"file":"SKILL.md","line_end":203,"line_start":203},{"file":"SKILL.md","line_end":239,"line_start":239}]},{"factor":"env_access","evidence":[{"file":"scripts/publish.mjs","line_end":109,"line_start":109},{"file":"scripts/publish.mjs","line_end":110,"line_start":110},{"file":"scripts/publish.mjs","line_end":109,"line_start":109},{"file":"scripts/publish.mjs","line_end":110,"line_start":110}]}],"critical_findings":[],"high_findings":[{"title":"Owner-token history follows repository-controlled paths","locations":[{"file":"scripts/brewpage-lib.sh","line_end":71,"line_start":43},{"file":"scripts/brewpage-lib.sh","line_end":81,"line_start":75}],"confidence":0.96,"description":"History writes follow symlinks, and chmod failures are ignored. A crafted checkout can redirect owner tokens outside the intended private history file.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"The code checks -f but never rejects symlinked history files or parent directories. Redirection and chmod follow these paths before token append."},{"title":"Recovery guidance conflicts with owner-token confidentiality","locations":[{"file":"SKILL.md","line_end":213,"line_start":213},{"file":"SKILL.md","line_end":244,"line_start":244}],"confidence":0.95,"description":"The recovery note says \"report the new URL and owner token\", contradicting the explicit prohibition on conversational token disclosure. Following it could expose management credentials.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"Both conflicting instructions appear verbatim in the skill. Exposure depends on agent interpretation; the script does not itself print owner tokens in normal results."}],"medium_findings":[{"title":"Unanswered privacy prompts permit unprotected publication","locations":[{"file":"SKILL.md","line_end":119,"line_start":119},{"file":"SKILL.md","line_end":139,"line_start":125},{"file":"SKILL.md","line_end":183,"line_start":169}],"confidence":0.91,"description":"Missing namespace and password answers default to an unlisted link without authentication. Unattended runs can publish selected content without explicit access-policy approval.","review_kind":"security","source_category":"semantic","source_severity":"medium","confidence_reasoning":"The workflow explicitly treats no answer as permission to use an unlisted namespace and no password. Publication is intended, but privacy consent fails open."},{"title":"Archive integrity checks lack local resource limits","locations":[{"file":"scripts/publish.mjs","line_end":135,"line_start":121},{"file":"scripts/publish.mjs","line_end":214,"line_start":197}],"confidence":0.94,"description":"Supplied ZIP files undergo decompression testing before upload without a timeout or expansion cap. A malicious archive can exhaust local CPU or stall inspection.","review_kind":"security","source_category":"semantic","source_severity":"medium","confidence_reasoning":"unzip -tq processes archive contents synchronously with no timeout. maxBuffer limits captured output, not decompression work or expanded bytes."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":6,"total_lines":1086,"audit_model":"codex","audited_at":"2026-10-26T20:38:18.166+00:00","created_at":"2026-10-26T21:05:54.542032+00:00","static_findings":[{"id":"network:LICENSE:3:hardcoded-url","file":"LICENSE","pattern":"Hardcoded URL","snippet":"Copyright (c) 2025-2026 Maksim Kochetkov (kochetkov-ma), https://github.com/kochetkov-ma/claude-brew","category":"network","line_end":3,"severity":"low","line_start":3},{"id":"network:README.md:113:hardcoded-url","file":"README.md","pattern":"Hardcoded URL","snippet":"curl -X DELETE \"https://brewpage.app/api/{type}/{ns}/{id}\" -H \"X-Owner-Token: {token}\"","category":"network","line_end":113,"severity":"low","line_start":113},{"id":"network:README.md:123:hardcoded-url","file":"README.md","pattern":"Hardcoded URL","snippet":"claude plugin marketplace add https://github.com/kochetkov-ma/claude-brewcode","category":"network","line_end":123,"severity":"low","line_start":123},{"id":"sensitive:README.md:68:environment-file-access","file":"README.md","pattern":"Environment file access","snippet":"The directory bundle is **allowlisted**: it drops system files (`.DS_Store`, `__MACOSX/`, `Thumbs.db","category":"sensitive","line_end":68,"severity":"high","line_start":68},{"id":"sensitive:README.md:68:sqlite-database-file","file":"README.md","pattern":"SQLite database file","snippet":"The directory bundle is **allowlisted**: it drops system files (`.DS_Store`, `__MACOSX/`, `Thumbs.db","category":"sensitive","line_end":68,"severity":"medium","line_start":68},{"id":"blocker:README.md:87:system-reconnaissance","file":"README.md","pattern":"System reconnaissance","snippet":"An upload may return an existing publication. Keep that winner's identity, metadata and exact server","category":"blocker","line_end":87,"severity":"low","line_start":87},{"id":"external_commands:scripts/brewpage-lib.sh:52:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"> Delete: `curl -s -X DELETE \"<Owner API>\" -H \"X-Owner-Token: TOKEN\"`; rows without one: `https://br","category":"external_commands","line_end":52,"severity":"medium","line_start":52},{"id":"external_commands:scripts/brewpage-lib.sh:53:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"> Update a site (same URL; old publications answer 409, see above): `PUT /api/sites/<ns>/<id>` with ","category":"external_commands","line_end":53,"severity":"medium","line_start":53},{"id":"external_commands:scripts/brewpage-lib.sh:65:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"# `.git` is a FILE in a worktree and in a submodule, so `-d` misses both and the owner tokens","category":"external_commands","line_end":65,"severity":"medium","line_start":65},{"id":"external_commands:scripts/brewpage-lib.sh:66:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"# end up committable. `rev-parse --git-dir` is correct for plain, worktree and nested checkouts.","category":"external_commands","line_end":66,"severity":"medium","line_start":66},{"id":"external_commands:scripts/brewpage-lib.sh:77:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"printf '| %s | [%s](%s) | `%s` | %sd | %s | %s | `%s` |\\n' \\","category":"external_commands","line_end":77,"severity":"medium","line_start":77},{"id":"external_commands:scripts/brewpage-lib.sh:80:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"printf '| %s | [%s](%s) | `%s` | %sd | %s |\\n' \\","category":"external_commands","line_end":80,"severity":"medium","line_start":80},{"id":"external_commands:scripts/brewpage-lib.sh:181:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"# A function has its own positional parameters, so no `set --` juggling is needed.","category":"external_commands","line_end":181,"severity":"medium","line_start":181},{"id":"external_commands:scripts/brewpage-lib.sh:202:ruby-shell-backtick-execution","file":"scripts/brewpage-lib.sh","pattern":"Ruby/shell backtick execution","snippet":"# `site` is the only type whose response carries .fileCount.","category":"external_commands","line_end":202,"severity":"medium","line_start":202},{"id":"external_commands:scripts/brewpage-lib.sh:8:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"p=$(cd \"$1\" 2>/dev/null && pwd -P) || return 1","category":"external_commands","line_end":8,"severity":"medium","line_start":8},{"id":"external_commands:scripts/brewpage-lib.sh:9:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"[ -n \"${HOME:-}\" ] && [ \"$p\" = \"$(cd \"$HOME\" 2>/dev/null && pwd -P)\" ] && return 0","category":"external_commands","line_end":9,"severity":"medium","line_start":9},{"id":"external_commands:scripts/brewpage-lib.sh:10:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"[ -n \"${CLAUDE_CONFIG_DIR:-}\" ] && [ \"$p/.claude\" = \"$(cd \"$CLAUDE_CONFIG_DIR\" 2>/dev/null && pwd -P","category":"external_commands","line_end":10,"severity":"medium","line_start":10},{"id":"external_commands:scripts/brewpage-lib.sh:21:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"root=$(git rev-parse --show-toplevel 2>/dev/null) || root=\"\"","category":"external_commands","line_end":21,"severity":"medium","line_start":21},{"id":"external_commands:scripts/brewpage-lib.sh:32:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"d=$(dirname \"$d\")","category":"external_commands","line_end":32,"severity":"medium","line_start":32},{"id":"external_commands:scripts/brewpage-lib.sh:37:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"BP_ROOT=\"$(bp_project_root)\"","category":"external_commands","line_end":37,"severity":"medium","line_start":37},{"id":"external_commands:scripts/brewpage-lib.sh:46:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"mkdir -p \"$(dirname \"$HISTORY_FILE\")\" || return 1","category":"external_commands","line_end":46,"severity":"medium","line_start":46},{"id":"external_commands:scripts/brewpage-lib.sh:78:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"\"$(date '+%Y-%m-%d %H:%M')\" \"$1\" \"$1\" \"$2\" \"$3\" \"$4\" \"$5\" \"${6:-}\" >> \"$HISTORY_FILE\"","category":"external_commands","line_end":78,"severity":"medium","line_start":78},{"id":"external_commands:scripts/brewpage-lib.sh:81:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"\"$(date '+%Y-%m-%d %H:%M')\" \"$1\" \"$1\" \"$2\" \"$3\" \"$4\" >> \"$HISTORY_FILE\"","category":"external_commands","line_end":81,"severity":"medium","line_start":81},{"id":"external_commands:scripts/brewpage-lib.sh:120:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"[ -n \"$(find \"$BP_RUN_DIR\" -maxdepth 0 -type d -perm 0700 -print)\" ] || {","category":"external_commands","line_end":120,"severity":"medium","line_start":120},{"id":"external_commands:scripts/brewpage-lib.sh:205:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"url=$(printf '%s' \"$response\" | jq -r '.link // empty')","category":"external_commands","line_end":205,"severity":"medium","line_start":205},{"id":"external_commands:scripts/brewpage-lib.sh:207:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"reason=$(bp_error_reason \"$response\")","category":"external_commands","line_end":207,"severity":"medium","line_start":207},{"id":"external_commands:scripts/brewpage-lib.sh:211:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"token=$(printf '%s' \"$response\" | jq -r '.ownerToken // empty')","category":"external_commands","line_end":211,"severity":"medium","line_start":211},{"id":"external_commands:scripts/brewpage-lib.sh:212:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"owner_api=$(printf '%s' \"$response\" | jq -r '.ownerLink // empty')","category":"external_commands","line_end":212,"severity":"medium","line_start":212},{"id":"external_commands:scripts/brewpage-lib.sh:213:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"identity=$(printf '%s' \"$response\" | jq -c '{id, namespace, type, routingCohort, deliveryMode, modeL","category":"external_commands","line_end":213,"severity":"medium","line_start":213},{"id":"external_commands:scripts/brewpage-lib.sh:215:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"fcount=$(printf '%s' \"$response\" | jq -r '.fileCount // \"?\"')","category":"external_commands","line_end":215,"severity":"medium","line_start":215},{"id":"external_commands:scripts/brewpage-lib.sh:239:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"ENTRY=$(printf '%s\\n' \"$manifest\" | sed -n 's/^ENTRY: //p')","category":"external_commands","line_end":239,"severity":"medium","line_start":239},{"id":"external_commands:scripts/brewpage-lib.sh:77:template-literal-with-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Template literal with command substitution","snippet":"printf '| %s | [%s](%s) | `%s` | %sd | %s | %s | `%s` |\\n' \\","category":"external_commands","line_end":80,"severity":"medium","line_start":77},{"id":"external_commands:scripts/brewpage-lib.sh:80:template-literal-with-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Template literal with command substitution","snippet":"printf '| %s | [%s](%s) | `%s` | %sd | %s |\\n' \\","category":"external_commands","line_end":181,"severity":"medium","line_start":80},{"id":"network:scripts/brewpage-lib.sh:52:hardcoded-url","file":"scripts/brewpage-lib.sh","pattern":"Hardcoded URL","snippet":"> Delete: `curl -s -X DELETE \"<Owner API>\" -H \"X-Owner-Token: TOKEN\"`; rows without one: `https://br","category":"network","line_end":52,"severity":"low","line_start":52},{"id":"filesystem:scripts/brewpage-lib.sh:99:path-traversal-sequence","file":"scripts/brewpage-lib.sh","pattern":"Path traversal sequence","snippet":"*[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._/-]* | */../* | ../* | */..) echo","category":"filesystem","line_end":99,"severity":"high","line_start":99},{"id":"filesystem:scripts/brewpage-lib.sh:10:hidden-file-access","file":"scripts/brewpage-lib.sh","pattern":"Hidden file access","snippet":"[ -n \"${CLAUDE_CONFIG_DIR:-}\" ] && [ \"$p/.claude\" = \"$(cd \"$CLAUDE_CONFIG_DIR\" 2>/dev/null && pwd -P","category":"filesystem","line_end":10,"severity":"medium","line_start":10},{"id":"filesystem:scripts/brewpage-lib.sh:14:hidden-file-access","file":"scripts/brewpage-lib.sh","pattern":"Hidden file access","snippet":"# walk for .git/.claude (profile parents skipped) -> PWD. The history file must not follow a nested ","category":"filesystem","line_end":14,"severity":"medium","line_start":14},{"id":"filesystem:scripts/brewpage-lib.sh:28:hidden-file-access","file":"scripts/brewpage-lib.sh","pattern":"Hidden file access","snippet":"if [ -d \"$d/.git\" ] || { [ -d \"$d/.claude\" ] && ! bp_is_profile_parent \"$d\"; }; then","category":"filesystem","line_end":28,"severity":"medium","line_start":28},{"id":"filesystem:scripts/brewpage-lib.sh:38:hidden-file-access","file":"scripts/brewpage-lib.sh","pattern":"Hidden file access","snippet":"HISTORY_FILE=\"$BP_ROOT/.claude/brewpage-history.md\"","category":"filesystem","line_end":38,"severity":"medium","line_start":38},{"id":"filesystem:scripts/brewpage-lib.sh:64:hidden-file-access","file":"scripts/brewpage-lib.sh","pattern":"Hidden file access","snippet":"local line=\"$1\" gi=\"$BP_ROOT/.gitignore\"","category":"filesystem","line_end":64,"severity":"medium","line_start":64},{"id":"filesystem:scripts/brewpage-lib.sh:8:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"p=$(cd \"$1\" 2>/dev/null && pwd -P) || return 1","category":"filesystem","line_end":8,"severity":"low","line_start":8},{"id":"filesystem:scripts/brewpage-lib.sh:9:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"[ -n \"${HOME:-}\" ] && [ \"$p\" = \"$(cd \"$HOME\" 2>/dev/null && pwd -P)\" ] && return 0","category":"filesystem","line_end":9,"severity":"low","line_start":9},{"id":"filesystem:scripts/brewpage-lib.sh:10:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"[ -n \"${CLAUDE_CONFIG_DIR:-}\" ] && [ \"$p/.claude\" = \"$(cd \"$CLAUDE_CONFIG_DIR\" 2>/dev/null && pwd -P","category":"filesystem","line_end":10,"severity":"low","line_start":10},{"id":"filesystem:scripts/brewpage-lib.sh:21:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"root=$(git rev-parse --show-toplevel 2>/dev/null) || root=\"\"","category":"filesystem","line_end":21,"severity":"low","line_start":21},{"id":"filesystem:scripts/brewpage-lib.sh:59:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"chmod 600 \"$HISTORY_FILE\" 2>/dev/null || true","category":"filesystem","line_end":59,"severity":"low","line_start":59},{"id":"filesystem:scripts/brewpage-lib.sh:67:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"git -C \"$BP_ROOT\" rev-parse --git-dir >/dev/null 2>&1 || [ -f \"$gi\" ] || return 0","category":"filesystem","line_end":67,"severity":"low","line_start":67},{"id":"filesystem:scripts/brewpage-lib.sh:147:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"command -v jq >/dev/null || { echo \"FAILED: jq required\"; return 1; }","category":"filesystem","line_end":147,"severity":"low","line_start":147},{"id":"filesystem:scripts/brewpage-lib.sh:148:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"jq -ner --rawfile password \"$1\" \"$BP_PW_FILTER\" >/dev/null 2>&1 ||","category":"filesystem","line_end":148,"severity":"low","line_start":148},{"id":"filesystem:scripts/brewpage-lib.sh:163:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"command -v jq >/dev/null || { echo \"FAILED: jq required\"; return 1; }","category":"filesystem","line_end":163,"severity":"low","line_start":163},{"id":"filesystem:scripts/brewpage-lib.sh:175:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"(umask 077; jq -ner --rawfile password \"$password_file\" \"$BP_PW_FILTER\" > \"$BP_HEADER_FILE\") 2>/dev/","category":"filesystem","line_end":175,"severity":"low","line_start":175},{"id":"filesystem:scripts/brewpage-lib.sh:198:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"| \"HTTP \\(.status): \\((.message // .error // \"\") | tostring | explode | map(if . < 32 then 32 else .","category":"filesystem","line_end":198,"severity":"low","line_start":198},{"id":"filesystem:scripts/brewpage-lib.sh:222:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"printf '%s' \"$response\" | jq -r '.notices[]?.message // empty | \"NOTICE: \" + (tostring | explode | m","category":"filesystem","line_end":222,"severity":"low","line_start":222},{"id":"filesystem:scripts/brewpage-lib.sh:108:temp-file-creation","file":"scripts/brewpage-lib.sh","pattern":"Temp file creation","snippet":"(umask 077; mktemp -d \"$BP_TMPDIR/brewpage.XXXXXX\")","category":"filesystem","line_end":108,"severity":"low","line_start":108},{"id":"blocker:scripts/brewpage-lib.sh:115:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"*) echo \"FAILED: invalid publish run id\"; return 1 ;;","category":"blocker","line_end":115,"severity":"low","line_start":115},{"id":"blocker:scripts/brewpage-lib.sh:117:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"case \"$id\" in *[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.]*) echo \"FAILED: in","category":"blocker","line_end":117,"severity":"low","line_start":117},{"id":"blocker:scripts/brewpage-lib.sh:140:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"then \"X-Password: \" + $p else error(\"invalid password\") end'","category":"blocker","line_end":140,"severity":"low","line_start":140},{"id":"blocker:scripts/brewpage-lib.sh:142:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"# {password_file} slot: absolute path to a readable non-symlink regular file with a valid password.","category":"blocker","line_end":142,"severity":"low","line_start":142},{"id":"blocker:scripts/brewpage-lib.sh:225:network-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"Network reconnaissance","snippet":"# publish.mjs verdict for both site blocks: success -> ENTRY from manifest; else rc 2 (needs human O","category":"blocker","line_end":225,"severity":"low","line_start":225},{"id":"external_commands:scripts/brewpage-run.sh:6:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"HERE=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"","category":"external_commands","line_end":6,"severity":"medium","line_start":6},{"id":"external_commands:scripts/brewpage-run.sh:17:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"BP_FRESH=$(bp_prepare) || die \"cannot allocate a private run directory\"","category":"external_commands","line_end":17,"severity":"medium","line_start":17},{"id":"external_commands:scripts/brewpage-run.sh:38:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"abs=$(cd \"$p\" && pwd -P)","category":"external_commands","line_end":38,"severity":"medium","line_start":38},{"id":"external_commands:scripts/brewpage-run.sh:40:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"html_files=$(cd \"$abs\" && find . -type f \\( -name '*.html' -o -name '*.htm' \\) | sed 's|^\\./||' | LC","category":"external_commands","line_end":40,"severity":"medium","line_start":40},{"id":"external_commands:scripts/brewpage-run.sh:43:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"entry=$(printf '%s\\n' \"$html_files\" | awk -F/ 'NF { print NF \"\\t\" $0 }' | LC_ALL=C sort -s -n -k1,1 ","category":"external_commands","line_end":43,"severity":"medium","line_start":43},{"id":"external_commands:scripts/brewpage-run.sh:46:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"\"$(find \"$abs\" -type f | wc -l | tr -d ' ')\" \"$(printf '%s' \"$html_files\" | grep -c . || true)\" \\","category":"external_commands","line_end":46,"severity":"medium","line_start":46},{"id":"external_commands:scripts/brewpage-run.sh:47:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"\"$(du -sk \"$abs\" | cut -f1)\" \"${entry:-none}\"","category":"external_commands","line_end":47,"severity":"medium","line_start":47},{"id":"external_commands:scripts/brewpage-run.sh:49:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"abs=\"$(cd \"$(dirname \"$p\")\" && pwd -P)/$(basename \"$p\")\"","category":"external_commands","line_end":49,"severity":"medium","line_start":49},{"id":"external_commands:scripts/brewpage-run.sh:52:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"printf 'TYPE: %s\\nPATH: %s\\nBYTES: %s\\nMIME: %s\\n' \"$type\" \"$abs\" \"$(wc -c < \"$abs\" | tr -d ' ')\" \\","category":"external_commands","line_end":52,"severity":"medium","line_start":52},{"id":"external_commands:scripts/brewpage-run.sh:53:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"\"$(file --mime-type -b -- \"$abs\" 2>/dev/null || echo unknown)\"","category":"external_commands","line_end":53,"severity":"medium","line_start":53},{"id":"external_commands:scripts/brewpage-run.sh:64:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"body=$(curl -s -A \"ClaudeCode/1.0\" https://brewpage.app/api/limits) || die \"limits request failed\"","category":"external_commands","line_end":64,"severity":"medium","line_start":64},{"id":"external_commands:scripts/brewpage-run.sh:94:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"printf 'RUN: %s\\nBYTES: %s\\n' \"$run\" \"$(wc -c < \"$file\" | tr -d ' ')\"","category":"external_commands","line_end":94,"severity":"medium","line_start":94},{"id":"external_commands:scripts/brewpage-run.sh:117:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"--text) need \"$#\" \"$1\"; text=\"$2\"; have_text=1; sources=$((sources + 1)); shift 2 ;;","category":"external_commands","line_end":117,"severity":"medium","line_start":117},{"id":"external_commands:scripts/brewpage-run.sh:118:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"--run) need \"$#\" \"$1\"; run=\"$2\"; sources=$((sources + 1)); shift 2 ;;","category":"external_commands","line_end":118,"severity":"medium","line_start":118},{"id":"external_commands:scripts/brewpage-run.sh:119:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"--path) need \"$#\" \"$1\"; path=\"$2\"; sources=$((sources + 1)); shift 2 ;;","category":"external_commands","line_end":119,"severity":"medium","line_start":119},{"id":"external_commands:scripts/brewpage-run.sh:169:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"response=$(bp_post \"https://brewpage.app/api/html?ns=$NS&ttl=$DAYS&format=markdown\" \\","category":"external_commands","line_end":170,"severity":"medium","line_start":169},{"id":"external_commands:scripts/brewpage-run.sh:175:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"response=$(bp_post \"https://brewpage.app/api/json?ns=$NS&ttl=$DAYS\" \\","category":"external_commands","line_end":176,"severity":"medium","line_start":175},{"id":"external_commands:scripts/brewpage-run.sh:180:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"response=$(bp_post \"https://brewpage.app/api/files?ns=$NS&ttl=$DAYS\" -F \"file=@$path\") || die \"uploa","category":"external_commands","line_end":180,"severity":"medium","line_start":180},{"id":"external_commands:scripts/brewpage-run.sh:186:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"manifest=$(node \"$HERE/publish.mjs\" pack --dir \"$path\" --out \"$archive\" ${ENTRY:+--entry \"$ENTRY\"}) ","category":"external_commands","line_end":186,"severity":"medium","line_start":186},{"id":"external_commands:scripts/brewpage-run.sh:191:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"manifest=$(node \"$HERE/publish.mjs\" inspect --zip \"$path\" ${ENTRY:+--entry \"$ENTRY\"}) || rc=$?","category":"external_commands","line_end":191,"severity":"medium","line_start":191},{"id":"external_commands:scripts/brewpage-run.sh:195:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"response=$(bp_post \"https://brewpage.app/api/sites?ns=$NS&ttl=$DAYS&entry=$(jq -nr --arg e \"$ENTRY\" ","category":"external_commands","line_end":195,"severity":"medium","line_start":195},{"id":"network:scripts/brewpage-run.sh:64:hardcoded-url","file":"scripts/brewpage-run.sh","pattern":"Hardcoded URL","snippet":"body=$(curl -s -A \"ClaudeCode/1.0\" https://brewpage.app/api/limits) || die \"limits request failed\"","category":"network","line_end":64,"severity":"low","line_start":64},{"id":"network:scripts/brewpage-run.sh:169:hardcoded-url","file":"scripts/brewpage-run.sh","pattern":"Hardcoded URL","snippet":"response=$(bp_post \"https://brewpage.app/api/html?ns=$NS&ttl=$DAYS&format=markdown\" \\","category":"network","line_end":169,"severity":"low","line_start":169},{"id":"network:scripts/brewpage-run.sh:175:hardcoded-url","file":"scripts/brewpage-run.sh","pattern":"Hardcoded URL","snippet":"response=$(bp_post \"https://brewpage.app/api/json?ns=$NS&ttl=$DAYS\" \\","category":"network","line_end":175,"severity":"low","line_start":175},{"id":"network:scripts/brewpage-run.sh:180:hardcoded-url","file":"scripts/brewpage-run.sh","pattern":"Hardcoded URL","snippet":"response=$(bp_post \"https://brewpage.app/api/files?ns=$NS&ttl=$DAYS\" -F \"file=@$path\") || die \"uploa","category":"network","line_end":180,"severity":"low","line_start":180},{"id":"network:scripts/brewpage-run.sh:195:hardcoded-url","file":"scripts/brewpage-run.sh","pattern":"Hardcoded URL","snippet":"response=$(bp_post \"https://brewpage.app/api/sites?ns=$NS&ttl=$DAYS&entry=$(jq -nr --arg e \"$ENTRY\" ","category":"network","line_end":195,"severity":"low","line_start":195},{"id":"filesystem:scripts/brewpage-run.sh:53:standard-device-file-access","file":"scripts/brewpage-run.sh","pattern":"Standard device file access","snippet":"\"$(file --mime-type -b -- \"$abs\" 2>/dev/null || echo unknown)\"","category":"filesystem","line_end":53,"severity":"low","line_start":53},{"id":"filesystem:scripts/brewpage-run.sh:62:standard-device-file-access","file":"scripts/brewpage-run.sh","pattern":"Standard device file access","snippet":"command -v jq >/dev/null || die \"jq required\"","category":"filesystem","line_end":62,"severity":"low","line_start":62},{"id":"filesystem:scripts/brewpage-run.sh:68:standard-device-file-access","file":"scripts/brewpage-run.sh","pattern":"Standard device file access","snippet":"\"PATH_MAX_CHARS: \\($s.maxPathChars)\", \"PATH_MAX_BYTES: \\($s.maxPathBytes)\", \"NAME_MAX_BYTES: \\($s.ma","category":"filesystem","line_end":68,"severity":"low","line_start":68},{"id":"filesystem:scripts/brewpage-run.sh:174:standard-device-file-access","file":"scripts/brewpage-run.sh","pattern":"Standard device file access","snippet":"jq empty \"$content\" 2>/dev/null || die \"payload is not valid JSON\"","category":"filesystem","line_end":174,"severity":"low","line_start":174},{"id":"blocker:scripts/brewpage-run.sh:141:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"local id pwmode=none","category":"blocker","line_end":141,"severity":"low","line_start":141},{"id":"blocker:scripts/brewpage-run.sh:159:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"[ -f \"$content\" ] || die \"run $id has no staged text\"","category":"blocker","line_end":159,"severity":"low","line_start":159},{"id":"blocker:scripts/brewpage-run.sh:174:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"jq empty \"$content\" 2>/dev/null || die \"payload is not valid JSON\"","category":"blocker","line_end":174,"severity":"low","line_start":174},{"id":"external_commands:scripts/publish.mjs:4:node-js-child-process-module","file":"scripts/publish.mjs","pattern":"Node.js child_process module","snippet":"import { spawnSync } from 'node:child_process';","category":"external_commands","line_end":4,"severity":"high","line_start":4},{"id":"external_commands:scripts/publish.mjs:123:synchronous-spawn","file":"scripts/publish.mjs","pattern":"Synchronous spawn","snippet":"const r = spawnSync('unzip', [flag, zipPath], { encoding: 'utf8', maxBuffer: LIST_MAX_BUFFER });","category":"external_commands","line_end":123,"severity":"high","line_start":123},{"id":"external_commands:scripts/publish.mjs:173:synchronous-spawn","file":"scripts/publish.mjs","pattern":"Synchronous spawn","snippet":"const z = spawnSync('zip', ['-q', '-X', '-@', out], {","category":"external_commands","line_end":173,"severity":"high","line_start":173},{"id":"external_commands:scripts/publish.mjs:2:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** Offline SITE bundle build/verify: `pack --dir <abs-dir> --out <abs.zip> [--entry <name>]` | `ins","category":"external_commands","line_end":2,"severity":"medium","line_start":2},{"id":"external_commands:scripts/publish.mjs:26:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** True when a dot-named segment, outside the root `.well-known/`, keeps the path out of a site. */","category":"external_commands","line_end":26,"severity":"medium","line_start":26},{"id":"external_commands:scripts/publish.mjs:29:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** Extension-less files ship only inside the root `.well-known/` (e.g. `apple-app-site-association`","category":"external_commands","line_end":29,"severity":"medium","line_start":29},{"id":"external_commands:scripts/publish.mjs:30:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"const isWellKnownBare = (rel) => rel.startsWith(`${TRUSTED_DOT_DIR}/`) && extname(rel) === '';","category":"external_commands","line_end":30,"severity":"medium","line_start":30},{"id":"external_commands:scripts/publish.mjs:37:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** `unzip` stdout cap: Node's 1 MB default kills `-Z1` on a valid site with >1 MB of names (ENOBUFS","category":"external_commands","line_end":37,"severity":"medium","line_start":37},{"id":"external_commands:scripts/publish.mjs:41:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`FAILED: ${msg}`);","category":"external_commands","line_end":41,"severity":"medium","line_start":41},{"id":"external_commands:scripts/publish.mjs:51:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (!k.startsWith('--') || v === undefined) die(`bad argument near \"${k}\"`);","category":"external_commands","line_end":51,"severity":"medium","line_start":51},{"id":"external_commands:scripts/publish.mjs:60:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"die(`entry \"${entry}\" is not a plain relative file name`);","category":"external_commands","line_end":60,"severity":"medium","line_start":60},{"id":"external_commands:scripts/publish.mjs:90:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (!names.includes(requested)) die(`entry \"${requested}\" is not in the archive`);","category":"external_commands","line_end":90,"severity":"medium","line_start":90},{"id":"external_commands:scripts/publish.mjs:102:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** True when `p` is an executable regular file. */","category":"external_commands","line_end":102,"severity":"medium","line_start":102},{"id":"external_commands:scripts/publish.mjs:111:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (!dirs.some((dir) => exts.some((ext) => isExecutable(join(dir, bin + ext))))) die(`${bin} require","category":"external_commands","line_end":111,"severity":"medium","line_start":111},{"id":"external_commands:scripts/publish.mjs:116:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (r.status !== 0 && r.status !== null) return `${bin} exited ${r.status}`;","category":"external_commands","line_end":116,"severity":"medium","line_start":116},{"id":"external_commands:scripts/publish.mjs:117:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (r.error) return `${bin} failed (${r.error.code || r.error.message})`;","category":"external_commands","line_end":117,"severity":"medium","line_start":117},{"id":"external_commands:scripts/publish.mjs:118:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"return r.signal ? `${bin} killed by ${r.signal}` : '';","category":"external_commands","line_end":118,"severity":"medium","line_start":118},{"id":"external_commands:scripts/publish.mjs:121:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** One `unzip` run: { out }, or { why } telling a bad archive (non-zero exit) from a check that nev","category":"external_commands","line_end":121,"severity":"medium","line_start":121},{"id":"external_commands:scripts/publish.mjs:126:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"return why ? { why: `archive could not be checked: ${why}` } : { out: r.stdout || '' };","category":"external_commands","line_end":126,"severity":"medium","line_start":126},{"id":"external_commands:scripts/publish.mjs:129:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"/** `unzip -tq` then `unzip -Z1`: { names } sorted, directory entries dropped, or { why }. */","category":"external_commands","line_end":129,"severity":"medium","line_start":129},{"id":"external_commands:scripts/publish.mjs:141:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`ARCHIVE MANIFEST — ${basename(zipPath)}`);","category":"external_commands","line_end":141,"severity":"medium","line_start":141},{"id":"external_commands:scripts/publish.mjs:142:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"for (const n of names) console.log(`  ${n}`);","category":"external_commands","line_end":142,"severity":"medium","line_start":142},{"id":"external_commands:scripts/publish.mjs:143:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`FILES: ${names.length}`);","category":"external_commands","line_end":143,"severity":"medium","line_start":143},{"id":"external_commands:scripts/publish.mjs:144:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`BYTES: ${bytes}`);","category":"external_commands","line_end":144,"severity":"medium","line_start":144},{"id":"external_commands:scripts/publish.mjs:145:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`ENTRY: ${entry}`);","category":"external_commands","line_end":145,"severity":"medium","line_start":145},{"id":"external_commands:scripts/publish.mjs:146:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`SKIPPED: ${skipped.length}${skipped.length ? ` (${skipped.join(', ')})` : ''}`);","category":"external_commands","line_end":146,"severity":"medium","line_start":146},{"id":"external_commands:scripts/publish.mjs:147:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (unexpected.length) console.log(`UNEXPECTED: ${unexpected.join(', ')}`);","category":"external_commands","line_end":147,"severity":"medium","line_start":147},{"id":"external_commands:scripts/publish.mjs:149:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (flagged.length) console.log(`SENSITIVE: ${flagged.join(', ')}`);","category":"external_commands","line_end":149,"severity":"medium","line_start":149},{"id":"external_commands:scripts/publish.mjs:151:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`RESULT: ${confirm ? 'confirm' : 'ok'}`);","category":"external_commands","line_end":151,"severity":"medium","line_start":151},{"id":"external_commands:scripts/publish.mjs:160:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (!existsSync(dir) || !statSync(dir).isDirectory()) die(`not a directory: ${dir}`);","category":"external_commands","line_end":160,"severity":"medium","line_start":160},{"id":"external_commands:scripts/publish.mjs:166:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (kept.length === 0) die(`no publishable files under ${dir} after the allowlist filter`);","category":"external_commands","line_end":166,"severity":"medium","line_start":166},{"id":"external_commands:scripts/publish.mjs:169:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"// BD-N03: `mktemp` leaves a 0-byte file that Info-ZIP reads as a corrupt","category":"external_commands","line_end":169,"severity":"medium","line_start":169},{"id":"external_commands:scripts/publish.mjs:174:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"cwd: dir, input: `${kept.join('\\n')}\\n`, encoding: 'utf8',","category":"external_commands","line_end":174,"severity":"medium","line_start":174},{"id":"external_commands:scripts/publish.mjs:180:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"die(`${zipWhy} — no archive produced`);","category":"external_commands","line_end":180,"severity":"medium","line_start":180},{"id":"external_commands:scripts/publish.mjs:192:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"die(`archive contents differ from the selected file set (in archive: ${listed.length}, selected: ${k","category":"external_commands","line_end":192,"severity":"medium","line_start":192},{"id":"external_commands:scripts/publish.mjs:200:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (!existsSync(zipPath) || !statSync(zipPath).isFile()) die(`not a file: ${zipPath}`);","category":"external_commands","line_end":200,"severity":"medium","line_start":200},{"id":"filesystem:scripts/publish.mjs:80:hidden-file-access","file":"scripts/publish.mjs","pattern":"Hidden file access","snippet":"if (/[\\r\\n]/.test(rel)) { skipped.push(rel); continue; }","category":"filesystem","line_end":80,"severity":"medium","line_start":80},{"id":"filesystem:scripts/publish.mjs:169:temp-file-creation","file":"scripts/publish.mjs","pattern":"Temp file creation","snippet":"// BD-N03: `mktemp` leaves a 0-byte file that Info-ZIP reads as a corrupt","category":"filesystem","line_end":169,"severity":"low","line_start":169},{"id":"env_access:scripts/publish.mjs:109:environment-variable-access-dot-notation","file":"scripts/publish.mjs","pattern":"Environment variable access (dot notation)","snippet":"const exts = process.platform === 'win32' ? ['', ...(process.env.PATHEXT || '.EXE;.CMD;.BAT').split(","category":"env_access","line_end":109,"severity":"low","line_start":109},{"id":"env_access:scripts/publish.mjs:110:environment-variable-access-dot-notation","file":"scripts/publish.mjs","pattern":"Environment variable access (dot notation)","snippet":"const dirs = (process.env.PATH || '').split(delimiter).filter(Boolean);","category":"env_access","line_end":110,"severity":"low","line_start":110},{"id":"env_access:scripts/publish.mjs:109:environment-variable-object","file":"scripts/publish.mjs","pattern":"Environment variable object","snippet":"const exts = process.platform === 'win32' ? ['', ...(process.env.PATHEXT || '.EXE;.CMD;.BAT').split(","category":"env_access","line_end":109,"severity":"low","line_start":109},{"id":"env_access:scripts/publish.mjs:110:environment-variable-object","file":"scripts/publish.mjs","pattern":"Environment variable object","snippet":"const dirs = (process.env.PATH || '').split(delimiter).filter(Boolean);","category":"env_access","line_end":110,"severity":"low","line_start":110},{"id":"sensitive:scripts/publish.mjs:33:ssh-private-key-file","file":"scripts/publish.mjs","pattern":"SSH private key file","snippet":"const SENSITIVE_RE = /(^|\\/)(\\.env|id_rsa|id_ed25519)|secret|credential|password|token|\\.(pem|key|p1","category":"sensitive","line_end":33,"severity":"critical","line_start":33},{"id":"sensitive:scripts/publish.mjs:33:environment-file-access","file":"scripts/publish.mjs","pattern":"Environment file access","snippet":"const SENSITIVE_RE = /(^|\\/)(\\.env|id_rsa|id_ed25519)|secret|credential|password|token|\\.(pem|key|p1","category":"sensitive","line_end":33,"severity":"high","line_start":33},{"id":"sensitive:scripts/publish.mjs:109:environment-file-access","file":"scripts/publish.mjs","pattern":"Environment file access","snippet":"const exts = process.platform === 'win32' ? ['', ...(process.env.PATHEXT || '.EXE;.CMD;.BAT').split(","category":"sensitive","line_end":109,"severity":"high","line_start":109},{"id":"sensitive:scripts/publish.mjs:110:environment-file-access","file":"scripts/publish.mjs","pattern":"Environment file access","snippet":"const dirs = (process.env.PATH || '').split(delimiter).filter(Boolean);","category":"sensitive","line_end":110,"severity":"high","line_start":110},{"id":"sensitive:scripts/publish.mjs:24:sqlite-database-file","file":"scripts/publish.mjs","pattern":"SQLite database file","snippet":"const SYSTEM_RE = /^(__MACOSX|\\.Spotlight-V100|\\.Trashes|\\.fseventsd)\\/|(^|\\/)(\\.DS_Store|Thumbs\\.db","category":"sensitive","line_end":24,"severity":"medium","line_start":24},{"id":"blocker:scripts/publish.mjs:37:system-reconnaissance","file":"scripts/publish.mjs","pattern":"System reconnaissance","snippet":"/** `unzip` stdout cap: Node's 1 MB default kills `-Z1` on a valid site with >1 MB of names (ENOBUFS","category":"blocker","line_end":37,"severity":"low","line_start":37},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Every shell step is ONE command of the exact shape in the fences below: the single `allowed-tools`","category":"external_commands","line_end":18,"severity":"medium","line_start":18},{"id":"external_commands:SKILL.md:21:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Fill each `'{...}'` slot with the raw value and write every `'` inside it as `'\\''`; nothing else ","category":"external_commands","line_end":21,"severity":"medium","line_start":21},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"escaped. Never wrap a value in double quotes. An empty slot stays `''` (= omitted).","category":"external_commands","line_end":22,"severity":"medium","line_start":22},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Never quote the script path, prefix or chain the command (`cd`, `VAR=...`, `;`, `&&`, `|`, `$(...)","category":"external_commands","line_end":23,"severity":"medium","line_start":23},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"through `stage` (Step 6).","category":"external_commands","line_end":26,"severity":"medium","line_start":26},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- The script prints one decisive line: `OK {url}` or `OK {url} | Files: N` (then any `NOTICE: ...` l","category":"external_commands","line_end":27,"severity":"medium","line_start":27},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"what the server skipped or adjusted), `CONFIRM: ...` (exit 2, nothing uploaded) or `FAILED: ...` (se","category":"external_commands","line_end":28,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:35:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Extract from `$ARGUMENTS`:","category":"external_commands","line_end":35,"severity":"medium","line_start":35},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `--ttl N` → TTL in days (default: `15`)","category":"external_commands","line_end":36,"severity":"medium","line_start":36},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `--entry <filename>` → entry file for SITE uploads (default: auto-detect)","category":"external_commands","line_end":37,"severity":"medium","line_start":37},{"id":"external_commands:SKILL.md:38:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `--delivery-mode path|subdomain` → optional creation header; omitted means server defaults. Reject","category":"external_commands","line_end":38,"severity":"medium","line_start":38},{"id":"external_commands:SKILL.md:39:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Remaining text → `content_arg`: a path, or the exact text to publish. Fired by Claude mid-task, th","category":"external_commands","line_end":39,"severity":"medium","line_start":39},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"A `content_arg` that names a path -> probe it (read-only; prints `TYPE:`, the absolute `PATH:` to us","category":"external_commands","line_end":44,"severity":"medium","line_start":44},{"id":"external_commands:SKILL.md:47:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":49,"severity":"medium","line_start":47},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":51,"severity":"medium","line_start":49},{"id":"external_commands:SKILL.md:51:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| Input | Type | `publish` type + source | API |","category":"external_commands","line_end":53,"severity":"medium","line_start":51},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `TYPE: site-dir` | SITE | `site-dir` + `--path` | `POST /api/sites` (ZIP built from the dir — prim","category":"external_commands","line_end":53,"severity":"medium","line_start":53},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `TYPE: site-zip` (`.zip` file) | SITE | `site-zip` + `--path` | `POST /api/sites` (pre-built archi","category":"external_commands","line_end":54,"severity":"medium","line_start":54},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `TYPE: file` or `TYPE: markdown` (any other file) | FILE | `file` + `--path` | `POST /api/files` (","category":"external_commands","line_end":55,"severity":"medium","line_start":55},{"id":"external_commands:SKILL.md:56:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| No path (`TYPE: none`), `content_arg` starts with `{` or `[` | JSON | `json` + `--text` | `POST /a","category":"external_commands","line_end":56,"severity":"medium","line_start":56},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| Anything else | HTML | `html` + `--text` | `POST /api/html` (format=markdown) |","category":"external_commands","line_end":57,"severity":"medium","line_start":57},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Mode rule: directory/ZIP → SITE. Single file → FILE. `POST /api/sites` accepts a multipart `archive=","category":"external_commands","line_end":59,"severity":"medium","line_start":59},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"From the probe lines — SITE (dir): `HTML`, `SIZE_KB`, `ENTRY`. SITE (ZIP): `BYTES`, entry override. ","category":"external_commands","line_end":63,"severity":"medium","line_start":63},{"id":"external_commands:SKILL.md:66:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":69,"severity":"medium","line_start":66},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":71,"severity":"medium","line_start":69},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"For SITE (entry = server rule: `--entry` > root `index.html` > shallowest `.html`; another page → pa","category":"external_commands","line_end":71,"severity":"medium","line_start":71},{"id":"external_commands:SKILL.md:74:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- No `.html` file in the directory (`ENTRY: none`) → **FAIL** with an explicit error: \"No `.html` fo","category":"external_commands","line_end":74,"severity":"medium","line_start":74},{"id":"external_commands:SKILL.md:75:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- The directory looks like un-built sources (has `package.json` + `src/` but no top-level `.html`) →","category":"external_commands","line_end":75,"severity":"medium","line_start":75},{"id":"external_commands:SKILL.md:76:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":80,"severity":"medium","line_start":76},{"id":"external_commands:SKILL.md:80:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":82,"severity":"medium","line_start":80},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"`ENTRY:` line is the entry `scripts/publish.mjs` resolved in the built archive.","category":"external_commands","line_end":82,"severity":"medium","line_start":82},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Site limits** (`GET https://brewpage.app/api/limits` returns the current ones): 25 MB per request;","category":"external_commands","line_end":86,"severity":"medium","line_start":84},{"id":"external_commands:SKILL.md:86:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"380 characters / 900 bytes, each file or folder name at most 200 bytes. A big site (`FILES` or `SIZE","category":"external_commands","line_end":86,"severity":"medium","line_start":86},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":91,"severity":"medium","line_start":89},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":92,"severity":"medium","line_start":91},{"id":"external_commands:SKILL.md:92:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Pre-checks, folder or ZIP: system files (`.DS_Store`, `__MACOSX/`, `Thumbs.db`) never count and are","category":"external_commands","line_end":92,"severity":"medium","line_start":92},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"dropped; hidden files and folders are dropped too, except the root `.well-known/`; at least one `.ht","category":"external_commands","line_end":93,"severity":"medium","line_start":93},{"id":"external_commands:SKILL.md:100:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":110,"severity":"medium","line_start":100},{"id":"external_commands:SKILL.md:110:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":113,"severity":"medium","line_start":110},{"id":"external_commands:SKILL.md:113:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- File → topic/purpose of the file (e.g. `api-docs`, `login-page`, `report-q2`)","category":"external_commands","line_end":113,"severity":"medium","line_start":113},{"id":"external_commands:SKILL.md:114:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Text/HTML → main subject or title (e.g. `pricing`, `team-intro`, `changelog`)","category":"external_commands","line_end":114,"severity":"medium","line_start":114},{"id":"external_commands:SKILL.md:115:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- JSON → data type or schema name (e.g. `user-config`, `metrics`)","category":"external_commands","line_end":115,"severity":"medium","line_start":115},{"id":"external_commands:SKILL.md:119:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Resolution: `2`, `4`, empty, or no answer (headless) → suggested slug | `1` → `public` | `3` or any ","category":"external_commands","line_end":119,"severity":"medium","line_start":119},{"id":"external_commands:SKILL.md:125:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":134,"severity":"medium","line_start":125},{"id":"external_commands:SKILL.md:134:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":136,"severity":"medium","line_start":134},{"id":"external_commands:SKILL.md:136:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Resolution: `1`, `3`, empty, or no answer → `{password_file}` = `''` (no password). `2` + an existin","category":"external_commands","line_end":136,"severity":"medium","line_start":136},{"id":"external_commands:SKILL.md:137:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"local file path → `{password_file}` = that absolute path: the script moves the bytes via private hea","category":"external_commands","line_end":143,"severity":"medium","line_start":137},{"id":"external_commands:SKILL.md:143:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Delivery mode: NEW sites always get a Dedicated subdomain (an explicit `path` is not refused: the si","category":"external_commands","line_end":144,"severity":"medium","line_start":143},{"id":"external_commands:SKILL.md:144:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"its subdomain and the response reports the mismatch); everything else defaults to Promotion (`path`)","category":"external_commands","line_end":145,"severity":"medium","line_start":144},{"id":"external_commands:SKILL.md:145:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"select `subdomain`, password-protected included. Send it only as `X-Delivery-Mode`, never in authore","category":"external_commands","line_end":145,"severity":"medium","line_start":145},{"id":"external_commands:SKILL.md:146:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"OLD or NEW winner may differ: keep its identity, cohort, mode and exact `link`. Missing/null OLD rou","category":"external_commands","line_end":155,"severity":"medium","line_start":146},{"id":"external_commands:SKILL.md:155:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{ns}` | `^[a-z0-9-]{1,32}$` |","category":"external_commands","line_end":155,"severity":"medium","line_start":155},{"id":"external_commands:SKILL.md:156:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{days}` | positive integer; `''` = 15 |","category":"external_commands","line_end":156,"severity":"medium","line_start":156},{"id":"external_commands:SKILL.md:157:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{entry}` | plain relative file name, no `..`; `''` = auto-detect; sites only |","category":"external_commands","line_end":157,"severity":"medium","line_start":157},{"id":"external_commands:SKILL.md:158:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{delivery_mode}` | `''`, `path` or `subdomain` |","category":"external_commands","line_end":158,"severity":"medium","line_start":158},{"id":"external_commands:SKILL.md:159:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{password_file}` | `''` or an absolute path to an existing regular file |","category":"external_commands","line_end":159,"severity":"medium","line_start":159},{"id":"external_commands:SKILL.md:162:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"any run is touched, so staged text survives the retry. `{type}` comes from the Step 2 table.","category":"external_commands","line_end":164,"severity":"medium","line_start":162},{"id":"external_commands:SKILL.md:164:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**SITE, FILE** — `{path}` is the probe's `PATH:` — **EXECUTE** using Bash tool:","category":"external_commands","line_end":164,"severity":"medium","line_start":164},{"id":"external_commands:SKILL.md:165:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":167,"severity":"medium","line_start":165},{"id":"external_commands:SKILL.md:167:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":169,"severity":"medium","line_start":167},{"id":"external_commands:SKILL.md:169:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**HTML text, JSON** — `{content}` is the exact text or JSON, verbatim — **EXECUTE** using Bash tool:","category":"external_commands","line_end":170,"severity":"medium","line_start":169},{"id":"external_commands:SKILL.md:170:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":172,"severity":"medium","line_start":170},{"id":"external_commands:SKILL.md:172:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":175,"severity":"medium","line_start":172},{"id":"external_commands:SKILL.md:175:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"of at most 6,000 characters. The first `stage` call passes `--run ''` and prints `RUN: brewpage.XXXX","category":"external_commands","line_end":175,"severity":"medium","line_start":175},{"id":"external_commands:SKILL.md:178:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":180,"severity":"medium","line_start":178},{"id":"external_commands:SKILL.md:180:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":182,"severity":"medium","line_start":180},{"id":"external_commands:SKILL.md:182:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":184,"severity":"medium","line_start":182},{"id":"external_commands:SKILL.md:184:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":186,"severity":"medium","line_start":184},{"id":"external_commands:SKILL.md:186:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":188,"severity":"medium","line_start":186},{"id":"external_commands:SKILL.md:188:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":192,"severity":"medium","line_start":188},{"id":"external_commands:SKILL.md:192:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Success** (the script printed `OK {url}`):","category":"external_commands","line_end":193,"severity":"medium","line_start":192},{"id":"external_commands:SKILL.md:193:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":197,"severity":"medium","line_start":193},{"id":"external_commands:SKILL.md:197:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":199,"severity":"medium","line_start":197},{"id":"external_commands:SKILL.md:199:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Success for SITE** (the script printed `OK {url} | Files: {count}`):","category":"external_commands","line_end":200,"severity":"medium","line_start":199},{"id":"external_commands:SKILL.md:200:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":207,"severity":"medium","line_start":200},{"id":"external_commands:SKILL.md:207:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":211,"severity":"medium","line_start":207},{"id":"external_commands:SKILL.md:211:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"For a private (non-`public`) namespace, append one short line after the link (skip if the reply must","category":"external_commands","line_end":211,"severity":"medium","line_start":211},{"id":"external_commands:SKILL.md:215:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Needs confirmation** (the script printed `CONFIRM: ...`, exit 2; nothing uploaded): show the manif","category":"external_commands","line_end":216,"severity":"medium","line_start":215},{"id":"external_commands:SKILL.md:216:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"lines, name the flagged entries, ask ONE `AskUserQuestion` (publish anyway / cancel). Publish anyway","category":"external_commands","line_end":217,"severity":"medium","line_start":216},{"id":"external_commands:SKILL.md:217:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"re-run the identical command with ` --confirmed` appended. Cancel or no answer -> stop: the script a","category":"external_commands","line_end":220,"severity":"medium","line_start":217},{"id":"external_commands:SKILL.md:220:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Error** (the script printed `FAILED: ...`):","category":"external_commands","line_end":221,"severity":"medium","line_start":220},{"id":"external_commands:SKILL.md:221:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":223,"severity":"medium","line_start":221},{"id":"external_commands:SKILL.md:223:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":229,"severity":"medium","line_start":223},{"id":"external_commands:SKILL.md:229:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 422 | No servable file left (every file has an unsupported or missing extension) | Add the `.html`","category":"external_commands","line_end":237,"severity":"medium","line_start":229},{"id":"external_commands:SKILL.md:237:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Scripts: `scripts/brewpage-run.sh` (the only entry), `scripts/brewpage-lib.sh` (sourced helpers), ","category":"external_commands","line_end":237,"severity":"medium","line_start":237},{"id":"external_commands:SKILL.md:238:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **`format` is a query param**: `/api/html` reads only `?format=` from the URL; a body `format` key","category":"external_commands","line_end":238,"severity":"medium","line_start":238},{"id":"external_commands:SKILL.md:239:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- History: `<project-root>/.claude/brewpage-history.md` (root: `CLAUDE_PROJECT_DIR` → git toplevel →","category":"external_commands","line_end":239,"severity":"medium","line_start":239},{"id":"external_commands:SKILL.md:240:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Run dirs: private `brewpage.XXXXXX` under `$TMPDIR` (else `/tmp`), outside the protected `.claude/","category":"external_commands","line_end":240,"severity":"medium","line_start":240},{"id":"external_commands:SKILL.md:241:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Permissions: model-invocable, so `allowed-tools` holds one scoped Bash rule that matches every ste","category":"external_commands","line_end":242,"severity":"medium","line_start":241},{"id":"external_commands:SKILL.md:242:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- TTL default is `15` days; stored `createdAt`/`expiresAt` are authoritative: a deduplicated winner ","category":"external_commands","line_end":242,"severity":"medium","line_start":242},{"id":"external_commands:SKILL.md:243:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Use returned `ownerLink` and stored identity metadata for owner API operations; never parse NEW ro","category":"external_commands","line_end":244,"severity":"medium","line_start":243},{"id":"external_commands:SKILL.md:244:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- To **update a published site**, `PUT` the replacement bundle to its apex owner API with `X-Owner-T","category":"external_commands","line_end":244,"severity":"medium","line_start":244},{"id":"external_commands:SKILL.md:245:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Only NEW publications without a required subdomain allow owner-only `PATCH /api/{type}/{ns}/{id}/h","category":"external_commands","line_end":245,"severity":"medium","line_start":245},{"id":"external_commands:SKILL.md:246:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- NEW password-protected links stay clean: never generate or append `?p=`. API requests use `X-Passw","category":"external_commands","line_end":246,"severity":"medium","line_start":246},{"id":"external_commands:SKILL.md:247:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **SITE bundles are allowlisted**: the directory build drops dot-entries (`.env`, `.git/`, `.DS_Sto","category":"external_commands","line_end":247,"severity":"medium","line_start":247},{"id":"external_commands:SKILL.md:248:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Preserve `.link` exactly: NEW subdomain roots retain `/`; OLD links retain their existing form. Ne","category":"external_commands","line_end":248,"severity":"medium","line_start":248},{"id":"external_commands:SKILL.md:23:shell-command-substitution","file":"SKILL.md","pattern":"Shell command substitution","snippet":"- Never quote the script path, prefix or chain the command (`cd`, `VAR=...`, `;`, `&&`, `|`, `$(...)","category":"external_commands","line_end":23,"severity":"medium","line_start":23},{"id":"external_commands:SKILL.md:23:template-literal-with-command-substitution","file":"SKILL.md","pattern":"Template literal with command substitution","snippet":"- Never quote the script path, prefix or chain the command (`cd`, `VAR=...`, `;`, `&&`, `|`, `$(...)","category":"external_commands","line_end":23,"severity":"medium","line_start":23},{"id":"network:SKILL.md:84:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"**Site limits** (`GET https://brewpage.app/api/limits` returns the current ones): 25 MB per request;","category":"network","line_end":84,"severity":"low","line_start":84},{"id":"network:SKILL.md:196:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"Optional: sign in free (Google or any email) at https://account.brewpage.app to never lose your page","category":"network","line_end":196,"severity":"low","line_start":196},{"id":"network:SKILL.md:204:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"Optional: sign in free (Google or any email) at https://account.brewpage.app to never lose your page","category":"network","line_end":204,"severity":"low","line_start":204},{"id":"network:SKILL.md:257:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| **[brewpage.app](https://brewpage.app)** | Free instant hosting — HTML, JSON, files, sites, KV. No","category":"network","line_end":257,"severity":"low","line_start":257},{"id":"network:SKILL.md:258:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| **[brewcode](https://github.com/kochetkov-ma/claude-brewcode)** | Claude Code plugin suite — skill","category":"network","line_end":258,"severity":"low","line_start":258},{"id":"filesystem:SKILL.md:195:hidden-file-access","file":"SKILL.md","pattern":"Hidden file access","snippet":"Owner token saved to <project-root>/.claude/brewpage-history.md (mode 600, git-ignored)","category":"filesystem","line_end":195,"severity":"medium","line_start":195},{"id":"filesystem:SKILL.md:203:hidden-file-access","file":"SKILL.md","pattern":"Hidden file access","snippet":"Owner token saved to <project-root>/.claude/brewpage-history.md (mode 600, git-ignored)","category":"filesystem","line_end":203,"severity":"medium","line_start":203},{"id":"filesystem:SKILL.md:239:hidden-file-access","file":"SKILL.md","pattern":"Hidden file access","snippet":"- History: `<project-root>/.claude/brewpage-history.md` (root: `CLAUDE_PROJECT_DIR` → git toplevel →","category":"filesystem","line_end":239,"severity":"medium","line_start":239},{"id":"sensitive:SKILL.md:247:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"- **SITE bundles are allowlisted**: the directory build drops dot-entries (`.env`, `.git/`, `.DS_Sto","category":"sensitive","line_end":247,"severity":"high","line_start":247},{"id":"sensitive:SKILL.md:92:sqlite-database-file","file":"SKILL.md","pattern":"SQLite database file","snippet":"Pre-checks, folder or ZIP: system files (`.DS_Store`, `__MACOSX/`, `Thumbs.db`) never count and are","category":"sensitive","line_end":92,"severity":"medium","line_start":92},{"id":"sensitive:SKILL.md:247:sqlite-database-file","file":"SKILL.md","pattern":"SQLite database file","snippet":"- **SITE bundles are allowlisted**: the directory build drops dot-entries (`.env`, `.git/`, `.DS_Sto","category":"sensitive","line_end":247,"severity":"medium","line_start":247},{"id":"blocker:SKILL.md:232:system-reconnaissance","file":"SKILL.md","pattern":"System reconnaissance","snippet":"Unstorable metadata (tags, names, control characters) is stored as the closest valid value with a no","category":"blocker","line_end":232,"severity":"low","line_start":232},{"id":"obfuscation:scripts/brewpage-lib.sh:117:heuristic-very-high-entropy-string-6-03-bits-lik","file":"scripts/brewpage-lib.sh","pattern":"[HEURISTIC] Very high entropy string (6.03 bits) - likely encoded/encrypted payload","snippet":" in *[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.]*) echo ","category":"obfuscation","line_end":117,"severity":"high","line_start":117}],"finding_verdicts":[{"id":"network:LICENSE:3:hardcoded-url","reason":"The GitHub URL is copyright attribution in the license, not a network request.","verdict":"false_positive","confidence":0.98},{"id":"network:README.md:113:hardcoded-url","reason":"This is a documented owner-authorized deletion example against the publishing service, not an automatic or hidden network request.","verdict":"false_positive","confidence":0.98},{"id":"network:README.md:123:hardcoded-url","reason":"This is an optional installation example for the upstream GitHub repository, not an executed download or exfiltration destination.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:README.md:68:environment-file-access","reason":"The documentation describes excluding environment files, hidden paths, or Thumbs.db from site publications; it does not instruct reading or uploading those files.","verdict":"false_positive","confidence":1},{"id":"sensitive:README.md:68:sqlite-database-file","reason":"The documentation describes excluding environment files, hidden paths, or Thumbs.db from site publications; it does not instruct reading or uploading those files.","verdict":"false_positive","confidence":1},{"id":"blocker:README.md:87:system-reconnaissance","reason":"This prose discusses publication identity or metadata handling, not local system discovery or reconnaissance.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:52:ruby-shell-backtick-execution","reason":"The backticks are Markdown inside a single-quoted heredoc, so the example curl command is written as documentation and never executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:53:ruby-shell-backtick-execution","reason":"The backticks describe a PUT API operation inside a single-quoted heredoc; shell expansion is disabled.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:65:ruby-shell-backtick-execution","reason":"The backticks occur in a shell comment explaining git worktrees, not an executable expression.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:66:ruby-shell-backtick-execution","reason":"The backticks occur in a shell comment explaining a fixed git command, not an executable expression.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:77:ruby-shell-backtick-execution","reason":"The backticks are literal Markdown in a single-quoted printf format; they cannot trigger command substitution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:80:ruby-shell-backtick-execution","reason":"The backticks are literal Markdown in a single-quoted printf format; arguments are formatted as data.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:181:ruby-shell-backtick-execution","reason":"The backticks occur in a shell comment about function parameters and are not executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:202:ruby-shell-backtick-execution","reason":"The backticks occur in a shell comment describing a response field and are not executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:8:shell-command-substitution","reason":"Captures a canonical directory using quoted cd and pwd arguments, not dynamically supplied shell code.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:9:shell-command-substitution","reason":"Canonicalizes HOME for a directory comparison; no credential contents are read or transmitted.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:10:shell-command-substitution","reason":"Canonicalizes the configured Claude directory to avoid treating a profile as a project; input remains a quoted argument.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:21:shell-command-substitution","reason":"Runs the fixed git rev-parse --show-toplevel command to locate the project, without interpolating shell source.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:32:shell-command-substitution","reason":"Runs dirname on a quoted directory value during the upward project-root search.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:37:shell-command-substitution","reason":"Captures the result of the local project-root helper; the substitution does not evaluate its output as shell code.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:46:shell-command-substitution","reason":"Runs dirname on the quoted history path before creating its parent directory; command substitution itself permits no injected shell code.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:78:shell-command-substitution","reason":"Captures a timestamp from date with a fixed format; the surrounding single-quoted printf format treats backticks literally.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:81:shell-command-substitution","reason":"Captures a timestamp from date with a fixed format; response values are printf arguments rather than executable shell source.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:120:shell-command-substitution","reason":"Runs find on a quoted run directory to require private permissions before using or deleting it.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:205:shell-command-substitution","reason":"Extracts the returned link with a fixed jq filter; response data is not evaluated as shell commands.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:207:shell-command-substitution","reason":"Captures a local error-formatting helper result; it uses fixed jq expressions rather than evaluating server text.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:211:shell-command-substitution","reason":"Extracts the owner token with a fixed jq filter for local history storage, not shell execution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:212:shell-command-substitution","reason":"Extracts ownerLink with a fixed jq filter; the returned string is stored as data rather than executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:213:shell-command-substitution","reason":"Selects identity fields with a fixed jq expression; response values are serialized as data.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:215:shell-command-substitution","reason":"Extracts the site file count with a fixed jq expression, without shell evaluation of the response.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:239:shell-command-substitution","reason":"Parses the entry field with a fixed sed expression; the result is later URI-encoded, not executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:77:template-literal-with-command-substitution","reason":"The matched backticks are literal Markdown inside single-quoted printf formats; the broad match crosses unrelated comments and does not execute a template.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-lib.sh:80:template-literal-with-command-substitution","reason":"The matched backticks are literal Markdown inside single-quoted printf formats; the broad match crosses unrelated comments and does not execute a template.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/brewpage-lib.sh:52:hardcoded-url","reason":"The service URL is a literal example in the history header within a quoted heredoc; it initiates no network request.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:99:path-traversal-sequence","reason":"The ../ sequences are rejection patterns in the entry validator, not paths being accessed. The site helper independently rejects .. segments.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:10:hidden-file-access","reason":"Checks whether a directory is the active Claude profile to avoid placing project history there; it does not read profile secrets.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:14:hidden-file-access","reason":"This is a comment describing project-root discovery, not an operation that reads hidden-file contents.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:28:hidden-file-access","reason":"Checks for .git or project .claude directories to locate the project; no credential contents are read.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:38:hidden-file-access","reason":"Defines the documented local owner-token history path; hidden naming itself is not a threat. Destination-hardening defects are assessed separately.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:64:hidden-file-access","reason":"Identifies the project .gitignore so the token history can be excluded from future untracked-file commits.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:8:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:9:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:10:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:21:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:59:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:67:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:147:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:148:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:163:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:175:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:198:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:222:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:108:temp-file-creation","reason":"Uses mktemp -d under umask 077 for a private per-run directory; ownership, permissions and symlink status are checked before reuse.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-lib.sh:115:system-reconnaissance","reason":"This is run-ID validation, password-header validation, or explanatory prose, not a system reconnaissance command.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-lib.sh:117:system-reconnaissance","reason":"This is run-ID validation, password-header validation, or explanatory prose, not a system reconnaissance command.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-lib.sh:140:system-reconnaissance","reason":"This is run-ID validation, password-header validation, or explanatory prose, not a system reconnaissance command.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-lib.sh:142:system-reconnaissance","reason":"This is run-ID validation, password-header validation, or explanatory prose, not a system reconnaissance command.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-lib.sh:225:network-reconnaissance","reason":"This comment describes archive verification and its upload gate; it performs no network discovery.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:6:shell-command-substitution","reason":"Locates the bundled script directory with dirname, cd and pwd using quoted arguments; it does not evaluate user input.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:17:shell-command-substitution","reason":"Captures a directory allocated by the private mktemp helper; the substitution is ordinary resource setup.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:38:shell-command-substitution","reason":"Canonicalizes the selected directory with quoted cd and pwd; its contents are not executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:40:shell-command-substitution","reason":"Lists and sorts HTML paths using fixed find, sed and awk commands for a read-only probe.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:43:shell-command-substitution","reason":"Selects the shallowest HTML path using a fixed text-processing pipeline; filenames are data, not shell source.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:46:shell-command-substitution","reason":"Counts files and HTML entries through fixed find, wc, tr and grep commands during a read-only probe.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:47:shell-command-substitution","reason":"Measures the selected directory using du and cut with a quoted path; no reconnaissance outside that input is requested.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:49:shell-command-substitution","reason":"Combines quoted dirname, basename and canonical directory results to identify the selected file.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:52:shell-command-substitution","reason":"Counts bytes in the selected file through wc and tr; no file contents are transmitted by this probe.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:53:shell-command-substitution","reason":"Invokes file with -- and a quoted filename for MIME detection, not arbitrary command execution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:64:shell-command-substitution","reason":"Fetches upload limits from the documented HTTPS service endpoint; the response is parsed, not executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:94:shell-command-substitution","reason":"Counts bytes in staged content with fixed wc and tr commands; the content is not evaluated.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:117:shell-command-substitution","reason":"The expression is arithmetic expansion that increments a source counter, not command substitution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:118:shell-command-substitution","reason":"The expression is arithmetic expansion that increments a source counter, not command substitution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:119:shell-command-substitution","reason":"The expression is arithmetic expansion that increments a source counter, not command substitution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:169:shell-command-substitution","reason":"Uploads explicitly selected text to the documented HTTPS publishing endpoint; namespace and TTL are validated before URL construction.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:175:shell-command-substitution","reason":"Uploads validated JSON to the documented HTTPS publishing endpoint with validated namespace and TTL arguments.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:180:shell-command-substitution","reason":"Captures the response from the documented file upload operation; quoted expansion does not evaluate filenames as shell source.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:186:shell-command-substitution","reason":"Runs the bundled Node pack helper with argument values, not generated shell source, and gates upload on its result.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:191:shell-command-substitution","reason":"Runs the bundled Node archive inspector with argument values and gates upload on its result; its output is not executed.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/brewpage-run.sh:195:shell-command-substitution","reason":"Uploads the selected site archive to the documented endpoint and URI-encodes the entry using a fixed jq filter.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/brewpage-run.sh:64:hardcoded-url","reason":"The HTTPS URL fetches the publishing service limits and sends no content or credentials.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/brewpage-run.sh:169:hardcoded-url","reason":"The HTTPS URL is the advertised destination for user-selected publication content, not an unrelated exfiltration endpoint.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/brewpage-run.sh:175:hardcoded-url","reason":"The HTTPS URL is the advertised destination for user-selected publication content, not an unrelated exfiltration endpoint.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/brewpage-run.sh:180:hardcoded-url","reason":"The HTTPS URL is the advertised destination for user-selected publication content, not an unrelated exfiltration endpoint.","verdict":"false_positive","confidence":0.98},{"id":"network:scripts/brewpage-run.sh:195:hardcoded-url","reason":"The HTTPS URL is the advertised destination for user-selected publication content, not an unrelated exfiltration endpoint.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-run.sh:53:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-run.sh:62:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-run.sh:68:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-run.sh:174:standard-device-file-access","reason":"The device is /dev/null, used to suppress command output or validation diagnostics; no sensitive device data is read.","verdict":"false_positive","confidence":1},{"id":"blocker:scripts/brewpage-run.sh:141:system-reconnaissance","reason":"This is a local variable declaration, staged-file existence check, or JSON validation step; it performs no system enumeration.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-run.sh:159:system-reconnaissance","reason":"This is a local variable declaration, staged-file existence check, or JSON validation step; it performs no system enumeration.","verdict":"false_positive","confidence":0.98},{"id":"blocker:scripts/brewpage-run.sh:174:system-reconnaissance","reason":"This is a local variable declaration, staged-file existence check, or JSON validation step; it performs no system enumeration.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:4:node-js-child-process-module","reason":"The module supports the advertised offline zip and unzip workflow. Its fixed executable names use argument arrays without a shell.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:123:synchronous-spawn","reason":"Invokes the fixed unzip program with an argument array and no shell, so this is not shell injection. Inspection resource limits are assessed separately.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:173:synchronous-spawn","reason":"Invokes the fixed zip program with an argument array and a filename list on stdin, without a shell or execution of site code.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:2:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:26:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:29:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:30:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:37:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:41:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:51:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:60:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:90:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:102:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:111:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:116:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:117:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:118:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:121:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:126:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:129:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:141:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:142:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:143:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:144:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:145:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:146:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:147:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:149:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:151:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:160:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:166:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:169:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:174:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:180:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:192:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:200:ruby-shell-backtick-execution","reason":"These backticks are JavaScript template strings or documentation comments, not shell execution. Process invocation uses separate spawnSync argument arrays.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:80:hidden-file-access","reason":"This line rejects filenames containing carriage returns or newlines; it does not access any hidden file.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:169:temp-file-creation","reason":"The match is a comment explaining why the generated archive starts absent, not an unsafe temporary-file creation operation.","verdict":"false_positive","confidence":0.98},{"id":"env_access:scripts/publish.mjs:109:environment-variable-access-dot-notation","reason":"Reads only PATH or PATHEXT to locate required archive executables; it does not read .env files, collect environment secrets, or transmit these values.","verdict":"false_positive","confidence":0.98},{"id":"env_access:scripts/publish.mjs:110:environment-variable-access-dot-notation","reason":"Reads only PATH or PATHEXT to locate required archive executables; it does not read .env files, collect environment secrets, or transmit these values.","verdict":"false_positive","confidence":0.98},{"id":"env_access:scripts/publish.mjs:109:environment-variable-object","reason":"Reads only PATH or PATHEXT to locate required archive executables; it does not read .env files, collect environment secrets, or transmit these values.","verdict":"false_positive","confidence":0.98},{"id":"env_access:scripts/publish.mjs:110:environment-variable-object","reason":"Reads only PATH or PATHEXT to locate required archive executables; it does not read .env files, collect environment secrets, or transmit these values.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:scripts/publish.mjs:33:ssh-private-key-file","reason":"The private-key and environment filenames are regex indicators used to flag archive entries for human confirmation, not files opened for credential collection.","verdict":"false_positive","confidence":1},{"id":"sensitive:scripts/publish.mjs:33:environment-file-access","reason":"The private-key and environment filenames are regex indicators used to flag archive entries for human confirmation, not files opened for credential collection.","verdict":"false_positive","confidence":1},{"id":"sensitive:scripts/publish.mjs:109:environment-file-access","reason":"Reads only PATH or PATHEXT to locate required archive executables; it does not read .env files, collect environment secrets, or transmit these values.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:scripts/publish.mjs:110:environment-file-access","reason":"Reads only PATH or PATHEXT to locate required archive executables; it does not read .env files, collect environment secrets, or transmit these values.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:scripts/publish.mjs:24:sqlite-database-file","reason":"Thumbs.db is a system-file exclusion pattern, not a SQLite database read; no database API or file-content access appears here.","verdict":"false_positive","confidence":1},{"id":"blocker:scripts/publish.mjs:37:system-reconnaissance","reason":"This comment describes an unzip output-buffer limit, not a reconnaissance command.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:21:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:35:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:38:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:39:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:47:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:51:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:56:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:66:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:74:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:75:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:76:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:80:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:86:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:92:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:100:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:110:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:113:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:114:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:115:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:119:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:125:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:134:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:136:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:137:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:143:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:144:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:145:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:146:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:155:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:156:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:157:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:158:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:159:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:162:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:164:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:165:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:167:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:169:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:170:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:172:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:175:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:178:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:180:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:182:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:184:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:186:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:188:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:192:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:193:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:197:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:199:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:200:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:207:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:211:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:215:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:216:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:217:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:220:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:221:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:223:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:229:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:237:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:238:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:239:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:240:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:241:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:242:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:243:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:244:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:245:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:246:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:247:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:248:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown examples or inline documentation, not Ruby or shell command substitution. The documented workflow invokes the bundled publishing script.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:23:shell-command-substitution","reason":"The document explicitly prohibits $(...) and command chaining in generated commands; the matched text is a safety instruction, not execution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:23:template-literal-with-command-substitution","reason":"The Markdown text explicitly forbids command substitution and chaining; it is not an executable template.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:84:hardcoded-url","reason":"The URL documents the publishing service, its limits endpoint, or the upstream repository; it is not a concealed destination.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:196:hardcoded-url","reason":"This is an explicitly optional account link in the result template; the skill does not require sign-in or send credentials there.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:204:hardcoded-url","reason":"This is an explicitly optional account link in the result template; the skill does not require sign-in or send credentials there.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:257:hardcoded-url","reason":"The URL documents the publishing service, its limits endpoint, or the upstream repository; it is not a concealed destination.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:258:hardcoded-url","reason":"The URL documents the publishing service, its limits endpoint, or the upstream repository; it is not a concealed destination.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:195:hidden-file-access","reason":"This documents the local token-history location and intended protection, not hidden credential harvesting. Implementation weaknesses are assessed separately.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:203:hidden-file-access","reason":"This documents the local token-history location and intended protection, not hidden credential harvesting. Implementation weaknesses are assessed separately.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:239:hidden-file-access","reason":"This documents the local token-history location and intended protection, not hidden credential harvesting. Implementation weaknesses are assessed separately.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:SKILL.md:247:environment-file-access","reason":"The documentation describes excluding environment files, hidden paths, or Thumbs.db from site publications; it does not instruct reading or uploading those files.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:92:sqlite-database-file","reason":"The documentation describes excluding environment files, hidden paths, or Thumbs.db from site publications; it does not instruct reading or uploading those files.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:247:sqlite-database-file","reason":"The documentation describes excluding environment files, hidden paths, or Thumbs.db from site publications; it does not instruct reading or uploading those files.","verdict":"false_positive","confidence":1},{"id":"blocker:SKILL.md:232:system-reconnaissance","reason":"This prose discusses publication identity or metadata handling, not local system discovery or reconnaissance.","verdict":"false_positive","confidence":0.98},{"id":"obfuscation:scripts/brewpage-lib.sh:117:heuristic-very-high-entropy-string-6-03-bits-lik","reason":"The high-entropy text is an explicit ASCII character allowlist for run IDs, not an encoded payload or executable data.","verdict":"false_positive","confidence":1}],"semantic_findings":[{"title":"Owner-token history follows repository-controlled paths","severity":"high","locations":[{"file":"scripts/brewpage-lib.sh","line_end":71,"line_start":43},{"file":"scripts/brewpage-lib.sh","line_end":81,"line_start":75}],"confidence":0.96,"description":"History writes follow symlinks, and chmod failures are ignored. A crafted checkout can redirect owner tokens outside the intended private history file.","confidence_reasoning":"The code checks -f but never rejects symlinked history files or parent directories. Redirection and chmod follow these paths before token append."},{"title":"Unanswered privacy prompts permit unprotected publication","severity":"medium","locations":[{"file":"SKILL.md","line_end":119,"line_start":119},{"file":"SKILL.md","line_end":139,"line_start":125},{"file":"SKILL.md","line_end":183,"line_start":169}],"confidence":0.91,"description":"Missing namespace and password answers default to an unlisted link without authentication. Unattended runs can publish selected content without explicit access-policy approval.","confidence_reasoning":"The workflow explicitly treats no answer as permission to use an unlisted namespace and no password. Publication is intended, but privacy consent fails open."},{"title":"Archive integrity checks lack local resource limits","severity":"medium","locations":[{"file":"scripts/publish.mjs","line_end":135,"line_start":121},{"file":"scripts/publish.mjs","line_end":214,"line_start":197}],"confidence":0.94,"description":"Supplied ZIP files undergo decompression testing before upload without a timeout or expansion cap. A malicious archive can exhaust local CPU or stall inspection.","confidence_reasoning":"unzip -tq processes archive contents synchronously with no timeout. maxBuffer limits captured output, not decompression work or expanded bytes."},{"title":"Recovery guidance conflicts with owner-token confidentiality","severity":"high","locations":[{"file":"SKILL.md","line_end":213,"line_start":213},{"file":"SKILL.md","line_end":244,"line_start":244}],"confidence":0.95,"description":"The recovery note says \"report the new URL and owner token\", contradicting the explicit prohibition on conversational token disclosure. Following it could expose management credentials.","confidence_reasoning":"Both conflicting instructions appear verbatim in the skill. Exposure depends on agent interpretation; the script does not itself print owner tokens in normal results."}],"subject_marketplace_commit_sha":"98e33e143b9d10591d1a0a45cf7515e6a50429e6","subject_content_hash":"c8abc29f3e57aefe8ab9b8dd5742dc6c9d7ba66affe74c1464a12bd61a2bddfc","subject_tree_hash":"1707afcafed0ce833cb8e64e59ee92d637707d17f72af438dd7009da6580f5e8","subject_plugin_path":"skills/kochetkov-ma/brewpage-publish","audit_payload_hash":"3c48a5a7d1f12f1973644ebc9150dd25","confirmed_risk_level":"high","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"98e33e143b9d10591d1a0a45cf7515e6a50429e6","contentHash":"c8abc29f3e57aefe8ab9b8dd5742dc6c9d7ba66affe74c1464a12bd61a2bddfc","treeHash":"1707afcafed0ce833cb8e64e59ee92d637707d17f72af438dd7009da6580f5e8","pluginPath":"skills/kochetkov-ma/brewpage-publish","auditPayloadHash":"3c48a5a7d1f12f1973644ebc9150dd25"},"scannerVersion":"3.0.0","policyVersion":"skillstore-security-audit-policy-v1"},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"issued","url":"/api/skills/kochetkov-ma-brewpage-publish/audits/5/attestation","status":"superseded"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"high","confirmedFindingCount":4,"capabilityReviewCount":0,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"confirmation_required","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"superseded","verificationState":"not_verified"},"isLatest":false}}