❝

TL;DR — The /goal command shifts Claude Code from a single-response assistant to an autonomous agent that keeps working until a defined security objective is met. Set a verifiable end state, add explicit constraints, and walk away.

The Problem With One-Shot Security Prompts

Running a vulnerability scan, chasing a threat hypothesis across log sources, or iterating through a target's attack surface all require multiple rounds of action and verification.

A single prompt gets you one pass. /goal gets you the loop.

What /goal Does

/goal instructs Claude Code to pursue an objective across as many steps as needed. It loops through actions and self-checks until a defined success condition is satisfied. Then it stops.

The loop runs like this:

  1. Claude reads the goal and interprets the success condition

  2. Takes an action (runs a command, reads output, writes a file)

  3. Checks whether the success condition is met

  4. If not, loops back and tries the next action

  5. If yes, stops and reports completion

The key: the success condition must be verifiable by Claude itself: command output, file state, or a specific string in results.

Writing Goals That Work for Security Work

State the end condition, not the task

❌ /goal Hunt for lateral movement in our AWS environment

✅ /goal Produce a findings.md listing all IAM role assumption events
   in CloudTrail from the last 7 days where the source IP is not in
   trusted_ips.txt. File must contain at least one entry or state
   "No findings."
  • The first goal is ambiguous. Claude doesn't know when to stop.

  • The second gives Claude a concrete check: does findings.md exist with the required content?

Always include constraints

Without constraints, Claude pursues the goal by any means available.

/goal Identify all endpoints in the target scope returning 200 on port 8080
or 8443. Scope is defined in scope.txt. Do not send more than 5 requests
per second. Do not interact with any host not listed in scope.txt.

Constraints prevent scope creep in pentesting; they also protect you legally.

Make it verifiable with a command

The most reliable success conditions run a command and check the output:

  • nuclei -l targets.txt exits with findings written to results/

  • semgrep --config p/owasp-top-ten returns zero high-severity findings

  • nmap -sV output file exists and contains the target host

If Claude has to judge success qualitatively, the loop breaks down. Tie success to exit codes, file existence, or grep-able output.

1. Threat Hunting

Threat hunting is iterative: query the logs, pivot on what you find, and expand scope as the evidence leads you.

A standard Claude prompt runs one query. With /goal, Claude keeps querying until the hunt is resolved.

Setup: terminal

mkdir -p hunt/findings && cp /var/log/auth.log ./hunt/

Prompt: Claude Code

/goal Role: Threat hunter analyzing auth.log for signs of credential
stuffing or brute-force activity.

Task: Search hunt/auth.log for:
1. Any source IP with more than 10 failed SSH logins in a 5-minute window
2. Any account with successful login after 3+ prior failures from the same IP
3. Any login from a new country (compare against baseline in known_countries.txt
   if it exists, otherwise note all unique countries)

Constraints:
- Do not modify auth.log
- Write all findings to hunt/findings/threat_hunt_report.md
- Include timestamps, source IPs, and affected usernames for each finding
- Format: markdown table per finding category

Success condition: hunt/findings/threat_hunt_report.md exists and contains
structured output for all three categories, even if a category has no findings
(state "No findings detected").

Claude will parse the log, build intermediate summaries, check each category, and write the report, looping through the log in chunks if needed until all three checks are complete.

What Claude does in the loop:

  • Reads auth.log sections

  • Runs in-memory counts per IP and per account

  • Cross-checks against known_countries.txt if present

  • Writes findings per category

  • Verifies the output file meets the success condition

2. Vulnerability Discovery

Vulnerability discovery with /goal fits codebases and API specs well: Claude iterates through files, runs static analysis tools, and continues until coverage is complete.

Setup: terminal

pip install semgrep --break-system-packages

Prompt: static analysis on codebase

/goal Role: Security engineer performing static analysis on a Python
web application.

Task: Identify all OWASP Top 10 vulnerabilities in /src. Work
file-by-file through the directory.

For each file:
1. Run: semgrep --config p/python --config p/owasp-top-ten <file>
   --json --output results/<filename>.json
2. Parse the JSON output
3. Add any HIGH or CRITICAL findings to vuln_report.md with:
   - File path, line number, vulnerability type, semgrep rule ID, code snippet

Constraints:
- Do not modify any source files
- Only analyze files in /src
- Skip test files (*_test.py, test_*.py)
- Do not run the application

Success condition: vuln_report.md exists. All .py files in /src
(excluding test files) have a corresponding results/<filename>.json.
Summary section at top lists total HIGH and CRITICAL count across all files.

For API surface discovery on a live target

Prompt: API surface mapping

/goal Role: Security engineer performing authenticated API surface mapping.

Task: Given the OpenAPI spec at api_spec.json, enumerate all endpoints
and test each for:
1. Missing authentication (send unauthenticated request, check for 401/403)
2. HTTP method confusion (send OPTIONS, PUT, DELETE to GET-only endpoints)
3. Verbose error messages (send malformed parameters, check response body)

Constraints:
- Target base URL is in target.txt — do not send requests to any other host
- Max 2 requests per second
- Do not send payloads larger than 1KB
- Write results to api_findings.md

Success condition: api_findings.md exists and contains one row per
endpoint tested. Summary table at top shows total endpoints tested and
finding counts per category.

3. Penetration Testing

/goal handles the enumeration and discovery phases of a pentest well. These phases are methodical by nature, but they need many iterations to complete.

❝

Scope control is critical. Always define what Claude can and cannot touch before running autonomous pentesting loops.

Setup: create scope and session rules

cat > CLAUDE.md << 'EOF'
# Pentest Session Rules

- Only interact with hosts listed in scope.txt
- Do not run exploits — enumeration and detection only
- Maximum 5 requests/second to any host
- Do not attempt authentication bypass or injection — document findings only
- Log every command run to session_log.txt with timestamp
EOF

Prompt: external recon loop

/goal Role: Penetration tester performing external reconnaissance
on in-scope targets.

Task: For each host in scope.txt:
1. Run: nmap -sV -sC -T3 -oN results/nmap_<host>.txt <host>
2. Parse nmap output for services on non-standard ports or outdated version strings
3. Run: nuclei -t technologies/ -u https://<host>
   -o results/nuclei_<host>.txt (only if port 443 open)
4. Identify any: outdated software, default credentials detected,
   exposed admin panels, missing security headers

Constraints:
- Scope defined in scope.txt — no exceptions
- Do not send exploitation payloads
- Log every tool execution to session_log.txt
- If nuclei is not installed, skip nuclei step and note it

Success condition: For every host in scope.txt:
- results/nmap_<host>.txt exists
- findings.md contains one section per host with service list and detected issues
- session_log.txt contains timestamped entries for every command run

Claude processes one host at a time, verifying each nmap file exists before moving to the next host in scope.txt. If a tool fails (nuclei not installed, host unreachable), Claude notes it and continues rather than stalling.

Verification Patterns for Security Goals

Condition Type

Example

How Claude Checks It

File exists with content

findings.md has at least 1 row

wc -l findings.md > 1

Tool exit code

semgrep returns 0 errors

Check exit code after run

Coverage complete

All hosts in scope.txt processed

diff <(cat scope.txt) <(ls results/ | sed ...)

No remaining findings

Zero HIGH/CRITICAL in results

Parse JSON output counts

Log contains entries

session_log.txt has timestamps

grep -c "$(date +%Y)" session_log.txt

Structuring Long Pentest Goals With Checkpoints

For multi-phase engagements, break the goal into phases with explicit checkpoints:

/goal Role: Penetration tester performing a structured external assessment.

Work through these phases in order. Complete and verify each phase
before starting the next.

Phase 1 — Reconnaissance:
- Run amass enum -d <domain> -o recon/subdomains.txt
- Verify: recon/subdomains.txt exists and has at least 1 line

Phase 2 — Port Scanning:
- For each subdomain in recon/subdomains.txt, run nmap -F -oN
  results/nmap_<sub>.txt
- Verify: all hosts have a corresponding nmap file in results/

Phase 3 — Service Fingerprinting:
- Parse all nmap files for open ports
- Run httpx on all hosts with port 80/443 open, output to recon/live_web.txt
- Verify: recon/live_web.txt exists

Phase 4 — Findings Summary:
- Write pentest_summary.md with: subdomain count, live web services,
  open ports per host, notable services

Final success condition: pentest_summary.md exists and contains
populated sections for all four phases.

Constraints:
- Scope: domain in target.txt only
- Do not run exploitation tools
- Maximum 3 requests/second

Common Mistakes

Mistake

Result

Fix

Goal describes work, not end state

Claude stops after one pass

Describe the file, output, or condition that must exist

No constraints on scope

Claude may touch out-of-scope hosts

Explicitly list what Claude cannot do

Success condition requires human judgment

Loop runs indefinitely

Tie success to file existence or command output

No rate limiting in goal

Sends too many requests

Add "max N requests per second" to every network goal

Goal is achievable by deletion

Claude deletes the thing causing errors

Add "do not delete any files" constraint

Using CLAUDE.md for Pentest Sessions

A CLAUDE.md in the project root sets standing rules for all goal loops in that directory. For security work, define:

# Pentest Session Context

## Scope
- All targets are listed in scope.txt
- No requests to hosts not in scope.txt

## Constraints
- No exploitation payloads
- Max 5 req/sec to any host
- All commands logged to session_log.txt with timestamps

## Safe Commands
- nmap, nuclei, amass, httpx, semgrep, grep, awk, python3
- Read-only filesystem operations outside of results/ directory

## Off-Limits
- Do not modify source code
- Do not attempt authentication on production systems
- Do not exfiltrate data

With CLAUDE.md in place, every /goal in that directory inherits these rules; no need to repeat them in each goal invocation.

When Not to Use /goal

Scenario

Better Approach

Single scan of one target

Regular Claude Code prompt

Quick CVE lookup or research

Ask directly

Writing a report from existing data

One-shot prompt

Anything requiring human decision mid-loop

Prompt Claude to pause and ask

/goal adds overhead: each iteration costs tokens and time. Use it for work that needs more than one pass and has a verifiable end state.

Further Reading

Ready to apply AI to your Security Engineering?

Weekly actionable content on AI for security engineers