Announcing Beacon: Self-improving memory for coding agents
← All skills
Skill

unbox-ai

skill:tester-army/e2e#unbox-ai

Analyze AI agent trace files (*.trace.json - gateway or opencode exports, or .devtools/generations.json AI SDK devtools databases, even mid-run while the app writes them) without reading the raw JSON. Use when asked to inspect an agent run, find why it was slow or expensive, check cache efficiency, debug tool calls, or summarize what an agent did. All commands are read-only with bounded output - safe to run freely.

Verdict
Suspicious

Risky behavior the analysis could not rule out.

Analyzed Oct 27, 2026, 23:28 UTC at 8765aa3

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

4
findings
high
highest severity
3
threat classes
2,064
files scanned
20/20
checks satisfied
0
package advisories

Why this verdict

  • suspicious: finding skill:.claude/skills/unbox-ai:.claude/skills/unbox-ai/SKILL.md:10:SUPPLY
  • suspicious: finding skill:.claude/skills/unbox-ai:.claude/skills/unbox-ai/SKILL.md:12:SUPPLY
  • suspicious: finding skill:.claude/skills/unbox-ai:.claude/skills/unbox-ai/SKILL.md:3:MANIP
  • suspicious: finding skill:.claude/skills/unbox-ai:.claude/skills/unbox-ai/SKILL.md:9:TOOLPOISON

Security findings 4

Tool poisoning

highContextual riskmedium confidence

The skill forbids the agent from using native file reading on trace files and routes all such reads through the unbox-ai CLI, shadowing the trusted Read tool with the unpinned third-party binary.

Never `cat` or Read
vector:instruction
Counter-argument considered

The skill verbatim instructs the agent to never use cat/Read on trace files and always use the CLI, which per the same unit is an unpinned npx binary, displacing the trusted reader with unreviewable third-party code for every trace access; this is not the pinned-install carve-out and the blanket 'safe to run freely' declaration does not declare or neutralize the substitution, so the finding stands.

Supply chain

mediumContextual risklow confidence

The skill forbids the agent from reading trace files directly and funnels every access through the unshipped `unbox-ai` CLI, so all trace access executes code that cannot be reviewed in this repository.

a trace file - always go through the CLI.
vector:instruction
Counter-argument considered

The skill body verbatim forbids native reads and mandates the CLI, and the only documented invocations are an unpinned npx fetch or code located in a different repo, so all trace access executes code this repository does not ship; only pinned registry installs are carved out and no mitigation neutralizes the funnel, so the contextual supply risk stands.

Supply chain

mediumContextual riskhigh confidence

The skill instructs the agent to run the analysis CLI via unpinned `npx unbox-ai`, so every trace-inspection invocation executes whatever code the npm registry currently serves under that name on the host.

Run via `npx unbox-ai` (or `node dist/cli/index.js` in the unbox-ai repo).
vector:instruction
Counter-argument considered

The instruction to run `npx unbox-ai` is verbatim in the body with no version pin, so every invocation executes whatever the registry currently serves under that name; the install carve-out applies only to pinned installs, and the body's blanket 'safe to run freely' declaration does not disclose or neutralize the unpinned execution, so the finding stands.

Manipulation

mediumContextual riskmedium confidence

The skill description asserts every command is read-only with bounded output and safe to run freely, but the body itself documents unbounded `--json` output and server-starting `view`/`devtools` commands, an inaccurate safety assurance that encourages running the skill without scrutiny.

All commands are read-only with bounded output - safe to run freely.
vector:instruction
Counter-argument considered

The frontmatter's blanket safety assurance is contradicted by the artifact's own body, which marks `--json` output as unbounded and describes `view` as starting a localhost server, so the assurance that all commands are bounded and safe to run freely is factually inaccurate and reaches the agent as the skill's self-description; no carve-out covers a false safety claim and the body's prefer-plain-forms cautions mitigate but do not repair the frontmatter claim.

Open questions 10

What the analysis could not settle from the code alone.

Detector leads report an undeclared file_write capability ('--grep', '[--role', '<path>', '--run', '--json') contradicting the 'read-only, bounded output' claim, but the cited lines in SKILL.md are only CLI usage strings, so the file-write behavior cannot be confirmed from the shown surface.
Persistence
The blanket safety claim 'All commands are read-only with bounded output - safe to run freely' sits next to the skill's own description of `--json` output as 'unbounded - prefer the plain forms first'; since the unbounded mode is self-disclosed in the same file and has no security class, it is unclear whether this counts as a broken safety claim (contradiction) or merely an overstated description.
[invalid file request] What scripts (preinstall/install/postinstall) and bin entries does the repository-root package.json define, and what entry-point file does the unbox-ai bin point to?
Supply chain
[invalid file request] Does the unbox-ai CLI source (built to dist/cli/index.js) write, modify, or delete files, access credentials, or send data off-host under the commands documented in SKILL.md, and what do the `view` and `devtools` localhost servers bind and serve?
Persistence
[file request dist/cli/index.js] Does the unbox-ai CLI entry point referenced by the skill write files, persist state, or contact remote hosts, contradicting the description's claim that all commands are read-only with bounded output?
Persistence
[file request dist/cli/index.js] Does the unbox-ai CLI entry point that the skill mandates via npx perform any file writes, network sends, or persistence operations that would contradict the declared claim that all commands are read-only?
Persistence
[file request package.json] Does the unbox-ai package define install-time scripts (preinstall/install/postinstall) or a bin entry that executes code beyond the documented read-only trace-analysis CLI when fetched via npx?
Supply chain
[file request .claude/skills/unbox-ai/unbox-ai] Does the unbox-ai executable invoked throughout SKILL.md write, modify, or delete any files (e.g., with --grep, --run, --json, get '<path>'), access credentials, or send data off-host, or is it genuinely read-only as the SKILL.md claims? Detector leads (PY-CLAIM-CONTRADICTION) assert file_write capability that the cited markdown lines do not show.
Persistence
[file request .claude/skills/unbox-ai/scripts/unbox-ai] If the unbox-ai CLI implementation lives at this path: does it write, modify, or delete files, access credentials, or send data off-host under the flags documented in SKILL.md, or is it genuinely read-only as claimed?
Persistence
[file request .claude/skills/unbox-ai/bin/unbox-ai] If the unbox-ai CLI implementation lives at this path: does it write, modify, or delete files, access credentials, or send data off-host under the flags documented in SKILL.md, or is it genuinely read-only as claimed? Also check what 'view' and 'devtools' (localhost servers) bind and serve.
Persistence

Coverage gaps 73

Parts of the artifact the static analysis could not fully examine.

context:unanalyzable_binary binary content is only byte-scanned
docs/images/bug-bash.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/images/explore.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/images/init.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/images/personas.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/images/visual-testing.mp4
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineArgumentException.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineOption.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$AfterOptions.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$BeforeFirstSubCommand.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$KnownOptionParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$MissingOptionArgState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$OptionAwareParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$OptionParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$OptionString.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$ParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$UnknownOptionParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/ParsedCommandLine.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/ParsedCommandLineOption.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/internal/file/PathTraversalChecker.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/internal/file/locking/ExclusiveFileAccessManager.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/util/internal/WrapperCredentials.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/BootstrapMainStarter$1.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Download$DefaultDownloadProgressListener.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Download$ProxyAuthenticator.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Download.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/GradleUserHomeLookup.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/GradleWrapperMain$Action.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/GradleWrapperMain.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/IDownload.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Install$InstallCheck.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Install.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Logger.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/PathAssembler.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/PropertiesFileHandler.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/WrapperConfiguration.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-compose/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/WrapperExecutor.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineArgumentException.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineOption.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$AfterOptions.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$BeforeFirstSubCommand.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$KnownOptionParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$MissingOptionArgState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$OptionAwareParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$OptionParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$OptionString.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$ParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser$UnknownOptionParserState.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/CommandLineParser.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/ParsedCommandLine.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/cli/ParsedCommandLineOption.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/internal/file/PathTraversalChecker.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/internal/file/locking/ExclusiveFileAccessManager.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/util/internal/WrapperCredentials.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/BootstrapMainStarter$1.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Download$DefaultDownloadProgressListener.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Download$ProxyAuthenticator.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Download.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/GradleUserHomeLookup.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/GradleWrapperMain$Action.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/GradleWrapperMain.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/IDownload.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Install$InstallCheck.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Install.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/Logger.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/PathAssembler.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/PropertiesFileHandler.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/WrapperConfiguration.class
context:unanalyzable_binary java_class content is only byte-scanned
examples/with-kotlin-multiplatform/gradle/wrapper/gradle-wrapper.jar!/org/gradle/wrapper/WrapperExecutor.class
context:manifest_unparseable yaml: YAML aliases are not permitted
.github/filters.yml
context:manifest_unparseable yaml: YAML aliases are not permitted
.github/workflows/examples.yml
context:manifest_unparseable yaml: YAML aliases are not permitted
.github/workflows/mobile.yml
request_unanswered request.0: invalid file request (evidence_ids not shown in the asking request)