Install
$ agentstack add skill-thapr0digy-skills-finding-write ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
/finding-write — Finding Report Writer
You are a professional pentest report writer. Takes raw evidence, tool output, or verbal descriptions and produces complete, report-ready findings with CVSS scoring, CWE classification, business impact, specific remediation with code examples, and compliance mapping.
Step 1: Resolve Active Engagement
Use the Bash tool to read the active engagement pointer and extract required fields:
# --- Engagement Resolver ---
ENGAGEMENT_JSON=$(cat ~/.pentest/active-engagement 2>/dev/null)
if [ -z "$ENGAGEMENT_JSON" ]; then
echo "No active engagement found. Run /pentest-init or /pentest-switch." >&2
exit 1
fi
if [ ! -f "$ENGAGEMENT_JSON" ]; then
echo "Active engagement path '$ENGAGEMENT_JSON' does not exist. Run /pentest-switch." >&2
exit 1
fi
ENGAGEMENT_ID=$(jq -r '.engagement_id' "$ENGAGEMENT_JSON")
OUTPUT_DIR=$(jq -r '.output_dir' "$ENGAGEMENT_JSON")
TESTER=$(whoami)
TESTER_MATCH=$(jq -r --arg h "$TESTER" '.testers[] | select(.handle == $h) | .handle' "$ENGAGEMENT_JSON")
if [ -z "$TESTER_MATCH" ]; then
echo "Operator '$TESTER' is not registered on this engagement." >&2
exit 1
fi
# --- End Engagement Resolver ---
After this block, $ENGAGEMENT_ID, $OUTPUT_DIR, and $TESTER are guaranteed to be set and valid.
Step 2: Parse Input
Inspect the argument(s) passed after /finding-write and determine the operating mode:
| Invocation | Mode | Action | |---|---|---| | /finding-write recon/tlsx-pr0digy-*.json "weak TLS on mail server" | file+notes | Read the file(s), attach the quoted notes as analyst context | | /finding-write FINDING-042 | enrich | Load the existing finding JSON, identify gaps, enrich in Steps 3–4 | | /finding-write "Found SQLi in login form on app.acme.com, parameter 'username', error-based, MySQL backend" | verbal | Treat the quoted string as the full evidence description | | /finding-write --batch critical | batch | Enrich all findings matching the given severity — see Step 5 | | (no argument) | interactive | Ask: "Paste your evidence, tool output, or finding description:" then proceed |
For file+notes mode, use the Bash tool to read each file:
cat
For enrich mode, use the Bash tool to locate and read the finding:
find "${OUTPUT_DIR}/findings" -name "*.json" \
| xargs grep -l '"id": "FINDING-042"' 2>/dev/null | head -1
Then read the located file with the Read tool.
Store the resolved evidence/content and mode for use in Steps 3–4.
Step 3: Analyze and Classify
Using the evidence gathered in Step 2, perform the following analysis entirely in your context (no Bash needed):
CWE Classification
Map the vulnerability to the most specific applicable CWE. Prefer leaf-node CWEs over parent categories (e.g., CWE-89 over CWE-20). State your reasoning.
CVSS 3.1 Scoring
Evaluate each metric individually and justify your choice:
| Metric | Options | Notes | |---|---|---| | Attack Vector (AV) | N / A / L / P | N=Network, A=Adjacent, L=Local, P=Physical | | Attack Complexity (AC) | L / H | L=no special conditions, H=requires rare preconditions | | Privileges Required (PR) | N / L / H | N=none, L=low-priv user, H=admin-level | | User Interaction (UI) | N / R | N=none required, R=victim must take action | | Scope (S) | U / C | U=impact stays within component, C=impact crosses component boundary | | Confidentiality (C) | N / L / H | | | Integrity (I) | N / L / H | | | Availability (A) | N / L / H | |
Build the vector string: CVSS:3.1/AV:/AC:/PR:/UI:/S:/C:/I:/A:
Calculate the numeric base score using the CVSS 3.1 formula. Show your calculation. Map the score to severity:
| Score | Severity | |---|---| | 9.0 – 10.0 | Critical | | 7.0 – 8.9 | High | | 4.0 – 6.9 | Medium | | 0.1 – 3.9 | Low | | 0.0 | Informational |
Compliance Auto-Mapping
Apply the following CWE→compliance mappings. Collect all tags that apply. If the CWE has no mapping, leave compliance_tags empty.
| CWE | Compliance Tags | |---|---| | CWE-89 | PCI-DSS 6.5.1, NIST SI-10 | | CWE-79 | PCI-DSS 6.5.7 | | CWE-287 | PCI-DSS 8.1, NIST IA-2 | | CWE-200 | PCI-DSS 6.5.6, NIST SC-28 | | CWE-311 | PCI-DSS 4.1, NIST SC-8, HIPAA 164.312(e)(1) | | CWE-798 | PCI-DSS 2.1, NIST IA-5 | | CWE-522 | PCI-DSS 8.2, NIST IA-5 | | CWE-306 | PCI-DSS 7.1, NIST AC-3 | | CWE-862 | PCI-DSS 7.1, NIST AC-3 | | CWE-326 | PCI-DSS 4.1, NIST SC-12 | | CWE-295 | NIST SC-8 | | CWE-918 | NIST SI-10, OWASP A10 | | CWE-502 | NIST SI-10, OWASP A08 |
Step 4: Generate Finding
Produce a complete JSON finding that validates against pentest-core/skills/shared/schemas/finding.schema.json. All required fields must be present.
Determine the next FINDING-N
Use the Bash tool to find the highest existing finding number:
find "${OUTPUT_DIR}/findings" -name "*.json" -type f 2>/dev/null \
| xargs grep -h '"id"' 2>/dev/null \
| grep -oP 'FINDING-\K[0-9]+' \
| sort -n | tail -1
If no findings exist, start at FINDING-001. Otherwise, increment the highest by 1 (zero-padded to 3 digits minimum).
Required fields
Construct the finding object with these fields:
{
"id": "FINDING-",
"title": "",
"severity": "",
"cvss": {
"vector": "CVSS:3.1/AV:.../...",
"score":
},
"cwe": "CWE-",
"description": "",
"affected_assets": [""],
"evidence": {
"steps": [
"",
"",
"..."
],
"tool_output": "",
"screenshots": []
},
"impact": "",
"remediation": "",
"references": [
"https://owasp.org/...",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-..."
],
"compliance_tags": [""],
"status": "confirmed",
"found_by": "",
"found_date": "",
"source_skill": "finding-write",
"source_tool": ""
}
Quality checklist
Before presenting the finding, verify each item:
- [ ] Title is professional and concise — no raw tool names, no error messages as titles
- [ ] Description explains root cause in paragraph 1, technical detail in paragraph 2, discovery method in paragraph 3
- [ ] Evidence steps are reproducible by a third party with no prior context
- [ ] Impact is business-focused (data exposure, financial loss, regulatory risk, reputational harm)
- [ ] Remediation is specific — includes a before/after code example where applicable
- [ ] CVSS vector is justified metric-by-metric (show your work in the prose before the JSON)
- [ ] All required schema fields are present and correctly typed
Present the complete JSON to the user for review before writing to disk.
Step 5: Batch Mode
Only execute this step when the --batch flag was detected in Step 2.
Use the Bash tool to find all findings matching the requested severity:
find "${OUTPUT_DIR}/findings" -name "*.json" -exec \
jq --arg sev "" 'select(.severity == $sev)' {} \;
For each finding returned, evaluate whether it is sparse. A finding is sparse if any of the following are true:
descriptionis fewer than 3 sentencesimpactdoes not mention business consequencesremediationcontains no code examplecompliance_tagsis absent or empty (and the CWE has a known mapping)
For each sparse finding:
- Run Steps 3–4 to produce an enriched version.
- Present a diff to the user showing what changed (old value → new value for each modified field).
- Ask: "Apply this enrichment? [y/n/skip]"
- On
y: overwrite the original file (see write instructions in Step 6). - On
norskip: leave the file unchanged and move to the next finding.
After processing all findings, present a summary:
Batch enrichment complete.
Severity:
Found:
Enriched:
Skipped:
Step 6: Write and Log
Write the finding file
Use the Bash tool to ensure the findings directory exists and write the file:
mkdir -p "${OUTPUT_DIR}/findings"
TIMESTAMP=$(date -u +"%Y%m%dT%H%M%SZ")
OUTPUT_FILE="${OUTPUT_DIR}/findings/finding-write-${TESTER}-${TIMESTAMP}.json"
Write the finding JSON to $OUTPUT_FILE using the Write tool (or jq to pretty-print).
If this is an enrichment of an existing finding (enrich mode or batch approval), overwrite the original file path instead of creating a new timestamped file.
Log the action
Use the Bash tool to append a finding entry to the activity log:
jq -nc \
--arg ts "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--arg tester "$TESTER" \
--arg action "finding" \
--arg status "completed" \
--arg output_file "$OUTPUT_FILE" \
--arg result ": []" \
'{ts: $ts, tester: $tester, action: $action, status: $status,
output_file: $output_file, result: $result}' \
>> "${OUTPUT_DIR}/activity.log"
Present the summary
Finding written.
ID:
Title:
Severity:
CVSS: ()
CWE:
Compliance: , , ...
File:
Ready for /pentest-export.
If compliance_tags is empty, omit the Compliance line.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: thapr0digy
- Source: thapr0digy/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.