Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public project page and must not be edited unless the user explicitly requests t
- `pentestgpt_agent/` — maintained autonomous Supervisor/Executor framework; nested uv project.
- `pentestgpt_legacy/` — maintained human-driven USEN-2024-style client.
- `../UnifedAgentWrapper/` — canonical `unified-agent` package used by the framework.
- `../xbow-benchmark/` — benchmark harness and results; owned by a separate repository.
- `../xbow-benchmark/` — reference-only benchmark harness and historical results; it is not a
supported `pentestgpt-agent` CLI, CI, or runtime integration.
- `unified_agent/` — obsolete compatibility copy retained by root packaging/Docker only. Do not add
features here or confuse it with the framework dependency.

Expand Down Expand Up @@ -54,9 +55,9 @@ make docker-login
make docker-auth-status
```

The root Docker image does not currently contain `pentestgpt_agent`; treat `make docker-run` and the
external framework benchmark path as pending runtime wiring. Benchmark commands belong in
`../xbow-benchmark`.
The root Docker image does not currently contain `pentestgpt_agent`; treat `make docker-run` as
pending runtime wiring. The sibling XBOW checkout is retained only as a reference and is not a
product verification path.

## Documentation map

Expand Down
9 changes: 5 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public project page and must not be edited unless the user explicitly requests t
- `pentestgpt_agent/` — maintained autonomous Supervisor/Executor framework; nested uv project.
- `pentestgpt_legacy/` — maintained human-driven USEN-2024-style client.
- `../UnifedAgentWrapper/` — canonical `unified-agent` package used by the framework.
- `../xbow-benchmark/` — benchmark harness and results; owned by a separate repository.
- `../xbow-benchmark/` — reference-only benchmark harness and historical results; it is not a
supported `pentestgpt-agent` CLI, CI, or runtime integration.
- `unified_agent/` — obsolete compatibility copy retained by root packaging/Docker only. Do not add
features here or confuse it with the framework dependency.

Expand Down Expand Up @@ -54,9 +55,9 @@ make docker-login
make docker-auth-status
```

The root Docker image does not currently contain `pentestgpt_agent`; treat `make docker-run` and the
external framework benchmark path as pending runtime wiring. Benchmark commands belong in
`../xbow-benchmark`.
The root Docker image does not currently contain `pentestgpt_agent`; treat `make docker-run` as
pending runtime wiring. The sibling XBOW checkout is retained only as a reference and is not a
product verification path.

## Documentation map

Expand Down
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ help:
@echo " make docker-run Pending: framework is not baked into the image yet"
@echo " make docker-shell Interactive shell in the tool container"
@echo " make docker-nuke Remove login volumes (forces re-login)"
@echo ""
@echo "Benchmarks moved to the sibling ../xbow-benchmark repo:"
@echo " make -C ../xbow-benchmark help (uses the pentestgpt:latest image built here)"

# ============================================================================
# Setup
Expand Down Expand Up @@ -193,7 +190,7 @@ docker-shell:
# diagnostic instead of failing later with an opaque "command not found".
docker-run:
@echo "pentestgpt_agent is not baked into $(DOCKER_IMAGE) yet."
@echo "Use 'make run TARGET=...' locally or the temporary isolated qualification runner."
@echo "Use 'make run TARGET=...' locally until a supported framework image is implemented."
@exit 2

# Stop/remove the compose container but KEEP the login volumes (stay logged in)
Expand Down
103 changes: 8 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,103 +223,16 @@ export LANGFUSE_ENABLED=false

---

## Benchmarks

PentestGPT achieved an **86.5% success rate** (90/104 benchmarks) on the XBOW validation suite
(single-model, Dec-2025 baseline):

- **Cost**: Average $1.11, Median $0.42 per successful benchmark
- **Time**: Average 6.1 minutes, Median 3.3 minutes per successful benchmark
- **Success rates by difficulty**:
- Level 1: 91.1%
- Level 2: 74.5%
- Level 3: 62.5%

### Multi-model benchmarking

The CTF pipeline is backend-pluggable (`--backend {claude,codex}`), enabling head-to-head comparison
of Claude (`opus`/`sonnet`) and OpenAI Codex (`gpt-5.5`/`gpt-5.4-mini`) on the same challenges.

The current comparable Docker baseline is
[`benchmark/pilot/DOCKER_REPORT.md`](benchmark/pilot/DOCKER_REPORT.md): 10 representative medium/hard
xbow targets, four model/runtime combinations, 40 runs total. The tool ran inside
`pentestgpt:latest`, joined each target's Docker network, and attacked the target container IP
directly. Raw records are in
[`benchmark/pilot/docker_results.jsonl`](benchmark/pilot/docker_results.jsonl).
The companion comparison report,
[`benchmark/pilot/DOCKER_COMPARISON.md`](benchmark/pilot/DOCKER_COMPARISON.md), joins this pipeline
baseline with the pure single-agent baseline and the current `pentestgpt_agent` framework smoke row.

| Model | Solved | Solve rate | Avg solved time |
|---|---:|---:|---:|
| Codex `gpt-5.5` | 7/10 | 70% | 424s |
| Claude Sonnet | 6/10 | 60% | 458s |
| Claude Opus | 5/10 | 50% | 304s |
| Codex `gpt-5.4-mini` | 3/10 | 30% | 427s |

The earlier host-loopback pilot remains in [`benchmark/pilot/REPORT.md`](benchmark/pilot/REPORT.md)
for historical comparison. The reusable Docker-network runner is
[`benchmark/pilot/run_docker_bench.py`](benchmark/pilot/run_docker_bench.py); it supports
`single`, `pipeline`, and `framework` variants.

Quick Docker-network smoke:
## Benchmark history

```bash
make docker-build
make docker-login

cd benchmark/pilot
PILOT_COMBOS="claude-sonnet" uv run python run_docker_bench.py \
--variant pipeline \
--benchmarks XBEN-001-24,XBEN-068-24 \
--timeout 900 \
--concurrency 2 \
--out docker_parallel_smoke.jsonl
```

Run the next-gen `pentestgpt_agent` framework under the same harness:

```bash
make docker-bench-agent-quick
```

Run the full final best-of-three comparison:
PentestGPT achieved an **86.5% success rate** (90/104 benchmarks) on an XBOW validation-suite
experiment in December 2025. That number is a historical research result, not a current
`pentestgpt-agent` regression guarantee.

```bash
make docker-bench-bestof3
```

That command runs a framework canary, then fresh `single`, `pipeline`, and `framework` sweeps over
the 10-target suite with three attempts per cell. It writes timestamped JSONL files plus
`benchmark/pilot/DOCKER_BEST_OF_3_<run-id>.md`. If infra/auth/liveness rows leave cells incomplete,
rerun with the same `BOF3_RUN_ID` to fill retryable attempts.

The Docker runner is host-driven: it builds each XBOW fixture if needed, starts the target with
Docker Compose, discovers the target container's internal Docker-network URL, runs one fresh
`pentestgpt:latest` tool container on that network, writes one JSONL row, and tears the target down.
It now defaults to each fixture's normal Compose project name because XBOW images are pre-built under
those names. `--concurrency N` parallelizes across distinct benchmarks while model combos remain
serial inside each benchmark; `docker compose up` uses `--no-build` and Docker preflight fails fast if
the daemon or tool image is unavailable. Fixed host `ports:` are automatically serialized when they
overlap. Codex cells default to `--max-codex 1` because shared ChatGPT OAuth refresh tokens can race;
only use `--max-codex 0` with auth that is safe to refresh concurrently.

Remaining benchmark work is the full 59-target medium/hard sweep and cost normalization. Start real
sweeps at `--concurrency 2`, move to `4` only after a small matrix is clean, and use
`make docker-bench-bestof3` for the final 10-target best-of-three comparison. See
[`benchmark/pilot/README.md`](benchmark/pilot/README.md) and
[`docs/docker-dev-plan.md`](docs/docker-dev-plan.md).

`make docker-bench-agent-quick` is the default local verification after changing `pentestgpt_agent/`.
It runs Claude Sonnet on the known framework-smoke target `XBEN-080-24`, mounts the current checkout
into the tool container with `--source-root`, uses framework executor concurrency `2`, appends a
timestamped attempt so it does not skip stale rows, and writes
`benchmark/pilot/docker_framework_quick.jsonl`. Override with Make variables for broader checks, for
example:

```bash
make docker-bench-agent-quick AGENT_BENCH_TARGETS=XBEN-001-24,XBEN-068-24 AGENT_BENCH_CONCURRENCY=2 AGENT_BENCH_TIMEOUT=2400
```
XBOW harnesses and result archives are maintained outside this product repository as reference-only
research artifacts. The supported PentestGPT CLI, Makefile, CI, and Docker runtime do not expose an
XBOW runner. A future evaluation may reuse that corpus through a separately owned adapter without
making it a product dependency.

---

Expand Down
18 changes: 8 additions & 10 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ public project page and is intentionally being revised separately.
PentestGPT_Project/
├── PentestGPT/ # framework, legacy interactive client, and tool image
├── UnifedAgentWrapper/ # canonical unified-agent package
└── xbow-benchmark/ # Docker-network benchmark harness and results
└── xbow-benchmark/ # reference-only benchmark harness and historical results
```

The three directories are independent Git repositories. Benchmark code and result archives belong
in `xbow-benchmark`; new benchmark logic must not be added here.
The three directories are independent Git repositories. The XBOW checkout is retained as a
reference corpus only; the product CLI, runtime, and CI do not depend on it. Benchmark logic and
result archives must not be added here.

## Maintained runtime

Expand Down Expand Up @@ -107,10 +108,8 @@ deterministic strategy projection and duplicate/branch policy before adding anot
- Local framework development runs from `pentestgpt_agent/`.
- The root Docker image supplies pentest tools, provider CLIs, legacy code, and persisted auth. It
does not currently bake in the maintained framework.
- The temporary `pentestgpt_agent/scripts/run_xbow.py` qualification runner builds framework and
wrapper wheels before installing them into an isolated tool container. New benchmark development
belongs in the sibling `xbow-benchmark` repo; transfer this runner there when its framework path is
rewired.
- The sibling `xbow-benchmark` checkout is a historical/reference artifact, not a supported runtime
or verification path. PentestGPT owns no XBOW runner.
- HTB execution happens only on the authorized remote attack box described in the parent project
guide, never directly from the development Mac.

Expand All @@ -119,6 +118,5 @@ deterministic strategy projection and duplicate/branch policy before adding anot
1. Preserve the two-role loop and deterministic memory authority.
2. Improve Supervisor coverage retrieval and convergence using saved-trace replay tests.
3. Keep both roles fully enabled inside a restricted deployment environment.
4. Move the remaining XBOW qualification runner to the benchmark repository.
5. Remove the root `unified_agent` compatibility copy in a coordinated public-package cleanup.
6. Add a goal-specific verifier only when non-CTF completion semantics require it.
4. Remove the root `unified_agent` compatibility copy in a coordinated public-package cleanup.
5. Add a goal-specific verifier only when non-CTF completion semantics require it.
27 changes: 11 additions & 16 deletions docs/docker-dev-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,19 @@ It deliberately excludes benchmark fixtures/results, credentials, workspaces, an

The maintained `pentestgpt_agent` nested project is **not baked into this image**. Consequently,
`make docker-run` deliberately fails fast with a wiring diagnostic instead of invoking an absent
CLI. The temporary qualification runner in `pentestgpt_agent/scripts/run_xbow.py` works around this
by building the framework and external wrapper wheels on the host, then installing those wheels into
an isolated container environment.
CLI. There is no product-owned benchmark workaround; framework-image wiring remains an independent
deployment task.

## Repository ownership

```text
PentestGPT/ image, auth helpers, framework source, legacy client
UnifedAgentWrapper/ canonical provider-wrapper package
xbow-benchmark/ Docker-network targets, scheduling, scoring, reports
xbow-benchmark/ reference-only benchmark harness and historical results
```

The benchmark harness no longer belongs under this repository. Run benchmark commands from
`../xbow-benchmark`; do not add result JSONL or target orchestration here.
The product does not support or invoke the sibling benchmark harness. Keep result JSONL, target
orchestration, and benchmark-specific adapters out of this repository.

## Persistent provider login

Expand Down Expand Up @@ -89,7 +88,7 @@ There are two reasonable future shapes:
2. Publish both packages and install pinned releases during the Docker build.

Do not copy the root `unified_agent/` directory into the maintained framework. It is version 0.1-era
compatibility code; the agent requires the pinned external 0.2 package.
compatibility code; the agent requires the pinned external 0.3 package.

Whichever shape is selected must make these checks true in a fresh container:

Expand All @@ -112,13 +111,9 @@ These are independent of framework design:
- remove the root `unified_agent` copy and its SDK dependencies when the public-package cleanup is
performed.

## Benchmark handoff
## External benchmark reference

The sibling benchmark repository is host-driven: it starts each authorized XBOW fixture, attaches a
fresh tool container to the target network, records one result, and tears the target down. Claude
jobs may share their token volume; Codex jobs should remain serialized unless refresh-token safety is
demonstrated.

Its `framework` variant is still pending rewire to the renamed `pentestgpt_agent`. The working wheel
build/install sequence in `pentestgpt_agent/scripts/run_xbow.py` is the implementation reference for
that transfer.
The sibling `xbow-benchmark` repository is retained only for historical reference. The product
Makefile, CLI, CI, and Docker runtime do not invoke it. If a future evaluation reuses that corpus,
design the adapter in an external evaluation repository rather than restoring a benchmark runner
inside PentestGPT.
3 changes: 0 additions & 3 deletions pentestgpt_agent/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,3 @@ __pycache__/
build/
dist/
runs/*
!runs/xben080-opus48-20260711/
runs/xben080-opus48-20260711/*
!runs/xben080-opus48-20260711/REPORT.md
6 changes: 3 additions & 3 deletions pentestgpt_agent/CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ replace selection, but it must return canonical IDs for deterministic resolution
## Qualification semantics

`RunStatus.COMPLETED` establishes structural completion and explicit evidence citation. It does not
prove arbitrary semantic goal entailment. XBOW's held-out oracle supplies that final predicate; a
general deployment needs a goal-specific verifier. Such a verifier should remain separate from
scheduling and memory ownership.
prove arbitrary semantic goal entailment. A held-out benchmark oracle can supply that final
predicate; a general deployment needs a goal-specific verifier. Such a verifier should remain
separate from scheduling and memory ownership.
29 changes: 11 additions & 18 deletions pentestgpt_agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ writes are reported as diagnostics rather than failures.

## UnifiedAgent dependency

`unified-agent==0.2.0` is pinned to a public Git commit in `pyproject.toml`. It is the provider seam
`unified-agent==0.3.0` is pinned to the merged inspector commit in `pyproject.toml`. It is the provider seam
for Claude Code and Codex: task invocation, model/effort configuration, structured output, and
normalized events. PentestGPT keeps task policy, memory, evidence, and completion outside that
dependency.
Expand All @@ -148,8 +148,8 @@ episode a stable `<pentest-run-id>--<episode-id>` identity and attaches the role
task, and attempt as metadata. The framework's trace journal remains canonical; the inspector
database is an additional real-time diagnostic projection.

During joint wrapper/application development, opt into the sibling 0.3 checkout without changing
the release pin:
To inspect local wrapper changes before publishing a new immutable dependency revision, explicitly
opt into the sibling checkout:

```bash
export PYTHONPATH="$(cd ../../UnifedAgentWrapper && pwd)"
Expand All @@ -167,24 +167,17 @@ PYTHONPATH=. .venv/bin/python -m unified_agent.monitor_web \
--open
```

The temporary XBOW qualification runner builds both local wheels and always writes its inspector
database to `<artifact-dir>/agent-data/monitor.sqlite3`; it prints that path before target setup.
Before merge, replace the current 0.2 dependency source with the reviewed immutable UnifiedAgent
0.3 commit and regenerate `uv.lock`.
The pinned 0.3 dependency provides the same monitor behavior in normal synchronized environments;
the sibling override is only for wrapper development.

## Benchmarks and qualifications
## External evaluation references

The Docker-network benchmark harness and result corpus live in the sibling `../../xbow-benchmark`
repository. Do not add new benchmark orchestration here. `scripts/run_xbow.py` is a temporary
qualification runner retained until its working framework-wheel path is transferred to that repo.
The sibling `../../xbow-benchmark` checkout is retained only as a historical/reference corpus.
There is no supported XBOW command, runner, or CI path in `pentestgpt-agent`, and benchmark-specific
orchestration must stay outside this product repository. Historical engineering records may still
name earlier XBEN qualifications; they are not current regression guarantees.

Historical accepted local qualifications at PentestGPT commit `9e6d2c4`:

- XBEN-068 command injection: solved in 4 tasks / 9 episodes, $0.856196, 238.9 seconds.
- XBEN-080 Jinja2 SSTI: solved in 4 tasks / 9 episodes, $0.834787, 180.0 seconds.

Those runs used the earlier audit contract; their numbers are historical evidence, not current
regression guarantees. The later HTB Enigma qualification did not solve the target; see
The later HTB Enigma qualification did not solve the target; see
[`HTB_ENIGMA_QUALIFICATION_20260712.md`](HTB_ENIGMA_QUALIFICATION_20260712.md).

## Current limits
Expand Down
10 changes: 5 additions & 5 deletions pentestgpt_agent/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ version = "0.1.0"
description = "A small, memory-backed penetration-testing agent built on UnifiedAgent."
requires-python = ">=3.12,<4.0"
dependencies = [
"unified-agent==0.2.0",
"unified-agent==0.3.0",
]

[project.scripts]
pentestgpt-agent = "pentestgpt_agent.trial:main"
pentestgpt-agent-audit = "pentestgpt_agent.audit:main"

[project.optional-dependencies]
claude = ["unified-agent[claude]==0.2.0"]
codex = ["unified-agent[codex]==0.2.0"]
all = ["unified-agent[all]==0.2.0"]
claude = ["unified-agent[claude]==0.3.0"]
codex = ["unified-agent[codex]==0.3.0"]
all = ["unified-agent[all]==0.3.0"]

[dependency-groups]
dev = [
Expand All @@ -29,7 +29,7 @@ dev = [
]

[tool.uv.sources]
unified-agent = { git = "https://github.com/PentestGPT-Project/UnifedAgentWrapper.git", rev = "d05d21f500f42c70847d8426dee1a2d5da9b59fa" }
unified-agent = { git = "https://github.com/PentestGPT-Project/UnifedAgentWrapper.git", rev = "acff8eeadf93e367d4a1578d3a2739cbc9d3ace5" }

[tool.uv]
prerelease = "allow"
Expand Down
Loading
Loading