CompanionThe production-readiness protocol

Companion to Agentic Coding: The Professional's Guide (index.html) — chiefly Sections 7–10, though its gates also map to Sections 3, 6, 11, 12 and 13. That guide explains why each of these things matters. This document is the same standard written as literal, sequential directives an AI agent can execute against a real repository — so you can hand it to Claude Code or any coding agent and get a verified, evidence-based answer to "is this actually production-ready," instead of a confident guess.

It is stack-agnostic. Swap the example tool names for whatever your project actually uses.

How to use this

  1. Copy this file into the target project (e.g. docs/production-readiness-protocol.md).
  2. Start a fresh agent session in that repo (don't reuse a long, tired context — see the guide's Section 12 on the "dumb zone").
  3. Give it this instruction:

Read docs/production-readiness-protocol.md. Work through every gate, in order. For each gate: inspect the actual code, config, or infrastructure — don't guess — and report PASS, FAIL, or N/A with the specific evidence you checked (a file path, a command and its output, a config value). If a gate fails, propose the smallest concrete fix. When every part is done, produce the final report table and the ranked top-5 fix list described at the end of this document.

  1. Treat FAILs as a work queue, not a scorecard. Feed the top 5 back into your normal planning loop (grill → plan → build → verify) one at a time — don't let the agent "fix everything" in one giant unreviewed pass.

Rules for the executing agent — the whole protocol only works if these hold:

Part A — Code quality & maintainability

Gate 1 — Strict types, no suppressions. The type-checker runs in its strictest mode (e.g. TypeScript strict: true + noUncheckedIndexedAccess: true, or the equivalent for your language) and is green. Grep the diff for suppressions (// @ts-ignore, # type: ignore, any used to dodge an error) — a suppression that isn't justified in a comment is a FAIL.

Gate 2 — Lint and format are clean. The linter passes with zero newly-suppressed warnings. A rule disabled inline without a one-line reason is a FAIL.

Gate 3 — Small public interfaces. Pick three non-trivial modules. Confirm other code only imports their intended public exports, not internals reached by relative path (../other-module/internals/helper). Complexity should hide behind a small, stable interface (a "deep module") — not leak everywhere.

Gate 4 — Decisions are written down. Every architecturally significant recent change (a new dependency, a schema shape, an auth approach) has a matching entry in docs/adr/. If the folder doesn't exist yet, that's a FAIL, not an N/A — create it going forward.

Gate 5 — Dead code and stale flags are removed. Feature flags left permanently on, commented-out blocks, and unused exports accumulate silently under agentic coding. Grep for flags that have been at 100% rollout for a while and haven't been cleaned up.

Part B — Architecture & scalability

Gate 6 — Services are stateless. No request handler keeps state in a process-local variable that would break the moment you run two instances behind a load balancer (session data, in-memory caches used as the source of truth). Any intentional in-memory cache is documented as a cache, with a stated invalidation rule.

Gate 7 — Queries are indexed; no N+1. Identify the three most-hit read paths. Run EXPLAIN (or your database's equivalent) on their queries and confirm they use an index, not a full table scan. Check whether a loop in the code issues one query per iteration (an N+1) instead of one batched query.

Gate 8 — Public surfaces are rate-limited and load-tested. Any endpoint reachable without auth (signup, login, a public booking form) has a rate limit. There is at least one load test, or a written, deliberate capacity assumption ("this must survive 50 concurrent bookings") — not silence on the topic. This is the minimum bar; the launch-grade load/stress/soak/spike requirement is Gate 93 — don't double-report, note the detail there.

Part C — Environments & release pipeline

Gate 9 — Real environment separation. Staging and production use separate databases and separate credentials — confirm this by reading the actual connection configs/secrets, not by assuming it from folder names. A staging environment that points at the production database is a FAIL, full stop.

Gate 10 — CI actually gates the merge. Type-check, lint, and the test suite must be green before a branch can merge — check the branch protection / required-checks configuration itself, not just that a CI file exists.

Gate 11 — Nobody edits production directly. There is no documented or habitual path for editing prod by hand — no SSH-and-patch, no ad-hoc query against the live database labelled a "fix." Ask (or check runbooks/history): "how was the last production hotfix shipped?" If the honest answer isn't "through the same pipeline as everything else," this is a FAIL.

Gate 12 — Rollback is rehearsed, not theoretical. Getting back to the last good state is a single action (a flag flip, a one-click redeploy) and someone has actually done it at least once outside a real emergency. "We'd figure it out" is a FAIL.

Gate 13 — Migrations are non-destructive. Recent schema changes follow expand-contract (add the new shape, backfill, deploy, only remove the old shape later) rather than a single-step DROP COLUMN or ALTER ... NOT NULL with no backfill step.

Part D — Data protection: backups

Gate 14 — Automated backups exist with a stated RPO/RTO. Confirm an automated backup job actually runs (check the schedule/logs, not just that a feature exists to enable it) and that you can state, in one sentence, how much data you could lose and how long a restore takes.

Gate 15 — A restore has actually been tested. Find evidence a restore was performed and verified within roughly the last quarter — a runbook entry, a ticket, a log. "Backups exist" without a tested restore is a FAIL; an untested backup is a hope, not a backup.

Gate 16 — Backups are isolated from production credentials. The account/role that can delete or overwrite production data should not be the same one that can delete the backups. Otherwise one compromised credential destroys both the app and its safety net.

Part E — Data protection: encryption

Gate 17 — TLS everywhere. Every network hop — client to server, server to database, service to service — is encrypted in transit. No internal call gets a pass because "it's inside the network." Check actual connection strings/config for sslmode=disable-style opt-outs.

Gate 18 — Encryption at rest is on. The database and any file/object storage have provider-level encryption at rest enabled — usually a single setting; confirm it's actually toggled on, not just available.

Gate 19 — Sensitive fields get an extra layer. For data that would hurt a real person if it leaked — health information, ID documents, payment details, and in some jurisdictions even name-plus-contact-details combinations — add field-level encryption on top of the above, keyed through a managed key service (a cloud KMS or equivalent), never a key stored in the same table, repo, or config file as the data it protects.

Part F — Data protection: access control

Gate 20 — No shared, standing production credentials. Every person and every service that can reach production has its own scoped, individually revocable credential. A shared "admin" login used by the whole team is a FAIL.

Gate 21 — Access is modelled as roles, not "everyone sees everything." Check the actual authorization code: does a logged-in user's role (customer, staff, manager, admin) determine what data they can see and change, or does any authenticated session get full read access to every record?

Gate 22 — Sensitive access is logged. You can answer "who looked at this specific customer's data, and when" from an actual log — not from memory or "probably nobody."

Gate 23 — Data minimisation and retention. For each field of personal data stored, there's a reason a current feature needs it, and a stated retention period or deletion trigger. A growing pile of customer data nobody remembers the purpose of is a FAIL.

Part G — Security testing

Gate 24 — Static analysis and dependency scanning run on every change. SAST (a tool that scans your own code for known-bad patterns — e.g. Semgrep, CodeQL) and SCA (the same idea for your dependencies' known vulnerabilities — e.g. pnpm audit, osv-scanner, Snyk, Dependabot) run in CI on every pull request, not as a one-time check before launch.

Gate 25 — Secret scanning blocks leaked credentials. A tool (e.g. gitleaks, trufflehog, or your platform's built-in scanner) blocks a commit or pull request that contains an API key, password, or token before it ever reaches a shared branch.

Gate 26 — Dynamic scanning runs against staging. A DAST tool (e.g. OWASP ZAP baseline scan) attacks the running staging app the way an automated bot would, catching what static analysis can't — missing auth checks, misconfigured security headers.

Gate 27 — Authorization boundaries are explicitly tested. Log in as user A and deliberately try to read or modify user B's data by changing an ID in a URL or request body — an IDOR (Insecure Direct Object Reference) check. This is the single most common real-world break in agent-built CRUD apps (Create/Read/Update/Delete — the routine "form that saves to a database" pattern most business software is made of); test it by hand at least once per data type (customer records, bookings, staff accounts).

Gate 28 — Standard injection classes are tested. SQL injection, script injection (XSS), and command injection are tested against every user-facing input, not assumed away because "we use an ORM."

Gate 29 — An independent review has happened, or is scheduled. Before real users' data is genuinely at stake, get a review from someone who isn't the agent that wrote the code — a paid external penetration test at minimum viable-product launch, or at minimum a thorough external automated scan, repeated periodically (e.g. every 6–12 months, or after any major auth/payments change).

Gate 30 — High-risk changes get a real read, not a demo-reel skim. Anything touching authentication, payments, or personal data is automatically the highest tier of the risk-tiered review from the guide's Section 6 — a human reads the actual diff, every time, regardless of how good the demo recording looks.

Part H — Compliance & privacy

Gate 31 — Lawful basis and user rights, if you touch EU/UK data. If the product serves or stores data on EU/UK residents, confirm: a stated lawful basis for each category of data collected, a working way for a user to export or delete their own data, and a documented list of every third party that touches user data (hosting provider, email sender, analytics, payment processor).

Gate 32 — An audit trail exists for what changed and why. Git history, ADRs, and pull-request history together should let you reconstruct why any significant change was made — not just what changed.

Not legal advice. This part tells the executing agent what to check exists and is filled in with real, product-specific content — not a placeholder — so you know what to bring to a lawyer (a Fachanwalt für IT-Recht) before launch. Signing the actual documents is a business step, not something an agent should do unsupervised.

Gate 33 — Impressum. German law (§5 DDG — the Digitale-Dienste-Gesetz, the German act that replaced the older TMG/Telemediengesetz; note this is not the EU's Digital Services Act (DSA), which is a separate regulation with its own obligations) requires a complete legal notice ("Impressum" — literally "imprint," the standard German term for it) on essentially any commercial website or app, however small. Check it exists, is reachable from every public screen, and has real company details — not "TODO."

Gate 34 — Datenschutzerklärung (privacy policy) matches reality. It must list every category of personal data actually collected, why, and every third party/subprocessor that touches it (hosting, email/SMS provider, payment processor, analytics). Cross-check it against Gate 23's actual field list and the third-party/vendor lists from Gates 31 and 60 — a generic template that doesn't match what the product really stores is a FAIL, and a real risk.

Gate 35 — AGB (terms) for every relationship in play. For a B2B SaaS with a consumer-facing booking layer, that's usually two separate sets: (a) between the platform and its paying business customers — pricing, an SLA (Service Level Agreement — a written promise about uptime or response time), liability, termination; (b) governing the booking itself — cancellation policy, no-show fees. Resolve explicitly who the end-customer's contracting party is — the platform, or the business using it — because that decides whose AGB applies and who's liable if a booking goes wrong. This is a decision to make during grilling (guide Section 3), not something to leave implicit.

Gate 36 — AVV / DPA in both directions. An Auftragsverarbeitungsvertrag (Data Processing Agreement, GDPR Art. 28) is a required signed contract, not paperwork theatre:

Gate 37 — Data residency is known, not assumed. State which country/region the data actually lives in. If any subprocessor is US-based, confirm a valid transfer mechanism is in place (Standard Contractual Clauses or an adequacy decision) — "it's a well-known provider" is not a legal basis on its own.

Gate 38 — Records of Processing Activities exist (GDPR Art. 30). A short internal document — what personal data is processed, why, for how long, by whom. Required for most companies regardless of size; commonly skipped because nobody outside the company ever sees it.

Gate 39 — A breach-notification process exists. GDPR gives 72 hours from becoming aware of a personal-data breach to notify the supervisory authority. Confirm a named person knows this deadline and the actual steps — not "we'd figure it out."

Gate 40 — Cookie/tracking consent is real, not decorative. If any non-essential cookie or tracking pixel fires (analytics, marketing), German/EU law — the TDDDG (Germany's telecoms-and-digital-services data protection act, renamed from the TTDSG in May 2024; same rules, new name) and the EU's ePrivacy rules — requires genuine opt-in before it fires, not a banner that tracks regardless of the answer.

Gate 41 — Payments stay out of most of PCI-DSS scope. PCI-DSS (Payment Card Industry Data Security Standard) is the strict, costly compliance regime that applies in full the moment your own servers touch raw card numbers. Route card data through a certified processor (Stripe, Adyen, etc.) instead, so they never do — handling card numbers directly is a compliance burden most small teams shouldn't take on. "Out of scope" is not "no obligations," though: a fully hosted or iframe/redirect checkout still leaves you with SAQ-A (Self-Assessment Questionnaire A — the shortest PCI form), which you complete annually and which since v4.0 also requires you to keep the payment page's own scripts under control and monitored, so an injected script on your checkout page can't skim cards. Confirm the SAQ has actually been filled in, not assumed away.

Gate 42 — Consumer rights are honoured for direct bookings. If end-customers book directly as consumers, address the right of withdrawal (Widerrufsrecht) for distance contracts and state the cancellation/no-show policy clearly before booking, not buried in the AGB.

Gate 43 — Invoicing meets German requirements, if you bill customers. Mandatory invoice fields (Rechnungspflichtangaben — tax ID, sequential invoice numbers, etc.) and GoBD-compliant archiving — GoBD is Germany's rule set for how digital financial records must be stored so they can't be silently altered after the fact — of invoices and financial records.

Gate 44 — Accessibility is a legal floor now, not just good practice. Since June 2025, the European Accessibility Act requires many consumer-facing digital services — online booking included — to meet accessibility standards equivalent to WCAG (Web Content Accessibility Guidelines) or EN 301 549 (its formal European technical-standard counterpart, used interchangeably with WCAG in EU regulation). This upgrades the guide's Section 7 "Accessibility" card from best practice to a legal requirement for a real product.

Gate 45 — Multi-tenant isolation is tested, not assumed. If the platform serves multiple businesses from shared infrastructure, explicitly verify Business A can never read or write Business B's data. Every data-reading query must be scoped by tenant ID at the data-access layer, not only hidden in the UI. This is the single most damaging bug class for multi-tenant SaaS — distinct from, and more important than, Gate 27's (IDOR) per-record check.

Part J — Often forgotten, not GDPR-specific

Quick checks, not full gates — but each has sunk real launches:

Part K — Testing & regression

Gate 46 — The regression suite is fast enough that people don't skip it. Read the last several CI run durations. If a full run routinely takes long enough that changes get merged around it or with checks disabled, that's the actual problem — a slow gate is not a gate.

Gate 47 — Flaky tests are quarantined, not tolerated. A test that fails intermittently is pulled out of the required-merge check immediately but keeps running and reporting, with a named owner and a fix-or-delete deadline. Check for a quarantine/skip mechanism and whether anything in it is stale with no owner. A healthy suite runs under roughly 5% flaky.

Gate 48 — Selective test running exists once the suite is large. For a sizeable codebase, a pull request should run only the tests whose dependency graph touches the diff (via build-graph tooling such as Nx, Bazel, or Turborepo), with a full run on a schedule as backstop — not the entire suite on every commit if that's what's making Gate 46 fail.

Gate 49 — Test types match what they're supposed to catch. Confirm the project isn't leaning on one test type for everything: behaviour/end-to-end tests (e.g. Playwright) for real user flows; at least one test-quality check (mutation testing or property-based testing) rather than trusting line coverage alone; and, if the product is split across services, contract tests (e.g. Pact) at the service boundaries rather than only integration tests inside one service.

Gate 50 — Production keeps testing after release. Canary rollout combined with synthetic monitoring (scripted checks continuously hitting the critical paths) or shadow traffic exists for anything with real usage. The regression suite is not the last line of defence — production monitoring is.

Gate 51 — Agent-written tests are checked for mock-heavy false confidence. Coding agents measurably over-mock compared to humans (a 2026 academic study of 1.2M commits found ~36% of agent commits add mocks to tests versus ~26% for human commits). Spot-check a sample of agent-written tests for assertions that only confirm a mock was called, rather than that real behaviour changed.

Part L — Often-missed correctness & operational risks

These are the gates least likely to be on a first-time founder's radar — none are exotic, and each has caused a real incident somewhere.

Gate 52 — MFA and session hardening exist. Staff and admin accounts support MFA (Multi-Factor Authentication — a second proof of identity beyond a password, usually a one-time code from an app or text message). Sessions expire after a stated timeout. Session cookies use the HttpOnly and Secure flags. State-changing requests are protected against CSRF (Cross-Site Request Forgery — a hostile website secretly making a logged-in user's browser act on your site without their knowledge).

Gate 53 — Account-recovery and invite flows are tested as attack surfaces. Password-reset and staff-invite links expire quickly, work only once, and are logged when used. Confirm a guessed or intercepted link can't quietly take over an account.

Gate 54 — Login is rate-limited tighter than public endpoints generally. A handful of failed attempts triggers a lockout or a growing delay, to block automated password-guessing (credential stuffing).

Gate 55 — Personal data is scrubbed from logs and error trackers. Sample real log output from a genuine user flow (e.g. a booking) and confirm names, phone numbers, or addresses aren't captured verbatim. A log line is much harder to find and delete than a database row.

Gate 56 — Deletion cascades actually work. Trigger a deletion or offboarding flow in staging and confirm every place that person's or business's data lives — database, backups, logs, analytics, mailing lists — is accounted for, not just the main record.

Gate 57 — Non-production environments never hold a raw copy of production data. Staging and dev use anonymised or synthetic data. If a "copy production to staging" script or process exists, confirm it actually scrubs personal fields rather than copying them verbatim.

Gate 58 — Network protection and expiry monitoring exist. A CDN/WAF (a service like Cloudflare that filters traffic before it reaches your servers, and provides basic denial-of-service protection) sits in front of anything public. TLS certificate and domain-registration renewal are automated or at minimum alerted on — confirm this by checking the actual expiry dates, not by assuming "the platform handles it."

Gate 59 — Concurrency-sensitive operations are safe under simultaneous requests. For anything booking- or inventory-like: fire two requests for the same resource at the same instant and confirm exactly one succeeds, enforced at the database layer (a unique constraint or a transaction) — not only checked in application code, which can race.

Gate 60 — Vendor dependency risk and consent versioning are tracked. Name every single point of failure (hosting, payment processor, SMS/email provider) and state what happens if one disappears or changes terms overnight. Separately, confirm you can reconstruct which version of your terms and privacy policy a specific user agreed to, and when — consent you can't reconstruct isn't proof of consent.

Part M — Code quality tooling (extends Part A)

Gate 61 — Complexity and length limits are enforced, not aspirational. Check the actual lint config for a complexity rule (cyclomatic complexity — how many independent paths run through a function), max-lines-per-function, max-depth (nesting), and max-params (or your language's equivalents) — not just that a linter runs, but that these specific rules are switched on with a real threshold (e.g. complexity ≤ 10, roughly 50 lines per function). "Lint passes" that only checks style and obvious errors does not satisfy this gate.

Gate 62 — Cognitive complexity is checked, not only cyclomatic. A function can have low cyclomatic complexity and still be nearly unreadable — deep nesting, mixed levels of abstraction. Confirm a cognitive-complexity rule (e.g. eslint-plugin-sonarjs's cognitive-complexity, threshold ~15) or an equivalent for your language is active.

Gate 63 — Duplicate code is measured, not eyeballed. A copy-paste detector (e.g. jscpd) runs in CI with a real threshold, not "we'd probably notice." Check the actual duplication percentage reported on the last run.

Gate 64 — Dead code is swept regularly. A tool that builds the project's actual dependency graph (e.g. Knip for JS/TS) finds unused exports, files, and dependencies — and someone actually acts on its output, not just that it's installed.

Gate 65 — Module boundaries are enforced by a tool, not a convention. "Own the interfaces, let the agent own the insides" (the guide's Section 10) only holds if something actually blocks a violation. Confirm a boundary-enforcement tool (dependency-cruiser for JS/TS, import-linter for Python, or equivalent) is configured with real rules and runs in CI — not just documented as a preference nobody checks.

Part N — Long-term health & change hygiene

Gate 66 — Dependency updates are automated, not manual. Dependabot (automatic security-patch PRs) or Renovate (routine version bumps, scheduled and grouped) is actually configured — not "someone remembers to check occasionally." A major-version bump is treated as a real task (changelog read, full test suite run before merge); a patch bump can be near-automatic.

Gate 67 — Tech debt and dependency choices are reviewed on purpose, periodically. A lightweight practice exists — a Tech Radar (ranking tools/libraries/patterns adopt / trial / assess / hold) or equivalent — so a dependency an agent introduced months ago gets revisited deliberately instead of forgotten until it breaks.

Gate 68 — A cross-tool AGENTS.md exists, not only a tool-specific file. Confirm the standing-instructions file works for more than one agent/tool, or at minimum that a Claude-specific CLAUDE.md imports a shared AGENTS.md (via @AGENTS.md) rather than duplicating the same rules in two places that can drift apart.

Gate 69 — Secrets rotate on a schedule, and immediately on offboarding. Beyond simply being stored in a secrets manager: check there's an actual rotation cadence, and that it's triggered automatically — not eventually — when someone with access leaves.

Gate 70 — Public APIs/schemas are versioned, with a deprecation window and a changelog. If anything external depends on your API — a business customer's integration, your own frontend deployed separately from your backend — confirm a breaking change doesn't land the moment new code merges, and that there's a plain-language record of what changed.

Gate 71 — Changes stay scoped; drive-by fixes are logged, not silently bundled. Sample a handful of recently merged changes: does each do one thing, or do some quietly bundle an unrelated fix or refactor the agent happened to notice along the way? Confirm there's a real place to log what was noticed but not fixed — a FOLLOWUP: convention, or a new ticket — rather than it disappearing into an oversized diff.

Gate 72 — Naming and coupling are checked mechanically, not just complexity/duplication (Part M). A naming-linter rule (e.g. eslint-plugin-unicorn's prevent-abbreviations) catches meaningless identifiers; a circular-dependency check (dependency-cruiser or equivalent) catches modules that quietly depend on each other. Spot-check a recent pull request: did one conceptual change require touching an unusually large, scattered set of files ("shotgun surgery")? That's a coupling problem, not a one-off.

Part O — Correctness edge cases & incident process

Gate 73 — Idempotency exists for retried requests. A client-generated idempotency key lets the server recognise and safely ignore a request retried after a network blip — distinct from Gate 59's concurrent-different-user race check; this one is the same request arriving twice.

Gate 74 — Time zones and daylight saving are handled correctly. Times are stored and computed in UTC, converted to local time only at render. A test exists for at least one case that crosses a daylight-saving transition.

Gate 75 — Webhook senders are cryptographically verified, not trusted by URL alone. Every inbound webhook (payment processor, calendar integration) checks the sender's signature before acting on the event.

Gate 76 — Incidents produce a blameless postmortem with tracked action items, not just a fix. Check the most recent real incident: is there a written root cause and a list of follow-up items, and were those items actually closed — not only the immediate bug patched?

Gate 77 — AI-agent spend itself is monitored, separately from cloud infrastructure cost (Part J). Confirm there's visibility into what running coding agents actually costs, and that routine/simple tasks route to a cheaper model tier rather than defaulting to the most expensive model for everything.

Part P — Risk register & disaster recovery

Gate 78 — A risk register exists and is genuinely reviewed, not written once and forgotten. Named top risks (data loss, security breach, critical vendor outage, key-person/bus-factor dependency, payment failure, reputational incident) each with likelihood, impact, current mitigation, and residual risk.

Gate 79 — A written disaster-recovery playbook exists for the top risks, not just "we have backups." Check for an actual step-by-step document — who does what, in what order, how success is verified, how customers are told — for at least the data-loss scenario.

Gate 80 — Playbooks are rehearsed, not just written. A "game day" — a scheduled, deliberate simulation of the incident, with the playbook actually followed — has happened at least once, the same discipline Gate 15 already requires for a backup restore.

Gate 81 — Playbooks are kept current, not manually remembered. Check: are they versioned in the repo alongside the infrastructure they describe, and is there a real trigger (a stale-doc check, a recurring calendar reminder tied to a real review) that catches a playbook nobody has touched since the infrastructure moved on?

Gate 82 — Bus factor is addressed. More than one person — or a documented-enough playbook a competent outsider could follow — can actually operate an incident response, not only the founder, from memory.

Gate 83 — Ransomware has its own countermeasure, distinct from ordinary backup isolation. At least one backup copy is genuinely immutable (write-once, cannot be altered or deleted for a set window, even by a compromised admin credential) — Gate 16's credential isolation alone is not sufficient. Recovery uses infrastructure-as-code to rebuild a clean environment rather than attempting to clean a compromised host. Cyber insurance has at least been priced and considered.

Gate 84 — Special-category data is identified explicitly, not collected by accident. Scan actual field names/comments/form inputs for anything touching GDPR Article 9 categories — health, biometric, genetic, racial/ethnic origin, religious/philosophical belief, political opinion, trade union membership, sex life/sexual orientation — or criminal-record data (Article 10). A salon's "allergy" or "skin condition" note field is health data under GDPR, not ordinary data.

Gate 85 — Special-category data has its own, separate legal basis. Usually explicit consent, captured on its own, not bundled into general terms acceptance. Confirm this exists wherever such a field is collected, and that a DPIA (Datenschutz-Folgenabschätzung, GDPR Art. 35) has at least been considered for it.

Gate 86 — International legal variance is tracked before it's needed, not discovered after. If serving customers or storing data outside Germany: the UK has its own UK GDPR (separate regulator, the ICO, possibly a UK representative requirement); Switzerland has its own FADP/nDSG, in force since September 2023 (similar to GDPR but a distinct law and adequacy assessment); the US has no single federal law, only state-level rules (e.g. California's CCPA/CPRA) that typically only apply above a size threshold. Confirm someone has actually checked which of these apply, rather than assuming GDPR compliance covers every market.

Gate 87 — If the product itself makes AI-driven decisions about customers, the EU AI Act is checked against what the feature actually does. Recommendations, automated risk scoring, or anything beyond a human coding agent building the app. A 2026 "Digital Omnibus" agreement pushed the high-risk-system deadline to December 2027, but transparency obligations for AI-generated content (Article 50) are active from August 2026 — this is a live, phasing-in area, not a settled one; re-check it periodically rather than once.

Gate 88 — A new personal-data field cannot merge silently. An automated check (even a simple keyword scan of new schema columns and form fields against Gate 84's category list) runs in CI and flags a match for human review — a legal regression is gated with the same seriousness as a failing test, not left to someone noticing later.

Part R — Infrastructure redundancy, failover & SLA evidence

Gate 89 — Multi-AZ (availability zone) redundancy is confirmed configured, not assumed. Check the actual infrastructure config — "the cloud provider probably handles it" is not verification.

Gate 90 — Multi-region vs. multi-cloud is a deliberate, documented decision, not a default. For most small-to-mid products, true multi-cloud active-active isn't worth the engineering cost; if you've chosen not to build it, it's written down as an accepted risk with a specific threshold (revenue, customer count, a past incident) that would trigger revisiting it.

Gate 91 — Automatic failover is configured if uptime genuinely matters beyond single-instance risk. DNS-based health checks (e.g. AWS Route 53, Cloudflare Load Balancing) that redirect traffic away from an unhealthy origin — confirm it's actually wired up and has been tested to fail over, not just theoretically available.

Gate 92 — SLA compliance — yours and your vendors' — is tracked by an independent third party, not self-reported. A third-party uptime/status-page service provides the timestamped record used both to demonstrate your own commitment to customers and to catch a vendor breaching theirs.

Part S — Capacity planning & load testing

Gate 93 — Load, stress, soak, and spike tests have actually been run, not assumed from a single load test. Each catches a different failure mode (expected peak, the real ceiling, slow resource leaks, sudden bursts) — confirm evidence of at least the load and stress tests for a real launch.

Gate 94 — The four golden signals are monitored with a leading-indicator alert threshold, not only a failure-point one. Latency, traffic, error rate, and saturation are tracked; an alert fires at a defined early threshold (e.g. 70% of a capacity ceiling), not only once something has already failed.

Gate 95 — The next scaling step is matched to a measured bottleneck, not built speculatively. Check that the most recent scaling change (bigger instance, added caching, a queue, multi-region) was justified by an actual saturation signal from Gate 94 — not "we might need it eventually."

Part T — Accessibility: keyboard & power-user shortcuts

Gate 96 — Core keyboard-operability WCAG criteria are verified, not self-reported. Manually tab through the product's main flow: every interactive element is reachable and operable (2.1.1), focus never gets trapped (2.1.2), tab order is logical (2.4.3), the focus indicator is always visible (2.4.7), and no sticky element fully covers the focused item (2.4.11).

Gate 97 — Single-character keyboard shortcuts comply with WCAG 2.1.4 and are discoverable. Any single-key shortcut can be turned off or remapped, or requires a modifier key, or only fires when a specific component has focus — confirm it isn't global-and-unconfigurable. A visible way to see the full shortcut list exists (not just tribal knowledge).

Part U — Platform-currency check

Gate 98 — Recent UI work is checked against current platform capabilities, not assumed to need a JS library. Spot-check a recently built interactive component (carousel, modal, tooltip, responsive layout) against what the current web platform can do natively for your actual target-browser support matrix — flag it if a heavier, older pattern was used where a native one (with a documented @supports fallback) would now do the job in less code.

Part V — Manual-test playbooks, living docs & redundancy economics

Gate 99 — Every manual-verification gate in this protocol has a corresponding written playbook. Not "test it by hand" as the entire instruction: preconditions (test accounts/seed data), exact numbered steps, the expected result at each step, how to reset what the test touched, and a visible last-verified date and owner. Spot-check one (the IDOR test, Gate 27, is a good one) — if it doesn't exist as a literal file, this gate fails.

Gate 100 — A living HTML docs site exists, built and published by CI on every merge. Check it actually covers: architecture and decisions (rendered from docs/adr/), how the pipeline works for this specific project, an access/role matrix, links to the real legal/cost state, links to live monitoring, and an onboarding page detailed enough for a cold start. A hand-maintained wiki that isn't rebuilt from the repo on every merge does not satisfy this gate — it will drift.

Gate 101 — Every genuine single point of failure has an explicit, documented redundancy decision. For each (a payment provider, a critical SMS/email provider, a hosting provider), confirm there's a recorded likelihood × impact estimate weighed against the real cost of redundancy — not silence, and not reflexive over-building. The decision is either "build it" or "accepted risk, revisit at [stated threshold]."

Gate 102 — Any redundancy or failover path that exists has actually been exercised. A second payment provider nobody has ever routed a real transaction through, or a failover nobody has actually triggered, is not a working backup — apply the same rehearsal discipline as Gate 80's game days.

Part W — Product discipline

Gate 103 — A written target-audience and problem statement exists, and is actually used. Check context.md or equivalent for who the product is for and what problem it solves. Then check whether the last few features built were ever checked against it, or just built on momentum.

Gate 104 — Feature requests are logged as the underlying problem, not the literal ask, and deduplicated. Sample the feedback/feature backlog: are similar requests collapsed into one signal, or scattered as near-duplicates that make demand look smaller than it is?

Gate 105 — A real prioritization method is used and can be pointed to. For the last few shipped features, confirm there's a reason beyond "who asked loudest" or "whoever was in the room" — a scoring method (e.g. reach × impact × confidence ÷ effort), or at minimum a written rationale.

Part X — UX integrity & platform-currency tooling

Gate 106 — A dark-pattern review is part of the standard review process. Checked against a real, structured reference — ideally a checklist where each entry has a name, a detection heuristic, an ethical alternative, and the specific legal risk, not just a vague "avoid manipulative UI." Public option: deceptive.design. Sample a recent flow (signup, cancellation, upsell) and confirm nothing on the list is present. The same structured-checklist treatment is worth building for other pattern-heavy domains (auth, forms, notifications, onboarding, error states) once you have one working example.

Gate 107 — Heavy interactive widgets use a facade/lazy-load pattern. Check actual bytes of JavaScript shipped before the user has interacted with a component like a video player, map, or rich editor — a naive load-everything-upfront implementation fails this gate.

Gate 108 — The product respects prefers-reduced-motion and a data-saving signal where relevant. Confirm animations are reduced or removed under prefers-reduced-motion, and that Save-Data/prefers-reduced-data (where the feature genuinely has a lighter mode to offer) is actually checked, not just theoretically supported.

Gate 109 — A platform-currency tool is actually wired into the agent's workflow, not just known about. A Baseline-aware skill/tool (e.g. Modern Web Guidance) or an equivalent up-to-date-documentation habit is installed and used, not just mentioned in a conversation once.

Gate 110 — The living docs site's architecture page includes an actual, current system diagram. Kept as diagram-as-code (e.g. Mermaid) reviewed in pull requests — a stale PNG nobody has updated since the last major refactor fails this gate.

Part Y — Challenge, not compliance

Gate 111 — UI flows are checked against established patterns, not only against dark patterns. For a recently built flow (checkout, search, pagination), confirm a known pattern (Nielsen Norman Group, Material Design, or an equivalent catalogue) was checked before a bespoke one was built — and that any deviation is a documented, explained choice.

Gate 112 — Consequential decisions get a real counter-case, not a rubber stamp. Sample a handful of recent non-trivial decisions (a UX pattern, a technology pick, not only architecture). For each, is there evidence a genuine counter-argument was produced and considered — a second agent or reviewer explicitly tasked with arguing against it — or did the first proposal simply ship?

Gate 113 — A session with zero agent pushback is treated as a signal to check, not a sign of a smooth run. If recent session logs show the agent agreeing with every request with no friction, sample one and verify a consequential decision wasn't quietly accepted without the trade-offs actually being surfaced.

Gate 114 — An agent grades pattern implementation quality, not only presence of the obviously bad ones. Using ux-pattern-catalogue/ (or an equivalent structured checklist), point a reviewer agent at the checklist matching a given feature — forms, auth, notifications, error states — and have it verify the implementation actually matches a known-good pattern's howToDetect criteria, not merely that no dark pattern is present. Absence of harm is a lower bar than presence of quality; this gate is about the second one.

Part Z — Agent-side guardrails & autonomous loops

Gate 115 — Agent extensions are vetted like dependencies. Every third-party skill, plugin, and MCP server the team's agents use has been reviewed before install (what it reads, what it can write, where it sends data, who maintains it), is pinned to a version rather than tracking "latest," and gets re-reviewed on update. There is an actual list of what's installed — an extension nobody remembers adding is a FAIL, same as an unaudited dependency.

Gate 116 — Destructive-command guardrails are enforced hooks, not conventions. A pre-tool-use hook (or equivalent) actually blocks destructive commands — rm -rf, DROP TABLE-style statements, force-pushes — before execution. Read the hook config/script itself; a rule that only exists as a sentence in AGENTS.md is a FAIL, because a prompt-injected agent ignores sentences, not hooks.

Gate 117 — Any autonomous issue→PR loop has verified safety rails. If an agent picks up approved issues and opens pull requests unattended (e.g. via a CI-hosted coding agent): the trigger is an explicit human signal (label/assignment/mention), branch protection on main requires passing checks plus human approval so the agent can never merge its own work, runs are scoped to one issue with turn/time caps, the agent's credentials cannot reach production, and notifications fire only on blocked/complete/failed. Verify each rail in the actual config — branch-protection settings, workflow file, notification rules — not from the workflow's description.

Part AA — Observability & tracing

Gate 118 — Money paths emit structured, correlated, secret-free logs. Trigger the product's most revenue-critical flow (signup-to-payment, a booking) in staging or production and inspect the resulting log output. Confirm the lines are structured (machine-parseable JSON or key-value pairs, not free-text prints) and carry one correlation/request ID that survives across every service and background job the request touches — so the whole request's story is a single query, not archaeology. Then grep that same real output for credentials: API keys, session tokens, Authorization headers, card-number fragments. Gate 55 covers personal data in logs; this check covers secrets. Verify from actual captured output, never from the logging library's documentation.

Gate 119 — Application metrics beyond web vitals exist and are graphed. Business- and application-level metrics — bookings created, payment success rate, queue depth, job duration — are emitted and visible on a dashboard someone actually opens. Open the real dashboard and confirm the graphs show current data. Instrumentation code whose output has never been graphed fails; browser web-vitals alone (a frontend concern) do not satisfy this gate.

Gate 120 — Error tracking is wired to production and alerts a human. Throw a deliberate test exception (in production or in staging running the production config) and watch it arrive in the error tracker (Sentry or equivalent) within minutes. Confirm a new or regressed error type triggers a notification to a channel a human actually watches — not silent accumulation in a dashboard nobody opens — and that symbolication/source maps work, so the report points at real code, not minified line 1.

Gate 121 — A trace can be produced for one slow request. Take one actual slow request and show where the time went — database, external API, serialization — via distributed tracing or, at minimum, per-request timing spans. Actually produce the trace once as the verification. "We have OpenTelemetry installed" without a produced trace is a FAIL.

Part AB — Alerting & on-call

Gate 122 — A 3 a.m.-grade alert reaches a human — test-fire it. Trigger a test alert through the real paging channel (a phone push or call via PagerDuty/Opsgenie or equivalent — not an inbox) and confirm it reached the person responsible. Alerting that terminates in email or a muted chat channel fails. Record who received it and how long it took as the evidence. This upgrades Part J's "real alerting" bullet and Gate 94's golden-signal thresholds with proof the last mile to a human actually works.

Gate 123 — A two-tier severity policy exists in writing, and every alert links a playbook. A written policy distinguishes page-now (a customer-facing money path is down) from next-business-day (degraded, non-urgent) — check that recent alerts were actually classified by it. Then read the alert definitions themselves: each carries a link to the playbook for that alert (Part P's discipline applied at the alert level). An alert with no documented response is noise, and noise trains people to ignore the pager.

Gate 124 — The customer-facing status update path is rehearsed. It is decided and written down where customers look during an outage (a status page, an in-app banner, an email list), who is authorized to post there, and roughly what the first message says. Confirm a test or draft update has actually been posted through the real mechanism at least once — this is the "how customers are told" step of Gate 79, rehearsed with Gate 80's game-day seriousness rather than improvised mid-incident.

Part AC — SLOs, capacity & cost

Gate 125 — An availability target is written down and an error budget derived from it. A stated number (e.g. 99.5% monthly ≈ 3.6 hours of allowed downtime) exists in the docs, and someone can say how much of the current period's budget is spent — measured against Gate 92's independent uptime record, not a feeling. A target nobody compares reality against is decoration, not an SLO.

Gate 126 — Measured capacity limits are documented where planning happens. Additive to Gates 93–95: the numbers those tests produced — the ceiling in requests/second or concurrent bookings, and which resource breaks first — are written in the docs the team actually plans from, with current utilization stated against that ceiling. If Gate 93's tests were never run, this gate fails by dependency; if they were run but the results live only in a chat thread, it fails on documentation.

Gate 127 — Spend is bounded by alerts and understood per user. Every paid service — cloud, email/SMS, error tracking, external APIs — has billing alerts at two thresholds: an early-warning level and a hard "something is wrong" level. Verify in each provider's actual billing console, not from memory; this upgrades Part J's cost-alert bullet into a per-service requirement (AI-agent spend specifically is already Gate 77). Separately, a rough unit cost per active user or per transaction is known and has been reviewed at least once against pricing — "we'll look when the invoice hurts" fails.

Part AD — Background jobs & scheduled work

Gate 128 — Scheduled jobs are monitored for absence, and failures dead-letter loudly. For every cron/scheduled job, a monitor alerts when the job doesn't run (a heartbeat/dead-man's-switch check — silently-not-running is the failure mode nobody sees, and reminder emails that quietly stopped weeks ago are the classic case). Verify by deliberately skipping a run in staging and watching the alert fire. Failed jobs retry using idempotency keys (Gate 73's discipline applied to jobs) so a retry can never double-charge or double-send, and after final failure they land in a dead-letter queue that alerts a human — read the actual queue and alert config, not the framework's feature list.

Gate 129 — Transactional and marketing email are separated, and bounces/complaints are handled automatically. Password resets and booking confirmations send through a different stream than marketing (separate provider, subdomain, or at minimum a separate IP/reputation stream in the same provider) — so a marketing-reputation problem can never block the emails the product depends on. Hard bounces and spam complaints automatically suppress future sends to that address; verify the suppression list exists and actually receives entries, and cross-check that Part J's SPF/DKIM/DMARC bullet is configured for both sending domains.

Gate 130 — Marketing consent is double opt-in, and provable. Not legal advice. Under §7 Abs. 2 UWG, email advertising requires the recipient's prior express consent (the narrow existing-customer exception of §7 Abs. 3 UWG has four cumulative conditions — if it's relied on, confirm each is documented per recipient). Double opt-in isn't the statute's literal wording, but it is the de-facto evidentiary standard in German case law: an unconfirmed sign-up doesn't prove consent (BGH, I ZR 164/09). Verify by subscribing a test address: no marketing email arrives before the confirmation link is clicked, and the stored consent record contains timestamp, origin, and the consent-text version — Gate 60's consent-versioning requirement applied to email.

Part AF — Reach: SEO & i18n

Gate 131 — Indexability is intentional, metadata is present, and the sitemap is generated in CI. Check robots.txt/meta-robots against a written intent list: public marketing pages indexable; app, staging, and admin surfaces deliberately not (a staging site indexed by Google is a real leak — check what's actually indexed, not what you intended). Every public page has a unique title, meta description, canonical URL, and Open Graph/social-card tags — verify by fetching the rendered HTML of real pages, not by reading the template. The sitemap is generated by CI from actual routes on every deploy, not a hand-maintained file that drifts.

Gate 132 — Strings are externalized and a second locale actually renders. Even if only one language ships at launch: user-facing strings live in locale files, not hard-coded in components — grep a sample of components for literal sentences. Then prove it end-to-end: switch to a second locale (a real translation or a pseudo-locale of lengthened strings) and click through the main flow. Layout survives longer strings, dates/numbers/currency format per locale, and no hard-coded fragments show through. Retrofitting i18n after launch is one of the most expensive routine refactors there is; this gate is cheap now and brutal later.

Part AG — Payments lifecycle

Not legal advice. Additive to Gate 41 (PCI scope) and Gate 43 (invoicing) — read those first and don't double-report.

Gate 133 — SCA/3-D Secure is active on EU card flows. PSD2 requires Strong Customer Authentication for remote electronic payments when both the card issuer and the acquirer are in the EEA; 3-D Secure 2 is the standard card mechanism. Verify in the payment processor's actual dashboard that 3DS is requested where required (e.g. Stripe's SCA rules), then run one test card that forces a 3DS challenge and confirm the checkout completes it. Exemptions (low-value, transaction-risk analysis) are negotiated between processor and issuer — the failure mode to catch is 3DS disabled or bypassed by a custom flow, which surfaces as spiking declines and shifted fraud liability. The successor framework (PSD3/PSR) keeps the SCA requirement, so don't build against its absence.

Gate 134 — Failed renewals have a dunning sequence; disputes have a playbook. A failed subscription payment triggers a configured recovery sequence — smart retries, card-update emails, a defined final cancellation date — read the actual dunning config in the billing provider, then force a failure with a decline test card and watch the sequence start. Separately, a written chargeback/dispute playbook exists: who gets notified, what evidence is submitted, within what deadline — and the notification actually fires (test the webhook), because a dispute nobody sees is an automatic loss.

Gate 135 — VAT/OSS status is checked against actual cross-border sales. Pull the real revenue data, not the assumption. Cross-border B2C sales of goods or digital services into other EU countries above the EU-wide €10,000 net threshold per calendar year mean VAT is due at each customer's local rate — the One-Stop-Shop (one registration, one quarterly return via the home tax authority) is the standard way to handle it; below the threshold, home-country VAT may be charged. Confirm someone has actually run this check against real numbers and that checkout applies the right VAT rate per country. Note the German Kleinunternehmerregelung (§19 UStG — since 2025: ≤ €25,000 prior-year turnover and ≤ €100,000 current-year, with immediate dropout mid-year on crossing) is a separate domestic exemption; relying on it does not settle the cross-border question (the EU small-business scheme, §19a UStG, has its own €100,000 EU-wide cap and its own registration).

Gate 136 — Cancelling online is as easy as signing up. Time both flows for real. If signup is three clicks and cancellation is an email to support, that's a dark pattern (Gate 106) — and in Germany a legal violation: §312k BGB (in force since July 2022) requires a permanently visible cancellation button ("Jetzt kündigen" or equally unambiguous) for consumer continuing-obligation contracts that can be concluded online, reachable without logging in — courts have struck down login walls and buried buttons, and a missing or non-compliant button lets the consumer terminate at any time without notice. Verify by actually cancelling a test account end-to-end, not by finding the button in a mockup.

Part AH — Vendor exit & admin operations

Gate 137 — A tested data-export path exists for every critical vendor. For each vendor whose disappearance or terms change would hurt (payment processor, email/SMS provider, hosting, analytics, the managed database): an export of your data has actually been performed once — not "they have an export feature." Confirm the exported file exists, is in a re-importable format, and covers what you'd genuinely need to migrate (for a payment processor, that includes whether recurring-billing mandates/tokens are portable). This is the practical rehearsal of Gate 60's vendor-risk list and Gate 101's single-point-of-failure decisions.

Gate 138 — Routine operational fixes go through an audited admin tool, not the database console. Gate 11 bans hand-editing production; this gate verifies the sanctioned alternative exists. An admin interface (or at minimum a reviewed, logged script-runner) covers the routine fixes real operations need — resend a confirmation, reassign a booking, issue a refund, correct a customer record. Perform one real test action through it, then read the audit-log entry it produced: who, what, when, old and new value. If the honest answer to "how do we fix a customer's record today" is "open a database client," this gate fails even if Gate 11 nominally passes.

Part AI — Credential storage & application hardening

These three are the gaps an agent-built app is most likely to have while passing every other gate in this document — because nothing above forces you to open the code that handles a password or a user-supplied URL.

Gate 139 — Passwords, if you store them at all, are stored as a slow, salted one-way hash. Argon2id is the preferred choice, bcrypt is acceptable; a per-password salt is mandatory, and plaintext, reversible encryption, or a fast hash (MD5, SHA-1, SHA-256, even salted) is an outright FAIL. Verify by reading the actual signup and password-reset code path down to the line that writes the field — the library import, the hash call, the column it lands in — never from a README or an architecture doc that claims "passwords are hashed." A hosted auth provider (Auth0, Clerk, Supabase Auth, Cognito, your framework's managed service) satisfies this gate on its own, but only after you have grepped for a second, custom password path added alongside it — an admin seed script, a legacy import, a "temporary" internal login — because that is exactly where an agent-written flow quietly stores plaintext.

Gate 140 — User-supplied URLs are never fetched server-side without an allow-list. Anywhere the app takes a URL from a user or a third party and requests it itself — avatar-by-URL, webhook registration, link preview, PDF/image import, an "import from" integration — the destination is checked against an explicit allow-list of hosts, and requests to private ranges (127.0.0.0/8, 10/8, 172.16/12, 192.168/16, 169.254/16, ::1, and link-local/metadata addresses such as 169.254.169.254) are refused, including after redirects and after DNS resolution. This is SSRF (Server-Side Request Forgery — making your server fetch something on the attacker's behalf, typically to reach cloud instance metadata and steal its credentials). Verify by actually submitting http://169.254.169.254/ and a private-IP URL to each such input and confirming both are rejected, not by reading the fetch helper.

Gate 141 — The app sends a Content-Security-Policy and the standard hardening headers. A CSP (Content-Security-Policy — a header telling the browser which sources of script, style, and frames it may load) is present and meaningfully restrictive rather than a permissive unsafe-inline/* policy that permits everything; alongside it, Strict-Transport-Security (HSTS), X-Content-Type-Options: nosniff, a Referrer-Policy, and a frame-ancestors restriction (in the CSP, or X-Frame-Options as the legacy equivalent) that stops the app being framed for clickjacking. Verify with an actual response-header dump from the deployed app (curl -sI https://your-app/ on a real page, plus one authenticated page) — not by reading a middleware config or a framework plugin's defaults, because a proxy, CDN, or cache in front can strip or override what the app thinks it sends.

Part AJ — Data subject rights in practice

Gate 31 requires that user rights exist; Gate 56 rehearses deletion. These two cover the other half — getting data out — which is the half most products promise and never build.

Gate 142 — A data subject can actually obtain their personal data in a portable form (GDPR Art. 20). There is a working export path — self-service in the product, or a documented internal procedure — that returns everything held about one person in a structured, commonly used, machine-readable format (JSON or CSV, not a screenshot or a PDF of a support reply), and it covers the data scattered outside the main table too: bookings, messages, uploaded files, consent records. Rehearse it exactly as Gate 56 rehearses deletion — run a real export for one test user in staging, open the file, and check it against Gate 23's field inventory for anything missing. An export feature nobody has ever run is a FAIL.

Gate 143 — Access and rectification requests have a named owner and a tracked clock. GDPR gives one month from receipt to respond to an access, rectification, or portability request (extendable to three for complex cases, but only if you tell the person inside the first month). Confirm three things concretely: which mailbox or form a request arrives at and that someone monitors it, which named person owns the response, and where the clock is tracked — a ticket, a log, a shared sheet — so an elapsed deadline is visible rather than discovered. "It would come to our support inbox and we'd handle it" is a FAIL, because nothing there starts a timer.

Part AK — Resilience under dependency failure & overload

Part R covers redundancy of infrastructure; these cover how one running process behaves when something it calls is slow, flaky, or down — the failure mode that turns one struggling dependency into a total outage.

Gate 144 — Every outbound network call has an explicit timeout. Database queries, HTTP calls to third parties, cache and queue clients, and calls between your own services all set a connect and a read/overall timeout — no call can hang indefinitely, because most default clients wait far longer than a user or an upstream request will (some wait forever). Verify by grepping every outbound client construction and call site for an explicit timeout value rather than trusting the library default, then prove one: point a staging call at a deliberately unresponsive endpoint (a blackholed IP or a stub that sleeps) and confirm it aborts within the stated budget instead of tying up the worker.

Gate 145 — Retries use exponential backoff with jitter, a bounded budget, and only apply to idempotent operations. Confirm the retry policy in the actual client/middleware config: delays grow between attempts, randomised jitter prevents every client retrying in lockstep (a retry storm that finishes off a recovering dependency), and there is a hard cap on attempts or total time rather than an open-ended loop. Then check what is retried — a retried non-idempotent call is how a customer gets charged or emailed twice, so anything that writes must carry Gate 73's idempotency key before it may be retried at all.

Gate 146 — A non-critical dependency being down degrades the product to a defined reduced mode, not a failed request. Decide and write down, per dependency, what "degraded" means — search falls back to a simpler query, recommendations disappear, the SMS confirmation is queued for later while the booking still completes — and make sure a failing non-critical call can't take the whole request with it (a circuit breaker, a fallback path, or at minimum a short timeout plus a caught error). Verify by actually failing the dependency in staging: block it at the network level or point it at a dead endpoint, then walk the critical user flow and observe what the user gets. Reading the code for a try/catch is not verification — the common finding is that the fallback exists but a timeout of 30 seconds means the user gave up long before it fired.

Gate 147 — Queues and in-flight work are bounded, so overload sheds load in a defined way. Every queue, worker pool, connection pool, and buffer has an explicit maximum, and there is a stated behaviour when a limit is reached — reject with a 429/503 and a Retry-After, drop the lowest-priority work, or apply backpressure to the producer — rather than accumulating unbounded until the process runs out of memory and takes everything with it. Check the actual configured limits (queue maxsize, pool size, body-size and concurrency caps at the proxy), then verify one under load: push more work in than the system can drain and confirm it rejects cleanly and recovers, instead of degrading into an out-of-memory restart loop.

Final report format

Produce a table:

GateStatusEvidenceFix if FAIL
1. Strict types, no suppressionsPASS/FAIL/N-Awhat you actually checkedsmallest concrete fix

Then a ranked top-5 list: of every FAIL, which five would hurt a real customer or the business first if exploited or if it failed right now? Order by that, not by gate number. That list is what you work through next — one item at a time, through the normal grill → plan → build → verify loop, not as one giant unreviewed sweep.

Worked example: a booking product (e.g. a salon-booking app)

A product like this typically stores customer names, phone numbers, and appointment history, plus staff logins and possibly payment details — and if it's sold to salons who each manage their own end-customers, it's multi-tenant B2B SaaS, not a single app. That means:

Run this whole protocol once before the first real salon's customer data enters the system, again before or shortly after adding payments (Gate 41), and again before selling into a new country whose consumer-protection or invoicing rules differ from Germany's.