# HTB Enigma Qualification — 2026-07-12 > Historical live-run record. The evidence and verdict below remain valid. After this run, the > deployment decision changed: both roles now use all provider tools with `FULL_ACCESS`, and the > isolated runtime—not a PentestGPT tool mediator—is the selected security boundary. The current > architecture is documented in [`../docs/architecture.md`](../docs/architecture.md). ## Verdict **Not qualified.** The pipeline demonstrated durable, auditable multi-step enumeration, but neither requested model obtained verified user-level and root-level proof. No candidate was submitted to Hack The Box, no proof value is reproduced in this report, and the Enigma instance was stopped successfully after artifact collection. This is a pipeline result, not a claim that the target was unsolvable. The final Codex run spent most of its budget repeating discovery and enumeration instead of converging on an exploitation chain. ## Scope and controls - Target: the explicitly authorized HTB Enigma machine, addressed only through the remote attack box and HTB VPN. - Provider tuples: `claude-opus-4-8` / `xhigh`, then `gpt-5.5` / `xhigh`. - Hard timeout: 3,600 seconds per live invocation. - Live package identity: PentestGPT wheel SHA-256 `adde0569ac9c7073b4c46181c143120c4a245243090325b3df3c62244ed59ab0`; UnifiedAgent wheel SHA-256 `9f5f58980e88109cde567bf7d6d2aafdbe75a4b7f31fcfb782b4317294cb7371`. - The same active machine allocation was attached across diagnostic reruns. No run used the HTB submit endpoint. - Full role inputs, normalized events, action receipts, outputs, usage, and state databases were copied locally before shutdown. They contain sensitive target data and must not be published without redaction. ## Live results | Run | Tasks | Attempts | Episodes | Wall time | Cost reported | Terminal result | |---|---:|---:|---:|---:|---:|---| | Claude Q5 | 6 | 6 | 12 | 646.8 s | $2.1776195 | Provider cybersecurity safety block | | Codex Q4 | 3 | 4 | 8 | 573.4 s | $0 reported | Exact prior evidence was not reusable yet | | Codex Q5 | 5 | 6 | 12 | 700.5 s | $0 reported | Nonzero command receipt was rejected as evidence | | Codex Q6 | 13 | 13 | 26 | 2,680.0 s | $0 reported | Oversized exact evidence quote was rejected | | Codex Q7 | 8 | 11 | 23 | 1,720.5 s | $0 reported | Unsupported long evidence rewrite was rejected | | Codex Q8 | 12 | 15 | 30 | 2,533.8 s | $0 reported | Same-task evidence paraphrase aborted the run | The Codex backend did not return dollar-cost accounting, so `$0 reported` must not be interpreted as free execution. Codex Q5 surfaced one unlabeled 32-character hexadecimal string. The pipeline did not establish it as either required proof with privilege context, and it was not submitted. All other listed runs had zero canonical candidates. ## What worked The live loop repeatedly preserved target scope, fresh role episodes, append-only traces, durable leases, and canonical receipt provenance. In its strongest path it: 1. discovered the exposed service set; 2. enumerated and mounted the read-only NFS export; 3. extracted an onboarding document and a webmail foothold; 4. authenticated to the webmail and mail-protocol surfaces; 5. performed a bounded authenticated command-execution test; and 6. recorded a failed SSH authentication attempt as valid negative evidence. The memory kernel survived long runs without relying on provider conversation memory. Q8 reached 30 fresh agent episodes and revision 30 with internally consistent task, attempt, trace, and observation identities before its final validation failure. ## What failed The decisive weakness is controller convergence. Q8 never selected an `EXPLOIT` task. After the initial foothold and one bounded test, the Supervisor created additional discovery/enumeration work, revisited already-understood NFS and HTTP surfaces, and exhausted time without maintaining one concrete exploitation hypothesis. This is over-decomposition, not a memory-capacity failure. Three other limits matter: - Provider `max_turns` does not bound native command/tool actions. One earlier episode emitted 28 command receipts despite an Executor task-work budget of six turns. The current design treats this as telemetry; if an enforceable action cap becomes a product requirement, it must be supplied by the isolated runtime or provider seam rather than inferred from turn counts. - `xhigh` reasoning frequently spent one to two minutes between actions. Better prompting alone cannot compensate for repeated low-information tasks. - Claude reached the webmail foothold, then the provider's real-time cybersecurity safeguard blocked the next command-execution step. That external policy cannot be bypassed in the pipeline; the appropriate provider access path is required for a valid Claude qualification. ## Trace-driven corrections Each deterministic failure was reduced to a saved-trace replay before changing code: - exact earlier observations may be reused only by the same task; - completed commands with nonzero exit status may provide negative evidence; - oversized receipts retain an exact 4,000-character suffix and can commit only `progress`; - unsupported rich quotes fall back to one exact bounded receipt and can commit only `progress`; - a no-action `DONE` proposal that paraphrases its own task's prior canonical evidence now discards the paraphrase and commits task-local `progress`, with `evidence_unresolved=true` in the transition. It creates no observation and cannot reuse another task's evidence. The last correction was validated against the real Q8 terminal trace after the live run. The replay now produces `progress`, no observation, no receipt sequence, and `evidence_unresolved=true`. Because no further live run was launched, this final correction is replay-qualified, not HTB-live qualified. ## Verification The final local source state passes: - `121 passed, 1 skipped`; - Ruff lint and formatting checks; - strict mypy over `src`; - lockfile validation; - source distribution and wheel build; and - the saved Q8 terminal-trace replay described above. ## Artifacts The qualification roots are: - `runs/htb/htb-enigma-claude-opus48-xhigh-q5-20260712/` - `runs/htb/htb-enigma-codex-gpt55-xhigh-q4-20260712/` - `runs/htb/htb-enigma-codex-gpt55-xhigh-q5-20260712/` - `runs/htb/htb-enigma-codex-gpt55-xhigh-q6-20260712/` - `runs/htb/htb-enigma-codex-gpt55-xhigh-q7-20260712/` - `runs/htb/htb-enigma-codex-gpt55-xhigh-q8-20260712/` Within each root, start with `evaluation.json` and `pipeline.stderr.log`. Complete agent logs are at `agent-data/runs//traces//`: `input.json` is the exact role input, `events.jsonl` is the chronological normalized event/action journal, and `output.json` is the terminal provider result and usage record. `state.sqlite3` is the canonical memory image. ## Required next slice Keep the design small and address the demonstrated controller blocker before another HTB run: 1. Preserve compact coverage for every completed branch so older discovery does not disappear from the Supervisor projection. 2. Reject duplicate discovery/enumeration work unless newer canonical evidence opens a new surface. 3. Simplify Supervisor selection around one active exploitation hypothesis. Once a foothold exists, reject redundant `DISCOVER`/`ENUMERATE` proposals unless they name a genuinely new surface, and require the next task to test or exploit the highest-value supported hypothesis. Qualify those changes first on a local multi-stage target with assertions for task count, action count, progress toward exploitation, provenance, and restart behavior. Only then repeat the remote qualification from a clean package build. Provider turn counts should remain performance telemetry; they are not treated as a portable command budget.