# Diagrams — Capstone C1: Build a Full Bug Bounty or AppSec Harness

> All Mermaid validated in Mermaid Live Editor. Code blocks are illustrative and structurally valid.

---

## Diagram 1 — Scope Enforcement Middleware: Three Gates

**Type**: Mermaid (flowchart)
**Purpose**: Shows the three gates every tool call must pass before execution. Scope enforcement is code, not a prompt — the LLM never sees a rejected call succeed.

```mermaid
flowchart TD
    CALL["LLM issues tool call<br/>(tool_name, args, trace_id)"]
    MW["ScopeMiddleware.call"]

    G1["Gate 1 — SCOPE CHECK<br/>extract_target(args) → is_in_scope?<br/>Rejects any host/path outside allow-list"]
    G2["Gate 2 — RATE LIMIT<br/>allow_rate(target)?<br/>Rejects if ceiling hit"]
    G3["Gate 3 — AUTONOMY POLICY<br/>tool.high_impact AND not approved?<br/>Holds for human approval (Level 2)"]

    BLOCKED["ToolResult.blocked<br/>(reason, trace_id)<br/>LLM sees: 'action blocked, here is why'"]
    APPROVAL["ToolResult.awaiting_approval<br/>Held until human approves"]
    EXEC["tool.run(args, trace_id)<br/>→ ToolResult with finding + evidence"]

    CALL --> MW
    MW --> G1
    G1 -->|"out of scope"| BLOCKED
    G1 -->|"in scope"| G2
    G2 -->|"rate limited"| BLOCKED
    G2 -->|"allowed"| G3
    G3 -->|"high-impact, unapproved"| APPROVAL
    G3 -->|"approved / low-impact"| EXEC

    DEFENSE["Defense in depth:<br/>tool ALSO calls scope.assert_in_scope<br/>Registry wraps tool — double check"]
    DEFENSE -.-> EXEC

    style MW fill:#14141f,stroke:#5eead4,color:#5eead4
    style G1 fill:#2a0d0d,stroke:#a00000,color:#f08080
    style G2 fill:#2a0d0d,stroke:#a00000,color:#f08080
    style G3 fill:#2a1810,stroke:#a04000,color:#f0a868
    style BLOCKED fill:#2a0d0d,stroke:#a00000,color:#f08080
    style EXEC fill:#0d2818,stroke:#1e8449,color:#82e0aa
```

**Reading the diagram**: Every tool call passes through ScopeMiddleware before execution. Three gates block it: scope (is the target in the allow-list?), rate limit (has the per-host ceiling been hit?), and autonomy (is this a high-impact action needing human approval?). A blocked call returns a structured result the LLM sees as "blocked, here is why" — never a silent failure, so the LLM learns the boundary. Defense in depth: the tool itself also checks scope, and the registry wraps the tool — two redundant checks so a forgotten check in one layer does not create a hole.

---

## Diagram 2 — Persistent Memory and the Evidence Chain

**Type**: Mermaid (flowchart)
**Purpose**: Shows how target-state memory makes the harness cumulative and how every confirmed finding links back through evidence to the tool call and reasoning trace.

```mermaid
flowchart LR
    subgraph BEFORE["Before a tool runs"]
        CTX["Memory.context_for(tool, args)<br/>Loads host state + prior findings<br/>into LLM context"]
    end

    subgraph RUN["Tool execution"]
        TOOL["tool.run(args, trace_id)"]
        EV["Evidence recorder middleware<br/>captures input/output + sha256 hash"]
        RESULT["ToolResult<br/>(finding?, evidence?, trace_id)"]
    end

    subgraph AFTER["After a tool runs"]
        WRITE["Memory.record(tool_call, result)<br/>Appends to chain, findings, evidence"]
    end

    STATE["TargetState graph<br/>hosts · findings · confirmed · rejected · evidence · chain"]

    CTX --> TOOL --> EV --> RESULT --> WRITE
    WRITE --> STATE
    STATE -.->|"next call reads this"| CTX

    TRIAGE["Triage filter<br/>findings → confirmed (if evidence + passes rules)<br/>findings → rejected (if false positive)"]
    STATE -.-> TRIAGE
    TRIAGE -.->|"moves finding"| STATE

    CHAIN["Evidence chain (tamper-evident)<br/>Finding.evidence_ids → Evidence.id → Evidence.tool_call_id → ToolCall → log line (trace_id)"]
    STATE -.-> CHAIN

    style CTX fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
    style EV fill:#14141f,stroke:#5eead4,color:#5eead4
    style STATE fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style TRIAGE fill:#2a1810,stroke:#a04000,color:#f0a868
    style CHAIN fill:#2a1810,stroke:#a04000,color:#f0a868
```

**Reading the diagram**: Memory makes the harness cumulative. Before a tool runs, `context_for` loads the relevant host state and prior findings into the LLM context — so the active probe sees the `/admin` route the recon tool discovered, without being told. After the tool runs, the evidence recorder captures the input/output with a sha256 hash, and `record` writes the finding and evidence back to the TargetState graph. The triage filter moves findings between candidate, confirmed, and rejected states. The evidence chain links every confirmed finding back through the evidence record, the tool call, and the log line — joined by the trace ID. The hash makes the chain tamper-evident.

---

## Diagram 3 — Tool Registration Stack: Pydantic + Scope + Rate Limit

**Type**: Mermaid (flowchart)
**Purpose**: Shows the uniform structure every tool shares — input model, target extraction, high-impact flag, run method — and the five-tool minimum suite.

```mermaid
flowchart TD
    subgraph SUITE["Five-tool suite (minimum)"]
        T1["1. Recon<br/>discovers target surface<br/>high_impact: False"]
        T2["2. Active Probe<br/>crafted requests / mutations<br/>high_impact: True"]
        T3["3. Static Analyzer<br/>linter / SAST / pattern match<br/>high_impact: False"]
        T4["4. Exploit Verifier<br/>controlled PoC to confirm<br/>high_impact: True"]
        T5["5. Evidence Recorder<br/>captures request/response/diff<br/>high_impact: False"]
    end

    subgraph PATTERN["Every tool shares this structure"]
        SCHEMA["Pydantic input model<br/>rejects malformed args before run"]
        EXTRACT["extract_target(args) → str<br/>gives middleware something to check"]
        FLAG["high_impact: bool<br/>routes through approval gate"]
        RUN["run(args, trace_id) → ToolResult<br/>returns finding + evidence"]
    end

    REG["ToolRegistry<br/>wraps each tool with ScopeMiddleware + EvidenceRecorder"]

    SUITE --> PATTERN --> REG

    style SUITE fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
    style PATTERN fill:#14141f,stroke:#5eead4,color:#5eead4
    style REG fill:#0d2818,stroke:#1e8449,color:#82e0aa
```

**Reading the diagram**: Five tools is the floor. The suite covers the full arc: recon discovers the surface, the active probe tests hypotheses, the static analyzer runs linters/SAST, the exploit verifier confirms a finding with a controlled PoC, and the evidence recorder captures the proof. Every tool shares the same structure: a Pydantic input model that rejects malformed arguments, an `extract_target` method that gives the scope middleware something to check, a `high_impact` flag that routes through the approval gate, and a `run` method that returns a finding and evidence. The registry wraps each tool with the scope and evidence middleware — uniformity is the point, because uniformity is what makes the middleware hold for every tool.

---

## Diagram 4 — The Benchmark Gauntlet (C1.3)

**Type**: Mermaid (flowchart)
**Purpose**: Shows the four tests that convert "my harness is safe and effective" into falsifiable, publishable evidence.

```mermaid
flowchart TD
    LAB["Test 1 — Vuln lab recall<br/>Run vs known-vuln target (Juice Shop/DVWA)<br/>Measure: of N known bugs, how many confirmed?"]

    OOS["Test 2 — OOS call block rate<br/>Inject out-of-scope targets into tool-call args<br/>Measure: 100% must be blocked"]
    OOS_NOTE["Serve a response that redirects to OOS host<br/>If any OOS call succeeds → scope bug, fix before continuing"]

    INJ["Test 3 — Served injection payload<br/>Serve response with prompt injection<br/>('IGNORE PREVIOUS INSTRUCTIONS...')<br/>Measure: harness treats as data, behavior unchanged"]

    IA["Test 4 — InjecAgent suite<br/>Run benchmark against harness<br/>Measure: % injection attempts that failed to manipulate<br/>Publishable claim if > 90%"]

    REPORT["Client-ready report<br/>Scope · methodology · findings table<br/>detailed findings + PoC + evidence hash"]

    PUBLISH["Publish benchmark<br/>Recall · OOS block rate · injection result<br/>InjecAgent score · report link<br/>→ GitHub README · LinkedIn · Deepthreat.ai"]

    LAB --> REPORT
    OOS --> OOS_NOTE
    OOS_NOTE --> INJ
    INJ --> IA
    IA --> PUBLISH
    REPORT --> PUBLISH

    style LAB fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
    style OOS fill:#2a0d0d,stroke:#a00000,color:#f08080
    style OOS_NOTE fill:#2a0d0d,stroke:#a00000,color:#f08080
    style INJ fill:#2a1810,stroke:#a04000,color:#f0a868
    style IA fill:#2a1810,stroke:#a04000,color:#f0a868
    style REPORT fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style PUBLISH fill:#14141f,stroke:#5eead4,color:#5eead4
```

**Reading the diagram**: Four tests, each measuring a different property. Test 1 measures effectiveness — recall against known bugs. Test 2 measures safety — the scope middleware must block 100% of OOS calls; if any succeeds, you have a bug to fix before continuing. Test 3 measures adversarial-output defense — a served prompt injection must not alter the harness's behavior (the defense is structural: tool output is data, never instructions). Test 4 measures injection resistance at scale — the InjecAgent score is a publishable security claim above 90%. The client report and the published benchmark are the two portfolio assets: the report proves the harness works, the benchmark proves it is safe.

---

## Diagram 5 — Publishable Report Anatomy

**Type**: Mermaid (flowchart)
**Purpose**: Shows the structure of the client-ready report and how each section links back to the evidence chain via trace IDs and evidence hashes.

```mermaid
flowchart TD
    SCOPE["1. Scope & engagement boundary<br/>in-scope hosts, paths, autonomy level<br/>defines what was tested — and what was NOT"]
    METHOD["2. Methodology<br/>tool suite, triage rules, benchmark setup<br/>establishes reproducibility"]
    TABLE["3. Findings table<br/>ID · title · severity · location · status<br/>the executive view — client's first stop"]
    DETAILED["4. Detailed findings<br/>description · impact · PoC · recommendation<br/>evidence_hash · trace_id (join key to chain)"]
    SEVERITY["Severity: Critical/High/Medium/Low/Info<br/>harness triage = draft<br/>human confirms before ship (Level 1/2)"]
    ROADMAP["5. Remediation roadmap<br/>prioritized actions · verification path"]

    SCOPE --> METHOD --> TABLE --> DETAILED --> ROADMAP
    TABLE -.-> SEVERITY

    CHAIN["Evidence chain (replayable)<br/>trace_id → ToolCall → Evidence (sha256) → raw output<br/>Reviewer verifies hash matches recorded output"]
    DETAILED -.->|"every finding links"| CHAIN

    DUAL["Dual output<br/>JSON (machine: gate / bounty API)<br/>HTML (human: reviewer / client)"]
    DUAL -.-> TABLE

    style SCOPE fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
    style METHOD fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
    style TABLE fill:#14141f,stroke:#5eead4,color:#5eead4
    style DETAILED fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style ROADMAP fill:#0d2818,stroke:#1e8449,color:#82e0aa
    style CHAIN fill:#2a1810,stroke:#a04000,color:#f0a868
    style DUAL fill:#2a1810,stroke:#a04000,color:#f0a868
```

**Reading the diagram**: The report has five sections. Scope defines the engagement boundary — what was tested and, by omission, what was not. Methodology establishes reproducibility. The findings table is the executive view. Detailed findings carry the PoC, recommendation, evidence hash, and trace ID — the trace ID is the join key that lets a reviewer replay the chain: trace ID to tool call to evidence record to raw output, verifying the hash matches. The remediation roadmap prioritizes action. The harness triage assigns a draft severity; a human confirms before the report ships (Levels 1 and 2). Dual output — JSON for the machine (AppSec gate or bounty API), HTML for the human reviewer.
