Orchestrates authorized web app pentesting on Kali Linux using Opus sub-agents with difficulty-aware planning (TDA/EGATS), browser-first exploration, iterative verification, two-layer review (per-sub-agent + phase-level), optional cross-model gap audit (GPT/codex via codex-plugin-cc), and enforced KB updates. Trigger on: pentesting, penetration testing, web app security assessment, vulnerability assessment, OWASP testing, PTES, attack surface mapping, API security testing, pentest reporting, ...
Scanned 5/27/2026
Install via CLI
openskills install samklee1/web-pentest---
name: web-pentest
description: "Orchestrates authorized web app pentesting on Kali Linux using Opus sub-agents with difficulty-aware planning (TDA/EGATS), browser-first exploration, iterative verification, two-layer review (per-sub-agent + phase-level), optional cross-model gap audit (GPT/codex via codex-plugin-cc), and enforced KB updates. Trigger on: pentesting, penetration testing, web app security assessment, vulnerability assessment, OWASP testing, PTES, attack surface mapping, API security testing, pentest reporting, or 'help me test this app'. NOT for network-only pentesting, malware analysis, reverse engineering, or CTFs."
# ── Configuration — override in engagement-plan.md if needed ──
subagent_model: opus
# max_subagent_prompt_tokens was the pre-tiered-cap single knob, kept as the
# upstream ceiling. See prompt_budget below for the three-tier policy used by
# scripts/build_prompt_pack.py.
max_subagent_prompt_tokens: 100000
wordlists:
seclists: /opt/SecLists
rockyou: /usr/share/wordlists/rockyou.txt
rate_limits:
browser_agent_weight: 10
autonomous_backoff_on: ["429", "latency_spike", "connection_reset"]
context_budget:
# Passive token tracking is ALWAYS on. `enabled` controls whether
# threshold-triggered behavior changes (compression, reviewer mode) fire.
# When false (default), dispatch_mode.py always returns NORMAL.
enabled: false
tier_required_when_enabled: true
small: 500000
medium: 1500000
large: 3000000
threshold_compress: 0.70
kb_update:
mandatory_after: ["each_subagent_completion", "phase_transition", "checkpoint", "tester_input", "cleanup"]
verify_every_n_completions: 3
verify_at_phase_transition: true
level3_required_before_checkpoint: true
checkpoints:
mandatory: true
approval_phrases: ["proceed", "continue", "go ahead", "approved", "next phase"]
override_end_to_end_requests: true # "end-to-end" does NOT waive checkpoints
online_research:
enabled: true
max_pct_of_agent_tokens: 15
cross_model_review:
enabled: true # auto-disables if /codex:setup fails
plugin: codex-plugin-cc
audit_command: "/codex:adversarial-review"
preflight_command: "/codex:setup"
execution_mode: background
model_config_path: ".codex/config.toml"
phases: [2, 3, 4, 5]
max_passes: 2
fail_open: true
advisory_only: true
do_not_enable_review_gate: true # incompatible with this skill's checkpoint model
destructive_ops:
# Full list + semantics: references/destructive-ops.md
# Canonical category enum: references/registry.yml
enforcement: sub_agent_consults_before_action
default: deny
reviewer_compliance:
mandatory_for: ["phase4_exploit_agents", "phase5_findings_compiler", "phase5_report_writer",
"phase3_scan_api", "phase3_scan_session", "phase3_scan_authz"]
transition_gate: true
skip_requires_decisions_entry: true
fid_allocation:
owner: lead_agent
scheme: sequential_integer
prompt_budget:
# Initial engagement tuning — generous headroom so the first real engagement
# is not blocked by synthetic-measurement-derived caps. Re-run
# scripts/measure_bundle_sizes.py --write-frontmatter after collecting data
# from real runs to recalibrate.
#
# Measured floor (synthetic workspace, 34 agents): P95=13.3K, max=15.8K.
# These caps sit well above that ceiling; see source field.
soft_cap_tokens: 30000
hard_cap_tokens: 60000
absolute_cap_tokens: 150000
source: first_engagement_headroom
registry_hash_at_measurement: 1f780ee6103d
---
# Web Application Penetration Testing Skill
This file is the **router**. It tells the lead agent what happens when, where
to read for the detail, and which scripts to run. The detail lives in
`references/`; the hard rules live in `references/enforcement-contract.yml`.
## Purpose
Orchestrates authorized web app pentesting using PTES methodology with
difficulty-aware planning (TDA/EGATS), iterative verification (3-pass rule),
two-layer editorial review, optional cross-model gap audit, and enforced KB
updates.
**Authorization**: the tester confirms in their initial prompt or
`engagement-brief.md` — they name the target organization and state the basis
for authorization (employee, contracted pentester with SoW, bug bounty). Once
stated, proceed. If mid-engagement signals contradict, pause and confirm.
## Environment
- **OS**: Kali Linux — tools pre-installed or via `apt install`
- **Sub-agent model**: `opus`
- **Docker**: available for MCP servers
- **Wordlists**: `$SECLISTS` → `/opt/SecLists` | `$ROCKYOU` → rockyou.txt
---
## Operational Principles
- **Checkpoints are hard stops.** Wait for explicit tester approval
(`proceed`, `continue`, `approved`). Opening-prompt "end-to-end" phrases
do NOT waive checkpoints. See `references/checkpoint-protocol.md`.
- **Lead agent orchestrates; sub-agents execute.** Lead agent handles
workspace setup, KB management, TDA scoring, attack-tree updates,
dispatch, merging, and checkpoints. All scanning, exploitation, and
verification runs in sub-agents. Exception: Phase 1 setup (workspace,
tool-check, hook install) is lead-agent bash.
- **Sub-agent prompts are assembled by `scripts/build_prompt_pack.py`.**
The lead agent does NOT hand-inject references. If a reference is missing
from a bundle, fix the generator, not the prompt. Every bundle produces a
manifest in `workspace/prompts/manifests.jsonl` with source hashes, per-
section token counts, and the bundle hash.
- **Scope adherence.** Sub-agents do not probe out-of-scope targets.
Discoveries documented with `OUT-OF-SCOPE-NOTABLE`, not acted on.
- **Non-destructive by default — matrix-gated.** Irreversible or high-impact
operations gated by `kb/destructive-ops-matrix.md` (populated at Checkpoint
1). Every category defaults to deny. See
`references/destructive-ops.md`.
- **Browser-first.** Playwright / Chrome MCP is a primary tool in every
phase, not a supplement.
- **Data handling.** KB stores full unredacted values. Redaction only at
report time. Prove access, don't exfiltrate.
- **Responsible disclosure.** Critical zero-days → pause, ask tester.
- **If it's not in the log, it didn't happen.** `actions-log.md` (human
narrative) + `actions-log.jsonl` (machine) are dual-authoritative.
---
## Architecture
```
LEAD AGENT (Opus) — orchestration, TDA, attack tree, KB, dispatch
│
├── assembles sub-agent prompts via scripts/build_prompt_pack.py
├── scores TDA → EXPLOIT / INVESTIGATE / DEPRIORITIZE / PRUNE
├── dispatches sub-agents in batches (3-4 at a time)
├── after each sub-agent: spawns LAYER 1 REVIEWER (Opus, per-task editorial)
├── at phase merge: spawns PHASE-REVIEWER (Opus, phase-level editorial, blocking)
├── after phase-reviewer accepts: invokes LAYER 2 CROSS-MODEL AUDITOR (optional, GPT/codex)
├── runs 3-pass iterative loops per phase
├── runs KB enforcement (Level 1/2/3) on schedule
├── NEVER runs pentest tools in Phases 2-4 — always re-spawns sub-agents
│
┌────┼────┬────────┬────────┬──────────┬──────────────────┬─────────────────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
Recon Scan Exploit Report Cleanup Layer 1 Reviewer Phase-Reviewer Layer 2 Auditor
(Opus, per-agent) (Opus, per-phase) (GPT/codex, optional)
▲ BLOCKS CHECKPOINT
```
---
## Reference map
Read each file **only when its "When" column applies**, not at session start.
| File | When to read | Purpose |
|---|---|---|
| `references/enforcement-contract.yml` | Phase 1 setup + CI | The canonical "law" — every hard rule with its enforcer |
| `references/enforcement-contract.md` | When adding/changing a rule | Human index + upgrade instructions |
| `references/registry.yml` | Phase 1 setup; whenever agents/tools change | Single source of truth: agents, kb_inputs, recipes, dependencies, canonical enums |
| `references/output-contract.yml` | Cross-referenced at merge | Required-outputs-per-agent-class declaration |
| `references/checkpoint-protocol.md` | **Every phase transition** | Hard-stop gates, approval requirements |
| `references/phase-cards/phase{1-5}-card.md` | **Start of each phase — RE-READ** | Phase-specific rules, merge checklists |
| `references/agent-tasks/shared-header.md` | (Read by `build_prompt_pack.py`) | Universal sub-agent contract |
| `references/agent-tasks/deltas/<kind>.md` | (Read by `build_prompt_pack.py`) | Per-agent specialization |
| `references/tda-egats.md` | Every decision point | TDA scoring, mode switching, attack tree |
| `references/recipes/index.md` | Spawning exploit agent | Route finding-type → recipe file |
| `references/recipes/<category>.md` | Spawning that category | Single matching recipe, injected by prompt pack |
| `references/ptes-phases.md` | Phase transitions | Orchestration, merge, rate math |
| `references/adaptive-playbooks.md` | After Phase 2 | Framework/language testing strategies |
| `references/adaptive-tooling.md` | After Phase 2 | Trusted tools to auto-install |
| `references/kb-schema.md` | Phase 1 (KB init) | 11 KB file templates + contribution schema |
| `references/kb-enforcement.md` | Every merge + phase transition | KB verification protocol (Level 1/2/3) |
| `references/destructive-ops.md` | Phase 1 matrix + every Phase 3/4 sub-agent | 10-category gate + JSONL schema + state-change verification |
| `references/online-research.md` | When using web_search / web_fetch | Rules, sources, logging format |
| `references/loop-detection.md` | Referenced from sub-agent prompts | Single source on loop rules |
| `references/cross-model-review.md` | Phase 1 preflight + every Phase 2+ merge | Optional Layer 2 audit |
| `references/failure-modes.md` | When things break | Consolidated failure playbook |
| `references/report-template.md` | Phase 5 | findings.json schema + .docx structure |
### Scripts
| Script | When | Purpose |
|---|---|---|
| `scripts/setup.sh` | Phase 1 setup | Installs Kali tools |
| `scripts/check_registry.py` | Phase 1 + after skill edits | Registry consistency, binary presence, delta-file correspondence |
| `scripts/check_enforcement_contract.py` | Phase 1 + CI | Cross-checks contract / registry / output-contract |
| `scripts/build_prompt_pack.py` | Before every sub-agent dispatch | Assembles bundle, writes manifest, enforces tiered budget |
| `scripts/measure_bundle_sizes.py` | After meaningful registry.yml or kb_inputs changes | Measures bundle sizes and writes `prompt_budget` defaults to SKILL.md frontmatter |
| `scripts/dispatch_mode.py` | Before each dispatch batch | Returns NORMAL / LIGHT-REVIEW / MANDATORY-ONLY / HALT-DISPATCH |
| `scripts/check_destructive_ops.py` | Every Phase 3 and Phase 4 merge | Two-pass: tagged-entry audit + untagged-command scan |
| `scripts/check_state_changes.py` | Every Phase 2/3/4 merge | Matches state-change claims in summary.md to verifications.jsonl |
| `scripts/check_output_contract.py` | Every merge | Every sub-agent's required outputs present and schema-valid |
| `scripts/check_reviewer_compliance.py` | Every phase transition (Level 3) | Sub-agent + phase-reviewer verdict gate |
| `scripts/validate_findings.py` | Phase 5 between compiler and writer | findings.json structural validator |
| `tests/run_regression.py` | After any skill edit | Fixture-based regression harness |
---
## Sub-agent dispatch
The lead agent never hand-builds prompts. For each sub-agent dispatch:
```
python3 scripts/build_prompt_pack.py \
--phase <N> \
--agent-kind <kind> \
--workspace <workspace-root> \
[--recipe <category>] # only when registry.recipe_family is null
# but the finding-category needs a recipe
# (typically exploit-finding-* instances)
```
The generator reads `registry.yml`, finds the agent entry, and assembles:
1. **Shared header** — `references/agent-tasks/shared-header.md`
2. **Per-agent delta** — `references/agent-tasks/deltas/<kind>.md`
3. **Tool ref** — `agent.tool_ref` (may be null for reporting agents)
4. **Recipe** — `agent.recipe_family` or `--recipe` override
5. **KB slices** — the files listed in `agent.kb_inputs`
6. **Live state slice** — `kb/attack-tree.md` + `kb/decisions.md` when they exist
Output: `workspace/prompts/<kind>-<timestamp>.md` plus one manifest line in
`workspace/prompts/manifests.jsonl` recording every source path, source hash,
section token count, and bundle hash. **This is the forensic record** — when
a sub-agent later appears to have missed a rule, the manifest shows exactly
what it saw.
### Tiered prompt budget
Every generated bundle is classified against three thresholds in the
`prompt_budget` block of this file's frontmatter. Thresholds come from
`scripts/measure_bundle_sizes.py`, not from intuition — re-run it after
meaningful registry.yml or kb_inputs changes.
| Tier | Status | Behavior |
|---|---|---|
| `< soft_cap_tokens` | `under_soft` | Proceed normally |
| `≥ soft_cap_tokens` | `over_soft` | Warn, proceed; manifest records status |
| `≥ hard_cap_tokens` | `over_hard_blocked` | Block unless `--allow-over-budget` |
| `≥ hard_cap_tokens` with override | `over_hard_overridden` | Proceed; manifest records override_reason verbatim |
| `≥ absolute_cap_tokens` | `over_absolute_blocked` | **Always block — no override path** |
Override above hard cap:
```
python3 scripts/build_prompt_pack.py \
--phase 4 --agent-kind exploit-auth-chain --workspace <ws> \
--allow-over-budget \
--override-reason "Cross-phase auth chain needs endpoints + credentials + prior scan evidence"
```
`--override-reason` must be ≥10 chars of substantive text. Trivial reasons
(`"just do it"`, `"override"`, `"needed"`, `"n/a"`) are rejected on exact
whole-string match. Logged verbatim in the manifest so the Layer 1 reviewer
can see why the bundle was large.
Then pass the bundle to the Task tool:
```
Task(description="<kind>",
prompt=open("<bundle-path>").read(),
subagent_type="general-purpose")
```
---
## Phase overview (high-level — details in phase cards)
### Phase 1: Pre-engagement & planning
Lead agent bash only. Workspace creation, KB init, registry check, hook
install, destructive-ops matrix population, test plan, adaptive strategy
selection. **→ Read `references/phase-cards/phase1-card.md` NOW.**
> **CHECKPOINT 1** — waits for tester approval.
### Phase 2: Reconnaissance & OSINT
Walkthrough (mandatory first, authoritative endpoint map) → 6 parallel CLI
recon sub-agents → merge → initial attack tree. **→ Read
`references/phase-cards/phase2-card.md` NOW.**
> **CHECKPOINT 2** — after phase-reviewer accepts.
### Phase 3: Scanning (with early exploitation)
Wave-based dispatch honoring `registry.agents[].depends_on`:
- Wave 1 — independent scanners (nuclei, nikto, params, ssl, burp,
exploit-research, api, session)
- Wave 2 — depends on Wave 1 (sqli, xss after params)
- Conditional — fire only when `trigger_artifact` exists (authz, spa,
graphql, websocket, ai, email, dns, http3)
Scanner returns TDI ≤ 2.0 → spawn exploit sub-agent immediately (early
exploitation). **→ Read `references/phase-cards/phase3-card.md` NOW.**
> **CHECKPOINT 3** — after phase-reviewer accepts.
### Phase 4: Exploitation & manual testing
Attack-tree reconciliation classifies every TDI ≤ 3.0 branch into
`proven_in_prior_phase` / `needs_phase4_formal_exploit` /
`chain_exploitation_opportunity`. Per-finding exploit agents dispatched with
matching recipe. Every exploit agent gets a Layer 1 reviewer (mandatory).
**→ Read `references/phase-cards/phase4-card.md` NOW.**
> **CHECKPOINT 4** — after phase-reviewer accepts.
### Phase 4.5: Cleanup
Cleanup sub-agent reads `kb/artifacts.md`, reverses test accounts, uploaded
files, modified data, stored payloads. Verifies reversal via Playwright.
### Phase 5: Reporting (two-stage)
- **Stage 1** — `findings-compiler` produces `deliverables/findings.json`
- **Validator** — `scripts/validate_findings.py` (hard structural gate)
- **Stage 2** — `report-writer` produces `deliverables/pentest-report.docx`
Every severity tier with findings must appear in the report. **→ Read
`references/phase-cards/phase5-card.md` NOW.**
> **CHECKPOINT 5** — engagement close.
---
## Iterative verification (3-pass rule)
Every phase runs at least 3 passes: **execute → gap check → fill gaps**.
At checkpoint, present the iteration summary. Full rules in
`references/ptes-phases.md`.
---
## Phase Transition Protocol
This is the most important mechanism in the skill. Instructions loaded at
session start lose attention strength as context grows.
At every phase transition (after tester approval, before starting next phase):
1. **Write handoff** — `workspace/phase-N-handoff.md`
2. **Re-read instructions** — use the read tool on
`phase-cards/phase{N+1}-card.md`, the Phase {N+1} section of this file,
`kb-schema.md`, `kb-enforcement.md`
3. **Re-verify KB** — run the Level 2 protocol from `kb-enforcement.md`
(verification, not passive re-read)
4. **Confirm transition** — print a short summary and proceed
Full protocol: `references/ptes-phases.md § Phase Transition Protocol`.
---
## Review architecture
- **Layer 1 reviewer** — Opus sub-agent, per sub-agent, editorial. Reads
evidence and judges whether it demonstrates the claim, judges reproduction
steps, remediation specificity, and coverage gaps.
Schema + verdict criteria: `references/agent-tasks/deltas/reviewer.md`
- **Phase-reviewer** — Opus sub-agent, per phase, fresh context. Judges
the phase as a whole for completeness, chain opportunities, strategic
direction. Has VETO power over checkpoint. Enforced by
`scripts/check_reviewer_compliance.py`.
- **Layer 2 cross-model auditor** — GPT/codex via `codex-plugin-cc`,
optional, advisory. Pass 1 → fix gaps → Pass 2 → surface remaining at
checkpoint. Fail-open. See `references/cross-model-review.md`.
---
## Critical reminders
1. **Checkpoints are hard stops** — not section headers. Wait for explicit
tester approval.
2. **KB Level 3 audit is a precondition** for presenting any checkpoint.
3. **Lead agent orchestrates; sub-agents execute.** Phase 1 setup is the
only lead-agent bash.
4. **Prompts come from `build_prompt_pack.py`** — never hand-injected. The generator enforces a three-tier budget (soft warn / hard block-or-override / absolute block) from `prompt_budget` in this file's frontmatter. Hard-cap overrides require `--allow-over-budget --override-reason "<substantive>"` and are logged verbatim in the manifest.
5. **Two review layers: per-sub-agent + phase-level.** Phase-reviewer
blocks checkpoint.
6. **Destructive-ops matrix gates irreversible actions.** 10 categories,
default deny, two-pass machine check.
7. **State-change claims are structurally gated.** 17-verb list; non-hedged
claims require verifications.jsonl entry with result=success.
8. **F-IDs are lead-agent-owned, sequential integers.** Sub-agents never
coin IDs.
9. **Cross-model audit is optional and advisory** — never blocks phase
transition.
10. **Browser in every phase.** Playwright primary, not optional.
11. **3-pass minimum.** Execute → gap check → fill gaps.
12. **Phase Transition Protocol** — re-read at every transition.
13. **KB enforcement is rolling.** Level 1 every 3 completions, Level 2 at
merge, Level 3 at transition (hard gate).
14. **Adaptive payload selection.** Walk the decision tree in
`recipes/injection/<variant>.md` before picking payloads.
15. **Two-stage reporting.** Compiler → validator → writer. Don't collapse.
16. **Hooks reality.** Sub-agent bash NOT hooked.
`actions-log.md` + `.jsonl` are authoritative.
17. **Online research is permitted.** Log queries + sources in actions-log.
18. **If it's not in the log, it didn't happen.**
**Everything above appears in `references/enforcement-contract.yml` as
explicit rules. When a rule is violated in practice, upgrade it from
`advisory_prose` to a blocking script. The contract shows which are
already mechanical and which are still honor-system.**
No comments yet. Be the first to comment!