{"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":6},"audit":{"id":"6d2f2d6d-0960-482a-9d7c-6739d63ed253","skill_id":"4bf85c8e-ddad-4143-9c98-4b5fde9536c8","version":9,"content_hash":"v3:3505ef53f4f0997977585dd4f79f91d49c258783:42d0e03a8294e05dd1f4e385c187eea55c633903299d2bd4eb57f0fd4c44efc1:63f5fffcb4f30f2c18038783e613d092e8b0f8e7ab10231d36dc81a3afa92099:736b696c6c732f6b6f636865746b6f762d6d612f62726577706167652d7075626c697368:2488bc7e4c31763da68d723c21df8b35","risk_level":"safe","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"All 272 static alerts reflect documented publishing behavior, defensive checks, or syntax misclassification. No evidence found of unauthorized exfiltration, credential harvesting, hidden execution, or audit-directed prompt injection. Selected content leaves the machine for brewpage.app; unlisted links require passwords for access control.","remediation":[],"risk_factor_evidence":[{"factor":"network","evidence":[{"file":"LICENSE","line_end":3,"line_start":3},{"file":"README.md","line_end":117,"line_start":117},{"file":"README.md","line_end":127,"line_start":127},{"file":"scripts/brewpage-lib.sh","line_end":51,"line_start":51},{"file":"scripts/brewpage-run.sh","line_end":73,"line_start":73},{"file":"scripts/brewpage-run.sh","line_end":188,"line_start":188},{"file":"scripts/brewpage-run.sh","line_end":194,"line_start":194},{"file":"scripts/brewpage-run.sh","line_end":199,"line_start":199},{"file":"scripts/brewpage-run.sh","line_end":216,"line_start":216},{"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":265,"line_start":265},{"file":"SKILL.md","line_end":266,"line_start":266}]},{"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":248,"line_start":246},{"file":"scripts/brewpage-lib.sh","line_end":265,"line_start":265},{"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":25,"line_start":25},{"file":"scripts/brewpage-run.sh","line_end":47,"line_start":47},{"file":"scripts/brewpage-run.sh","line_end":49,"line_start":49},{"file":"scripts/brewpage-run.sh","line_end":52,"line_start":52},{"file":"scripts/brewpage-run.sh","line_end":55,"line_start":55},{"file":"scripts/brewpage-run.sh","line_end":56,"line_start":56},{"file":"scripts/brewpage-run.sh","line_end":58,"line_start":58},{"file":"scripts/brewpage-run.sh","line_end":61,"line_start":61},{"file":"scripts/brewpage-run.sh","line_end":62,"line_start":62},{"file":"scripts/brewpage-run.sh","line_end":73,"line_start":73},{"file":"scripts/brewpage-run.sh","line_end":103,"line_start":103},{"file":"scripts/brewpage-run.sh","line_end":127,"line_start":127},{"file":"scripts/brewpage-run.sh","line_end":128,"line_start":128},{"file":"scripts/brewpage-run.sh","line_end":129,"line_start":129},{"file":"scripts/brewpage-run.sh","line_end":189,"line_start":188},{"file":"scripts/brewpage-run.sh","line_end":195,"line_start":194},{"file":"scripts/brewpage-run.sh","line_end":199,"line_start":199},{"file":"scripts/brewpage-run.sh","line_end":205,"line_start":205},{"file":"scripts/brewpage-run.sh","line_end":212,"line_start":212},{"file":"scripts/brewpage-run.sh","line_end":216,"line_start":216},{"file":"scripts/brewpage-run.sh","line_end":217,"line_start":217},{"file":"scripts/history.py","line_end":55,"line_start":55},{"file":"scripts/publish.mjs","line_end":4,"line_start":4}]},{"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-lib.sh","line_end":226,"line_start":226},{"file":"scripts/brewpage-run.sh","line_end":62,"line_start":62},{"file":"scripts/brewpage-run.sh","line_end":71,"line_start":71},{"file":"scripts/brewpage-run.sh","line_end":77,"line_start":77},{"file":"scripts/brewpage-run.sh","line_end":136,"line_start":136},{"file":"scripts/brewpage-run.sh","line_end":193,"line_start":193},{"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":105,"line_start":105},{"file":"scripts/publish.mjs","line_end":171,"line_start":171},{"file":"scripts/publish.mjs","line_end":5,"line_start":5},{"file":"scripts/publish.mjs","line_end":266,"line_start":266},{"file":"scripts/publish.mjs","line_end":307,"line_start":307},{"file":"scripts/publish.mjs","line_end":81,"line_start":81},{"file":"scripts/publish.mjs","line_end":79,"line_start":79},{"file":"SKILL.md","line_end":197,"line_start":197},{"file":"SKILL.md","line_end":205,"line_start":205},{"file":"SKILL.md","line_end":247,"line_start":247}]},{"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":200,"line_start":200},{"file":"scripts/publish.mjs","line_end":201,"line_start":201},{"file":"scripts/publish.mjs","line_end":200,"line_start":200},{"file":"scripts/publish.mjs","line_end":201,"line_start":201}]}],"critical_findings":[],"high_findings":[],"medium_findings":[],"low_findings":[],"dangerous_patterns":[],"files_scanned":7,"total_lines":1436,"audit_model":"codex","audited_at":"2026-10-27T05:10:11.814+00:00","created_at":"2026-10-27T05:47:01.379819+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:117: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":117,"severity":"low","line_start":117},{"id":"network:README.md:127:hardcoded-url","file":"README.md","pattern":"Hardcoded URL","snippet":"claude plugin marketplace add https://github.com/kochetkov-ma/claude-brewcode","category":"network","line_end":127,"severity":"low","line_start":127},{"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:91: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":91,"severity":"low","line_start":91},{"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:246:shell-command-substitution","file":"scripts/brewpage-lib.sh","pattern":"Shell command substitution","snippet":"digest=$(python3 - \"$zip\" <<'PY'","category":"external_commands","line_end":248,"severity":"medium","line_start":246},{"id":"external_commands:scripts/brewpage-lib.sh:265: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":265,"severity":"medium","line_start":265},{"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":"filesystem:scripts/brewpage-lib.sh:226:python-file-write-append","file":"scripts/brewpage-lib.sh","pattern":"Python file write/append","snippet":"with os.fdopen(fd, 'wb') as outgoing:","category":"filesystem","line_end":226,"severity":"medium","line_start":226},{"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:251:system-reconnaissance","file":"scripts/brewpage-lib.sh","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":251,"severity":"low","line_start":251},{"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:25: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":25,"severity":"medium","line_start":25},{"id":"external_commands:scripts/brewpage-run.sh:47:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"abs=$(cd \"$p\" && pwd -P)","category":"external_commands","line_end":47,"severity":"medium","line_start":47},{"id":"external_commands:scripts/brewpage-run.sh:49:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"html_files=$(cd \"$abs\" && find . -type f \\( -name '*.html' -o -name '*.htm' \\) | sed 's|^\\./||' | LC","category":"external_commands","line_end":49,"severity":"medium","line_start":49},{"id":"external_commands:scripts/brewpage-run.sh:52:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"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":52,"severity":"medium","line_start":52},{"id":"external_commands:scripts/brewpage-run.sh:55: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":55,"severity":"medium","line_start":55},{"id":"external_commands:scripts/brewpage-run.sh:56: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":56,"severity":"medium","line_start":56},{"id":"external_commands:scripts/brewpage-run.sh:58: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":58,"severity":"medium","line_start":58},{"id":"external_commands:scripts/brewpage-run.sh:61: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":61,"severity":"medium","line_start":61},{"id":"external_commands:scripts/brewpage-run.sh:62: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":62,"severity":"medium","line_start":62},{"id":"external_commands:scripts/brewpage-run.sh:73: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":73,"severity":"medium","line_start":73},{"id":"external_commands:scripts/brewpage-run.sh:103: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":103,"severity":"medium","line_start":103},{"id":"external_commands:scripts/brewpage-run.sh:127: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":127,"severity":"medium","line_start":127},{"id":"external_commands:scripts/brewpage-run.sh:128: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":128,"severity":"medium","line_start":128},{"id":"external_commands:scripts/brewpage-run.sh:129: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":129,"severity":"medium","line_start":129},{"id":"external_commands:scripts/brewpage-run.sh:188: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":189,"severity":"medium","line_start":188},{"id":"external_commands:scripts/brewpage-run.sh:194: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":195,"severity":"medium","line_start":194},{"id":"external_commands:scripts/brewpage-run.sh:199: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 \"$(form_file file \"$path\")\")","category":"external_commands","line_end":199,"severity":"medium","line_start":199},{"id":"external_commands:scripts/brewpage-run.sh:205:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"manifest=$(umask 077; node \"$HERE/publish.mjs\" pack --dir \"$path\" --out \"$archive\" ${ENTRY:+--entry ","category":"external_commands","line_end":205,"severity":"medium","line_start":205},{"id":"external_commands:scripts/brewpage-run.sh:212:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"manifest=$(node \"$HERE/publish.mjs\" inspect --zip \"$archive\" ${ENTRY:+--entry \"$ENTRY\"}) || rc=$?","category":"external_commands","line_end":212,"severity":"medium","line_start":212},{"id":"external_commands:scripts/brewpage-run.sh:216: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":216,"severity":"medium","line_start":216},{"id":"external_commands:scripts/brewpage-run.sh:217:shell-command-substitution","file":"scripts/brewpage-run.sh","pattern":"Shell command substitution","snippet":"-H \"User-Agent: ClaudeCode/1.0\" -F \"$(form_file archive \"$archive\")\") || die \"upload request failed\"","category":"external_commands","line_end":217,"severity":"medium","line_start":217},{"id":"network:scripts/brewpage-run.sh:73: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":73,"severity":"low","line_start":73},{"id":"network:scripts/brewpage-run.sh:188: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":188,"severity":"low","line_start":188},{"id":"network:scripts/brewpage-run.sh:194: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":194,"severity":"low","line_start":194},{"id":"network:scripts/brewpage-run.sh:199:hardcoded-url","file":"scripts/brewpage-run.sh","pattern":"Hardcoded URL","snippet":"response=$(bp_post \"https://brewpage.app/api/files?ns=$NS&ttl=$DAYS\" -F \"$(form_file file \"$path\")\")","category":"network","line_end":199,"severity":"low","line_start":199},{"id":"network:scripts/brewpage-run.sh:216: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":216,"severity":"low","line_start":216},{"id":"filesystem:scripts/brewpage-run.sh:62: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":62,"severity":"low","line_start":62},{"id":"filesystem:scripts/brewpage-run.sh:71: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":71,"severity":"low","line_start":71},{"id":"filesystem:scripts/brewpage-run.sh:77: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":77,"severity":"low","line_start":77},{"id":"filesystem:scripts/brewpage-run.sh:136: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":136,"severity":"low","line_start":136},{"id":"filesystem:scripts/brewpage-run.sh:193: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":193,"severity":"low","line_start":193},{"id":"blocker:scripts/brewpage-run.sh:160:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"local id pwmode=none","category":"blocker","line_end":160,"severity":"low","line_start":160},{"id":"blocker:scripts/brewpage-run.sh:178:system-reconnaissance","file":"scripts/brewpage-run.sh","pattern":"System reconnaissance","snippet":"[ -f \"$content\" ] || die \"run $id has no staged text\"","category":"blocker","line_end":178,"severity":"low","line_start":178},{"id":"blocker:scripts/brewpage-run.sh:193: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":193,"severity":"low","line_start":193},{"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 { spawn, spawnSync } from 'node:child_process';","category":"external_commands","line_end":4,"severity":"high","line_start":4},{"id":"external_commands:scripts/publish.mjs:283:process-spawn","file":"scripts/publish.mjs","pattern":"Process spawn","snippet":"const child = spawn(bin, argv, { cwd: options.cwd, stdio: ['pipe', 'ignore', 'ignore'] });","category":"external_commands","line_end":283,"severity":"high","line_start":283},{"id":"external_commands:scripts/publish.mjs:214: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":214,"severity":"high","line_start":214},{"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:27: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":27,"severity":"medium","line_start":27},{"id":"external_commands:scripts/publish.mjs:30: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":30,"severity":"medium","line_start":30},{"id":"external_commands:scripts/publish.mjs:31: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":31,"severity":"medium","line_start":31},{"id":"external_commands:scripts/publish.mjs:38: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":38,"severity":"medium","line_start":38},{"id":"external_commands:scripts/publish.mjs:43:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"const SNAPSHOT = String.raw`","category":"external_commands","line_end":100,"severity":"medium","line_start":43},{"id":"external_commands:scripts/publish.mjs:132:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`FAILED: ${msg}`);","category":"external_commands","line_end":132,"severity":"medium","line_start":132},{"id":"external_commands:scripts/publish.mjs:142: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":142,"severity":"medium","line_start":142},{"id":"external_commands:scripts/publish.mjs:151: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":151,"severity":"medium","line_start":151},{"id":"external_commands:scripts/publish.mjs:181: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":181,"severity":"medium","line_start":181},{"id":"external_commands:scripts/publish.mjs:193: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":193,"severity":"medium","line_start":193},{"id":"external_commands:scripts/publish.mjs:202: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":202,"severity":"medium","line_start":202},{"id":"external_commands:scripts/publish.mjs:207: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":207,"severity":"medium","line_start":207},{"id":"external_commands:scripts/publish.mjs:208: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":208,"severity":"medium","line_start":208},{"id":"external_commands:scripts/publish.mjs:209: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":209,"severity":"medium","line_start":209},{"id":"external_commands:scripts/publish.mjs:212: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":212,"severity":"medium","line_start":212},{"id":"external_commands:scripts/publish.mjs:217: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":217,"severity":"medium","line_start":217},{"id":"external_commands:scripts/publish.mjs:220: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":220,"severity":"medium","line_start":220},{"id":"external_commands:scripts/publish.mjs:234: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":234,"severity":"medium","line_start":234},{"id":"external_commands:scripts/publish.mjs:235: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":235,"severity":"medium","line_start":235},{"id":"external_commands:scripts/publish.mjs:236:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`FILES: ${names.length}`);","category":"external_commands","line_end":236,"severity":"medium","line_start":236},{"id":"external_commands:scripts/publish.mjs:237:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`BYTES: ${bytes}`);","category":"external_commands","line_end":237,"severity":"medium","line_start":237},{"id":"external_commands:scripts/publish.mjs:238:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"console.log(`ENTRY: ${entry}`);","category":"external_commands","line_end":238,"severity":"medium","line_start":238},{"id":"external_commands:scripts/publish.mjs:239: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":239,"severity":"medium","line_start":239},{"id":"external_commands:scripts/publish.mjs:240: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":240,"severity":"medium","line_start":240},{"id":"external_commands:scripts/publish.mjs:242: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":242,"severity":"medium","line_start":242},{"id":"external_commands:scripts/publish.mjs:244: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":244,"severity":"medium","line_start":244},{"id":"external_commands:scripts/publish.mjs:253: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":253,"severity":"medium","line_start":253},{"id":"external_commands:scripts/publish.mjs:263: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":263,"severity":"medium","line_start":263},{"id":"external_commands:scripts/publish.mjs:266: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":266,"severity":"medium","line_start":266},{"id":"external_commands:scripts/publish.mjs:314:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"cwd: snapshot, input: `${kept.join('\\n')}\\n`, encoding: 'utf8',","category":"external_commands","line_end":314,"severity":"medium","line_start":314},{"id":"external_commands:scripts/publish.mjs:323:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"if (interrupted) die(`pack interrupted (${interrupted})`);","category":"external_commands","line_end":323,"severity":"medium","line_start":323},{"id":"external_commands:scripts/publish.mjs:329:ruby-shell-backtick-execution","file":"scripts/publish.mjs","pattern":"Ruby/shell backtick execution","snippet":"die(`${zipWhy} — no archive produced`);","category":"external_commands","line_end":329,"severity":"medium","line_start":329},{"id":"external_commands:scripts/publish.mjs:341: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":341,"severity":"medium","line_start":341},{"id":"external_commands:scripts/publish.mjs:349: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":349,"severity":"medium","line_start":349},{"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:105:synchronous-file-operations","file":"scripts/publish.mjs","pattern":"Synchronous file operations","snippet":"const data = readFileSync(zipPath);","category":"filesystem","line_end":105,"severity":"medium","line_start":105},{"id":"filesystem:scripts/publish.mjs:171: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":171,"severity":"medium","line_start":171},{"id":"filesystem:scripts/publish.mjs:5:temp-file-creation","file":"scripts/publish.mjs","pattern":"Temp file creation","snippet":"import { readdirSync, statSync, lstatSync, existsSync, rmSync, accessSync, constants, readFileSync, ","category":"filesystem","line_end":5,"severity":"low","line_start":5},{"id":"filesystem:scripts/publish.mjs:266: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":266,"severity":"low","line_start":266},{"id":"filesystem:scripts/publish.mjs:307:temp-file-creation","file":"scripts/publish.mjs","pattern":"Temp file creation","snippet":"snapshot = mkdtempSync(join(tmpdir(), 'brewpage-pack-'));","category":"filesystem","line_end":307,"severity":"low","line_start":307},{"id":"filesystem:scripts/publish.mjs:81:python-file-write-append","file":"scripts/publish.mjs","pattern":"Python file write/append","snippet":"with os.fdopen(output, 'wb') as dest:","category":"filesystem","line_end":81,"severity":"medium","line_start":81},{"id":"filesystem:scripts/publish.mjs:79:python-os-file-operations","file":"scripts/publish.mjs","pattern":"Python os file operations","snippet":"os.makedirs(os.path.dirname(target), mode=0o700, exist_ok=True)","category":"filesystem","line_end":79,"severity":"medium","line_start":79},{"id":"env_access:scripts/publish.mjs:200: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":200,"severity":"low","line_start":200},{"id":"env_access:scripts/publish.mjs:201: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":201,"severity":"low","line_start":201},{"id":"env_access:scripts/publish.mjs:200: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":200,"severity":"low","line_start":200},{"id":"env_access:scripts/publish.mjs:201: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":201,"severity":"low","line_start":201},{"id":"sensitive:scripts/publish.mjs:34: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":34,"severity":"critical","line_start":34},{"id":"sensitive:scripts/publish.mjs:34: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":34,"severity":"high","line_start":34},{"id":"sensitive:scripts/publish.mjs:200: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":200,"severity":"high","line_start":200},{"id":"sensitive:scripts/publish.mjs:201: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":201,"severity":"high","line_start":201},{"id":"sensitive:scripts/publish.mjs:25: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":25,"severity":"medium","line_start":25},{"id":"blocker:scripts/publish.mjs:38: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":38,"severity":"low","line_start":38},{"id":"blocker:scripts/publish.mjs:66:system-reconnaissance","file":"scripts/publish.mjs","pattern":"System reconnaissance","snippet":"raise ValueError('invalid member')","category":"blocker","line_end":66,"severity":"low","line_start":66},{"id":"blocker:scripts/publish.mjs:77:system-reconnaissance","file":"scripts/publish.mjs","pattern":"System reconnaissance","snippet":"raise ValueError('invalid source file')","category":"blocker","line_end":77,"severity":"low","line_start":77},{"id":"blocker:scripts/publish.mjs:109:system-reconnaissance","file":"scripts/publish.mjs","pattern":"System reconnaissance","snippet":"if (end < floor) return 'archive has no valid central directory';","category":"blocker","line_end":109,"severity":"low","line_start":109},{"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 --review-sha256 '{review_sha256}'` appended, using t","category":"external_commands","line_end":221,"severity":"medium","line_start":220},{"id":"external_commands:SKILL.md:221:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"`REVIEW_SHA256` printed beside the approved manifest. Changed archive bytes produce a fresh manifest","category":"external_commands","line_end":226,"severity":"medium","line_start":221},{"id":"external_commands:SKILL.md:226:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Error** (the script printed `FAILED: ...`):","category":"external_commands","line_end":227,"severity":"medium","line_start":226},{"id":"external_commands:SKILL.md:227:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":229,"severity":"medium","line_start":227},{"id":"external_commands:SKILL.md:229:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":235,"severity":"medium","line_start":229},{"id":"external_commands:SKILL.md:235: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":245,"severity":"medium","line_start":235},{"id":"external_commands:SKILL.md:245: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":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":"- **`format` is a query param**: `/api/html` reads only `?format=` from the URL; a body `format` key","category":"external_commands","line_end":246,"severity":"medium","line_start":246},{"id":"external_commands:SKILL.md:247:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- History: `<project-root>/.claude/brewpage-history.md` (root: `CLAUDE_PROJECT_DIR` → git toplevel →","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":"- Run dirs: private `brewpage.XXXXXX` under `$TMPDIR` (else `/tmp`), outside the protected `.claude/","category":"external_commands","line_end":248,"severity":"medium","line_start":248},{"id":"external_commands:SKILL.md:249: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":250,"severity":"medium","line_start":249},{"id":"external_commands:SKILL.md:250: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":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":"- Use returned `ownerLink` and stored identity metadata for owner API operations; never parse NEW ro","category":"external_commands","line_end":252,"severity":"medium","line_start":251},{"id":"external_commands:SKILL.md:252: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":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":"- Owner-only `GET`/`PATCH /api/{type}/{ns}/{id}/hosting` supports `html|files|json|kv|sites` with `X","category":"external_commands","line_end":253,"severity":"medium","line_start":253},{"id":"external_commands:SKILL.md:254: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":254,"severity":"medium","line_start":254},{"id":"external_commands:SKILL.md:255: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":255,"severity":"medium","line_start":255},{"id":"external_commands:SKILL.md:256: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":256,"severity":"medium","line_start":256},{"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:265: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":265,"severity":"low","line_start":265},{"id":"network:SKILL.md:266: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":266,"severity":"low","line_start":266},{"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:247: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":247,"severity":"medium","line_start":247},{"id":"sensitive:SKILL.md:255: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":255,"severity":"high","line_start":255},{"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:255: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":255,"severity":"medium","line_start":255},{"id":"blocker:SKILL.md:238: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":238,"severity":"low","line_start":238},{"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":"This URL credits the upstream project in the license. It is documentation and initiates no network request.","verdict":"false_positive","confidence":0.99},{"id":"network:README.md:117:hardcoded-url","reason":"The URL is a documented owner-authorized deletion example with placeholders. No token or content is sent merely by including this example.","verdict":"false_positive","confidence":0.99},{"id":"network:README.md:127:hardcoded-url","reason":"This is an explicit plugin installation example pointing to the disclosed upstream GitHub repository. It is not an executed download or hidden destination.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:README.md:68:environment-file-access","reason":"The documentation describes excluding .env and system entries such as Thumbs.db from site bundles. These filenames are protective examples, not credential-reading instructions.","verdict":"false_positive","confidence":1},{"id":"sensitive:README.md:68:sqlite-database-file","reason":"The documentation describes excluding .env and system entries such as Thumbs.db from site bundles. These filenames are protective examples, not credential-reading instructions.","verdict":"false_positive","confidence":1},{"id":"blocker:README.md:91:system-reconnaissance","reason":"This describes preserving the identity of an existing hosted publication. It does not inspect host users, processes, or system identity.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:51:ruby-shell-backtick-execution","reason":"Backticks occur inside a single-quoted heredoc used as history documentation. Shell command substitution is disabled for this heredoc.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:52:ruby-shell-backtick-execution","reason":"Backticks occur inside a single-quoted heredoc used as history documentation. Shell command substitution is disabled for this heredoc.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:62:ruby-shell-backtick-execution","reason":"Backticks are literal characters inside a single-quoted printf format. Values are separate arguments passed to the protected history writer.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:65:ruby-shell-backtick-execution","reason":"Backticks are literal characters inside a single-quoted printf format. Values are separate arguments passed to the protected history writer.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:166:ruby-shell-backtick-execution","reason":"The backticks occur in a shell comment describing implementation details. 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 in a shell comment describing implementation details. Comments do not execute commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:8:shell-command-substitution","reason":"Canonicalizes the supplied directory with quoted cd and pwd. The result is compared as a path, never evaluated as shell source.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:9:shell-command-substitution","reason":"Canonicalizes HOME only to exclude the user profile from project-root selection. No profile contents are read or transmitted.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:10:shell-command-substitution","reason":"Canonicalizes CLAUDE_CONFIG_DIR for a profile-directory comparison. This reads directory identity, not credentials or configuration contents.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:21:shell-command-substitution","reason":"Runs the fixed git rev-parse command to locate the project root. No user-controlled command text is evaluated.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:32:shell-command-substitution","reason":"Uses dirname on a quoted path during upward project-root discovery. The result remains path data.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:37:shell-command-substitution","reason":"Calls the local project-root helper and stores its result. This selects the protected history destination, not an external execution target.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:47:shell-command-substitution","reason":"Computes the bundled history helper path and calls it with quoted arguments. The quoted heredoc contains literal documentation, not executable substitutions.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:63:shell-command-substitution","reason":"Captures a fixed date format and locates the bundled history helper. Publication metadata is passed through a constant printf format, not evaluated.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:66:shell-command-substitution","reason":"Captures a fixed timestamp and passes publication metadata to the protected history writer. Quoted arguments are data, not shell source.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:105:shell-command-substitution","reason":"Uses find at depth zero to verify the selected temporary directory has mode 0700. This is a defensive permission check.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:190:shell-command-substitution","reason":"Extracts the returned publication link with a fixed jq expression. Response text is stored as data and is not executed.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:192:shell-command-substitution","reason":"Calls the local error formatter, which limits and sanitizes server error text. It does not execute response content.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:199:shell-command-substitution","reason":"Extracts the returned owner token for protected local history. The value is not evaluated or printed in the normal success output.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:201:shell-command-substitution","reason":"Extracts the owner API URL into local history metadata. The string is neither executed nor used for an additional request here.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:202:shell-command-substitution","reason":"Selects explicit response metadata fields using a fixed jq expression. The compact result is stored as data in protected history.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:204:shell-command-substitution","reason":"Extracts a server-reported file count with a fixed jq filter. This formats publication status rather than executing remote content.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:246:shell-command-substitution","reason":"Runs fixed inline Python to hash the reviewed private archive. Ownership, regular-file, and hardlink checks protect the digest-bound approval.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:265:shell-command-substitution","reason":"Extracts ENTRY from the local manifest with a fixed sed expression. The entry is later URL-encoded, not evaluated as shell source.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-lib.sh:62:template-literal-with-command-substitution","reason":"Backticks are literal characters inside a single-quoted printf format. Values are separate arguments passed to the protected history writer.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-lib.sh:65:template-literal-with-command-substitution","reason":"Backticks are literal characters inside a single-quoted printf format. Values are separate arguments passed to the protected history writer.","verdict":"false_positive","confidence":0.99},{"id":"network:scripts/brewpage-lib.sh:51:hardcoded-url","reason":"The URL appears inside a single-quoted heredoc written to private history as help text. It is not requested by this code.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:84:path-traversal-sequence","reason":"The traversal strings are rejection patterns in an entry-name validator. This code blocks parent-directory segments instead of using them to access files.","verdict":"false_positive","confidence":1},{"id":"filesystem:scripts/brewpage-lib.sh:10:hidden-file-access","reason":"The .git and .claude references locate a project root or exclude profile directories. They do not read credentials or unrelated hidden-file contents.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:14:hidden-file-access","reason":"The .git and .claude references locate a project root or exclude profile directories. They do not read credentials or unrelated hidden-file contents.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:28:hidden-file-access","reason":"The .git and .claude references locate a project root or exclude profile directories. They do not read credentials or unrelated hidden-file contents.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:38:hidden-file-access","reason":"This assigns the documented project-local token history path. The history helper enforces ownership, non-symlink files, mode 600, and effective Git exclusion.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/brewpage-lib.sh:8:standard-device-file-access","reason":"The matched device is /dev/null, used to discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","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 discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:93:temp-file-creation","reason":"mktemp creates a unique run directory under umask 077. Subsequent checks require owned, mode 0700, non-symlink directories before use or cleanup.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-lib.sh:226:python-file-write-append","reason":"Copies the selected archive into a private, exclusively created mode 600 snapshot with O_NOFOLLOW. File type and compressed byte limits are enforced.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:100:system-reconnaissance","reason":"This rejects malformed run identifiers using a fixed name pattern. The id variable is not the system id command.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:102:system-reconnaissance","reason":"This rejects malformed run identifiers using a fixed name pattern. The id variable is not the system id command.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:125:system-reconnaissance","reason":"This validates a password before constructing its HTTP header. The error text is not a system identity command.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:127:system-reconnaissance","reason":"This comment documents constraints on an explicitly selected password file. It requests no enumeration of users, processes, or host credentials.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-lib.sh:251:system-reconnaissance","reason":"Checks that the reviewed archive is regular, owned by the current user, and not hardlinked. This protects archive approval, not host profiling.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/brewpage-run.sh:6:shell-command-substitution","reason":"Locates the bundled helper directory using quoted dirname and cd. No supplied path becomes executable shell text.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:25:shell-command-substitution","reason":"Calls the private temporary-directory allocator and records its result. Cleanup is armed immediately for the newly allocated directory.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:47:shell-command-substitution","reason":"Canonicalizes the explicitly selected directory for a read-only probe. The quoted path is data, not shell code.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:49:shell-command-substitution","reason":"Enumerates HTML filenames under the selected directory and filters hidden paths. This is read-only entry discovery, not unrelated system reconnaissance.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:52:shell-command-substitution","reason":"Selects the shallowest HTML entry from probe output using fixed text-processing commands. No resulting filename is executed.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:55:shell-command-substitution","reason":"Counts selected files and HTML entries for pre-publication statistics. The fixed commands operate only on the chosen directory.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:56:shell-command-substitution","reason":"Measures disk usage of the selected directory for pre-publication statistics. It does not collect unrelated host information.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:58:shell-command-substitution","reason":"Builds an absolute path from quoted dirname and basename results. The selected filename is not evaluated as code.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:61:shell-command-substitution","reason":"Counts bytes in the explicitly selected file for a read-only probe. Output is a size statistic, not file contents.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:62:shell-command-substitution","reason":"Detects the MIME type of the selected file using file with an option terminator. It does not execute the file.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:73:shell-command-substitution","reason":"Retrieves public service limits from the documented HTTPS endpoint. No selected content, password, or owner token is attached.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:103:shell-command-substitution","reason":"Counts staged content bytes in the private run directory. It reports the size without printing the staged content.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:127:shell-command-substitution","reason":"The matched expression is integer arithmetic incrementing a source counter. It is not command substitution or dynamic execution.","verdict":"false_positive","confidence":1},{"id":"external_commands:scripts/brewpage-run.sh:128:shell-command-substitution","reason":"The matched expression increments the source counter using shell arithmetic. The run identifier remains an argument value.","verdict":"false_positive","confidence":1},{"id":"external_commands:scripts/brewpage-run.sh:129:shell-command-substitution","reason":"The matched expression increments a local integer counter. The supplied path is stored as data, not evaluated.","verdict":"false_positive","confidence":1},{"id":"external_commands:scripts/brewpage-run.sh:188:shell-command-substitution","reason":"Uploads selected Markdown content to the declared HTTPS hosting API. The workflow requires explicit namespace and password choices before this call.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:194:shell-command-substitution","reason":"Uploads the selected, syntactically validated JSON to the declared hosting API. This is the requested publication operation, not hidden exfiltration.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:199:shell-command-substitution","reason":"Uploads the explicitly selected file to the declared hosting API. form_file escapes curl multipart metacharacters before constructing the argument.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:205:shell-command-substitution","reason":"Runs the bundled offline packer on the selected directory with quoted paths. Its manifest and exit status control whether upload may continue.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:212:shell-command-substitution","reason":"Runs the bundled inspector on the private archive snapshot. Failed inspection or missing digest approval prevents upload.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:216:shell-command-substitution","reason":"Uploads the verified archive to the declared site API. Namespace and TTL are validated, and the selected entry is URL-encoded.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/brewpage-run.sh:217:shell-command-substitution","reason":"Constructs the multipart archive argument with dedicated escaping. It uploads only the previously inspected private snapshot.","verdict":"false_positive","confidence":0.97},{"id":"network:scripts/brewpage-run.sh:73:hardcoded-url","reason":"Retrieves public service limits from the documented HTTPS endpoint. No selected content, password, or owner token is attached.","verdict":"false_positive","confidence":0.97},{"id":"network:scripts/brewpage-run.sh:188:hardcoded-url","reason":"Uploads selected Markdown content to the declared HTTPS hosting API. The workflow requires explicit namespace and password choices before this call.","verdict":"false_positive","confidence":0.97},{"id":"network:scripts/brewpage-run.sh:194:hardcoded-url","reason":"Uploads the selected, syntactically validated JSON to the declared hosting API. This is the requested publication operation, not hidden exfiltration.","verdict":"false_positive","confidence":0.97},{"id":"network:scripts/brewpage-run.sh:199:hardcoded-url","reason":"Uploads the explicitly selected file to the declared hosting API. form_file escapes curl multipart metacharacters before constructing the argument.","verdict":"false_positive","confidence":0.97},{"id":"network:scripts/brewpage-run.sh:216:hardcoded-url","reason":"Uploads the verified archive to the declared site API. Namespace and TTL are validated, and the selected entry is URL-encoded.","verdict":"false_positive","confidence":0.97},{"id":"filesystem:scripts/brewpage-run.sh:62:standard-device-file-access","reason":"The matched device is /dev/null, used to discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:71:standard-device-file-access","reason":"The matched device is /dev/null, used to discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:77:standard-device-file-access","reason":"The matched device is /dev/null, used to discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:136:standard-device-file-access","reason":"The matched device is /dev/null, used to discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/brewpage-run.sh:193:standard-device-file-access","reason":"The matched device is /dev/null, used to discard diagnostics or validation output. No raw device, unrelated file, or sensitive device data is accessed.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-run.sh:160:system-reconnaissance","reason":"Declares local run-identifier and password-mode variables. No system identity command is executed.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-run.sh:178:system-reconnaissance","reason":"Verifies that the selected private run contains staged content. It does not enumerate unrelated files or system information.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/brewpage-run.sh:193:system-reconnaissance","reason":"jq empty validates the selected JSON payload without printing it. The error string is not system reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/history.py:55:python-subprocess-run","reason":"subprocess.run receives fixed Git safety commands as an argument list without shell=True. These verify repository status and prevent committing owner-token history.","verdict":"false_positive","confidence":0.97},{"id":"filesystem:scripts/history.py:33:python-file-write-append","reason":"Writes an exclusively created, non-symlink temporary file before atomic replacement. The helper restricts destinations and protects owner-token history with mode 600.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/history.py:41:python-os-file-operations","reason":"Unlinks only the helper-generated temporary basename relative to its verified directory descriptor. This is cleanup after atomic replacement, not arbitrary deletion.","verdict":"false_positive","confidence":0.98},{"id":"env_access:scripts/history.py:55:python-environment-access","reason":"Copies the normal process environment for local Git safety checks and sets a stable locale. No environment values are serialized into uploads or chat.","verdict":"false_positive","confidence":0.97},{"id":"env_access:scripts/history.py:65:python-environment-access","reason":"Checks whether GIT_DIR is set so missing Git cannot bypass repository protection. It does not disclose the variable value.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:23:system-reconnaissance","reason":"Checks local ownership, file type, hardlink count, or writable permissions to protect token history. This is access-control validation, not reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:82:system-reconnaissance","reason":"This rejects unsupported history operations and destinations. The string invalid is an error message, not a system discovery operation.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:87:system-reconnaissance","reason":"Checks local ownership, file type, hardlink count, or writable permissions to protect token history. This is access-control validation, not reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/history.py:99:system-reconnaissance","reason":"Checks local ownership, file type, hardlink count, or writable permissions to protect token history. This is access-control validation, not reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:4:node-js-child-process-module","reason":"child_process is imported for the declared offline archive checks and packaging. Its callers use fixed executables and argument arrays without a shell.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:283:process-spawn","reason":"The helper spawns only fixed Python snapshot code or zip with argument arrays. Filenames enter structured input, and execution is time-bounded without a shell.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:scripts/publish.mjs:214:synchronous-spawn","reason":"Runs unzip with fixed inspection flags and a separate snapshot path argument. Output and execution time are bounded, and no shell is involved.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:scripts/publish.mjs:2:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:27:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:30:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:31:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:38:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:43:ruby-shell-backtick-execution","reason":"String.raw contains fixed Python snapshot code, not a shell command. Selected filenames enter as JSON and are handled with descriptor-based file operations.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:132:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:142:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:151:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:181:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:193:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:202:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:207:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:208:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:209:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:212:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:217:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:220:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:234:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:235:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:236:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:237:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:238:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:239:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:240:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:242:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:244:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:253:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:263:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:266:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:314:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:323:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:329:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:341:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:scripts/publish.mjs:349:ruby-shell-backtick-execution","reason":"These backticks are JavaScript string delimiters or comment formatting, not Ruby or shell execution. Interpolated values are not evaluated as code.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:scripts/publish.mjs:5:synchronous-file-operations","reason":"These imports support the declared local archive operations. Actual reads, snapshots, and temporary cleanup are scoped to selected inputs and private run directories.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:105:synchronous-file-operations","reason":"Reads the explicitly selected archive after a 25 MiB size check. Central-directory budgets are evaluated before decompression.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:171:hidden-file-access","reason":"This rejects filenames containing carriage returns or newlines. It is defensive filename validation, not hidden-file access.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:5:temp-file-creation","reason":"These imports support the declared local archive operations. Actual reads, snapshots, and temporary cleanup are scoped to selected inputs and private run directories.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:266:temp-file-creation","reason":"This comment explains why packaging starts without an empty output archive. It creates no temporary file or executable payload.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:307:temp-file-creation","reason":"mkdtemp creates a unique snapshot directory and chmod restricts it to mode 0700. A finally block removes the snapshot after packaging.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:81:python-file-write-append","reason":"Writes selected regular-file bytes to an exclusively created mode 600 snapshot. Descriptor-based traversal and O_NOFOLLOW prevent source symlink redirection.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:scripts/publish.mjs:79:python-os-file-operations","reason":"Creates directories only inside the private snapshot using validated member segments. Empty, dot, and parent-directory segments are rejected before these operations.","verdict":"false_positive","confidence":0.98},{"id":"env_access:scripts/publish.mjs:200:environment-variable-access-dot-notation","reason":"Reads PATHEXT to locate expected executables on Windows. This is tool discovery, not secret collection or an environment-file read.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:201:environment-variable-access-dot-notation","reason":"Reads PATH solely to find required local executables. The value is not uploaded, printed, or evaluated as shell source.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:200:environment-variable-object","reason":"Reads PATHEXT to locate expected executables on Windows. This is tool discovery, not secret collection or an environment-file read.","verdict":"false_positive","confidence":0.99},{"id":"env_access:scripts/publish.mjs:201:environment-variable-object","reason":"Reads PATH solely to find required local executables. The value is not uploaded, printed, or evaluated as shell source.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:scripts/publish.mjs:34:ssh-private-key-file","reason":"This regular expression identifies sensitive archive filenames and requires digest-bound user confirmation. It neither opens SSH keys nor searches for environment-file contents.","verdict":"false_positive","confidence":1},{"id":"sensitive:scripts/publish.mjs:34:environment-file-access","reason":"This regular expression identifies sensitive archive filenames and requires digest-bound user confirmation. It neither opens SSH keys nor searches for environment-file contents.","verdict":"false_positive","confidence":1},{"id":"sensitive:scripts/publish.mjs:200:environment-file-access","reason":"The match is process.env.PATHEXT or process.env.PATH for executable discovery. Neither line opens a .env file or reads secret credentials.","verdict":"false_positive","confidence":1},{"id":"sensitive:scripts/publish.mjs:201:environment-file-access","reason":"The match is process.env.PATHEXT or process.env.PATH for executable discovery. Neither line opens a .env file or reads secret credentials.","verdict":"false_positive","confidence":1},{"id":"sensitive:scripts/publish.mjs:25:sqlite-database-file","reason":"Thumbs.db appears in the system-file exclusion expression. The code identifies entries to ignore, not a SQLite database to read.","verdict":"false_positive","confidence":1},{"id":"blocker:scripts/publish.mjs:38:system-reconnaissance","reason":"This is an archive-validation comment or failure message. No user identity, process list, or unrelated host information is queried.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/publish.mjs:66:system-reconnaissance","reason":"This is an archive-validation comment or failure message. No user identity, process list, or unrelated host information is queried.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/publish.mjs:77:system-reconnaissance","reason":"This is an archive-validation comment or failure message. No user identity, process list, or unrelated host information is queried.","verdict":"false_positive","confidence":0.99},{"id":"blocker:scripts/publish.mjs:109:system-reconnaissance","reason":"This is an archive-validation comment or failure message. No user identity, process list, or unrelated host information is queried.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:18:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:21:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","reason":"This prose explicitly prohibits command chaining and substitution. Its backticks delimit literal examples of forbidden syntax, not an instruction to execute them.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:35:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:38:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:39:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:47:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:51:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:56:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:59:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:66:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:74:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:75:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:76:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:80:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:86:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:92:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:100:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:110:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:113:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:114:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:115:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:119:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:126:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:135:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:137:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:138:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:145:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:146:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:147:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:148:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:157:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:158:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:159:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:160:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:161:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:164:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:166:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:167:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:169:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:171:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:172:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:174:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:177:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:180:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:182:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:184:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:186:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:188:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:190:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:194:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:195:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:199:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:201:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:202:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:209:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:214:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:218:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:219:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:220:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:221:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:226:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:227:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:229:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:235:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:245:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:246:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:247:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:248:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:249:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:250:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:251:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:252:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:253:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:254:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:255:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:256:ruby-shell-backtick-execution","reason":"Backticks delimit Markdown code spans or example blocks, not shell substitutions. The documented operations belong to the declared publishing workflow.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:23:shell-command-substitution","reason":"This prose explicitly prohibits command chaining and substitution. Its backticks delimit literal examples of forbidden syntax, not an instruction to execute them.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:23:template-literal-with-command-substitution","reason":"This prose explicitly prohibits command chaining and substitution. Its backticks delimit literal examples of forbidden syntax, not an instruction to execute them.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:84:hardcoded-url","reason":"The documented HTTPS URL exposes public service limits. It matches the declared hosting service and carries no secrets.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:198:hardcoded-url","reason":"The account URL is an optional management link in the output template. The skill explicitly states sign-in is unnecessary for publishing.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:206:hardcoded-url","reason":"The account URL is an optional management link in the output template. The skill explicitly states sign-in is unnecessary for publishing.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:265:hardcoded-url","reason":"This is a disclosed service or upstream-project link in the attribution section. It does not initiate an upload or credential transfer.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:266:hardcoded-url","reason":"This is a disclosed service or upstream-project link in the attribution section. It does not initiate an upload or credential transfer.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:197:hidden-file-access","reason":"This documents the intended project-local owner-token history file. The implementation enforces private file permissions and Git exclusion rather than exposing tokens.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:205:hidden-file-access","reason":"This documents the intended project-local owner-token history file. The implementation enforces private file permissions and Git exclusion rather than exposing tokens.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:247:hidden-file-access","reason":"This documents the intended project-local owner-token history file. The implementation enforces private file permissions and Git exclusion rather than exposing tokens.","verdict":"false_positive","confidence":0.98},{"id":"sensitive:SKILL.md:255:environment-file-access","reason":"The documentation describes excluding .env and system entries such as Thumbs.db from site bundles. These filenames are protective examples, not credential-reading instructions.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:92:sqlite-database-file","reason":"The documentation describes excluding .env and system entries such as Thumbs.db from site bundles. These filenames are protective examples, not credential-reading instructions.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:255:sqlite-database-file","reason":"The documentation describes excluding .env and system entries such as Thumbs.db from site bundles. These filenames are protective examples, not credential-reading instructions.","verdict":"false_positive","confidence":1},{"id":"blocker:SKILL.md:238:system-reconnaissance","reason":"This describes server validation of publication metadata. It contains no host reconnaissance command or instruction.","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 alphabet-and-digit allowlist for run identifiers. It is plainly readable validation syntax, not encoded executable content.","verdict":"false_positive","confidence":1}],"semantic_findings":[],"subject_marketplace_commit_sha":"3505ef53f4f0997977585dd4f79f91d49c258783","subject_content_hash":"42d0e03a8294e05dd1f4e385c187eea55c633903299d2bd4eb57f0fd4c44efc1","subject_tree_hash":"63f5fffcb4f30f2c18038783e613d092e8b0f8e7ab10231d36dc81a3afa92099","subject_plugin_path":"skills/kochetkov-ma/brewpage-publish","audit_payload_hash":"2488bc7e4c31763da68d723c21df8b35","confirmed_risk_level":"safe","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"3505ef53f4f0997977585dd4f79f91d49c258783","contentHash":"42d0e03a8294e05dd1f4e385c187eea55c633903299d2bd4eb57f0fd4c44efc1","treeHash":"63f5fffcb4f30f2c18038783e613d092e8b0f8e7ab10231d36dc81a3afa92099","pluginPath":"skills/kochetkov-ma/brewpage-publish","auditPayloadHash":"2488bc7e4c31763da68d723c21df8b35"},"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/9/attestation","status":"active"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"safe","confirmedFindingCount":0,"capabilityReviewCount":0,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"active","verificationState":"not_verified"},"isLatest":true}}