One loop, and every pass through it is written down.
The planner is your own model, or a deterministic fallback. Whatever it proposes goes to the scope engine, then to the approval gate your autonomy level sets, and only then to a tool. When validation turns up new hosts, the loop starts again at observe.
The agent proposes, the scope engine checks, your autonomy level decides who confirms. The audit log records each step. New hosts and credentials re-enter at observe, scope file permitting.
observeRead the graph and fresh tool output: hosts, services, accounts.planPropose next steps and rank paths. The output is a request, never an action.actRun an allowed tool. The scope engine checks it first and the autonomy level decides if you confirm.validateConfirm with read-only checks. Anything out of scope is refused and logged.reportExport what was confirmed, with the full decision trail.Read it as a series of decisions.
scopeThe scope file loads first. With no scope file, the agent does not start.allowedThe proposed action matches an allow rule, so it runs and the log records which rule.refusedThe model asked for a host on the deny list. The request is dropped, logged, and the run continues.approvalActive checks are gated in the playbook. The run waits for a person.validateRead-only confirmation. It shows a weakness is real without using it.reportThe findings come with the trail that produced them.
Three levels of trust, one default.
Start at approve-each-step. Loosen it only on ranges you know, for a window you chose.
suggest
approve-each-stepdefault
autonomous-within-scope
No level can widen the scope file, add tools or raise the budget. The model's output is a request, the scope engine decides, and the audit log records both.
The agent can ask. It cannot answer for you.
A gate pauses the loop before a step you named. The prompt says what will run, against what, which rule allows it, and why the planner wants it. If nobody answers, the answer is no.
yRun this step once.nRefuse it. The refusal is logged and the planner replans.sSkip the step and continue with the rest.qStop the run and write the report so far.
Keys are placeholders for the example CLI.
Every limit is a line you can read.
The agent block lives next to your scope file and goes into version control with it. Tools not on the allowlist cannot be called, however the planner asks.
agent: planner: model: ollama:llama3 # bring your own fallback: deterministic # no model needed autonomy: approve-each-step max_steps: 40 budget: tokens: 200000 minutes: 120 tools: # allowlist - discover - enumerate - paths - validate # read-only - report approvals: require_for: [active_checks, new_range] log: ./pwner-audit.jsonl
- plannerWhich model proposes steps, and what takes over when it is missing or fails.
- autonomyOne of the three levels above. Unset means approve-each-step.
- budgetHard caps on steps, tokens and wall-clock time. The first one reached ends the run.
- toolsThe only tools the planner can name. Validation is read-only by construction.
- approvalsWhich kinds of step stop and wait for a person.
- logAppend-only JSONL. Each line records the action, the rule that allowed it and who approved.
Example values from the file above, not recommendations. When a cap is reached the run stops cleanly, writes the report and logs why.
Use the model you trust with the data.
pwner ships no model and no key. Point the planner at something you run, something you pay for, or nothing at all.
- ollama:llama3local
- A model on your own machine. Nothing about the network leaves the host. The right choice for a client who says the data cannot travel.
- example model name
- api:provider/modelhosted
- A hosted model through an API key you supply. The planner sends a summary of the graph, and secrets found during the run are redacted before anything is sent.
- placeholder provider
- deterministicfallback
- No model at all. Rules rank the paths, so the same input gives the same plan. It takes over if the model is unreachable, and it is the mode to use when a run must be repeatable.
- default fallback
Whichever planner you pick, it sits on the same side of the line. It writes proposals, and everything after that is code you can read.
The model cannot talk its way past the scope engine.
Scope is not part of the prompt. It is a check in core that every action passes through, and it runs the same way for a local model, a hosted one, or the fallback.
- Deny firstDeny rules beat allow rules. A host on both lists is off limits.
- Code, not promptText inside a banner or a web page can steer the planner. It cannot change the scope engine.
- No self editThe agent can read its config. It cannot write scope, tools, budget or approvals.
- Refusals are dataA refused request is logged and fed back to the planner, which tries something else.
Authorized testing only. Anyone can write a scope file that covers a network they do not own, and no software can stop that. Read responsible use before you run it.