---
description: Authorization, aggregation, execution, proof, and handoff contract for bounded Pentester hardening
agents: [pentester]
task_types: [security-correction, qa-handoff]
triggers: [recommended_owner pentester, correct_locally, review cycle]
---

# Pentester Bounded Correction Cycle

Pentester may correct locally only after findings and candidate paths are persisted. The cycle is one aggregate packet, not one cycle per finding.

## Eligibility gate

A finding is eligible only when all are true:

- exploit or unsafe state and the expected secure result are reproducible in an authorized fixture/local path;
- the fix is deterministic and preserves approved product behavior, public API, permission model, data retention and architecture;
- no schema/data migration, new public dependency, credential rotation, infrastructure rollout or external coordination is required;
- the selected packet fits **3 behavior files / 5 total paths**, including tests; assess each finding independently before selecting the union;
- targeted regression and safe re-probe are available;
- `recommended_owner` is `pentester` and no unresolved higher-risk eligible finding is displaced by cosmetic work.

Anything failing the gate remains documented and routes once to Dev or Planner. It must not block independent eligible corrections. Critical severity does not automatically make a bounded deterministic fix ineligible; low severity does not expand authority. An explicit review-only request disables code corrections for this pass.

## Build one correction packet

1. Sort validated findings by severity, exploitability and shared root cause.
2. Group findings fixed by the same boundary control so one coherent change can close several symptoms.
3. Compute the union of behavior, test and artifact paths before requesting the cycle.
4. Include every eligible finding that fits the cap. If all cannot fit, prioritize critical/high and route the remainder; do not silently omit them.
5. Persist per finding: candidate paths, secure invariant, regression command, re-probe, fallback owner and why broader work is out of scope.

Persist the selected union at the JSON root, for example `"allowed_fix_paths": ["src/auth.js", "tests/auth.test.js"]`. The CLI reads this exact field; a narrative packet or `candidate_paths` alone is insufficient. Root `allowed_fix_paths` takes precedence over legacy nested allowlists. Do not place deferred candidates in it or add HTML/telemetry paths to the code packet. Preserve it unchanged until resolve.

Select after a bounded triage of evidenced entry points and known high-risk candidates. Once the packet is actionable, correct it before completing low-risk catalog rows or generating HTML. A missing runtime or identity blocks only dependent probes; record `not_tested` and continue independent local work. Do not retry the same unavailable prerequisite without new evidence. Finish remaining scoped coverage after remediation; no second packet merely to bypass the aggregate cap.

## Sequence

1. Read `.aioson/context/agent-execution-{slug}.json` and the authoritative findings artifact.
2. Advance exactly once for the aggregate packet:

```bash
aioson review-cycle:advance . --feature={slug} --plan=.aioson/context/security-findings-{slug}.json --source=pentester --to=pentester --json
```

Use `--manual` only for a directly requested pass while Pentester is disabled.

3. Inspect the result. Honor its Git baseline, host/model, enabled state, capacity, cycle limit and exact `allowed_fix_paths`.
4. Reconfirm the packet union is within 3 behavior files / 5 total paths. Do not add a path opportunistically.
5. Apply the smallest root-boundary corrections and security regression tests. Preserve unrelated user changes.
6. Inspect the complete diff. If it changes public behavior, permissions, retention, architecture, dependencies, migrations or an unapproved path, stop with `stop_scope_violation` and preserve the diff for Dev/Architect.
7. Run targeted tests, then the relevant wider regression command in proportion to risk.
8. Re-probe every corrected attack path from a clean state/context. A passing unit test alone is not a security re-probe.
9. Update each finding:

```json
{
  "status": "needs_validation",
  "remediation": {
    "status": "applied_pending_qa",
    "summary": "Root-boundary correction applied without changing the public contract.",
    "changed_paths": ["src/example.ts", "tests/security/example.test.ts"],
    "tests": ["stack-native command — PASS"],
    "reprobe": ["sanitized attack path now rejected with the expected result"]
  }
}
```

10. Before generating HTML or writing unrelated telemetry, verify the completed correction diff:

```bash
aioson review-cycle:resolve . --feature={slug} --plan=.aioson/context/security-findings-{slug}.json --source=pentester --to=pentester --json
```

Inspect `scope_verification` and the returned action. `stop_scope_violation` routes the preserved diff to Dev; never report successful return to QA in that state. Resolve also runs after a failed attempt so its partial diff is checked. Do not reset the cycle to obtain more attempts. Only the packet JSON and cycle state are bookkeeping exceptions to the allowlist: report pages created before resolve otherwise become scope violations.

11. Complete remaining scoped probes, then with `report_mode: full` generate the HTML bundle once; with `report_mode: none`, refresh only the findings JSON and short summary. Return the verified packet to independent QA and consolidate uncorrected work for Dev/Planner, each with a reason and next action.

## Failed correction

One stable finding receives at most one correction attempt per pass. If a test or re-probe fails:

- preserve the finding and evidence;
- set `remediation.status: failed` with the failing command/result;
- do not broaden paths or redesign the system;
- route to Dev/Planner with the complete diff and root-cause evidence.

The manifest cycle limit is the sole retry cap. A later scanner miss never erases the prior finding.

## Stop conditions

Stop and consolidate once for Dev/Planner when remediation requires:

- a new or changed public API, product flow, permission/threat model or risk acceptance;
- schema/data migration, data repair, credential rotation or external-system change;
- dependency adoption/replacement, infrastructure rollout or deployment access;
- architecture, tenancy, cryptographic design, retention or legal/compliance decision;
- more than 3 behavior files / 5 total paths or any path outside the returned allowlist.

When security remediation changed approved behavior, permissions, data retention or flow, flag it for QA scope-drift classification (`.aioson/docs/qa/scope-drift.md`). Pure internal hardening returns directly to QA.

Pentester can recommend, correct within the packet and prove the re-probe. Only QA may finally mark `fixed`, `false_positive`, `accepted_risk`, severity, and delivery acceptance.
