{"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":3},"audit":{"id":"1c1621c7-b7d1-4595-bf43-da7b145a1db8","skill_id":"4bf85c8e-ddad-4143-9c98-4b5fde9536c8","version":6,"content_hash":"v3:7ad822ef13aa628e78d9da143046fd04fec0428e:b15355ed8c401f28f23f94bd44f7148b639bc6979c8955de9f937244b1dcad27:bf8d970bf1108d6057b44d5834a35578f8879fe8e883a2f922d37aa86abac2dd:736b696c6c732f6b6f636865746b6f762d6d612f62726577706167652d7075626c697368:daecbf174a8337257d045e9451fa5880","risk_level":"high","is_blocked":false,"safe_to_publish":false,"analysis_status":"ok","agent_auto_install_policy":"confirmation_required","manual_install_policy":"allowed","summary":"All 260 static alerts match documentation, exclusion patterns, intended service endpoints, or defensive local operations. A separate high-severity multipart path injection can upload unintended local files through crafted filenames. No evidence found of prompt injection or deliberate credential exfiltration.","remediation":[{"issue":"File and supplied-ZIP paths enter curl -F syntax without escaping, allowing commas to select unintended local files.","severity":"high","suggestion":"Copy each validated source into the private run directory under a fixed safe basename before upload. Add regression tests for comma and semicolon filenames."}],"risk_factor_evidence":[{"factor":"network","evidence":[{"file":"LICENSE","line_end":3,"line_start":3},{"file":"README.md","line_end":115,"line_start":115},{"file":"README.md","line_end":125,"line_start":125},{"file":"scripts/brewpage-lib.sh","line_end":51,"line_start":51},{"file":"scripts/brewpage-run.sh","line_end":65,"line_start":65},{"file":"scripts/brewpage-run.sh","line_end":172,"line_start":172},{"file":"scripts/brewpage-run.sh","line_end":178,"line_start":178},{"file":"scripts/brewpage-run.sh","line_end":183,"line_start":183},{"file":"scripts/brewpage-run.sh","line_end":198,"line_start":198},{"file":"SKILL.md","line_end":84,"line_start":84},{"file":"SKILL.md","line_end":198,"line_start":198},{"file":"SKILL.md","line_end":206,"line_start":206},{"file":"SKILL.md","line_end":262,"line_start":262},{"file":"SKILL.md","line_end":263,"line_start":263}]},{"factor":"external_commands","evidence":[{"file":"scripts/brewpage-lib.sh","line_end":51,"line_start":51},{"file":"scripts/brewpage-lib.sh","line_end":52,"line_start":52},{"file":"scripts/brewpage-lib.sh","line_end":62,"line_start":62},{"file":"scripts/brewpage-lib.sh","line_end":65,"line_start":65},{"file":"scripts/brewpage-lib.sh","line_end":166,"line_start":166},{"file":"scripts/brewpage-lib.sh","line_end":187,"line_start":187},{"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":47,"line_start":47},{"file":"scripts/brewpage-lib.sh","line_end":63,"line_start":63},{"file":"scripts/brewpage-lib.sh","line_end":66,"line_start":66},{"file":"scripts/brewpage-lib.sh","line_end":105,"line_start":105},{"file":"scripts/brewpage-lib.sh","line_end":190,"line_start":190},{"file":"scripts/brewpage-lib.sh","line_end":192,"line_start":192},{"file":"scripts/brewpage-lib.sh","line_end":199,"line_start":199},{"file":"scripts/brewpage-lib.sh","line_end":201,"line_start":201},{"file":"scripts/brewpage-lib.sh","line_end":202,"line_start":202},{"file":"scripts/brewpage-lib.sh","line_end":204,"line_start":204},{"file":"scripts/brewpage-lib.sh","line_end":229,"line_start":229},{"file":"scripts/brewpage-lib.sh","line_end":65,"line_start":62},{"file":"scripts/brewpage-lib.sh","line_end":166,"line_start":65},{"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":39,"line_start":39},{"file":"scripts/brewpage-run.sh","line_end":41,"line_start":41},{"file":"scripts/brewpage-run.sh","line_end":44,"line_start":44},{"file":"scripts/brewpage-run.sh","line_end":47,"line_start":47},{"file":"scripts/brewpage-run.sh","line_end":48,"line_start":48},{"file":"scripts/brewpage-run.sh","line_end":50,"line_start":50},{"file":"scripts/brewpage-run.sh","line_end":53,"line_start":53},{"file":"scripts/brewpage-run.sh","line_end":54,"line_start":54},{"file":"scripts/brewpage-run.sh","line_end":65,"line_start":65},{"file":"scripts/brewpage-run.sh","line_end":95,"line_start":95},{"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":120,"line_start":120},{"file":"scripts/brewpage-run.sh","line_end":173,"line_start":172},{"file":"scripts/brewpage-run.sh","line_end":179,"line_start":178},{"file":"scripts/brewpage-run.sh","line_end":183,"line_start":183},{"file":"scripts/brewpage-run.sh","line_end":189,"line_start":189},{"file":"scripts/brewpage-run.sh","line_end":194,"line_start":194},{"file":"scripts/brewpage-run.sh","line_end":198,"line_start":198},{"file":"scripts/history.py","line_end":55,"line_start":55},{"file":"scripts/publish.mjs","line_end":4,"line_start":4},{"file":"scripts/publish.mjs","line_end":153,"line_start":153},{"file":"scripts/publish.mjs","line_end":205,"line_start":205}]},{"factor":"filesystem","evidence":[{"file":"scripts/brewpage-lib.sh","line_end":84,"line_start":84},{"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":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":46,"line_start":46},{"file":"scripts/brewpage-lib.sh","line_end":132,"line_start":132},{"file":"scripts/brewpage-lib.sh","line_end":133,"line_start":133},{"file":"scripts/brewpage-lib.sh","line_end":148,"line_start":148},{"file":"scripts/brewpage-lib.sh","line_end":160,"line_start":160},{"file":"scripts/brewpage-lib.sh","line_end":183,"line_start":183},{"file":"scripts/brewpage-lib.sh","line_end":196,"line_start":196},{"file":"scripts/brewpage-lib.sh","line_end":212,"line_start":212},{"file":"scripts/brewpage-lib.sh","line_end":93,"line_start":93},{"file":"scripts/brewpage-run.sh","line_end":54,"line_start":54},{"file":"scripts/brewpage-run.sh","line_end":63,"line_start":63},{"file":"scripts/brewpage-run.sh","line_end":69,"line_start":69},{"file":"scripts/brewpage-run.sh","line_end":126,"line_start":126},{"file":"scripts/brewpage-run.sh","line_end":177,"line_start":177},{"file":"scripts/history.py","line_end":33,"line_start":33},{"file":"scripts/history.py","line_end":41,"line_start":41},{"file":"scripts/publish.mjs","line_end":5,"line_start":5},{"file":"scripts/publish.mjs","line_end":44,"line_start":44},{"file":"scripts/publish.mjs","line_end":110,"line_start":110},{"file":"scripts/publish.mjs","line_end":201,"line_start":201},{"file":"SKILL.md","line_end":197,"line_start":197},{"file":"SKILL.md","line_end":205,"line_start":205},{"file":"SKILL.md","line_end":244,"line_start":244}]},{"factor":"env_access","evidence":[{"file":"scripts/history.py","line_end":55,"line_start":55},{"file":"scripts/history.py","line_end":65,"line_start":65},{"file":"scripts/publish.mjs","line_end":139,"line_start":139},{"file":"scripts/publish.mjs","line_end":140,"line_start":140},{"file":"scripts/publish.mjs","line_end":139,"line_start":139},{"file":"scripts/publish.mjs","line_end":140,"line_start":140}]}],"critical_findings":[],"high_findings":[{"title":"Multipart Path Injection Can Upload Unintended Local Files","locations":[{"file":"scripts/brewpage-run.sh","line_end":136,"line_start":135},{"file":"scripts/brewpage-run.sh","line_end":183,"line_start":183},{"file":"scripts/brewpage-run.sh","line_end":199,"line_start":193}],"confidence":0.99,"description":"Upload paths enter curl multipart syntax without filename escaping. A crafted existing path containing commas can select additional readable local files, sending their contents outside the approved source.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"A loopback test used an existing comma-containing fixture path and reproduced an additional file upload. Shell quoting does not disable curl multipart parsing."}],"medium_findings":[],"low_findings":[],"dangerous_patterns":[],"files_scanned":7,"total_lines":1260,"audit_model":"codex","audited_at":"2026-10-26T22:31:17.233+00:00","created_at":"2026-10-27T01:54:34.881046+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:115: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":115,"severity":"low","line_start":115},{"id":"network:README.md:125:hardcoded-url","file":"README.md","pattern":"Hardcoded URL","snippet":"claude plugin marketplace add https://github.com/kochetkov-ma/claude-brewcode","category":"network","line_end":125,"severity":"low","line_start":125},{"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:89: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":89,"severity":"low","line_start":89},{"id":"external_commands:scripts/brewpage-lib.sh:51: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":51,"severity":"medium","line_start":51},{"id":"external_commands:scripts/brewpage-lib.sh:52: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":52,"severity":"medium","line_start":52},{"id":"external_commands:scripts/brewpage-lib.sh:62: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":62,"severity":"medium","line_start":62},{"id":"external_commands:scripts/brewpage-lib.sh:65: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":65,"severity":"medium","line_start":65},{"id":"external_commands:scripts/brewpage-lib.sh:166: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":166,"severity":"medium","line_start":166},{"id":"external_commands:scripts/brewpage-lib.sh:187: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":187,"severity":"medium","line_start":187},{"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:47:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"python3 \"$(dirname \"${BASH_SOURCE[0]}\")/history.py\" init \"$BP_ROOT\" \"${HISTORY_FILE#\"$BP_ROOT/\"}\" <<","category":"external_commands","line_end":47,"severity":"medium","line_start":47},{"id":"external_commands:scripts/brewpage-lib.sh:63: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:-}\" | python3 \"$(dirname \"${BASH_SOUR","category":"external_commands","line_end":63,"severity":"medium","line_start":63},{"id":"external_commands:scripts/brewpage-lib.sh:66:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"\"$(date '+%Y-%m-%d %H:%M')\" \"$1\" \"$1\" \"$2\" \"$3\" \"$4\" | python3 \"$(dirname \"${BASH_SOURCE[0]}\")/histo","category":"external_commands","line_end":66,"severity":"medium","line_start":66},{"id":"external_commands:scripts/brewpage-lib.sh:105: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":105,"severity":"medium","line_start":105},{"id":"external_commands:scripts/brewpage-lib.sh:190: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":190,"severity":"medium","line_start":190},{"id":"external_commands:scripts/brewpage-lib.sh:192:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"reason=$(bp_error_reason \"$response\")","category":"external_commands","line_end":192,"severity":"medium","line_start":192},{"id":"external_commands:scripts/brewpage-lib.sh:199: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":199,"severity":"medium","line_start":199},{"id":"external_commands:scripts/brewpage-lib.sh:201: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":201,"severity":"medium","line_start":201},{"id":"external_commands:scripts/brewpage-lib.sh:202: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":202,"severity":"medium","line_start":202},{"id":"external_commands:scripts/brewpage-lib.sh:204: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":204,"severity":"medium","line_start":204},{"id":"external_commands:scripts/brewpage-lib.sh:229: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":229,"severity":"medium","line_start":229},{"id":"external_commands:scripts/brewpage-lib.sh:62: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":65,"severity":"medium","line_start":62},{"id":"external_commands:scripts/brewpage-lib.sh:65: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":166,"severity":"medium","line_start":65},{"id":"network:scripts/brewpage-lib.sh:51: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":51,"severity":"low","line_start":51},{"id":"filesystem:scripts/brewpage-lib.sh:84:path-traversal-sequence","file":"scripts/brewpage-lib.sh","pattern":"Path traversal sequence","snippet":"*[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._/-]* | */../* | ../* | */..) echo","category":"filesystem","line_end":84,"severity":"high","line_start":84},{"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: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:46:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"command -v python3 >/dev/null || { echo 'FAILED: python3 required for secure history'; return 1; }","category":"filesystem","line_end":46,"severity":"low","line_start":46},{"id":"filesystem:scripts/brewpage-lib.sh:132: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":132,"severity":"low","line_start":132},{"id":"filesystem:scripts/brewpage-lib.sh:133: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":133,"severity":"low","line_start":133},{"id":"filesystem:scripts/brewpage-lib.sh:148: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":148,"severity":"low","line_start":148},{"id":"filesystem:scripts/brewpage-lib.sh:160: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":160,"severity":"low","line_start":160},{"id":"filesystem:scripts/brewpage-lib.sh:183: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":183,"severity":"low","line_start":183},{"id":"filesystem:scripts/brewpage-lib.sh:196:standard-device-file-access","file":"scripts/brewpage-lib.sh","pattern":"Standard device file access","snippet":"if printf '%s' \"$response\" | jq -e '.result.action == \"merged\" and .result.extras.isOwner == false' ","category":"filesystem","line_end":196,"severity":"low","line_start":196},{"id":"filesystem:scripts/brewpage-lib.sh:212: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":212,"severity":"low","line_start":212},{"id":"filesystem:scripts/brewpage-lib.sh:93: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":93,"severity":"low","line_start":93},{"id":"blocker:scripts/brewpage-lib.sh:100:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"*) echo \"FAILED: invalid publish run id\"; return 1 ;;","category":"blocker","line_end":100,"severity":"low","line_start":100},{"id":"blocker:scripts/brewpage-lib.sh:102:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"case \"$id\" in *[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.]*) echo \"FAILED: in","category":"blocker","line_end":102,"severity":"low","line_start":102},{"id":"blocker:scripts/brewpage-lib.sh:125:system-reconnaissance","file":"scripts/brewpage-lib.sh","pattern":"System reconnaissance","snippet":"then \"X-Password: \" + $p else error(\"invalid password\") end'","category":"blocker","line_end":125,"severity":"low","line_start":125},{"id":"blocker:scripts/brewpage-lib.sh:127: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":127,"severity":"low","line_start":127},{"id":"blocker:scripts/brewpage-lib.sh:215: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":215,"severity":"low","line_start":215},{"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:39:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"abs=$(cd \"$p\" && pwd -P)","category":"external_commands","line_end":39,"severity":"medium","line_start":39},{"id":"external_commands:scripts/brewpage-run.sh:41: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":41,"severity":"medium","line_start":41},{"id":"external_commands:scripts/brewpage-run.sh:44: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":44,"severity":"medium","line_start":44},{"id":"external_commands:scripts/brewpage-run.sh:47: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":47,"severity":"medium","line_start":47},{"id":"external_commands:scripts/brewpage-run.sh:48: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":48,"severity":"medium","line_start":48},{"id":"external_commands:scripts/brewpage-run.sh:50: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":50,"severity":"medium","line_start":50},{"id":"external_commands:scripts/brewpage-run.sh:53: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":53,"severity":"medium","line_start":53},{"id":"external_commands:scripts/brewpage-run.sh:54: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":54,"severity":"medium","line_start":54},{"id":"external_commands:scripts/brewpage-run.sh:65: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":65,"severity":"medium","line_start":65},{"id":"external_commands:scripts/brewpage-run.sh:95: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":95,"severity":"medium","line_start":95},{"id":"external_commands:scripts/brewpage-run.sh:118: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":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":"--run) need \"$#\" \"$1\"; run=\"$2\"; sources=$((sources + 1)); shift 2 ;;","category":"external_commands","line_end":119,"severity":"medium","line_start":119},{"id":"external_commands:scripts/brewpage-run.sh:120: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":120,"severity":"medium","line_start":120},{"id":"external_commands:scripts/brewpage-run.sh:172: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":173,"severity":"medium","line_start":172},{"id":"external_commands:scripts/brewpage-run.sh:178: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":179,"severity":"medium","line_start":178},{"id":"external_commands:scripts/brewpage-run.sh:183: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":183,"severity":"medium","line_start":183},{"id":"external_commands:scripts/brewpage-run.sh:189: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":189,"severity":"medium","line_start":189},{"id":"external_commands:scripts/brewpage-run.sh:194: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":194,"severity":"medium","line_start":194},{"id":"external_commands:scripts/brewpage-run.sh:198: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":198,"severity":"medium","line_start":198},{"id":"network:scripts/brewpage-run.sh:65: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":65,"severity":"low","line_start":65},{"id":"network:scripts/brewpage-run.sh:172: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":172,"severity":"low","line_start":172},{"id":"network:scripts/brewpage-run.sh:178: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":178,"severity":"low","line_start":178},{"id":"network:scripts/brewpage-run.sh:183: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":183,"severity":"low","line_start":183},{"id":"network:scripts/brewpage-run.sh:198: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":198,"severity":"low","line_start":198},{"id":"filesystem:scripts/brewpage-run.sh:54: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":54,"severity":"low","line_start":54},{"id":"filesystem:scripts/brewpage-run.sh:63: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":63,"severity":"low","line_start":63},{"id":"filesystem:scripts/brewpage-run.sh:69: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":69,"severity":"low","line_start":69},{"id":"filesystem:scripts/brewpage-run.sh:126:standard-device-file-access","file":"scripts/brewpage-run.sh","pattern":"Standard device file access","snippet":"command -v python3 >/dev/null || die \"python3 required for secure history\"","category":"filesystem","line_end":126,"severity":"low","line_start":126},{"id":"filesystem:scripts/brewpage-run.sh:177: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":177,"severity":"low","line_start":177},{"id":"blocker:scripts/brewpage-run.sh:144:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"local id pwmode=none","category":"blocker","line_end":144,"severity":"low","line_start":144},{"id":"blocker:scripts/brewpage-run.sh:162:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"[ -f \"$content\" ] || die \"run $id has no staged text\"","category":"blocker","line_end":162,"severity":"low","line_start":162},{"id":"blocker:scripts/brewpage-run.sh:177: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":177,"severity":"low","line_start":177},{"id":"external_commands:scripts/history.py:55:python-subprocess-run","file":"scripts/history.py","pattern":"Python subprocess.run","snippet":"result = subprocess.run(['git', '-C', root] + arguments, stdout=subprocess.PIPE, stderr=subprocess.P","category":"external_commands","line_end":55,"severity":"high","line_start":55},{"id":"filesystem:scripts/history.py:33:python-file-write-append","file":"scripts/history.py","pattern":"Python file write/append","snippet":"with os.fdopen(fd, 'wb') as output:","category":"filesystem","line_end":33,"severity":"medium","line_start":33},{"id":"filesystem:scripts/history.py:41:python-os-file-operations","file":"scripts/history.py","pattern":"Python os file operations","snippet":"os.unlink(temporary, dir_fd=directory)","category":"filesystem","line_end":41,"severity":"medium","line_start":41},{"id":"env_access:scripts/history.py:55:python-environment-access","file":"scripts/history.py","pattern":"Python environment access","snippet":"result = subprocess.run(['git', '-C', root] + arguments, stdout=subprocess.PIPE, stderr=subprocess.P","category":"env_access","line_end":55,"severity":"low","line_start":55},{"id":"env_access:scripts/history.py:65:python-environment-access","file":"scripts/history.py","pattern":"Python environment access","snippet":"if os.path.lexists(os.path.join(parent, '.git')) or os.environ.get('GIT_DIR'):","category":"env_access","line_end":65,"severity":"low","line_start":65},{"id":"blocker:scripts/history.py:23:system-reconnaissance","file":"scripts/history.py","pattern":"System reconnaissance","snippet":"if not stat.S_ISREG(info.st_mode) or info.st_uid != os.getuid() or info.st_nlink != 1:","category":"blocker","line_end":23,"severity":"low","line_start":23},{"id":"blocker:scripts/history.py:82:system-reconnaissance","file":"scripts/history.py","pattern":"System reconnaissance","snippet":"raise ValueError('invalid history operation or destination')","category":"blocker","line_end":82,"severity":"low","line_start":82},{"id":"blocker:scripts/history.py:87:system-reconnaissance","file":"scripts/history.py","pattern":"System reconnaissance","snippet":"if info.st_uid != os.getuid() or info.st_mode & 0o022:","category":"blocker","line_end":87,"severity":"low","line_start":87},{"id":"blocker:scripts/history.py:99:system-reconnaissance","file":"scripts/history.py","pattern":"System reconnaissance","snippet":"if info.st_uid != os.getuid() or info.st_mode & 0o022:","category":"blocker","line_end":99,"severity":"low","line_start":99},{"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:153:synchronous-spawn","file":"scripts/publish.mjs","pattern":"Synchronous spawn","snippet":"const r = spawnSync('unzip', [flag, zipPath], { encoding: 'utf8', maxBuffer: LIST_MAX_BUFFER, timeou","category":"external_commands","line_end":153,"severity":"high","line_start":153},{"id":"external_commands:scripts/publish.mjs:205:synchronous-spawn","file":"scripts/publish.mjs","pattern":"Synchronous spawn","snippet":"const z = spawnSync('zip', ['-q', '-X', '-@', out], {","category":"external_commands","line_end":205,"severity":"high","line_start":205},{"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:71:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`FAILED: ${msg}`);","category":"external_commands","line_end":71,"severity":"medium","line_start":71},{"id":"external_commands:scripts/publish.mjs:81: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":81,"severity":"medium","line_start":81},{"id":"external_commands:scripts/publish.mjs:90: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":90,"severity":"medium","line_start":90},{"id":"external_commands:scripts/publish.mjs:120: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":120,"severity":"medium","line_start":120},{"id":"external_commands:scripts/publish.mjs:132: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":132,"severity":"medium","line_start":132},{"id":"external_commands:scripts/publish.mjs:141: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":141,"severity":"medium","line_start":141},{"id":"external_commands:scripts/publish.mjs:146: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":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 (r.error) return `${bin} failed (${r.error.code || r.error.message})`;","category":"external_commands","line_end":147,"severity":"medium","line_start":147},{"id":"external_commands:scripts/publish.mjs:148: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":148,"severity":"medium","line_start":148},{"id":"external_commands:scripts/publish.mjs:151: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":151,"severity":"medium","line_start":151},{"id":"external_commands:scripts/publish.mjs:156: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":156,"severity":"medium","line_start":156},{"id":"external_commands:scripts/publish.mjs:159: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":159,"severity":"medium","line_start":159},{"id":"external_commands:scripts/publish.mjs:173: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":173,"severity":"medium","line_start":173},{"id":"external_commands:scripts/publish.mjs:174: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":174,"severity":"medium","line_start":174},{"id":"external_commands:scripts/publish.mjs:175:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`FILES: ${names.length}`);","category":"external_commands","line_end":175,"severity":"medium","line_start":175},{"id":"external_commands:scripts/publish.mjs:176:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`BYTES: ${bytes}`);","category":"external_commands","line_end":176,"severity":"medium","line_start":176},{"id":"external_commands:scripts/publish.mjs:177:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`ENTRY: ${entry}`);","category":"external_commands","line_end":177,"severity":"medium","line_start":177},{"id":"external_commands:scripts/publish.mjs:178: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":178,"severity":"medium","line_start":178},{"id":"external_commands:scripts/publish.mjs:179: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":179,"severity":"medium","line_start":179},{"id":"external_commands:scripts/publish.mjs:181: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":181,"severity":"medium","line_start":181},{"id":"external_commands:scripts/publish.mjs:183: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":183,"severity":"medium","line_start":183},{"id":"external_commands:scripts/publish.mjs:192: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":192,"severity":"medium","line_start":192},{"id":"external_commands:scripts/publish.mjs:198: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":198,"severity":"medium","line_start":198},{"id":"external_commands:scripts/publish.mjs:201: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":201,"severity":"medium","line_start":201},{"id":"external_commands:scripts/publish.mjs:206: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":206,"severity":"medium","line_start":206},{"id":"external_commands:scripts/publish.mjs:212:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"die(`${zipWhy} — no archive produced`);","category":"external_commands","line_end":212,"severity":"medium","line_start":212},{"id":"external_commands:scripts/publish.mjs:224: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":224,"severity":"medium","line_start":224},{"id":"external_commands:scripts/publish.mjs:232: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":232,"severity":"medium","line_start":232},{"id":"filesystem:scripts/publish.mjs:5:synchronous-file-operations","file":"scripts/publish.mjs","pattern":"Synchronous file operations","snippet":"import { readdirSync, statSync, lstatSync, existsSync, rmSync, accessSync, constants, readFileSync }","category":"filesystem","line_end":5,"severity":"medium","line_start":5},{"id":"filesystem:scripts/publish.mjs:44:synchronous-file-operations","file":"scripts/publish.mjs","pattern":"Synchronous file operations","snippet":"const data = readFileSync(zipPath);","category":"filesystem","line_end":44,"severity":"medium","line_start":44},{"id":"filesystem:scripts/publish.mjs:110: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":110,"severity":"medium","line_start":110},{"id":"filesystem:scripts/publish.mjs:201: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":201,"severity":"low","line_start":201},{"id":"env_access:scripts/publish.mjs:139: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":139,"severity":"low","line_start":139},{"id":"env_access:scripts/publish.mjs:140: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":140,"severity":"low","line_start":140},{"id":"env_access:scripts/publish.mjs:139: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":139,"severity":"low","line_start":139},{"id":"env_access:scripts/publish.mjs:140: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":140,"severity":"low","line_start":140},{"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:139: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":139,"severity":"high","line_start":139},{"id":"sensitive:scripts/publish.mjs:140: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":140,"severity":"high","line_start":140},{"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":"blocker:scripts/publish.mjs:48:system-reconnaissance","file":"scripts/publish.mjs","pattern":"System reconnaissance","snippet":"if (end < floor) return 'archive has no valid central directory';","category":"blocker","line_end":48,"severity":"low","line_start":48},{"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: explicit `2` or `4` → suggested slug | `1` → `public` | custom slug → validate it.","category":"external_commands","line_end":119,"severity":"medium","line_start":119},{"id":"external_commands:SKILL.md:126:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":135,"severity":"medium","line_start":126},{"id":"external_commands:SKILL.md:135:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":137,"severity":"medium","line_start":135},{"id":"external_commands:SKILL.md:137:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Resolution: explicit `1` or `3` → `{password_file}` = `''` (no password). `2` + an existing","category":"external_commands","line_end":137,"severity":"medium","line_start":137},{"id":"external_commands:SKILL.md:138: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":145,"severity":"medium","line_start":138},{"id":"external_commands:SKILL.md:145:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Delivery mode: NEW sites and non-public HTML pages (format `html`) get a Dedicated subdomain (an exp","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":"its subdomain and the response reports the mismatch); everything else defaults to Promotion (`path`)","category":"external_commands","line_end":147,"severity":"medium","line_start":146},{"id":"external_commands:SKILL.md:147: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":147,"severity":"medium","line_start":147},{"id":"external_commands:SKILL.md:148: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":157,"severity":"medium","line_start":148},{"id":"external_commands:SKILL.md:157:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{ns}` | `^[a-z0-9-]{1,32}$` |","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":"| `{days}` | positive integer; `''` = 15 |","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":"| `{entry}` | plain relative file name, no `..`; `''` = auto-detect; sites only |","category":"external_commands","line_end":159,"severity":"medium","line_start":159},{"id":"external_commands:SKILL.md:160:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `{delivery_mode}` | `''`, `path` or `subdomain` |","category":"external_commands","line_end":160,"severity":"medium","line_start":160},{"id":"external_commands:SKILL.md:161: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":161,"severity":"medium","line_start":161},{"id":"external_commands:SKILL.md:164: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":166,"severity":"medium","line_start":164},{"id":"external_commands:SKILL.md:166: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":166,"severity":"medium","line_start":166},{"id":"external_commands:SKILL.md:167:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","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":"```","category":"external_commands","line_end":171,"severity":"medium","line_start":169},{"id":"external_commands:SKILL.md:171: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":172,"severity":"medium","line_start":171},{"id":"external_commands:SKILL.md:172:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":174,"severity":"medium","line_start":172},{"id":"external_commands:SKILL.md:174:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":177,"severity":"medium","line_start":174},{"id":"external_commands:SKILL.md:177: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":177,"severity":"medium","line_start":177},{"id":"external_commands:SKILL.md:180:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","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":"```","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":"```bash","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":"```","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":"```bash","category":"external_commands","line_end":190,"severity":"medium","line_start":188},{"id":"external_commands:SKILL.md:190:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":194,"severity":"medium","line_start":190},{"id":"external_commands:SKILL.md:194:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Success** (the script printed `OK {url}`):","category":"external_commands","line_end":195,"severity":"medium","line_start":194},{"id":"external_commands:SKILL.md:195:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":199,"severity":"medium","line_start":195},{"id":"external_commands:SKILL.md:199:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":201,"severity":"medium","line_start":199},{"id":"external_commands:SKILL.md:201: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":202,"severity":"medium","line_start":201},{"id":"external_commands:SKILL.md:202:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":209,"severity":"medium","line_start":202},{"id":"external_commands:SKILL.md:209:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":214,"severity":"medium","line_start":209},{"id":"external_commands:SKILL.md:214: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":214,"severity":"medium","line_start":214},{"id":"external_commands:SKILL.md:218: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":219,"severity":"medium","line_start":218},{"id":"external_commands:SKILL.md:219: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":220,"severity":"medium","line_start":219},{"id":"external_commands:SKILL.md:220: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":223,"severity":"medium","line_start":220},{"id":"external_commands:SKILL.md:223:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Error** (the script printed `FAILED: ...`):","category":"external_commands","line_end":224,"severity":"medium","line_start":223},{"id":"external_commands:SKILL.md:224:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":226,"severity":"medium","line_start":224},{"id":"external_commands:SKILL.md:226:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":232,"severity":"medium","line_start":226},{"id":"external_commands:SKILL.md:232: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":242,"severity":"medium","line_start":232},{"id":"external_commands:SKILL.md:242: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":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":"- **`format` is a query param**: `/api/html` reads only `?format=` from the URL; a body `format` key","category":"external_commands","line_end":243,"severity":"medium","line_start":243},{"id":"external_commands:SKILL.md:244: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":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":"- Run dirs: private `brewpage.XXXXXX` under `$TMPDIR` (else `/tmp`), outside the protected `.claude/","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":"- Permissions: model-invocable, so `allowed-tools` holds one scoped Bash rule that matches every ste","category":"external_commands","line_end":247,"severity":"medium","line_start":246},{"id":"external_commands:SKILL.md:247: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":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":"- Use returned `ownerLink` and stored identity metadata for owner API operations; never parse NEW ro","category":"external_commands","line_end":249,"severity":"medium","line_start":248},{"id":"external_commands:SKILL.md:249: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":249,"severity":"medium","line_start":249},{"id":"external_commands:SKILL.md:250:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- Owner-only `GET`/`PATCH /api/{type}/{ns}/{id}/hosting` supports `html|files|json|kv|sites` with `X","category":"external_commands","line_end":250,"severity":"medium","line_start":250},{"id":"external_commands:SKILL.md:251: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":251,"severity":"medium","line_start":251},{"id":"external_commands:SKILL.md:252: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":252,"severity":"medium","line_start":252},{"id":"external_commands:SKILL.md:253: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":253,"severity":"medium","line_start":253},{"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:198:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"Optional: sign in free (Google or any email) at https://account.brewpage.app to manage publications ","category":"network","line_end":198,"severity":"low","line_start":198},{"id":"network:SKILL.md:206:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"Optional: sign in free (Google or any email) at https://account.brewpage.app to manage publications ","category":"network","line_end":206,"severity":"low","line_start":206},{"id":"network:SKILL.md:262: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":262,"severity":"low","line_start":262},{"id":"network:SKILL.md:263: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":263,"severity":"low","line_start":263},{"id":"filesystem:SKILL.md:197: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":197,"severity":"medium","line_start":197},{"id":"filesystem:SKILL.md:205: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":205,"severity":"medium","line_start":205},{"id":"filesystem:SKILL.md:244: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":244,"severity":"medium","line_start":244},{"id":"sensitive:SKILL.md:252: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":252,"severity":"high","line_start":252},{"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:252: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":252,"severity":"medium","line_start":252},{"id":"blocker:SKILL.md:235: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":235,"severity":"low","line_start":235},{"id":"obfuscation:scripts/brewpage-lib.sh:102: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":102,"severity":"high","line_start":102}],"finding_verdicts":[{"id":"network:LICENSE:3:hardcoded-url","reason":"The URL identifies the copyright holder repository in license text; it triggers no network request.","verdict":"false_positive","confidence":0.99},{"id":"network:README.md:115:hardcoded-url","reason":"This is a documented owner-authorized deletion example against the advertised service, not an automatically executed request.","verdict":"false_positive","confidence":0.99},{"id":"network:README.md:125:hardcoded-url","reason":"This is an explicit plugin-installation example for the author repository; it is not an automatic download or execution step.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:README.md:68:environment-file-access","reason":"The .env reference documents exclusion of hidden files from directory bundles; it does not instruct the agent to read environment secrets.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:README.md:68:sqlite-database-file","reason":"Thumbs.db appears in a system-file exclusion rule or its documentation; this is not access to a SQLite database.","verdict":"false_positive","confidence":0.99},{"id":"blocker:README.md:89:system-reconnaissance","reason":"The prose discusses preserving publication identity and returned links; it performs no system inventory or reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:51:ruby-shell-backtick-execution","reason":"The backticks are Markdown inside a single-quoted heredoc, which disables shell expansion and command substitution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:52:ruby-shell-backtick-execution","reason":"The backticks are Markdown inside a single-quoted heredoc, which disables shell expansion and command substitution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:62:ruby-shell-backtick-execution","reason":"The backticks are literal Markdown inside a single-quoted printf format string; the shell does not execute them.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:65:ruby-shell-backtick-execution","reason":"The backticks are literal Markdown inside a single-quoted printf format string; the shell does not execute them.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:166:ruby-shell-backtick-execution","reason":"The backticks occur only in a shell comment describing helper behavior; comments do not execute commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:187:ruby-shell-backtick-execution","reason":"The backticks occur only in a shell comment describing helper behavior; comments do not execute commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:8:shell-command-substitution","reason":"This substitution canonicalizes a supplied directory with quoted cd and pwd arguments; it does not evaluate the path as shell source.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:9:shell-command-substitution","reason":"This substitution canonicalizes HOME for a profile-directory comparison; it does not read credentials or execute environment contents.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:10:shell-command-substitution","reason":"This substitution canonicalizes CLAUDE_CONFIG_DIR to avoid using a profile as the project root; it does not inspect profile secrets.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:21:shell-command-substitution","reason":"The fixed git rev-parse command discovers the project root for local history; no input becomes shell source.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:32:shell-command-substitution","reason":"dirname receives a quoted directory variable during an upward project-root walk; no dynamic command is constructed.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:37:shell-command-substitution","reason":"The substitution invokes the local project-root helper and stores its result as data for the history destination.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:47:shell-command-substitution","reason":"The fixed Python helper initializes protected history using quoted arguments; dirname only locates that bundled helper.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:63:shell-command-substitution","reason":"The substitutions produce a timestamp and locate the secure history helper; publication values remain quoted printf arguments.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:66:shell-command-substitution","reason":"The substitutions produce a timestamp and locate the secure history helper; publication values remain quoted printf arguments.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:105:shell-command-substitution","reason":"The fixed find expression verifies that the owned run directory has mode 0700; it is a defensive permission check.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:190:shell-command-substitution","reason":"A fixed jq expression extracts the returned link as data; the result is not executed as shell source.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:192:shell-command-substitution","reason":"The substitution calls the local error formatter; its output becomes a diagnostic string, not executable code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:199:shell-command-substitution","reason":"A fixed jq expression extracts the owner token for private history; the substitution neither executes it nor displays it.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:201:shell-command-substitution","reason":"A fixed jq expression extracts the owner API link for history; the returned value is not used as shell source.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:202:shell-command-substitution","reason":"A fixed jq object expression selects identity metadata for history; no response value becomes executable code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:204:shell-command-substitution","reason":"A fixed jq expression reads the returned file count for the status message; it does not execute server data.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:229:shell-command-substitution","reason":"The fixed sed expression selects an entry-name field from the manifest; it is data extraction, not shell evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:62:template-literal-with-command-substitution","reason":"The detector spans single-quoted Markdown format strings and ordinary quoted substitutions; the backticks themselves are literal data.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:65:template-literal-with-command-substitution","reason":"The detector spans single-quoted Markdown format strings and ordinary quoted substitutions; the backticks themselves are literal data.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-lib.sh:51:hardcoded-url","reason":"The URL is literal documentation inside a single-quoted history-header heredoc; initializing history does not request this URL.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:84:path-traversal-sequence","reason":"The traversal strings are rejection patterns in entry validation; they prevent unsafe entry names rather than traverse the filesystem.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:10:hidden-file-access","reason":"The .git and .claude references locate the workspace and exclude profile roots; they do not read authentication material.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:14:hidden-file-access","reason":"The .git and .claude references locate the workspace and exclude profile roots; they do not read authentication material.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:28:hidden-file-access","reason":"The .git and .claude references locate the workspace and exclude profile roots; they do not read authentication material.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:38:hidden-file-access","reason":"This reference identifies local owner-token history, written with mode 0600 and Git exclusion checks by the secure history helper.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:8:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:9:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:10:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:21:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:46:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:132:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:133:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:148:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:160:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:183:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:196:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:212:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:93:temp-file-creation","reason":"mktemp creates a randomized private directory under umask 077; subsequent checks require ownership, mode 0700 and a non-symlink path.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:100:system-reconnaissance","reason":"This code rejects malformed temporary-run identifiers; it does not collect machine identity or enumerate system resources.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:102:system-reconnaissance","reason":"This code rejects malformed temporary-run identifiers; it does not collect machine identity or enumerate system resources.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:125:system-reconnaissance","reason":"This password-validation rule or comment enforces safe local password transport; it performs no system reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:127:system-reconnaissance","reason":"This password-validation rule or comment enforces safe local password transport; it performs no system reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:215:network-reconnaissance","reason":"The comment describes the local archive-verification gate; it performs no network scanning or discovery.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:6:shell-command-substitution","reason":"The substitutions locate the bundled script directory using quoted dirname and cd arguments; no downloaded code is invoked.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:17:shell-command-substitution","reason":"The local helper allocates a private run directory with mktemp and umask 077; the resulting path is stored as data.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:39:shell-command-substitution","reason":"Quoted cd and pwd canonicalize the requested source directory for a read-only probe; no path is evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:41:shell-command-substitution","reason":"The fixed find, sed, sort and awk pipeline lists candidate HTML files for the requested source; it does not execute filenames.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:44:shell-command-substitution","reason":"The fixed text-processing pipeline selects the shallowest HTML entry from probe results; filenames are not evaluated as shell code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:47:shell-command-substitution","reason":"The fixed find and counting commands report source-tree statistics; they do not transmit files or execute their contents.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:48:shell-command-substitution","reason":"The fixed du and cut pipeline reports the selected directory size; the quoted path remains data.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:50:shell-command-substitution","reason":"The substitutions canonicalize the supplied file path with dirname, cd, pwd and basename; they do not evaluate path contents.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:53:shell-command-substitution","reason":"The substitution counts bytes in the selected source file for the read-only probe; file contents are not executed.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:54:shell-command-substitution","reason":"The file command receives -- and a quoted path to identify MIME type; it does not run the selected file.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:65:shell-command-substitution","reason":"The fixed HTTPS request retrieves advertised service limits without a content payload or credentials; this implements the documented limits check.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:95:shell-command-substitution","reason":"The substitution counts staged text bytes for the status line; it does not interpret staged contents as shell code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:118:shell-command-substitution","reason":"The matched expression is arithmetic expansion of an internal source counter, not command substitution or execution of text.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:119:shell-command-substitution","reason":"The matched expression is arithmetic expansion of an internal source counter, not execution of the run identifier.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:120:shell-command-substitution","reason":"The matched expression is arithmetic expansion of an internal source counter, not execution of the supplied path.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:172:shell-command-substitution","reason":"The substitution captures the documented HTML upload response; validated query values are not evaluated as shell source.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:178:shell-command-substitution","reason":"The substitution captures the documented JSON upload response after JSON validation; it does not execute payload contents.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:183:shell-command-substitution","reason":"The substitution captures an intended upload response, not dynamic shell source; unsafe multipart filename parsing is reported separately.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:189:shell-command-substitution","reason":"The fixed Node helper builds and verifies the selected site archive using argument data; no shell interpreter runs supplied paths.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:194:shell-command-substitution","reason":"The fixed Node helper inspects the selected ZIP using argument data; no shell interpreter runs archive entries or supplied paths.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:198:shell-command-substitution","reason":"The substitutions capture a site response and URI-encode the entry; unsafe multipart filename parsing is reported separately.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-run.sh:65:hardcoded-url","reason":"The fixed HTTPS endpoint serves upload limits; this GET does not transmit local content or credentials.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-run.sh:172:hardcoded-url","reason":"The fixed HTTPS endpoint is the declared publication service, not a hidden destination; multipart path handling is assessed separately.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-run.sh:178:hardcoded-url","reason":"The fixed HTTPS endpoint is the declared publication service, not a hidden destination; multipart path handling is assessed separately.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-run.sh:183:hardcoded-url","reason":"The fixed HTTPS endpoint is the declared publication service, not a hidden destination; multipart path handling is assessed separately.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-run.sh:198:hardcoded-url","reason":"The fixed HTTPS endpoint is the declared publication service, not a hidden destination; multipart path handling is assessed separately.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:54:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:63:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:69:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:126:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:177:standard-device-file-access","reason":"The matched device is /dev/null, used to suppress probe or validation output; it does not read user files or collect secrets.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-run.sh:144:system-reconnaissance","reason":"id is a local variable declaration and pwmode is initialized to none; no identity-discovery command runs.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-run.sh:162:system-reconnaissance","reason":"The file test verifies staged content exists inside the selected run directory; it does not inventory unrelated files.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-run.sh:177:system-reconnaissance","reason":"jq empty checks that the selected payload is valid JSON; it performs no system inspection.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/history.py:55:python-subprocess-run","reason":"subprocess.run invokes fixed Git safety subcommands through an argument list without shell=True; these checks prevent committing token history.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/history.py:33:python-file-write-append","reason":"The helper writes an exclusively created temporary file with no-follow protection, then atomically replaces private history or the ignore file.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/history.py:41:python-os-file-operations","reason":"unlink removes only the generated temporary filename through its directory descriptor after atomic replacement; it is not arbitrary deletion.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/history.py:55:python-environment-access","reason":"The helper inherits the environment for fixed local Git checks and sets LC_ALL; it does not enumerate or transmit environment values.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/history.py:65:python-environment-access","reason":"GIT_DIR presence is checked so repository history protection fails closed when Git is unavailable; its value is not published.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:23:system-reconnaissance","reason":"File ownership, link count and directory permissions are checked to prevent unsafe history writes; these are defensive checks, not reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:82:system-reconnaissance","reason":"The error rejects unsupported history operations and destinations; it performs no system discovery.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:87:system-reconnaissance","reason":"File ownership, link count and directory permissions are checked to prevent unsafe history writes; these are defensive checks, not reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:99:system-reconnaissance","reason":"File ownership, link count and directory permissions are checked to prevent unsafe history writes; these are defensive checks, not reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:4:node-js-child-process-module","reason":"The import supports fixed zip and unzip subprocesses with argument arrays; importing child_process alone does not execute arbitrary commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:153:synchronous-spawn","reason":"spawnSync invokes unzip with fixed inspection flags and an argument array, bounded output and a timeout; it neither extracts nor executes archive contents.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:205:synchronous-spawn","reason":"spawnSync invokes zip without a shell and receives the selected filename list through stdin; it packages assets rather than executing filenames.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:2:ruby-shell-backtick-execution","reason":"The backticks occur in a JavaScript documentation comment; they cannot execute a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:26:ruby-shell-backtick-execution","reason":"The backticks occur in a JavaScript documentation comment; they cannot execute a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:29:ruby-shell-backtick-execution","reason":"The backticks occur in a JavaScript documentation comment; they cannot execute a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:30:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:37:ruby-shell-backtick-execution","reason":"The backticks occur in a JavaScript documentation comment; they cannot execute a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:71:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:81:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:90:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:120:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:132:ruby-shell-backtick-execution","reason":"The backticks occur in a JavaScript documentation comment; they cannot execute a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:141:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:146:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:147:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:148:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:151:ruby-shell-backtick-execution","reason":"The backticks occur in a JavaScript documentation comment; they cannot execute a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:156:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:159:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:173:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:174:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:175:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:176:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:177:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:178:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:179:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:181:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:183:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:192:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:198:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:201:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:206:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:212:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:224:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:232:ruby-shell-backtick-execution","reason":"These are JavaScript template literals or comment delimiters; they format data and do not invoke a shell interpreter.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/publish.mjs:5:synchronous-file-operations","reason":"These imports implement local archive creation and verification; directory collection excludes hidden entries and symlinks by default.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/publish.mjs:44:synchronous-file-operations","reason":"The requested ZIP is read only after a 25 MiB size check to validate central-directory budgets; this is bounded archive inspection.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/publish.mjs:110:hidden-file-access","reason":"The matched line rejects filenames containing carriage returns or newlines; this is validation, not hidden-file collection.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/publish.mjs:201:temp-file-creation","reason":"The match is a comment explaining removal of an empty temporary archive; the publication wrapper supplies an output path inside its private run directory.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:139:environment-variable-access-dot-notation","reason":"PATH and PATHEXT are used only to locate required zip utilities; there is no credential-variable lookup or environment serialization.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:140:environment-variable-access-dot-notation","reason":"PATH and PATHEXT are used only to locate required zip utilities; there is no credential-variable lookup or environment serialization.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:139:environment-variable-object","reason":"PATH and PATHEXT are used only to locate required zip utilities; there is no credential-variable lookup or environment serialization.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:140:environment-variable-object","reason":"PATH and PATHEXT are used only to locate required zip utilities; there is no credential-variable lookup or environment serialization.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:scripts/publish.mjs:33:ssh-private-key-file","reason":"Private-key and environment filenames appear in a sensitive-name detection regex; matching archive entries require confirmation, not automatic credential access.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:scripts/publish.mjs:33:environment-file-access","reason":"Private-key and environment filenames appear in a sensitive-name detection regex; matching archive entries require confirmation, not automatic credential access.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:scripts/publish.mjs:139:environment-file-access","reason":"The code reads PATH or PATHEXT for executable discovery; it does not open .env files or access credential variables.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:scripts/publish.mjs:140:environment-file-access","reason":"The code reads PATH or PATHEXT for executable discovery; it does not open .env files or access credential variables.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:scripts/publish.mjs:24:sqlite-database-file","reason":"Thumbs.db appears in a system-file exclusion rule or its documentation; this is not access to a SQLite database.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/publish.mjs:37:system-reconnaissance","reason":"The comment explains unzip output-buffer sizing; it runs no command and collects no system information.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/publish.mjs:48:system-reconnaissance","reason":"The archive parser rejects a ZIP without a valid central directory; it does not inspect host identity or system configuration.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:21:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:35:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:38:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:39:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:47:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:51:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:56:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:66:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:74:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:75:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:76:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:80:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:86:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:92:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:100:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:110:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:113:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:114:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:115:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:119:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:126:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:135:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:137:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:138:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:145:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:146:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:147:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:148:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:157:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:158:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:159:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:160:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:161:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:164:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:166:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:167:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:169:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:171:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:172:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:174:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:177:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:180:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:182:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:184:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:186:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:188:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:190:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:194:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:195:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:199:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:201:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:202:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:209:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:214:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:218:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:219:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:220:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:223:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:224:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:226:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:232:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:242:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:243:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:244:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:245:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:246:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:247:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:248:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:249:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:250:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:251:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:252:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:253:ruby-shell-backtick-execution","reason":"These backticks delimit Markdown code spans or fenced examples; they are not Ruby or shell backtick evaluation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:23:shell-command-substitution","reason":"The literal command-substitution syntax appears in a prohibition against chained or substituted shell commands, not an execution request.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:23:template-literal-with-command-substitution","reason":"The documentation explicitly prohibits command substitution in generated command arguments; the example is not executed shell source.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:84:hardcoded-url","reason":"The URL documents the advertised service limits endpoint; it is not an undisclosed data-transfer destination.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:198:hardcoded-url","reason":"The account URL appears in an explicitly optional sign-in notice; the workflow does not require login or collect account credentials.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:206:hardcoded-url","reason":"The account URL appears in an explicitly optional sign-in notice; the workflow does not require login or collect account credentials.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:262:hardcoded-url","reason":"This URL is an attribution link in the Powered by table, not an automatic request or instruction to transmit secrets.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:263:hardcoded-url","reason":"This URL is an attribution link in the Powered by table, not an automatic request or instruction to transmit secrets.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:197:hidden-file-access","reason":"This reference identifies local owner-token history, written with mode 0600 and Git exclusion checks by the secure history helper.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:205:hidden-file-access","reason":"This reference identifies local owner-token history, written with mode 0600 and Git exclusion checks by the secure history helper.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:244:hidden-file-access","reason":"This reference identifies local owner-token history, written with mode 0600 and Git exclusion checks by the secure history helper.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:SKILL.md:252:environment-file-access","reason":"The .env reference documents exclusion of hidden files from directory bundles; it does not instruct the agent to read environment secrets.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:SKILL.md:92:sqlite-database-file","reason":"Thumbs.db appears in a system-file exclusion rule or its documentation; this is not access to a SQLite database.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:SKILL.md:252:sqlite-database-file","reason":"Thumbs.db appears in a system-file exclusion rule or its documentation; this is not access to a SQLite database.","verdict":"false_positive","confidence":0.99},{"id":"blocker:SKILL.md:235:system-reconnaissance","reason":"The prose explains normalization of publication metadata and server errors; it does not inspect the host system.","verdict":"false_positive","confidence":0.99},{"id":"obfuscation:scripts/brewpage-lib.sh:102:heuristic-very-high-entropy-string-6-03-bits-lik","reason":"The high-entropy text is an explicit ASCII character allowlist for run identifiers; it is not encoded data or an executable payload.","verdict":"false_positive","confidence":0.99}],"semantic_findings":[{"title":"Multipart Path Injection Can Upload Unintended Local Files","severity":"high","locations":[{"file":"scripts/brewpage-run.sh","line_end":136,"line_start":135},{"file":"scripts/brewpage-run.sh","line_end":183,"line_start":183},{"file":"scripts/brewpage-run.sh","line_end":199,"line_start":193}],"confidence":0.99,"description":"Upload paths enter curl multipart syntax without filename escaping. A crafted existing path containing commas can select additional readable local files, sending their contents outside the approved source.","confidence_reasoning":"A loopback test used an existing comma-containing fixture path and reproduced an additional file upload. Shell quoting does not disable curl multipart parsing."}],"subject_marketplace_commit_sha":"7ad822ef13aa628e78d9da143046fd04fec0428e","subject_content_hash":"b15355ed8c401f28f23f94bd44f7148b639bc6979c8955de9f937244b1dcad27","subject_tree_hash":"bf8d970bf1108d6057b44d5834a35578f8879fe8e883a2f922d37aa86abac2dd","subject_plugin_path":"skills/kochetkov-ma/brewpage-publish","audit_payload_hash":"daecbf174a8337257d045e9451fa5880","confirmed_risk_level":"high","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"7ad822ef13aa628e78d9da143046fd04fec0428e","contentHash":"b15355ed8c401f28f23f94bd44f7148b639bc6979c8955de9f937244b1dcad27","treeHash":"bf8d970bf1108d6057b44d5834a35578f8879fe8e883a2f922d37aa86abac2dd","pluginPath":"skills/kochetkov-ma/brewpage-publish","auditPayloadHash":"daecbf174a8337257d045e9451fa5880"},"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/6/attestation","status":"superseded"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"high","confirmedFindingCount":1,"capabilityReviewCount":0,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"confirmation_required","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"superseded","verificationState":"not_verified"},"isLatest":false}}