<!-- Python backend verification is ENABLED for this project. The stop hook
     enforces a python cycle in addition to the browser cycle whenever an
     edited file matches `python.verifyPatterns`. -->

## Python cycle

Backend file changes IF the file matches `python.verifyPatterns` ALSO require verification through the **python-devtools** MCP server (prefix `MCP:pdt_*`). Python-cycle verification means attaching to the running Python process via debugpy (DAP), setting a probe (tracepoint / logpoint / exceptionpoint) at the changed code, exercising the path so the probe fires, and reading snapshots — OR inspecting runtime error logs — OR capturing the process's outbound HTTP traffic — OR dumping all thread stacks (for concurrency fixes).

Both cycles can be active simultaneously (e.g. you edit both a React component and a Django view in the same task). One `verification-start` covers all active cycles; one platform-agnostic verdict covers them all; one retry counter applies globally.

### ⚠️ `python-devtools` is ONLY for Python backends

`python-devtools` attaches via debugpy (DAP). It does NOT work for Node.js, Java, Go, Rust, Ruby, .NET, PHP, or any other runtime. If you see `package.json` (with no Python manifest), `pom.xml`, `build.gradle`, `go.mod`, `Cargo.toml`, etc., the backend is NOT Python and you must NOT call `MCP:pdt_*` tools — they will fail to connect to non-Python processes. The target's Python environment must also have `debugpy` installed (`pip install debugpy`).

**Misconfiguration recovery.** If you reach this state, the operator enabled the python cycle for a non-Python project by mistake. The stop hook will keep blocking with `incomplete_tools` for the python cycle until you call `MCP:pdt_debug_connect` (which will fail) or until `maxRetries` is exhausted. Don't attempt the connection. Instead, stop and clearly report to the user: the project's backend is not Python, and they must run `ironbee python disable` to unblock the gate. Continue with browser-cycle verification only in the meantime.

### Python-cycle additions to the main flow

These attach to the **Required steps** above — they don't replace any step. Numbering follows the main flow:

- **Within step 3 (run flow):** also run the python flow: connect (`MCP:pdt_debug_connect`) → set probe (`MCP:pdt_debug_put-tracepoint` / `put-logpoint` / `put-exceptionpoint`) AND exercise + read snapshots (`MCP:pdt_debug_get-probe-snapshots`), OR exercise + read logs (`MCP:pdt_debug_get-logs`), OR capture outbound HTTP (`MCP:pdt_o11y_get-http-requests` — call once to install, exercise, read again), OR dump all thread stacks (`MCP:pdt_debug_dump-threads`, for deadlock / hang fixes). When both browser and python cycles are active, run BOTH within the same verification cycle.
- **Within step 6 (submit verdict):** submit one platform-agnostic verdict with `status` + `checks` (+ `issues`/`fixes` as needed). Python-cycle pass criteria: process connected, probe triggered (or log path used with no ERROR entries, or the expected outbound request(s) captured, or the thread dump shows the expected states).

### Additional BANNED for python cycle

- Calling `MCP:pdt_*` tools without first opening a verification cycle (`ironbee hook verification-start`).
- **Calling `MCP:pdt_*` tools when the project's backend is NOT Python** (Node.js / Java / Go / Rust / .NET / Ruby / PHP / Elixir / etc.). Use the node cycle for Node.js backends; the browser cycle only for the rest.
- Claiming `status: pass` for a python cycle when no probe triggered AND no log / network / thread-dump path was used — those criteria must hold.
