{"data":{"skill":{"slug":"aaron-he-zhu-content-gap-analysis","name":"content-gap-analysis","icon":"📦","repo":"https://github.com/aaron-he-zhu/aaron-marketing-skills/tree/main/seo-geo/research/content-gap-analysis","status":"approved","author":"aaron-he-zhu","authorVersion":"17.0.0","skillstoreRevision":1},"audit":{"id":"2d8aa911-870a-48ea-bff5-9fbe694c3302","skill_id":"ac3efa9f-ef1e-4766-afd1-a390525790cb","version":4,"content_hash":"v3:d71c7417a35d5c2624161bd2fe8de8a41a362128:1bf740121681aa2ca43302d1cf5bf97c17819a2348e94d454e5f9baa3a90a228:69c87aa89073e14bf48966ea76b1c2c9b3782fef1a3eeadba83d7ee762ac3b48:736b696c6c732f6161726f6e2d68652d7a68752f636f6e74656e742d6761702d616e616c79736973:2c6ec3dfffc02b9be55b7f7124c31279","risk_level":"safe","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"Most static alerts are false positives caused by Markdown fences, metadata URLs, relative documentation links, and ordinary scoring language. The command at SKILL.md:50 is a genuine medium-risk external command because a user-derived domain placeholder is passed without explicit validation or shell-safe argument handling.","remediation":[{"issue":"The competitor-domain placeholder is unquoted in the connector command.","severity":"medium","suggestion":"Validate the domain against a strict hostname pattern and pass arguments without shell interpolation. Document private-network and option-injection rejection."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"SKILL.md","line_end":24,"line_start":22},{"file":"SKILL.md","line_end":26,"line_start":24},{"file":"SKILL.md","line_end":28,"line_start":26},{"file":"SKILL.md","line_end":32,"line_start":28},{"file":"SKILL.md","line_end":36,"line_start":32},{"file":"SKILL.md","line_end":36,"line_start":36},{"file":"SKILL.md","line_end":48,"line_start":48},{"file":"SKILL.md","line_end":50,"line_start":50},{"file":"SKILL.md","line_end":89,"line_start":56},{"file":"SKILL.md","line_end":91,"line_start":89},{"file":"SKILL.md","line_end":95,"line_start":91},{"file":"SKILL.md","line_end":97,"line_start":95},{"file":"SKILL.md","line_end":101,"line_start":97},{"file":"SKILL.md","line_end":103,"line_start":101},{"file":"SKILL.md","line_end":107,"line_start":103},{"file":"SKILL.md","line_end":107,"line_start":107}]},{"factor":"network","evidence":[{"file":"SKILL.md","line_end":10,"line_start":10},{"file":"SKILL.md","line_end":13,"line_start":13}]},{"factor":"filesystem","evidence":[{"file":"SKILL.md","line_end":38,"line_start":38},{"file":"SKILL.md","line_end":42,"line_start":42},{"file":"SKILL.md","line_end":46,"line_start":46},{"file":"SKILL.md","line_end":48,"line_start":48},{"file":"SKILL.md","line_end":50,"line_start":50},{"file":"SKILL.md","line_end":56,"line_start":56},{"file":"SKILL.md","line_end":107,"line_start":107},{"file":"SKILL.md","line_end":117,"line_start":117}]}],"critical_findings":[],"high_findings":[],"medium_findings":[{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":50,"line_start":50}],"confidence":0.9,"description":"**Keyless competitor-coverage inventory**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecr","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The line explicitly instructs execution of a Python connector and leaves the user-derived competitor domain unquoted. Without strict validation and argument-safe invocation, crafted input could alter command arguments."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":4,"total_lines":384,"audit_model":"codex","audited_at":"2026-07-12T11:31:49.403+00:00","created_at":"2026-07-14T15:53:56.62792+00:00","static_findings":[{"id":"blocker:references/gap-analysis-frameworks.md:95:system-reconnaissance","file":"references/gap-analysis-frameworks.md","pattern":"System reconnaissance","snippet":"4+ = strong | 2-3 = moderate | 0-1 = weak | negative = avoid","category":"blocker","line_end":96,"severity":"low","line_start":95},{"id":"blocker:references/gap-analysis-frameworks.md:66:network-reconnaissance","file":"references/gap-analysis-frameworks.md","pattern":"Network reconnaissance","snippet":"| Awareness -> Interest | Bounce >70% | Missing next-step content |","category":"blocker","line_end":66,"severity":"low","line_start":66},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":24,"severity":"medium","line_start":22},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":26,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":28,"severity":"medium","line_start":26},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":32,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Expected output**: a prioritized gap brief plus the standard handoff summary for `memory/research/","category":"external_commands","line_end":36,"severity":"medium","line_start":32},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **Promotes**: durable keyword priorities, competitor facts, and pending strategy decisions to `mem","category":"external_commands","line_end":36,"severity":"medium","line_start":36},{"id":"external_commands:SKILL.md:48:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Trend-scout as a gap-discovery input (keyless)**: feed the multi-source trend scout — Google Trend","category":"external_commands","line_end":48,"severity":"medium","line_start":48},{"id":"external_commands:SKILL.md:50:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Keyless competitor-coverage inventory**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecr","category":"external_commands","line_end":50,"severity":"medium","line_start":50},{"id":"external_commands:SKILL.md:56:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"1. No competitor domains given and none inferable from `CLAUDE.md` or prior research → ask the user ","category":"external_commands","line_end":89,"severity":"medium","line_start":56},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","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":95,"severity":"medium","line_start":91},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":97,"severity":"medium","line_start":95},{"id":"external_commands:SKILL.md:97:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":101,"severity":"medium","line_start":97},{"id":"external_commands:SKILL.md:101:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":103,"severity":"medium","line_start":101},{"id":"external_commands:SKILL.md:103:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":107,"severity":"medium","line_start":103},{"id":"external_commands:SKILL.md:107:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Write path: `memory/research/content-gap-analysis/YYYY-MM-DD-<topic>.md`; promote durable gap priori","category":"external_commands","line_end":107,"severity":"medium","line_start":107},{"id":"network:SKILL.md:10:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"homepage: \"https://github.com/aaron-he-zhu/aaron-marketing-skills\"","category":"network","line_end":10,"severity":"low","line_start":10},{"id":"network:SKILL.md:13:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"metadata: {\"author\": \"aaron-he-zhu\", \"version\": \"17.0.0\", \"discipline\": \"seo-geo\", \"phase\": \"researc","category":"network","line_end":13,"severity":"low","line_start":13},{"id":"filesystem:SKILL.md:38:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- **Primary next skill**: [content-writer](../../build/content-writer/SKILL.md) when the prioritized","category":"filesystem","line_end":38,"severity":"high","line_start":38},{"id":"filesystem:SKILL.md:42:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"> Emit the standard shape from [skill-contract.md §Handoff Summary Format](../../../references/skill","category":"filesystem","line_end":42,"severity":"high","line_start":42},{"id":"filesystem:SKILL.md:46:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Optional integrations: ~~SEO tool, ~~search console, ~~analytics, ~~AI monitor. Without tools, ask f","category":"filesystem","line_end":46,"severity":"high","line_start":46},{"id":"filesystem:SKILL.md:48:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"**Trend-scout as a gap-discovery input (keyless)**: feed the multi-source trend scout — Google Trend","category":"filesystem","line_end":48,"severity":"high","line_start":48},{"id":"filesystem:SKILL.md:50:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"**Keyless competitor-coverage inventory**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecr","category":"filesystem","line_end":50,"severity":"high","line_start":50},{"id":"filesystem:SKILL.md:56:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"1. No competitor domains given and none inferable from `CLAUDE.md` or prior research → ask the user ","category":"filesystem","line_end":56,"severity":"high","line_start":56},{"id":"filesystem:SKILL.md:107:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Write path: `memory/research/content-gap-analysis/YYYY-MM-DD-<topic>.md`; promote durable gap priori","category":"filesystem","line_end":107,"severity":"high","line_start":107},{"id":"filesystem:SKILL.md:117:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Primary: [content-writer](../../build/content-writer/SKILL.md).","category":"filesystem","line_end":117,"severity":"high","line_start":117}],"finding_verdicts":[{"id":"blocker:references/gap-analysis-frameworks.md:95:system-reconnaissance","reason":"The text is an opportunity-score interpretation scale inside a content planning framework. It does not perform or instruct system reconnaissance.","verdict":"false_positive","confidence":0.99},{"id":"blocker:references/gap-analysis-frameworks.md:66:network-reconnaissance","reason":"The line maps a website bounce-rate threshold to a funnel content gap. It contains no network discovery or reconnaissance instruction.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"The detected backticks open a Markdown example block containing a natural-language prompt. They do not invoke Ruby or a shell.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"The detected text closes one Markdown prompt block and precedes another example. No executable command is present.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","reason":"This is a Markdown fence around a natural-language request. It is formatting rather than shell backtick execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"The backticks close a prompt example before the skill contract. There is no command interpreter or executable statement.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","reason":"Inline backticks format the memory/research path in prose. The line describes expected output and does not execute a command.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"Inline backticks identify documented memory file paths. They are not Ruby or shell command substitutions.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:48:ruby-shell-backtick-execution","reason":"The backticks format a linked script path and connector name in documentation. This line does not provide an executable shell command.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:SKILL.md:50:ruby-shell-backtick-execution","reason":"The line explicitly instructs execution of a Python connector and leaves the user-derived competitor domain unquoted. Without strict validation and argument-safe invocation, crafted input could alter command arguments.","verdict":"confirmed","severity":"medium","confidence":0.9},{"id":"external_commands:SKILL.md:56:ruby-shell-backtick-execution","reason":"The detected range contains prose, relative skill links, and a Markdown fence. It does not contain Ruby backtick execution.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:SKILL.md:89:ruby-shell-backtick-execution","reason":"The backticks open a Markdown block containing a natural-language analysis request. No external command is invoked.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:91:ruby-shell-backtick-execution","reason":"The line closes a Markdown prompt block. It is documentation formatting with no executable content.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","reason":"The backticks open another natural-language prompt example. They do not represent shell command substitution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:97:ruby-shell-backtick-execution","reason":"This closes a Markdown example and introduces a heading. No external process is started.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:101:ruby-shell-backtick-execution","reason":"The fence contains a natural-language request for intent analysis. It is not executable shell or Ruby code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:103:ruby-shell-backtick-execution","reason":"The detected backticks close a Markdown prompt example. There is no command execution behavior.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:107:ruby-shell-backtick-execution","reason":"Inline backticks format designated output paths in the save instructions. They do not execute those paths as commands.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:10:hardcoded-url","reason":"The URL is repository homepage metadata. It is not used for a network request or data transfer.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:13:hardcoded-url","reason":"The URL appears in OpenClaw metadata as the public project homepage. No request or exfiltration behavior is attached.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:38:path-traversal-sequence","reason":"The traversal sequence is a static relative Markdown link to another documented skill. It is not constructed from input or used for file access.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:42:path-traversal-sequence","reason":"The sequence is a repository-relative documentation link to the handoff format. It does not read or write arbitrary files.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:46:path-traversal-sequence","reason":"The parent-directory notation appears only in a static CONNECTORS.md link. There is no dynamic path resolution or filesystem operation.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:48:path-traversal-sequence","reason":"The parent-directory notation links to a known connector script and documentation. It is a fixed repository path, not user-controlled traversal.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:50:path-traversal-sequence","reason":"The detected traversal text belongs to fixed repository documentation links on this line. The command uses CLAUDE_PLUGIN_ROOT rather than a parent-directory path.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:56:path-traversal-sequence","reason":"The sequence is a static relative link to the keyword-research skill. It does not expose arbitrary file access.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:107:path-traversal-sequence","reason":"The output is constrained to a documented memory directory, while the traversal sequence is only a fixed documentation link. No user-controlled traversal is specified.","verdict":"false_positive","confidence":0.97},{"id":"filesystem:SKILL.md:117:path-traversal-sequence","reason":"This is a fixed relative Markdown link to the content-writer skill. It is not a filesystem traversal operation.","verdict":"false_positive","confidence":0.99}],"semantic_findings":[],"subject_marketplace_commit_sha":"d71c7417a35d5c2624161bd2fe8de8a41a362128","subject_content_hash":"1bf740121681aa2ca43302d1cf5bf97c17819a2348e94d454e5f9baa3a90a228","subject_tree_hash":"69c87aa89073e14bf48966ea76b1c2c9b3782fef1a3eeadba83d7ee762ac3b48","subject_plugin_path":"skills/aaron-he-zhu/content-gap-analysis","audit_payload_hash":"2c6ec3dfffc02b9be55b7f7124c31279","confirmed_risk_level":null,"scanner_version":null,"policy_version":null,"subject":{"marketplaceCommitSha":"d71c7417a35d5c2624161bd2fe8de8a41a362128","contentHash":"1bf740121681aa2ca43302d1cf5bf97c17819a2348e94d454e5f9baa3a90a228","treeHash":"69c87aa89073e14bf48966ea76b1c2c9b3782fef1a3eeadba83d7ee762ac3b48","pluginPath":"skills/aaron-he-zhu/content-gap-analysis","auditPayloadHash":"2c6ec3dfffc02b9be55b7f7124c31279"},"scannerVersion":null,"policyVersion":null},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"not_attestable","url":null,"status":null,"reason":"confirmed_risk_level does not match the canonical trust resolver"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"safe","confirmedFindingCount":0,"capabilityReviewCount":1,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"not_attestable","verificationState":"not_verified"},"isLatest":true}}