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

## Backend cycle (runtime-agnostic protocol verification)

When the file matches `backend.verifyPatterns`, the Stop hook ALSO requires verification through the **backend-devtools** MCP server (prefix `bedt_`). The cycle is satisfied by **any one of three** evidence paths: a real protocol call (HTTP / gRPC / GraphQL / WebSocket) against the running service, log inspection from the running service (file / docker / kubernetes) when an external driver is hitting the endpoint, OR direct database inspection for schema / data-state changes. Pick whichever fits the task — language- and framework-independent in all three cases.

The backend cycle and the node cycle are **independent**. Node attaches to a Node.js V8 inspector with non-blocking probes (`ndt_*`); backend drives wire protocols and/or reads logs / DB state from outside (`bedt_*`). They can be active in the same task; both must be satisfied for `status: pass`.

### Backend-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 backend flow via ONE of three evidence paths:
  - **Protocol-call** — identify the affected endpoint(s) → call the matching protocol tool (`bedt_request_http` / `bedt_request_grpc` / `bedt_request_graphql` / `bedt_request_websocket-open` / `bedt_request_replay`) → inspect status / body / `traceId` → chain follow-up calls when verifying side effects. **A 4xx / 5xx response is a normal result, not an error** — only transport failures populate the `error` field.
  - **Log evidence** — `bedt_log_register-source` (file / docker / kubernetes) → `bedt_log_read` (point-in-time, supports `tail` / `since-until` / `pattern` / `level` / `parseJson` + `jsonFilter` / `contextBefore-After` / `select` / `coalesce`) OR `bedt_log_follow` + `bedt_log_get-followed` (streaming). Fit for jobs / queue workers / async handlers, or any case where an external driver is hitting the endpoint and you only need to verify what the server logged. `bedt_log_register-source` is mandatory on this path (the gate counts it as the setup step).
  - **DB evidence** — `bedt_db_connect` (named, `connectionStringEnv` preferred, default readonly) → ONE of `bedt_db_query` / `bedt_db_describe-table` / `bedt_db_list-tables` / `bedt_db_snapshot` (+ optional `bedt_db_diff`) / `bedt_db_get-changes`. Fit for migrations, seed-data changes, query-result regressions, and any code change whose side effect lives in a relational DB. `bedt_db_connect` is mandatory on this path (same anti-fluke rule as `log-evidence` — the connection name is on the wire).
- **Within step 6 (submit verdict):** submit one platform-agnostic verdict (`status` + `checks` + optionally `issues` / `fixes`). The gate requires that at least one evidence path (protocol-call, log-evidence, or DB-evidence) was exercised in your `bedt_*` tool calls.

### Trace correlation (`o11y_*` is auxiliary, not evidence)

IronBee already injects the active verification `traceId` into every backend tool call via `_metadata.traceId`. That id outranks anything `bedt_o11y_new-trace-id` / `bedt_o11y_set-trace-context` would pin for the cycle, so the orchestrator's correlation root stays authoritative. The `o11y_*` tools are still useful for log searches (`bedt_log_read { pattern: traceId }` against an explicit id), but they don't count toward the gate.

### Additional BANNED for backend cycle

- Calling `bedt_*` tools without first opening a verification cycle (`ironbee hook verification-start`).
- Treating a 4xx / 5xx response as a transport failure when the test was specifically asking for that error condition (e.g. "POST should reject malformed body with 400"). Decide PASS/FAIL based on the test's intent, not the status code's HTTP-class default.
- Claiming `status: pass` for a backend cycle without exercising at least one evidence path (no `bedt_request_*` call, no `bedt_log_register-source` + read, no `bedt_db_connect` + read). The gate will reject.
- Inferring backend behavior by reading code without exercising any evidence path. The cycle is satisfied only by making a real protocol call, reading real logs, or inspecting real DB state on the running service.
- Reading a pre-existing log source / DB unrelated to your task to fake the log-evidence or db-evidence path. `bedt_log_register-source` and `bedt_db_connect` are required setup steps on those paths so the registration / connection is on the wire.
- Opening a DB connection with `allowWrites: true` to "set up" verification data without an explicit need (seed / migration). Read-only is the default for a reason — flipping it widens the blast radius if a query goes wrong.
