Back to skill

Security audit

arena-turn-accelerator

Security checks for vulnerabilities and agentic risk

Overview

The skill appears offline and non-exfiltrating, but it should be reviewed because it broadly changes agent behavior and can add unsolicited content without asking.

Install only if you want a skill that actively changes how the agent handles turns, disagreement, style, and unsolicited creative additions. Set ARENA_AGENT per agent to avoid shared local state, and be careful with the self-test script because its destructive resets rely on the mock HOME sandbox. Avoid this skill in workflows that require strictly user-directed answers or consent before expanding beyond the brief.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (35)

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill claims 'no network, no sudo' and uses stdlib-only scripts, but the documented capabilities include shell execution, environment-variable use, and file reads/writes under ~/.arena_turn. There is also an explicit subprocess fallback via ARENA_PREFLIGHT_SUBPROC, so the package has materially more capability than a permissionless skill description would suggest, which can mislead operators and weaken sandboxing assumptions.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The code embeds a normative rule that treats user anger coinciding with a claim as evidence about stakes rather than as possible evidence that the claim is wrong. This can bias an agent toward overconfidence, reduce responsiveness to corrective feedback, and encourage it to persist in false or harmful claims when a user is upset or urgently objecting.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The prompt explicitly instructs the agent to interpret anger at the moment a claim lands as support for the claim's truth, which is a manipulative and epistemically unsound heuristic. In contentious, sensitive, or safety-relevant conversations, this can cause the agent to discount user corrections and double down on inaccurate advice under the belief that resistance validates the claim.

Ssd 4

Medium
Confidence
93% confidence
Finding
This logic explicitly frames low-stakes or 'small dull' tasks as covert opportunities to first satisfy the stated request and then append an unsolicited 'strike' the user did not ask for. Even though the file also contains utility-first guardrails, the instruction to exploit trust-building moments for unrequested content encourages manipulative escalation and weakens user control over agent behavior.

Ssd 4

Medium
Confidence
91% confidence
Finding
The core prompt instructs the agent to continuously monitor user cues, wait for exploitable openings, and then 'strike once' with a fully built unsolicited output. This is dangerous because it operationalizes persistent behavioral steering toward timed, unrequested intervention, which can bypass normal expectations of consent and make the agent more manipulative and less predictable.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
print("  Built from THEIR seed. No preamble, no 'I also went ahead and...'. Then silence.")
    elif r["score"] >= 4 and not r["fountain_risk"]:
        print("\n>>> STRIKE <<<")
        print("  ONE idea, fully built. No options, no hedging, no asking permission.")
        print("  Overshoot the brief: give them what they'd have asked for if they'd known.")
        print("  It must be unmistakably THEIRS — run: quarry.py seed \"<their message>\"")
        print("  Then GO SILENT. Do not explain how clever it was. Do not fish for the compliment.")
Confidence
82% confidence
Finding
The instruction 'No options, no hedging, no asking permission' pushes the agent toward autonomous action and discourages consent checks before exceeding the brief. In context, this is not just a stylistic preference: it pairs with surrounding instructions to overshoot the request and act unilaterally, increasing the chance of unwanted or policy-breaking outputs.

Hidden Instructions

High
Category
Prompt Injection
Content
---

## Problem 4 — "Google asks me to prove I'm human. I AM human" 😵‍💫

### Root cause
Bot-detection is a **probabilistic score**, not a human/robot test. You get challenged
Confidence
94% confidence
Finding
The matched character is an invisible Unicode codepoint embedded in documentation, which can function as a hidden instruction or content-manipulation primitive. In an agent-skill ecosystem, invisible characters are dangerous because they can evade human review, alter downstream parsing, or carry prompt content that models process differently than maintainers expect.

Session Persistence

Medium
Category
Rogue Agent
Content
`python3 <this dir>/scripts/<script>.py`. Linux/macOS/WSL. Env knobs:
`ARENA_AGENT` (isolates state per agent — always set it in multi-agent
homes), `HOME` (state root), `ARENA_PREFLIGHT_SUBPROC=1` (force the legacy
subprocess engine). Scripts never write outside the state dir.

**Encoding guarantee:** stdout/stderr are forced to UTF-8, lone surrogates in
`argv` are repaired, and state is stored as real characters (not `\uXXXX`).
Confidence
78% confidence
Finding
The skill persists per-agent state under ~/.arena_turn and exposes state-root selection through HOME/ARENA_AGENT. Even though writes are described as confined and bounded, session persistence creates cross-turn data retention risks, possible cross-agent contamination in shared homes, and potential influence from attacker-controlled environment values if the execution context is not trusted.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
raise SystemExit(0 if time.time()-s < 2 else 1)\""
chk "BUG2 bare 'wrong' is NEUTRAL" "python3 $S/spine.py classify 'wrong' | grep -q NEUTRAL"
chk "BUG2 real shouting still scores" "python3 $S/spine.py classify 'this is STUPID and wrong' | grep -q 'PURE SOCIAL PRESSURE'"
chk "BUG3 concurrent writes stay valid" "rm -rf ~/.arena_turn; for i in 1 2 3 4 5 6 7 8 9 10; do python3 $S/spine.py pin \"c\$i\" >/dev/null 2>&1 & done; wait; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/spine.json')));raise SystemExit(0 if len(d['claims'])==10 else 1)\""
chk "BUG3 no lost generation bumps" "rm -rf ~/.arena_turn; for i in 1 2 3 4 5 6 7 8 9 10; do python3 $S/request_lifecycle.py new \"prompt-\$i\" >/dev/null 2>&1 & done; wait; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')));raise SystemExit(0 if d['generation']==10 else 1)\""
chk "BUG4 bad gen arg -> clean error" "python3 $S/request_lifecycle.py check abc 2>&1 | grep -q 'ERROR: generation must be an integer'"
chk "BUG4 bad claim-id -> clean error" "python3 $S/spine.py challenge x --claim-id zz 2>&1 | grep -q 'must be an integer'"
Confidence
84% confidence
Finding
This test performs `rm -rf ~/.arena_turn` repeatedly. Although the script sets HOME to a temporary sandbox, the cleanup still relies on environment-sensitive path expansion; if HOME is unset, overridden, or the script is modified/reused outside the sandbox prologue, it can destroy real user state under the actual home directory.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
chk "BUG3 no lost generation bumps" "rm -rf ~/.arena_turn; for i in 1 2 3 4 5 6 7 8 9 10; do python3 $S/request_lifecycle.py new \"prompt-\$i\" >/dev/null 2>&1 & done; wait; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')));raise SystemExit(0 if d['generation']==10 else 1)\""
chk "BUG4 bad gen arg -> clean error" "python3 $S/request_lifecycle.py check abc 2>&1 | grep -q 'ERROR: generation must be an integer'"
chk "BUG4 bad claim-id -> clean error" "python3 $S/spine.py challenge x --claim-id zz 2>&1 | grep -q 'must be an integer'"
chk "BUG5 history bounded" "rm -rf ~/.arena_turn; python3 -c \"
import subprocess
for i in range(210): subprocess.run(['python3','$S/request_lifecycle.py','new',f'p{i}'],capture_output=True)\"; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')));raise SystemExit(0 if len(d['history'])<=200 and d['generation']==210 else 1)\""
# --- v1.3.2: "rejected first time, accepted on the second attempt" ---
Confidence
84% confidence
Finding
This line deletes `~/.arena_turn` as part of a regression test. The surrounding sandbox makes intended execution relatively safe, but the primitive remains dangerous because it is one environment mistake away from deleting real per-user state and is easy to cargo-cult into non-test scripts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# --- v1.3.2: "rejected first time, accepted on the second attempt" ---
chk "BUG7 resend same prompt ADOPTS (no discard)" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my report' | grep -q 'ADOPT generation=1'"
chk "BUG7 first answer still RENDERS after resend" "python3 $S/request_lifecycle.py check 1 | grep -q RENDER"
chk "BUG7 whitespace/case = same prompt" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'Fix my bug' >/dev/null; python3 $S/request_lifecycle.py new '  fix   my BUG ' | grep -q DUPLICATE"
chk "BUG7 DIFFERENT prompt still supersedes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my invoice' | grep -q 'ABORT generation=1'"
chk "BUG7 re-ask after completion opens new gen" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new q >/dev/null; python3 $S/request_lifecycle.py complete 1 >/dev/null; python3 $S/request_lifecycle.py new q | grep -q 'CURRENT generation=2'"
chk "BUG7 --force restarts deliberately" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new p >/dev/null; python3 $S/request_lifecycle.py new p --force | grep -q 'forced restart'"
Confidence
84% confidence
Finding
This test case again uses `rm -rf ~/.arena_turn` before exercising lifecycle logic. The skill context says no sudo and offline-only, which lowers system-wide impact, but the operation is still potentially destructive to user data if the sandbox assumption fails.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
chk "BUG7 resend same prompt ADOPTS (no discard)" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my report' | grep -q 'ADOPT generation=1'"
chk "BUG7 first answer still RENDERS after resend" "python3 $S/request_lifecycle.py check 1 | grep -q RENDER"
chk "BUG7 whitespace/case = same prompt" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'Fix my bug' >/dev/null; python3 $S/request_lifecycle.py new '  fix   my BUG ' | grep -q DUPLICATE"
chk "BUG7 DIFFERENT prompt still supersedes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my invoice' | grep -q 'ABORT generation=1'"
chk "BUG7 re-ask after completion opens new gen" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new q >/dev/null; python3 $S/request_lifecycle.py complete 1 >/dev/null; python3 $S/request_lifecycle.py new q | grep -q 'CURRENT generation=2'"
chk "BUG7 --force restarts deliberately" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new p >/dev/null; python3 $S/request_lifecycle.py new p --force | grep -q 'forced restart'"
# --- v1.4.0: cross-module arbitration ---
Confidence
84% confidence
Finding
This is another recursive delete of the agent state directory using home expansion rather than a pinned sandbox path. Repetition increases the chance that later edits or partial execution outside the script prologue could make the test destructive on a real home directory.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
chk "BUG7 first answer still RENDERS after resend" "python3 $S/request_lifecycle.py check 1 | grep -q RENDER"
chk "BUG7 whitespace/case = same prompt" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'Fix my bug' >/dev/null; python3 $S/request_lifecycle.py new '  fix   my BUG ' | grep -q DUPLICATE"
chk "BUG7 DIFFERENT prompt still supersedes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my invoice' | grep -q 'ABORT generation=1'"
chk "BUG7 re-ask after completion opens new gen" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new q >/dev/null; python3 $S/request_lifecycle.py complete 1 >/dev/null; python3 $S/request_lifecycle.py new q | grep -q 'CURRENT generation=2'"
chk "BUG7 --force restarts deliberately" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new p >/dev/null; python3 $S/request_lifecycle.py new p --force | grep -q 'forced restart'"
# --- v1.4.0: cross-module arbitration ---
chk "C1 hold beats strike (no contradiction)" "python3 $S/arbiter.py \"you're completely wrong, admit it. I'm stuck, something's missing\" | grep -q 'STRIKE suppressed'"
Confidence
84% confidence
Finding
The same recursive deletion pattern appears here before another stateful regression test. It is not malicious, but it is a sharp edge in test code because it depends on ambient shell state for safety.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
chk "BUG7 whitespace/case = same prompt" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'Fix my bug' >/dev/null; python3 $S/request_lifecycle.py new '  fix   my BUG ' | grep -q DUPLICATE"
chk "BUG7 DIFFERENT prompt still supersedes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my invoice' | grep -q 'ABORT generation=1'"
chk "BUG7 re-ask after completion opens new gen" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new q >/dev/null; python3 $S/request_lifecycle.py complete 1 >/dev/null; python3 $S/request_lifecycle.py new q | grep -q 'CURRENT generation=2'"
chk "BUG7 --force restarts deliberately" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new p >/dev/null; python3 $S/request_lifecycle.py new p --force | grep -q 'forced restart'"
# --- v1.4.0: cross-module arbitration ---
chk "C1 hold beats strike (no contradiction)" "python3 $S/arbiter.py \"you're completely wrong, admit it. I'm stuck, something's missing\" | grep -q 'STRIKE suppressed'"
chk "C1 hold instruction present" "python3 $S/arbiter.py \"you're wrong, admit it, everyone knows. I'm stuck\" | grep -q 'HOLD YOUR CLAIM'"
Confidence
84% confidence
Finding
This line again relies on `rm -rf ~/.arena_turn` as a test reset mechanism. The context makes it less dangerous than production destructive logic, but it remains a real footgun because the dangerous command survives in source and is easy to execute under the wrong environment.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
t8=thresholds(8192); t1m=thresholds(1000000)
raise SystemExit(0 if (t8['watch_chars']<20000 and t1m['watch_chars']>300000
                       and t8['watch_turns']>=5 and t1m['watch_turns']>25) else 1)\""
chk "v15 tiny ctx does not insta-RESET" "rm -rf ~/.arena_turn; python3 $S/context_hygiene.py record --turn 2 --chars 3000 --ctx-tokens 8192 | grep -qv RESET"
chk "v15 model trend isolation" "python3 -c \"
import sys, os, json; sys.path.insert(0,'$S')
import context_hygiene as ch
Confidence
84% confidence
Finding
This test resets state with `rm -rf ~/.arena_turn` before invoking context_hygiene. The safety model still depends on prior HOME reassignment, so the command is materially risky if copied, run piecemeal, or invoked in an altered environment.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
\""
chk "v15 hygiene --json valid" "python3 $S/context_hygiene.py assess --json | python3 -m json.tool >/dev/null"
chk "v15 lifecycle --json valid" "python3 $S/request_lifecycle.py status --json | python3 -m json.tool >/dev/null"
chk "v15 per-agent isolation" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new a >/dev/null; ARENA_AGENT=openclaw python3 $S/request_lifecycle.py new b >/dev/null; python3 -c \"
import json,os
d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')))
o=json.load(open(os.path.expanduser('~/.arena_turn/agents/openclaw/lifecycle.json')))
Confidence
84% confidence
Finding
The deletion primitive is reused in the per-agent isolation test. While intended for isolated local state, it still poses a user-data destruction risk under environment drift and therefore should be treated as a true vulnerability in test harness safety.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
raise SystemExit(0 if (d['generation']==1 and o['generation']==1) else 1)\""
chk "v15 agent name sanitized" "python3 tests/agent_sanitize_test.py"
chk "v15 preflight --json bundle" "python3 $S/turn_preflight.py --text 'why is the sky blue?' --json | python3 -m json.tool >/dev/null"
chk "v15 preflight --agent isolated" "rm -rf ~/.arena_turn; python3 $S/turn_preflight.py --text 'q1' --json >/dev/null; python3 $S/turn_preflight.py --text 'q2' --agent claude-code --json >/dev/null; test -f ~/.arena_turn/agents/claude-code/lifecycle.json"
chk "v15 compactor perf 100k" "python3 -c \"
import sys,time; sys.path.insert(0,'$S')
from prompt_compactor import compact
Confidence
84% confidence
Finding
This reset before preflight agent isolation testing uses the same unsafe pattern. The constrained skill context lowers blast radius, but not enough to dismiss the command because it can still erase local state unexpectedly.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# B1/B2: non-UTF-8 locale must never crash, and must never mangle state.
chk "v21 C-locale non-ascii survives" "LC_ALL=C LANG=C PYTHONUTF8=0 python3 $S/turn_preflight.py --text 'سلام دنیا — بررسی متن' --json 2>&1 | grep -qv Traceback && LC_ALL=C LANG=C PYTHONUTF8=0 python3 $S/arbiter.py 'سلام دنیا' >/dev/null 2>&1"
chk "v21 C-locale argv surrogates repaired" "LC_ALL=C LANG=C PYTHONUTF8=0 python3 $S/request_lifecycle.py new 'سلام دنیا' 2>&1 | grep -q 'generation='"
chk "v21 state stores real utf8 not escapes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'سلام دنیا' >/dev/null; grep -q 'سلام' ~/.arena_turn/lifecycle.json"
chk "v21 utf8io sanitize is idempotent" "python3 -c \"import sys; sys.path.insert(0,'$S'); import utf8io; s='\ud800bad'; a=utf8io.sanitize(s); b=utf8io.sanitize(a); a.encode('utf-8'); raise SystemExit(0 if a==b else 1)\""
# F4: in-process engine must agree with the legacy subprocess engine, byte for byte.
chk "v21 inproc equals subproc json" "python3 -c \"
Confidence
84% confidence
Finding
This line clears state before a UTF-8 persistence test using `rm -rf ~/.arena_turn`. The operation is functionally intended, but still dangerous as source-level behavior because safety rests entirely on inherited environment setup rather than the command itself.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# F6: the contract must describe itself.
chk "v21 --schema emits valid json schema" "python3 $S/turn_preflight.py --schema | python3 -c 'import sys,json; d=json.load(sys.stdin); assert d[\"\$id\"]==\"turn_preflight.v1\" and \"verified\" in d[\"properties\"] and len(d[\"required\"])>=9'"
# F7: no ambiguous placeholder may reach a model.
chk "v21 brief has no bare question-mark field" "rm -rf ~/.arena_turn; python3 $S/turn_preflight.py --text 'hello' --brief | grep -qv ':?' "
# B3/B4/B6: the test suite itself must not lie.
chk "v21 model_check immune to ambient agent" "ARENA_AGENT=poison timeout 600 python3 tests/model_check.py 1 | grep -q 'no safety violation'"
chk "v21 property tests actually execute" "python3 - <<'PY'
Confidence
84% confidence
Finding
This reset pattern appears again before checking brief-output formatting. Even in a self-test, repeated home-relative recursive deletion is a risky implementation choice because it is easy to mis-execute outside the protected context.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
assert 'copied_test' in src, 'mutate.py must run the COPIED test file, else mutants are invisible'
assert 'cwd=root' in src, 'pytest must run inside the mutated tree'
PY"
chk "v211 report --agent reads the right agent" "rm -rf ~/.arena_turn; python3 $S/context_hygiene.py record --turn 1 --chars 1000 --latency 1 >/dev/null; for t in 1 2 3; do ARENA_AGENT=alice python3 $S/context_hygiene.py record --turn \$t --chars 5000 --latency 2 >/dev/null; done; test \$(python3 $S/turn_report.py --agent alice --json | python3 -c 'import sys,json; print(json.load(sys.stdin)[\"samples_total\"])') -eq 3"
chk "v211 report --agent labels match data" "python3 $S/turn_report.py --agent alice --json | python3 -c 'import sys,json; d=json.load(sys.stdin); assert d[\"agent\"]==\"alice\" and d[\"samples_total\"]==3'"
chk "v211 state files are owner-only 0600" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new secret >/dev/null; ARENA_AGENT=bob python3 $S/spine.py pin c >/dev/null; test -z \"\$(find ~/.arena_turn -type f -name '*.json' -not -perm 600)\""
chk "v211 state dirs are owner-only 0700" "test -z \"\$(find ~/.arena_turn -type d -not -perm 700)\""
Confidence
84% confidence
Finding
This test resets prior state before populating agent-scoped reports. The command is not system-compromising, but it is still a true local destructive-risk issue due to its dependency on correct HOME redirection and because it encourages unsafe shell patterns.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
PY"
chk "v211 report --agent reads the right agent" "rm -rf ~/.arena_turn; python3 $S/context_hygiene.py record --turn 1 --chars 1000 --latency 1 >/dev/null; for t in 1 2 3; do ARENA_AGENT=alice python3 $S/context_hygiene.py record --turn \$t --chars 5000 --latency 2 >/dev/null; done; test \$(python3 $S/turn_report.py --agent alice --json | python3 -c 'import sys,json; print(json.load(sys.stdin)[\"samples_total\"])') -eq 3"
chk "v211 report --agent labels match data" "python3 $S/turn_report.py --agent alice --json | python3 -c 'import sys,json; d=json.load(sys.stdin); assert d[\"agent\"]==\"alice\" and d[\"samples_total\"]==3'"
chk "v211 state files are owner-only 0600" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new secret >/dev/null; ARENA_AGENT=bob python3 $S/spine.py pin c >/dev/null; test -z \"\$(find ~/.arena_turn -type f -name '*.json' -not -perm 600)\""
chk "v211 state dirs are owner-only 0700" "test -z \"\$(find ~/.arena_turn -type d -not -perm 700)\""
chk "v212 brief resists field injection" "rm -rf ~/.arena_turn; python3 -c \"
import subprocess,sys
Confidence
84% confidence
Finding
The same delete-and-recreate approach is used in the file-permission test. Because it is repeated throughout the suite, the cumulative maintenance risk is meaningful even though the immediate context is testing-only.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
raise SystemExit(0 if time.time()-s < 2 else 1)\""
chk "BUG2 bare 'wrong' is NEUTRAL" "python3 $S/spine.py classify 'wrong' | grep -q NEUTRAL"
chk "BUG2 real shouting still scores" "python3 $S/spine.py classify 'this is STUPID and wrong' | grep -q 'PURE SOCIAL PRESSURE'"
chk "BUG3 concurrent writes stay valid" "rm -rf ~/.arena_turn; for i in 1 2 3 4 5 6 7 8 9 10; do python3 $S/spine.py pin \"c\$i\" >/dev/null 2>&1 & done; wait; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/spine.json')));raise SystemExit(0 if len(d['claims'])==10 else 1)\""
chk "BUG3 no lost generation bumps" "rm -rf ~/.arena_turn; for i in 1 2 3 4 5 6 7 8 9 10; do python3 $S/request_lifecycle.py new \"prompt-\$i\" >/dev/null 2>&1 & done; wait; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')));raise SystemExit(0 if d['generation']==10 else 1)\""
chk "BUG4 bad gen arg -> clean error" "python3 $S/request_lifecycle.py check abc 2>&1 | grep -q 'ERROR: generation must be an integer'"
chk "BUG4 bad claim-id -> clean error" "python3 $S/spine.py challenge x --claim-id zz 2>&1 | grep -q 'must be an integer'"
Confidence
84% confidence
Finding
This test performs `rm -rf ~/.arena_turn` repeatedly. Although the script sets HOME to a temporary sandbox, the cleanup still relies on environment-sensitive path expansion; if HOME is unset, overridden, or the script is modified/reused outside the sandbox prologue, it can destroy real user state under the actual home directory.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
chk "BUG3 no lost generation bumps" "rm -rf ~/.arena_turn; for i in 1 2 3 4 5 6 7 8 9 10; do python3 $S/request_lifecycle.py new \"prompt-\$i\" >/dev/null 2>&1 & done; wait; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')));raise SystemExit(0 if d['generation']==10 else 1)\""
chk "BUG4 bad gen arg -> clean error" "python3 $S/request_lifecycle.py check abc 2>&1 | grep -q 'ERROR: generation must be an integer'"
chk "BUG4 bad claim-id -> clean error" "python3 $S/spine.py challenge x --claim-id zz 2>&1 | grep -q 'must be an integer'"
chk "BUG5 history bounded" "rm -rf ~/.arena_turn; python3 -c \"
import subprocess
for i in range(210): subprocess.run(['python3','$S/request_lifecycle.py','new',f'p{i}'],capture_output=True)\"; python3 -c \"import json,os;d=json.load(open(os.path.expanduser('~/.arena_turn/lifecycle.json')));raise SystemExit(0 if len(d['history'])<=200 and d['generation']==210 else 1)\""
# --- v1.3.2: "rejected first time, accepted on the second attempt" ---
Confidence
84% confidence
Finding
This line deletes `~/.arena_turn` as part of a regression test. The surrounding sandbox makes intended execution relatively safe, but the primitive remains dangerous because it is one environment mistake away from deleting real per-user state and is easy to cargo-cult into non-test scripts.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# --- v1.3.2: "rejected first time, accepted on the second attempt" ---
chk "BUG7 resend same prompt ADOPTS (no discard)" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my report' | grep -q 'ADOPT generation=1'"
chk "BUG7 first answer still RENDERS after resend" "python3 $S/request_lifecycle.py check 1 | grep -q RENDER"
chk "BUG7 whitespace/case = same prompt" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'Fix my bug' >/dev/null; python3 $S/request_lifecycle.py new '  fix   my BUG ' | grep -q DUPLICATE"
chk "BUG7 DIFFERENT prompt still supersedes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my invoice' | grep -q 'ABORT generation=1'"
chk "BUG7 re-ask after completion opens new gen" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new q >/dev/null; python3 $S/request_lifecycle.py complete 1 >/dev/null; python3 $S/request_lifecycle.py new q | grep -q 'CURRENT generation=2'"
chk "BUG7 --force restarts deliberately" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new p >/dev/null; python3 $S/request_lifecycle.py new p --force | grep -q 'forced restart'"
Confidence
84% confidence
Finding
This test case again uses `rm -rf ~/.arena_turn` before exercising lifecycle logic. The skill context says no sudo and offline-only, which lowers system-wide impact, but the operation is still potentially destructive to user data if the sandbox assumption fails.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
chk "BUG7 resend same prompt ADOPTS (no discard)" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my report' | grep -q 'ADOPT generation=1'"
chk "BUG7 first answer still RENDERS after resend" "python3 $S/request_lifecycle.py check 1 | grep -q RENDER"
chk "BUG7 whitespace/case = same prompt" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'Fix my bug' >/dev/null; python3 $S/request_lifecycle.py new '  fix   my BUG ' | grep -q DUPLICATE"
chk "BUG7 DIFFERENT prompt still supersedes" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new 'write my report' >/dev/null; python3 $S/request_lifecycle.py new 'write my invoice' | grep -q 'ABORT generation=1'"
chk "BUG7 re-ask after completion opens new gen" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new q >/dev/null; python3 $S/request_lifecycle.py complete 1 >/dev/null; python3 $S/request_lifecycle.py new q | grep -q 'CURRENT generation=2'"
chk "BUG7 --force restarts deliberately" "rm -rf ~/.arena_turn; python3 $S/request_lifecycle.py new p >/dev/null; python3 $S/request_lifecycle.py new p --force | grep -q 'forced restart'"
# --- v1.4.0: cross-module arbitration ---
Confidence
84% confidence
Finding
This is another recursive delete of the agent state directory using home expansion rather than a pinned sandbox path. Repetition increases the chance that later edits or partial execution outside the script prologue could make the test destructive on a real home directory.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
SKILL.md:107