npx claudepluginhub kalpmodi/akiraThis skill uses the workspace's default tool permissions.
Triage does three things:
Generates Markdown penetration test reports from triage.md and session.json, formatting Scalpel-certified findings with executive summaries, severity tables, and kill chain details.
Provides CVSS 3.1 vector examples, executive summary template, technical finding template, and remediation language for pentest reports. Useful for drafting security assessments.
Consolidates outputs from dev, design, writing, product, and UX detect skills into unified scored index, risk heatmap, and unknowns backlog for audit combination.
Share bugs, ideas, or general feedback.
Triage does three things:
Output: triage.md in Scalpel format + memory write-back to ~/.akira/memory.json
TARGET=$1
SESSION=~/pentest-toolkit/results/$TARGET/session.json
RESULTS=~/pentest-toolkit/results/$TARGET
MEMORY=~/.akira/memory.json
SIGNALS_FILE=$RESULTS/signals.jsonl
# Get current SCL counter
SCL_COUNTER=$(jq -r '.scalpel.id_counter // 6' $SESSION 2>/dev/null)
YEAR=$(date +%Y)
# Get all findings from report_draft
FINDINGS=$(jq -r '.report_draft.findings' $SESSION 2>/dev/null)
# Read intel from all phases that ran
PHASES_RAN=$(ls $RESULTS/interesting_*.md 2>/dev/null | sed 's/.*interesting_//' | sed 's/\.md//')
# Redteam intel (if redteam phase ran)
if echo "$PHASES_RAN" | grep -q "redteam"; then
DA_OBTAINED=$(jq -r '.intel_relay.from_redteam.da_credentials_obtained // false' $SESSION 2>/dev/null)
KILL_CHAIN=$(jq -r '.intel_relay.from_redteam.kill_chain // ""' $SESSION 2>/dev/null)
LATERAL_HOSTS=$(jq -r '.intel_relay.from_redteam.lateral_movement_hosts[]?' $SESSION 2>/dev/null | tr '\n' ',')
RT_TECHNIQUES=$(jq -r '.intel_relay.from_redteam.techniques_used[]?' $SESSION 2>/dev/null)
RT_PERSISTENCE=$(jq -r '.intel_relay.from_redteam.persistence_confirmed // false' $SESSION 2>/dev/null)
RT_EXFIL=$(jq -r '.intel_relay.from_redteam.exfil_confirmed // false' $SESSION 2>/dev/null)
echo "Redteam ran: DA=$DA_OBTAINED | persistence=$RT_PERSISTENCE | exfil=$RT_EXFIL"
echo "Lateral hosts: $LATERAL_HOSTS"
# Redteam kill chain + DA credentials = auto-Critical if scope valid
[ "$DA_OBTAINED" = "true" ] && echo "[!] DA credentials confirmed - KCCG 5/5 for domain compromise chain"
fi
# Signal totals from signals.jsonl
TOTAL_SIGNALS=$(wc -l < $SIGNALS_FILE 2>/dev/null | tr -d ' ' || echo 0)
CONFIRMED_SIGNALS=$(grep '"type":"VULN_CONFIRMED"' $SIGNALS_FILE 2>/dev/null | wc -l | tr -d ' ' || echo 0)
echo "Total signals: $TOTAL_SIGNALS | VULN_CONFIRMED: $CONFIRMED_SIGNALS"
ls $RESULTS/interesting_*.md 2>/dev/null
cat $RESULTS/interesting_*.md 2>/dev/null
Note which phases ran and which are missing. Any phase that ran but is missing from report_draft.findings[] needs its interesting_*.md reviewed for overlooked findings.
Process every entry in report_draft.findings[]. For each:
X-Cache: HIT, Age: N), no staging/test domain indicators*.staging.*, *.test.*, *.sandbox.*session.json program and known scope*.sandbox.*, CDN origin, third-party service not in scopePrecision Gate result:
status: "SCALPEL_CERTIFIED", assign SCL IDstatus: "POTENTIAL", document which layers failed and whystatus: "NOISE", exclude from report, log for ATW updateFor each finding, evaluate 5 completeness steps:
| Step | What it means | Evidence required |
|---|---|---|
initial_access | Entry point found and confirmed reachable | Specific endpoint/parameter that takes attacker input |
escalation | Privilege gained or auth bypassed | Credential extraction, auth token forged, role elevated |
data_access | Real impact demonstrated | PII accessed, credentials verified live, DB rows extracted, RCE output |
reproducible | Chain works on replay | 2/3 replays succeed (race: 1/3) |
scope_valid | Target in declared scope | Endpoint matches program scope definition |
KCCG score = steps_completed / 5
Severity caps:
Common cap triggers:
Write KCCG result back to the finding record in session.json.
For each SCALPEL_CERTIFIED finding:
# Assign SCL ID
SCL_ID="SCL-${YEAR}-$(printf "%03d" $SCL_COUNTER)"
SCL_COUNTER=$((SCL_COUNTER + 1))
# Generate DNA hash
# Combine: vuln_class + tech_fingerprint (sorted) + chain_fingerprint
DNA_INPUT="${vuln_class}:${tech_fingerprint_sorted}:${chain_fingerprint}"
DNA_HASH="sha256:$(echo -n "$DNA_INPUT" | sha256sum | cut -d' ' -f1)"
Write scl_id and dna.hash back to the finding in session.json report_draft.findings[].
# Read from session.json scalpel.snr
TOOL_RUNS=$(jq -r '.scalpel.snr.tool_runs // 1' $SESSION)
SIGNALS=$(jq -r '.scalpel.snr.signals_emitted // 0' $SESSION)
CONFIRMED=$(jq '.report_draft.findings | map(select(.status=="SCALPEL_CERTIFIED")) | length' $SESSION)
NOISE=$(jq '.report_draft.findings | map(select(.status=="NOISE")) | length' $SESSION)
POTENTIAL=$(jq '.report_draft.findings | map(select(.status=="POTENTIAL")) | length' $SESSION)
# Calculate
YIELD_RATE=$(echo "scale=3; $SIGNALS / $TOOL_RUNS" | bc 2>/dev/null || echo "0.000")
CONVERSION_RATE=$(echo "scale=3; $CONFIRMED / ($SIGNALS + 0.001)" | bc 2>/dev/null || echo "0.000")
NOISE_PENALTY=$(echo "scale=3; $NOISE / ($CONFIRMED + $NOISE + 0.001)" | bc 2>/dev/null || echo "0.000")
SCALPEL_SCORE=$(echo "scale=0; ($CONVERSION_RATE * 100) * (1 - $NOISE_PENALTY) / 1" | bc 2>/dev/null || echo "0")
Scalpel score interpretation:
Write to $RESULTS/triage.md:
# Triage: <target>
**Date:** <YYYY-MM-DD>
**Scalpel Score:** <score>/100 (<interpretation>)
---
## Coverage
- **Phases run:** <list>
- **Phases missing:** <list or "none">
---
## Scalpel Certified Findings
### Critical
#### [SCL-YYYY-NNN] <Title>
**KCCG:** 5/5 | **Confidence:** <N>/100 | **DNA:** sha256:<hash truncated to 16 chars>...
**Kill Chain:** <step 1> -> <step 2> -> <step 3>
**Evidence:** <one-line direct quote from HTTP response or tool output>
**PoC:** `pocs/SCL-YYYY-NNN.<sh|py>`
### High
...same format...
---
## Potential Findings (Precision Gate Incomplete)
- [POTENTIAL] <title> - Failed layers: <Layer N: reason>, <Layer M: reason>
- To upgrade: <specific evidence needed to pass failed layers>
---
## Noise (Excluded)
- [NOISE] <title> - Failed layers: <3+ reasons> - Excluded from report
---
## SNR Summary
| Metric | Value |
|--------|-------|
| Tool runs | <N> |
| Signals emitted | <N> |
| SCL Certified | <N> |
| Potential | <N> |
| Noise | <N> |
| Yield rate | <N>% |
| Conversion rate | <N>% |
| **Scalpel Score** | **<N>/100** |
---
## Top 5 Actionable
1. [SCL-YYYY-NNN] <highest severity certified finding>
2. ...
For each SCALPEL_CERTIFIED finding:
mkdir -p $RESULTS/pocs
# Bash PoC
cat > $RESULTS/pocs/${SCL_ID}_poc.sh << 'EOF'
#!/bin/bash
# SCL ID: <scl_id>
# DNA: <hash>
# Chain: <chain_fingerprint>
# Reproduced: <date>
TARGET="${1:-https://target.com}"
# Step 1: <technique>
# <actual curl/command from kill_chain[0]>
# Step 2: <technique>
# <actual curl/command from kill_chain[1]>
echo "Full chain complete. Evidence in: $RESULTS/http-responses/"
EOF
chmod +x $RESULTS/pocs/${SCL_ID}_poc.sh
# HTTP file (for Burp/Repeater)
# Write raw HTTP requests from kill_chain[] steps
At engagement close, update cross-engagement intelligence:
MEMORY=~/.akira/memory.json
# Initialize if not exists
[ ! -f $MEMORY ] && mkdir -p ~/.akira && echo '{"version":"1.0","scl_id_counter":1,"tech_vuln_priors":{},"atw":{},"hallucination_guard":{},"waf_bypass_priors":{},"program_patterns":{},"dna_registry":[],"snr_history":{"all_time_avg_scalpel_score":0,"total_engagements":0,"total_certified_findings":0,"total_false_positives":0}}' > $MEMORY
For each SCALPEL_CERTIFIED finding - concrete write-back:
TECH="<vuln_class_from_finding>" # e.g. "ssrf", "jwt_confusion", "kerberoast"
VULN_CLASS="<class>" # e.g. "injection", "auth_bypass", "ad_attack"
# 1. Update ATW confirmation rate for each technique in kill chain
for TECH in $(jq -r ".report_draft.findings[] | select(.status==\"SCALPEL_CERTIFIED\") | .kill_chain[]?" $SESSION 2>/dev/null); do
CONFS=$(jq -r ".atw[\"$TECH\"].confirmations // 0" $MEMORY)
DENIALS=$(jq -r ".atw[\"$TECH\"].denials // 0" $MEMORY)
TOTAL=$(( CONFS + DENIALS + 1 ))
NEW_CONFS=$(( CONFS + 1 ))
RATE=$(echo "scale=3; $NEW_CONFS / $TOTAL" | bc)
jq --arg t "$TECH" --argjson c "$NEW_CONFS" --argjson r "$RATE" \
'.atw[$t] = (.atw[$t] // {}) + {"confirmations":$c,"trust_level":"confirmed","confirmation_rate":$r}' \
$MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
done
# 2. Upsert tech_vuln_priors (Bayesian update: new_p = (prior * n + evidence) / (n + 1))
jq --arg tech "$TECH" --arg vuln "$VULN_CLASS" \
'.tech_vuln_priors[$tech] = (.tech_vuln_priors[$tech] // {"base_probability":0.4,"last_seen":null,"count":0}) |
.tech_vuln_priors[$tech].count += 1 |
.tech_vuln_priors[$tech].last_seen = now | todate |
.tech_vuln_priors[$tech].base_probability = (
[(.tech_vuln_priors[$tech].base_probability * .tech_vuln_priors[$tech].count + 0.85) /
(.tech_vuln_priors[$tech].count + 1), 0.85] | min
)' $MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
# 3. Upsert DNA registry
DNA_HASH="<calculated in Step 5>"
jq --arg h "$DNA_HASH" --arg t "$TARGET" \
'(.dna_registry[] | select(.dna==$h)) |= . + {"confirmed_count": (.confirmed_count + 1), "last_seen":now | todate} //
.dna_registry += [{"dna":$h,"target":$t,"confirmed_count":1,"first_seen":now | todate,"last_seen":now | todate}]' \
$MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
For each NOISE finding - hallucination guard update:
for TECH in $(jq -r ".report_draft.findings[] | select(.status==\"NOISE\") | .technique?" $SESSION 2>/dev/null); do
CONFS=$(jq -r ".atw[\"$TECH\"].confirmations // 0" $MEMORY)
DENIALS=$(jq -r ".atw[\"$TECH\"].denials // 0" $MEMORY)
NEW_DENIALS=$(( DENIALS + 1 ))
TOTAL=$(( CONFS + NEW_DENIALS ))
# Hallucination guard: if denial rate > 50% -> flag technique
DENIAL_RATE=$(echo "scale=3; $NEW_DENIALS / $TOTAL" | bc)
FLAGGED=$(echo "$DENIAL_RATE > 0.5" | bc)
jq --arg t "$TECH" --argjson d "$NEW_DENIALS" --argjson f "$FLAGGED" \
'.atw[$t] = (.atw[$t] // {}) + {"denials":$d} |
if $f == 1 then .atw[$t].trust_level = "flagged" | .hallucination_guard[$t] = {"flagged":true,"denial_rate":($d|tonumber)} else . end' \
$MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
done
Update global counters and prior decay:
# Increment SCL counter
jq ".scl_id_counter = $SCL_COUNTER" $MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
# Update SNR history
TOTAL_ENG=$(jq -r '.snr_history.total_engagements // 0' $MEMORY)
TOTAL_CERT=$(jq -r '.snr_history.total_certified_findings // 0' $MEMORY)
TOTAL_FP=$(jq -r '.snr_history.total_false_positives // 0' $MEMORY)
PREV_AVG=$(jq -r '.snr_history.all_time_avg_scalpel_score // 0' $MEMORY)
NEW_ENG=$(( TOTAL_ENG + 1 ))
NEW_CERT=$(( TOTAL_CERT + $(jq '.report_draft.findings | map(select(.status=="SCALPEL_CERTIFIED")) | length' $SESSION) ))
NEW_FP=$(( TOTAL_FP + $(jq '.report_draft.findings | map(select(.status=="NOISE")) | length' $SESSION) ))
NEW_AVG=$(echo "scale=1; ($PREV_AVG * $TOTAL_ENG + $SCALPEL_SCORE) / $NEW_ENG" | bc)
jq --argjson ne "$NEW_ENG" --argjson nc "$NEW_CERT" --argjson nf "$NEW_FP" --argjson na "$NEW_AVG" \
'.snr_history = {"total_engagements":$ne,"total_certified_findings":$nc,"total_false_positives":$nf,"all_time_avg_scalpel_score":$na}' \
$MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
# Prior decay - run on every memory write
TODAY=$(date +%s)
jq --argjson today "$TODAY" '
.tech_vuln_priors |= with_entries(
if .value.last_seen != null then
.value.days_old = (($today - (.value.last_seen | fromdateiso8601)) / 86400 | floor) |
if .value.days_old > 180 then
.value.decay_weight = ([0.7, (1.0 - (.value.days_old / 365.0) * 0.3)] | max) |
.value.base_probability = (.value.base_probability * .value.decay_weight)
else . end
else . end
)' $MEMORY > /tmp/m.json && mv /tmp/m.json $MEMORY
Triage complete.
SCL Certified: <N> findings
Potential: <N> findings (Precision Gate incomplete)
Noise: <N> excluded
Scalpel Score: <N>/100 (<interpretation>)
Memory updated: ~/.akira/memory.json
PoC files: ~/pentest-toolkit/results/<target>/pocs/
Run /report <target> to generate the final report.