facebook pixel
FRONTEND DELIVERY FACTORY

Not 10x developers.
10x delivery velocity.

Everyone is racing to ship. We install the system that takes a feature from idea to production without breaking anything.

SPECStructured, scoped
AGENTSSkills on your repo
GUARDSTests, a11y, design system
PRODUCTIONMerged, live

Hiring is slow.
The roadmap is not.

THE QUEUE
Every team waits on the same delivery bottleneck.
NO SYSTEM
Everyone prompts differently. Review becomes the traffic jam.
IT LIVES IN HEADS
Standards, review, releases. One vacation is a risk event.
WHY OURS WORKS

Years inside R&D orgs like yours.

We know where delivery breaks, because we have been there when it broke. Every trap became a guard. That is the harness.

  • Agent invents its own buttonDesign system gate
  • Accessibility quietly regressesA11y gate on every PR
  • User input lands in the DOMSecurity gate on every PR
  • Everyone prompts differentlyVersioned skills
  • Green suite that asserts nothingTest quality gate
  • Bundle quietly doublesPerformance budget in CI
THE HARNESS

The coding agent is the engine. The harness is everything else.

Anyone can buy the engine. What ships features safely is the seven layers we install, tune and keep running on top of it.

FACTORY CONTROL

A factory you can debug.

See which skill ran and which guard stopped it. Change the rule once, and every future run inherits it.

Evals: Every skill scored on your repo, so a change is proven, not felt.
Analytics: Where time goes, what gets rejected, what to fix next.
Storybook: Every component state visible, and gated, before merge.
RUN TRACEone pull request
  • SKILLspec-to-componentran
  • SKILLtest-authorran
  • GUARDdesign-systempassed
  • GUARDaccessibilityblocked
PATCH THE SKILL
The guard that blocked this run becomes a rule the skill obeys from now on.
THE LOOP

Every merge makes it sharper.

Knowledge stops walking out with the contractor. It compounds in the repo, in the skills, in the guards.

SHIPA feature mergesTRACEThe run is recordedLEARNA gap becomes a ruleUPGRADEThe skill gets betterKNOWLEDGECOMPOUNDS
THE ENGAGEMENT

We run it. Then you own it.

  1. 01
    Audit
    Where your hours actually go.
  2. 02
    Pilot
    One real feature, end to end.
  3. 03
    Run
    We operate it, your team inside it.
  4. 04
    Own
    Playbooks, configs, trained team.

The people who run those four stops are our forward deployed engineers. How the deployment model works →

Built for orgs where delivery is the bottleneck.

See it run on
your own code.

One real feature, through the whole system. That is the pilot.

Get a Factory Assessment
Factory Assessment

Bring one spec from your backlog.

Tell us where delivery is stuck: the queue behind your team, the review load, the AI output nobody can safely merge.

We audit the repo and the workflow, then run one real roadmap item through the pipeline, so you judge the factory on shipped code and not on our slides.

What happens next
  1. 01

    You send the form.

    Your stack, your team size, where delivery jams.

  2. 02

    We reply within a day.

    A short call to see whether the factory fits.

  3. 03

    We scope the assessment.

    Repo, workflow, and the first feature to pilot.

0/2000

Your info stays with us. That's it.

FAQ

Questions, answered.

The ones that come up once a team is actually evaluating: how it gets delivered, how it gets measured, what it costs, and whether it fits inside your constraints.

  • A.

    A forward deployed engineer, FDE, is an engineer who works inside your org rather than beside it. Same repo, same sprint, same Slack, same standup. The model comes out of enterprise deployment work and the AI labs have made it the default way serious AI capability gets installed, because the hard part was never the model, it was the last mile into a real codebase with real constraints and real people. The factory has the same shape. It is not a deliverable we hand across a table, it is infrastructure that has to be fitted to your architecture, your design system, your CI and your review culture, and then operated until the habits stick. Our FDEs install it, run it with your team inside the loop, teach it, and hand it over. The engagement is designed to end.

  • A.

    Seats give every engineer an engine. They do not give the org a line. A coding agent will happily produce a plausible component that ignores your tokens, duplicates a hook that already exists and ships without a test, and the seat has no opinion about any of it, so the cost lands on whoever reviews it. That is why teams frequently see output go up and merged throughput stay flat after a rollout. The factory is the part the seat does not sell you: context the agent reads before it writes, skills maintained per repo, guards that decide mergeability before a human is involved, telemetry on every run, and a loop that turns each failure into a permanent guard. You keep the seats. We make what they produce mergeable.

  • A.

    Eventually, yes, and that is exactly what handover is for. The reason it is rarely where a team starts is that the platform group is being asked to absorb a second category of user this year while still serving the first one. Platform engineering spent five years building for humans: golden paths as templates a person reads, a catalog a person browses, a paved road a person chooses to walk down. An agent does not read, browse or choose. A golden path only constrains an agent if it is executable, which means the path becomes a contract the agent dispatches against and a CI check is what enforces it, and that is a rewrite of the artifact rather than a new page in the developer portal. The layer around it is genuinely new work: a gateway that decides which tools an agent may call, a substrate where a run is sandboxed and reproducible, autonomy bounded per repo rather than declared per org, evals, and traces that outlive the run. The industry has started calling the destination an agentic development platform, and Gartner’s forecast that over 40% of agentic AI projects will be canceled by the end of 2027 attributes the failures to escalating cost, unclear value and inadequate risk controls rather than to the models. That is a governance failure, and it is what building this layer in the gaps between quarterly platform commitments produces. What we bring is that it exists already and it is Frontend-shaped, which is the part a general platform team is least equipped to specify: what mergeable means for a component, which token, which state, which accessibility contract, what a route may weigh. We install it inside your platform rather than beside it, on your CI and your conventions, and your platform team owns it at the end. If your platform group has the roadmap space to build it themselves, take the audit and the guard set and skip the rest. That is a real answer and we give it.

  • A.

    Worse, and predictably so. Every major tool shipped fleet execution in 2026: Claude Code Agent Teams running agents on isolated branches, Cursor composing several agents at once, Copilot dispatching background sub-agents from a single instruction, multi-agent sessions in VS Code. All of it scales the half of the pipeline that was never the constraint. Generation was already cheap. Deciding what is safe to merge was the expensive part, and a fleet multiplies the queue in front of that decision without adding a single reviewer. The teams operating fleets at real volume built the merge side first, which is why an org like Stripe can absorb over a thousand agent-authored pull requests a week and why Ramp can have roughly a third of its merged PRs come from agents, rather than drowning in them. The factory is that merge side: guards that decide mergeability before a human is involved, a review agent that runs first, evals and telemetry on every run, and one shared context the whole fleet reads so five agents do not each invent a different answer to the same question. Turn the fleet on after that, not before.

  • A.

    It is the front half of it, yes. Spec-driven development means the acceptance criteria, architectural constraints and domain rules are written down and handed to the agent, so it codes against a specification and validates against it, instead of being re-prompted until the output looks right. That is exactly what the structured specs in the factory are, and it is why PRs from a factory land smaller and more focused. The part teams underestimate is what falls out of it for governance. Once the spec is an artifact and every guard, eval and agent run is traced, you stop having to reconstruct after the fact what an agent was allowed to touch, what proved its output was mergeable, and who approved the merge. That trail is what an ISO 42001, NIST AI RMF or SOC 2 reviewer asks for when agent-written code reaches production, and it is generated as a by-product of shipping rather than assembled the week before the audit. We produce the evidence and wire the controls. We are not auditors and we do not certify anyone.

  • A.

    Because all of those are descriptions, and a description does not decide anything. This is the rare case where the research is unambiguous: a CHI 2026 comparison of three ways to hand an agent a design system found that describing the rules in the prompt landed around 71% compliance, injecting the style guide into context around 85%, and pointing the agent at a registry of real, pre-built components around 95%. Description loses to retrieval, and retrieval loses to giving the agent the actual component. Most teams are doing the weakest of the three and concluding the agent is careless. Keep the DESIGN.md, it is a good artifact and it belongs in the repo beside AGENTS.md and CLAUDE.md, but stack the other layers on top of it: your real component registry and Storybook metadata served to the agent over MCP so it queries the true prop API instead of inventing one, and then the piece none of them provide, which is a gate. Raw hex values, off-scale spacing and a hand-rolled duplicate of a component that already exists fail the run in CI. The agent never gets to negotiate with a guard, which is exactly why the guard works and the style guide does not.

  • A.

    A gate, and it is worth being precise about which hole, because the published measurements point somewhere most teams do not look. Veracode’s 2025 GenAI Code Security Report tested over 100 models across 80 curated tasks and found 45% of the AI-generated code it evaluated introduced a security flaw, and the worst single category in the entire set was cross-site scripting, where only around 12% of AI-written solutions came back secure. XSS is a Frontend defect class. The sharpest edge of the AI code security problem is sitting in exactly the layer the factory just opened up to more people. What makes it dangerous is how boring it looks: user input reaching the DOM without escaping, dangerouslySetInnerHTML reached for because it silenced a type error, a Content Security Policy loosened to unblock a build, an API key that ends up in the client bundle. None of those look wrong in a diff, and nobody catches them skimming a 400-line agent-authored PR. Asking reviewers to be more careful is not a control, it is a wish. So this is a guard like the others, running on every PR: taint paths from request data into DOM sinks, dangerouslySetInnerHTML and raw innerHTML behind an explicit allowlist with a documented reason, CSP and security headers asserted by tests rather than described in a wiki, secret scanning on the built bundle and not just the repo, and dependency checks on whatever an agent added to package.json. The run fails before a human is involved, and what ran and what it decided is traced, which is the same evidence a governance review wants later. The boundary: we build and operate the gate, we are not a security auditor, we do not run penetration tests, and we do not certify anyone.

  • A.

    It degrades quietly unless you gate it, and that is worth taking seriously now, because the European Accessibility Act applied on 28 June 2025 and enforcement has been ramping across member states since. It reaches e-commerce and consumer-facing digital services sold to EU consumers regardless of where the company is based, and the harmonized standard behind it, EN 301 549, adopts WCAG 2.1 Level AA. The uncomfortable part is the interaction with widening who can ship. Accessibility is the requirement that fails most invisibly: a keyboard trap, a focus ring lost to a custom control, a button with no accessible name, a color pair that misses contrast. Not one of those looks wrong in a screenshot, so it survives review and lands, and an agent given a design and a prompt will reproduce all four without hesitation. So we treat it exactly like the design system: physical, not remembered. Automated checks run on every PR and fail the mechanical criteria before a human is involved, contrast is validated against your committed tokens rather than eyeballed, keyboard and focus-order regressions are caught by tests, and the manual criteria no scanner can cover are routed to the people who can actually judge them. Your pipeline holds the standard instead of a consultant re-establishing it once a year. To be clear about where we stop: we build and operate the gate. We are not an accessibility auditor and we do not issue conformance statements or VPATs.

  • A.

    You are measuring the authoring half of a pipeline whose constraint has moved to the merge half, and the largest study of this says so directly. DORA’s 2025 State of AI-assisted Software Development, published in February 2026 off roughly 5,000 respondents, found that AI acts as an amplifier: it magnifies the strengths of organizations that already had a solid delivery foundation and magnifies the dysfunction of the ones that did not, and that it lifts throughput while often costing stability where that foundation was missing. Ninety percent of respondents were using AI in their daily work. So the tools are doing exactly what they promised and your line still is not moving, because more code arriving faster at an unchanged review and release process is not a delivery improvement. It is a bigger queue. The second half of the problem is the instrument. Deployment frequency and lead time were designed for a pipeline where a human wrote every line, and they quietly stop measuring what you think they measure once a large share of committed code is agent-authored. Watch the merge side instead: what a guard caught before a human opened the PR, review rejection rate on agent output, how much of your merged volume comes from outside the Frontend team, and the stability numbers read beside the throughput ones rather than after them. That pairing is the point. Throughput without stability is not speed, it is debt arriving sooner. It is also why the audit takes your baseline before anything is installed, and why the factory instruments itself rather than reporting on itself.

  • A.

    Neither, at least not first. A suite nobody trusts is not a testing problem, it is a signal problem, and adding tests to it makes the signal worse. So the audit sorts the suite before anything is generated: which tests have ever caught a real regression, which ones only fail when CI is busy, which ones are asserting on implementation detail and will break on the next refactor regardless of whether the behavior held. The ones that have never failed for a real reason are not free, they are the reason your team learned to re-run the pipeline instead of reading it. Then the guard goes on, and it is deliberately not a coverage number. Coverage counts lines a test walked past. What we gate on is whether a test can fail: mutation checks on the paths where a silent break would actually cost you, assertion quality on changed lines so a test that renders a component and asserts nothing does not pass as coverage, test impact analysis so a PR runs the tests that relate to it rather than all of them, flaky tests quarantined with an owner and a date instead of retried until green, and a rule that a snapshot is never accepted in the same run that changed the component it snapshots. That last one sounds small and it is the one that matters most once agents are writing both sides, because otherwise the agent that broke the behavior gets to sign off on the new expected output. New tests come after that, written against the spec rather than against the diff. To be clear about where we stop: we build and operate the gate, we are not a QA vendor, and we do not sell test headcount.

  • A.

    By sizing it off your current numbers rather than an ideal, and by giving every failure an owner and an escape hatch that leaves a trace. A budget set at what a healthy app should weigh fails on day one, gets muted in week two, and then everyone remembers performance guards as the thing that blocked the release. So the ceiling starts at what your routes weigh today, per route rather than for the whole app, and it ratchets down only when a change actually earns it. The failure message names the diff that pushed it over, which is usually specific and cheap to fix once someone can see it: a charting library pulled in for one sparkline, a second date library added because the agent preferred that API, a component marked client-side that had no reason to be, an icon set imported through a barrel file. An override is available, it needs a reason, and the reason is recorded, so the budget bends without quietly disappearing. Alongside the size ceiling we assert the field metrics against real interactions instead of a synthetic score on a static page, because Interaction to Next Paint is what agent-written React regresses first and a homepage Lighthouse run will never see it. The reason this belongs in the factory rather than in a quarterly performance project is the same reason the a11y gate does: as more people in the org ship UI, the regressions arrive faster than any audit cycle can absorb them, and a standard that lives in a report is a standard nobody is holding. We build and operate the gate. We are not a performance-audit shop, and we do not sell a score.

  • A.

    Both, and in that order, because a guard switched on over an existing mess fails everything on the first morning and gets disabled by Thursday. Start with what the measurement says about the shape of this debt, because it is not the shape teams assume. The largest study of it, a 2026 analysis of 304,362 verified AI-authored commits across 6,275 public repositories and five widely used assistants, ran static analysis before and after each change to attribute what the AI edit introduced. It found 484,606 issues, 89.1% of them code smells rather than outright bugs, and the planning number is that 24.2% of those issues were still present at the latest revision of the repository. The pool of surviving AI-introduced debt went from a few hundred issues in early 2025 to over 110,000 by February 2026. Normal churn does not pay this down, and the reason is that nobody chose to take it on. Ordinary technical debt is a shortcut someone made under a deadline and usually wrote a comment about. This accumulated invisibly in code that compiled, passed review and worked. So we sort before we gate. The audit maps where agent-authored code concentrates, which of it is load-bearing, and which classes of issue cost you something real (a duplicated component that will drift, a data-fetching pattern that will not survive the next refactor, an accessibility or XSS defect that is a liability today) against the ones that are merely ugly. Then the guards go on in ratchet mode, failing on changed lines rather than on the whole repository, so what you touch has to come up to standard and what you do not touch stops getting worse. Remediation rides the roadmap instead of running as its own project, because a cleanup project competes with features and loses every quarter. The non-negotiable part is context. The reason year two looks like year one is that the agents are still reading a codebase whose conventions live in three people’s heads, so they keep regenerating the patterns you are trying to remove. Committed context, a component registry the agent queries instead of guessing, and a guard on changed lines is what bends the curve. We do not sell a cleanup sprint and we do not rewrite your app.

  • A.

    No, and building a second lane is the mistake that undoes the rest of it. One merge standard, one gate, whatever authored the branch. What does change is the shape of what arrives, and there are three worth naming because each takes a different fix. The first is the scaffold. A prototype tool that has never read your repository produces generic output by construction: components that are not yours, a spacing scale it invented, a fourth shade of your brand color, an ad-hoc data layer. None of that is wrong as a prototype and none of it is mergeable, so the instruction we give is that a prototype is a specification rather than a branch. It gets read for intent and rebuilt against your components, which is quick when the agent doing the rebuilding is pointed at the real registry rather than asked to remember it. The second shape is the in-repo edit, and this is the genuinely new one. Figma Make’s GitHub integration, in limited beta since 28 May 2026, installs your dependencies, runs your actual application on the canvas, and turns visual edits into commits and a pull request, and Code Layers, announced at Config on 24 June 2026, holds a two-way link between a cloned repository and the canvas. Those PRs are already against your code and your components, so they usually land close, and they fail on the things a canvas cannot see: a state that only exists in a reducer, a keyboard path, what the change costs in bundle size. Guard-shaped failures, which is the point. The third is provenance. Once four different tools can author a branch, "who wrote this" stops being answerable from the commit author, so authorship and the run behind it are recorded at merge, and that trail is the same one an ISO 42001, NIST AI RMF or SOC 2 reviewer asks for later. What we will not do is soften a gate because a non-engineer hit it. A guard that yields to the author’s job title is not a guard, and design-system drift, accessibility regressions and the XSS class would all enter through exactly that door.

  • A.

    Engineering owns it, and it only stays ownable if it is metered where the work happens, which is infrastructure rather than a decision someone makes in a meeting. Start with why the naive version fails. A seat-based tool gets budgeted like a seat, and then consumption pricing behaves like infrastructure. Anthropic revised its own Claude Code estimate upward on 15 April 2026 to roughly $13 per developer per active day, about $150 to $250 per developer per month for enterprise use, with 90% of users under $30 a day, which tells you the distribution has a long tail and that the average is not the risk. Uber’s entire 2026 AI budget went in four months, reported by Forbes on 17 May 2026 with its CTO confirming, after the tool spread across roughly 5,000 engineers faster than the finance model expected. Now notice what a factory does to that distribution: widening who can ship adds authors to it. So the controls are deliberately boring. All agent traffic goes through a gateway, so spend is attributable per repo, per team, per run and per model instead of arriving as one invoice at the end of the month. Budgets sit on repos and teams, and a run that would cross one is stopped or routed to a cheaper model rather than allowed to finish quietly. Model choice becomes policy instead of habit, so the mechanical passes do not run on the expensive model because someone set it once. Cheap checks run first, which is an economic argument as much as a quality one: a lint, type or design-system failure at ninety seconds costs a fraction of the same failure found by a senior twenty minutes into a review. And the number that gets reported is cost per merged pull request, read beside guard catch rate, because cost per seat tells you what you bought and cost per merged PR tells you what you got. To be explicit about the boundary: we build and operate the metering, the gateway policy and the budget guards. We do not resell tokens, we take no margin on your model spend, and we are not your FinOps vendor.

  • A.

    We write the KPI down before the pilot starts, and it is a KPI about your line, not about our activity. Typical ones: a named non-Frontend person merges a production PR, demo-to-production cycle time measured against your own baseline from the weeks before we arrived, weekly merged-PR volume from outside the Frontend team, and review rejection rate on agent output. All of them are measured on your repo with your numbers, which is the only version worth anything. The factory instruments itself, so every agent run is traced and the eval results are visible to your team, not summarized by us in a monthly slide. If the pilot misses the KPI, that is a finding, and it is cheaper to find it in one team than after an org-wide rollout.

  • A.

    Phased fixed price: audit, pilot, run, hand over. Each stage has a defined scope and a defined output, and you decide at each boundary whether to continue. We do not bill hourly, externally, ever. Hourly billing pays us for the thing you are trying to eliminate, which is time spent, and it makes every efficiency we install a revenue cut for us. Fixed price puts us on the same side of the problem as you. The discovery fee is credited if the next stage starts. After handover, some clients keep an operation retainer to stand up new lines and keep the gates sharp, and that is a decision made at the end, not the shape of the deal at the start.

  • A.

    No, and a factory without them does not work. Someone has to decide what mergeable means in your codebase, and that judgement is exactly what we are turning into guards. Your seniors are the source, and they move from hand-carrying every PR to owning the system that carries them: writing the guards, tuning the gates, reviewing the changes that genuinely need a human, and doing the architecture work that has been sitting behind the review queue for two quarters. The people whose day changes most are the ones outside the Frontend team, because they can now ship at all. Nobody on the Frontend team runs out of work. They run out of other people’s small UI tickets.

  • A.

    Onboarding is a repo problem before it is a training problem, and that is the part teams get wrong. The agent has to be able to run your app, your tests and your Storybook the way an engineer does, so the work is environment access, a scoped branch and PR policy, secrets that never reach a non-engineer’s machine, and a path from a ticket to a running preview that does not require anyone to ask for help. We do that once as infrastructure rather than per person, which is why the second role costs a fraction of the first. The teaching part is short by comparison, usually a working session where the person ships something real, and it is the same session we run as a workshop, because a PM opening a genuine PR is the demo. On review load, the honest answer has two halves. Volume of PRs from outside the Frontend team goes up, that is the point. Review time per PR is what has to come down, and it only does if the guards run first: design-system, accessibility, security, test-quality, performance and a review agent all execute before a human is asked, and anything they catch is returned to the author with a specific reason instead of arriving as a senior’s comment. So a Frontend engineer sees more merged output and fewer PRs that need their eyes. If you install the roles before the guards you get the opposite, and that is the sequence we refuse to run.

  • A.

    The harness is the product, and the harness is not framework specific. Context structure, maintained skills, guards, telemetry and the learning loop are the same shape whatever renders the pixels. What changes is the content of the guards, and that is discovery work in the audit: what your design system actually enforces today, which tests are trustworthy, where the codebase has rules that live only in people’s heads. A codebase with no owned design system is not a blocker, it is usually the first guard we build, because an agent given no constraints invents new ones on every run. We are deepest in React and React Native, and we will tell you plainly at audit if your stack makes a stage more expensive rather than discovering it later.

  • A.

    By never letting it be one project. A rewrite fails because it runs as a second codebase racing your roadmap, and the day the two diverge past a certain point somebody has to choose between finishing it and shipping the quarter. So we do not build a parallel app. The new stack goes in behind the app you are already shipping, one route or one component at a time, both running in the same deployment with the boundary held by routing rather than by a branch. Every slice is separately mergeable and separately revertable, which means the migration has no point of no return and can be paused for a quarter without rotting. The audit does the part that decides the cost: it maps the codebase into the mechanical share and the ambiguous share. The mechanical share is the thousands of near-identical edits an agent is genuinely good at once something has found every site, and finding every site is static analysis work rather than model work. The ambiguous share is the behavior nobody wrote down, the workaround from 2019, the component with four callers that each rely on a different accident of it. That share is a person, and pretending otherwise is where migrations die. Sequencing follows blast radius rather than tidiness: leaf components before shared ones, low-traffic routes before the checkout, and the design system usually first, because migrating onto components nobody owns just moves the drift into a new framework. We do not sell big-bang rewrites, and if the audit says your migration is not worth doing yet we will say so.

  • A.

    That is the honest starting position for most codebases, and it is the first thing the migration budget pays for. Parity is not something a reviewer eyeballs on a diff, because the failures that hurt are the ones a diff cannot show. So parity gets defined as a test before the slice is attempted, never judged after it. On the Frontend that means characterization tests written against the old implementation first, while it is still the source of truth: what it renders, what it calls, what it does on empty, loading, error and offline, what the keyboard does through it. Those tests have to pass against the old code before anyone touches the new one, which is what makes them evidence rather than decoration. Then the seven guards do the rest, and this is where a migration gets more from a factory than from a team: the accessibility guard catches the focus trap that quietly stopped existing, the performance budget catches the route that came back 40% heavier because the new component pulled a second date library, the design-system guard catches the token that became a hex value in translation, and test-quality checks catch the migration agent doing the thing migration agents do, which is loosening a selector until the test goes green. The rule we hold hardest here is the one that already applies everywhere else and matters double during a migration: a snapshot is never accepted in the same run that changed the component it snapshots, because a regenerated snapshot is the test agreeing with the bug in writing. Where behavior genuinely cannot be characterized, we say so, and that slice runs behind a flag with real traffic on both paths rather than being declared done.

  • A.

    There is no published figure and we will not invent one, because the honest answer is that the number is a property of your codebase rather than of your engineers. What sets it is how much of a change can be judged without a person reading it, and that varies enormously between a repo with an enforced design system, trustworthy tests and typed boundaries and a repo where the rules live in three people’s heads. So we measure yours rather than quoting somebody else’s. The audit takes the baseline before anything is installed: how many PRs a senior touches in a week, how much of that time goes to things a machine could have decided (a token that should have been a variable, a missing empty state, a test that asserts nothing, a route that got heavier), and how much goes to the judgment nobody can automate, which is whether the change is the right change. The first share is what the guards take over, and it is usually the larger one. Four things move the number in practice, in the order we install them. Guards that run before a human and return a specific reason to the author, so a rejected change never spends a senior’s attention at all. Context and skills committed to the repo, so the same correction is not re-explained every session and the agent’s first attempt lands closer. Task shape, because a well-bounded change with a written acceptance criterion is reviewable in a glance while a sprawling one is not, whoever wrote it. And review routing, so the changes that genuinely need a senior are the ones that reach them, rather than arriving in the order they were opened. Two honest limits. The ratio has a ceiling that no amount of tooling removes, because some decisions are irreducibly human and those are the ones you are paying a senior for. And a ratio that improves because reviews got shallower is not an improvement, so the number we report always sits beside guard catch rate and review rejection rate on agent output. If those move the wrong way, the ratio is not real.

  • A.

    With evidence taken before anything is installed, because confidence and readiness turned out to be two different measurements. CloudBees published its State of Code Abundance report on 19 May 2026, based on research by TrendCandy across 213 enterprise technology leaders. In it, 92% said they were confident their AI-generated code was production ready, while 81% reported a rise in production issues tied to that same code. Those two numbers are from the same population, which is the finding: self-reported readiness is not evidence of readiness, and the gap is structural rather than dishonest. Two more from the same study explain how it stays open. Only 12% reported having a dedicated governance function, while 46% said the CTO or VP of Engineering carries the accountability when something fails. So the accountability landed on a person and the mechanism did not land anywhere, and a person cannot personally verify what a fleet of agents produces. What we do about it is not a survey. The audit reads what your pipeline can already prove, which is a short list on most codebases: what fails a build today versus what depends on a reviewer noticing, which of your tests would actually catch a regression, what the design system enforces rather than documents, and what evidence exists after a change ships that it behaved. That is the before, it is written down, and it is the thing every later claim gets checked against. This is a different question from proving the AI spend paid off, which is measured on the merge side afterwards. This one is upstream of it: whether the confidence anyone is reporting has anything under it. We do not certify anyone and we do not issue readiness statements. We build the gates that turn the claim into something your pipeline holds, and we tell you plainly at audit which parts of the current claim we could not find evidence for.

  • A.

    It starts by counting rather than by failing, for exactly the reason a performance budget does. A gate switched on at an ideal standard over a codebase that has been accumulating dependencies for six years blocks everything on the first morning and gets disabled by Thursday, and then the team remembers license checks as the thing that stopped the release. So the first pass is an inventory: the full dependency graph including transitive packages, which licenses are actually present, which of them are dual-licensed and under which terms you are using them, and which components arrived with no manifest entry at all. That last set is the one nobody has a list of, and it is where the surprises are. Your legal team then sets the policy, because we do not get to decide it: allowed, denied, and the middle tier that needs a person to look. Only then does the gate go on, and it goes on in ratchet mode like the others, failing on what a pull request changes rather than on the whole repository, so what you touch has to comply and what you do not touch stops getting worse. The checks that earn their place after that are specific. A new dependency in a denied tier fails the run with the package named and the license quoted, which is a thirty-second fix at PR time and a legal conversation six months later. A license that changed under you on an upgrade fails too, because a package relicensing in a minor version is a real event and semver says nothing about it. Transitive introductions are treated the same as direct ones, since your bundle does not care who asked for the package. An SBOM is produced by the build for every release rather than reconstructed for a questionnaire. And code that arrived outside a package manager is flagged for provenance, which is the check no manifest scanner performs and the one that matters most now that agents write the code, because a generated implementation does not carry the header of whatever it learned from. Exceptions exist, they need a reason, the reason is recorded with an owner, and the record is the artifact that makes the whole thing survivable. To be explicit about the boundary: we build and operate the gate, we are not your counsel, we do not give legal advice, we do not clear licenses, and we do not decide your policy.

  • A.

    Whatever your pipeline recorded while the code was being written, which in most companies right now is nothing, and that is the problem rather than the question. Reconstructing this after the fact is the expensive path: someone spends three weeks running a scanner over a repository that has taken two years of agent-authored commits, produces a list nobody can explain, and every entry on it becomes a question you answer from memory. The artifacts that make the conversation short are all by-products of shipping, and they are the same four whether the asker is an acquirer, an enterprise customer with a security questionnaire, or your own board. A component inventory with licenses, generated by the build, current as of the release rather than as of the audit. An SBOM per release, stored, so a claim about what shipped in March can be checked against March. A provenance record at merge saying which changes came from an agent run, which run, and which guards passed before it landed, which is the same evidence trail an ISO 42001, NIST AI RMF or SOC 2 reviewer asks for and it costs nothing extra to have it answer this question too. And the exception log: every place the license policy was overridden, by whom, with the reason. That last one reads as a liability and behaves as the opposite, because a documented decision is a decision, and an undocumented one is a discovery. What we do about it is install the gates that produce those four as a matter of course, and, on an existing codebase, take the inventory first so you know what is actually there before anyone asks. What we do not do is opine on any of it. We are not your counsel, we do not give legal advice, we do not clear licenses or issue IP opinions, and we are not auditors and do not certify anyone. Bring us the policy your legal team sets and we make your pipeline hold it and prove it.

  • A.

    It does, if nobody owns the switches, so the expiry is part of the install rather than a cleanup task for later. Take the mechanism first. The point of the release layer is to separate two things most Frontend pipelines have welded together: deploying code and exposing it to people. Once they are separate, a change can be merged and deployed while off, turned on for your own team, then a cohort, then everyone, and turned back off in seconds by whoever is awake rather than by whoever can run a rebuild. That single property is what changes the cost of being wrong, and it is why we install it after the guards rather than instead of them. Concretely, on a Frontend, it is four pieces. Flags evaluated where the page is rendered rather than after hydration, so a gated change does not arrive as a flash of the old UI and does not cost you a layout shift on every load. A default that is safe when the flag service is unreachable, because a flag system that fails closed on its own outage has just become your most fragile dependency. A kill switch at the level a person actually thinks in, which is a route or a feature rather than a deploy. And a release that accounts for the browsers already running the previous bundle, since a stale client requesting a lazy chunk that no longer exists is the most common self-inflicted Frontend incident there is, and it is entirely preventable with retained assets and a version check that asks the user to reload rather than failing silently. Now the debt, which is a real objection and the reason many teams tried this once and stopped. A flag is a branch in your code, and a codebase with two hundred of them is harder to reason about than one with none, for humans and for agents both. So every flag is created with a type and an owner. A release flag is temporary by definition and gets an expiry date at creation, and the same CI that runs your other guards fails the build when an expired one is still in the code, which turns removal into a normal task instead of a quarterly archaeology project. An operational kill switch is permanent on purpose and is exempt, because it is infrastructure. Experiment flags end when the experiment does. And the flag inventory is part of the context an agent reads, so it stops inventing a second flag for a thing that already has one. The boundary is the same one we hold everywhere else: we build and operate this inside your pipeline, with your flag provider, your error tracking and your analytics. We are not an SRE vendor, we do not carry your pager, we do not run your on-call rotation, and we are not selling you a platform to rent.

  • A.

    By deciding, before the release, what evidence would prove it worked, which is the same discipline the guards apply one stage earlier. Most Frontend teams have no alerting for a reason worth naming rather than apologizing for: the failures do not look like failures to a server. A broken handler returns 200. A form that rejects a valid input in Safari returns 200. A chart that renders empty for your largest accounts returns 200, twice. So the signal has to come from the client, and it has to be attached to the release rather than averaged over a week. Four things carry it, and none of them are exotic. Client error rate per release, keyed to the deployed version, so a rise shows up as a comparison instead of as a number nobody has a baseline for. Field performance on the routes the change actually touched, which means Interaction to Next Paint, LCP and CLS from real users, because the performance budget in CI proves the bundle did not grow and only real devices on real networks prove the interaction stayed fast. The one funnel step the change was supposed to affect, watched for the cohort that has it on against the cohort that does not, which is the only version of this that survives a seasonal Tuesday. And an explicit answer to "what would make us turn this off", written down before the flag is opened, because a threshold agreed in advance is a decision and a threshold argued about at 6pm is an incident. What that buys is the number the industry measures and most teams cannot move: CircleCI put median recovery at 72 minutes in its 2026 report, up 13% year over year, and the reason recovery is slow is almost never that reverting is hard. It is that nobody is sure yet, so the first forty minutes go to deciding whether something is actually wrong. Pre-agreed evidence and a switch that takes seconds is what collapses that. Two honest limits. Instrumentation is not free and we do not pretend otherwise: it is a real slice of the install, and on an existing product the first pass usually finds that the events you already send cannot answer a release question because they were designed for a funnel. And we build and operate this layer with your tools rather than replacing them. We are not an SRE vendor, we do not take your on-call, and we do not sell an observability product.

  • A.

    Because those answer a different question at a different point in time, and neither substitutes for the other. A vulnerability scanner tells you that a package you already depend on has a known flaw, and it can only tell you that once somebody has found the flaw, filed it and published an advisory. The package in this scenario has no advisory, because it was published on Tuesday for exactly this purpose, and by the time it has one your CI has already run its install script. So four questions get asked at the moment a name enters the repository, before anything else happens. Does this package exist, and did it exist last week? A dependency whose first publish is recent, whose download history is flat, whose repository field points nowhere and whose maintainer list is a single account created this month is not necessarily malicious, and it is precisely the profile of the ones that are, so the run stops and a person looks. Is this the package you meant? The documented Frontend case is unused-imports against eslint-plugin-unused-imports, one word apart, and no scanner reading a manifest of installed packages will ever raise it, because both names resolve perfectly well. What runs at install time? Lifecycle hooks are off by default for anything newly added and enabled only by allowlist, which is the single highest-value setting in this whole area and the one most repositories have never touched. And what did the lockfile actually change? An agent that adds one dependency can move forty transitive ones, and a lockfile diff nobody reads is the standard way that goes unnoticed, so it is reviewed as code with the additions summarized rather than collapsed to "lockfile updated". Then there is the part that is not a check at all, and it is the one that does the most work. An agent invents a package name when it has no better source, so we give it a better source: the inventory of components and libraries you already approve, served as agent context alongside the design-system registry, so a request for a chart, a date picker or a lint rule resolves from a list you own rather than from what the model half-remembers. The failures that still happen are recorded with the prompt that produced them, because the USENIX measurement is that 43% of hallucinated names return on every re-run of the same prompt. The list your codebase produces is short and repeatable rather than infinite, which is what makes recording it worth doing. None of this makes us a security vendor. We build and operate the gate in your pipeline with your registry, your scanner and your policy. We do not run a threat intelligence feed, we do not scan packages for malware, and we do not certify anything as safe.

  • A.

    Only in front of the ones with nothing behind them, which on a real codebase is a handful a month. The gate is tiered rather than binary, and the tiering is the whole reason it survives contact with a delivery team. A package already in your tree and in the approved inventory is not a decision at all: it resolves and the run continues. A widely used package with years of history, a real repository, a maintained release cadence and a license your policy allows passes automatically, because a rule that stops an engineer installing a well-known library has failed at being a guard and succeeded at being an obstacle, and obstacles get switched off. What actually stops is the narrow band the attack lives in: a name that does not resolve, a package first published inside a recency window you set, one with no repository, no download history or a single fresh maintainer account, and anything that wants to execute code at install time. That is where thirty seconds of a person’s attention goes, and the answer is usually obvious from the registry page. The sequencing matters as much as the tiers, and it is the same sequencing the performance budget and the license gate already use here. The first pass is an inventory rather than a failure: what you depend on today, direct and transitive, which packages run install scripts right now, and which arrived without anyone deciding. Nothing fails on the first morning, because a gate switched on at an ideal standard over a dependency tree that has been growing for six years blocks everything before lunch and gets disabled by Thursday, and then the team remembers this as the thing that stopped the release. After the inventory it ratchets, applying to what a pull request adds rather than to the whole repository, so what you touch has to clear it and what you do not touch stops getting worse. Two honest limits, because the alternative is overselling this. A package can be widely used, years old, and still get compromised through a maintainer account, and that case is not what this gate catches. That one is your scanner, your lockfile discipline and the same install isolation, and we build to those rather than replacing them. And a check at install can tell you whether a dependency is what it claims to be, never whether it was a good idea. Whether you needed a second date library at all is a design-system question, and it gets answered by the inventory the agent reads before it writes, which is where that decision belonged anyway.

  • A.

    No, and an engagement that opened with a restructure would be selling you the most expensive version of the smallest problem. Start from what the ETH Zurich and LogicStar.ai study actually found in February 2026, because it sets the size of the prize honestly. A hand-maintained context file was worth roughly four points of task success against having none, and a generated one was worth slightly less than nothing while costing 20 to 23% more in inference. Their explanation is the useful part: agents are good at discovering structure, so a listing you write by hand mostly burns reasoning tokens. What that leaves is the structure itself, and the structure you already have is the starting point rather than the obstacle. The first pass is measurement, not carpentry, and it happens in the audit before anything is installed. We take the routes and features your team touches most, and for each one we look at how far an agent has to travel to make a correct change: how many files a real ticket spans, how many of them are reachable only by knowing something, how often a change in one feature forces an edit in a sibling that nobody expected, and where the import graph has cycles. That produces a short and specific list, and on most Frontend codebases it is much shorter than the team fears, because the pain concentrates. Two or three shared modules that everything imports and nothing owns, one utility folder that became the place things go to avoid a decision, a component library and a feature tree that disagree about who owns a pattern. Fixing those is a handful of moves with codemods behind them, and each one is separately mergeable, separately revertable and shippable behind the running app, which is the same rule the migration work follows here for the same reason: no point of no return, and it survives a paused quarter. The monorepo question we answer with a question, because it is usually the wrong lever. A monorepo helps when you have several deployables that need to change together and a tool to enforce the graph between them. It does nothing for a single application whose real problem is that its modules import each other freely, and moving that application into a workspace will not stop them. If the boundaries you need are inside one app, they get drawn inside one app. If your product genuinely is several Frontends with shared surface, then the boundaries and the packaging are the same conversation and we have it once. Either way, the honest limit is that this is the slowest-compounding thing in the install, and we sequence it accordingly: guards and context first, because those pay back in the first weeks, and structure alongside the work rather than as a phase you fund up front and wait on. And where the ambiguity is genuine, we say so instead of automating it. A module that four callers each depend on a different accident of is not a codemod, it is a decision, and pretending otherwise is where this kind of work goes wrong.

  • A.

    By making it fail on the change rather than on the codebase, by writing the reason into the failure, and by keeping the exception route open and visible. That is the same sequencing the performance budget and the license gate use here, and it exists because the failure mode is completely predictable: a boundary rule turned on at the standard you wish you had, across a codebase that has been growing for years, produces several hundred errors on the first morning, and the fastest route back to shipping is the disable comment. After that the rule is decoration, and the next person to propose one gets a tired look. So the first pass writes the boundaries down as they are, not as they should be, and reports rather than fails. That inventory is genuinely informative on its own, because the map the team has in its head and the import graph on disk are rarely the same document. Then it ratchets onto changed lines: what a pull request adds has to respect the boundary, what it does not touch is allowed to stay wrong, and the graph gets better as the work happens instead of in a quarter nobody funds. The second thing that keeps it alive is the failure message, and this is where most implementations lose the room. "Import boundary violation" tells an engineer that a machine is unhappy. What the guard says instead is which boundary, why it exists, and what to do: this feature is reaching into another feature’s internals, the shared surface for that is here, and if it needs something that surface does not expose, that is a real design conversation and here is who owns it. The same message is what the agent gets back, which matters more than it sounds, because a specific reason is repairable in the next turn and a generic rejection just makes the agent try something else. Third, the exception is a first-class path, not a defeat. Some violations are correct, deadlines are real, and a gate with no legitimate way through gets routed around illegitimately. So an override is a line in a file with an owner and a reason, it shows up in review like any other change, and the count is something we read at the operating review. A rising exception count is not a discipline problem to be scolded about, it is the boundary telling you it was drawn in the wrong place, and the response is to move the boundary. Fourth, ownership rides on the same lines. CODEOWNERS is generated from the boundaries rather than maintained beside them, so the reviewer a change routes to is the team that owns the module by definition, and the two cannot drift apart. What you get out of it, and the reason it is worth doing at all: the effect compounds on agent work specifically, because an agent asked to change a feature that has one obvious home and a declared surface loads less, guesses less, and produces a diff a reviewer can read in one pass. And the honest limit is that a boundary is a decision about your product, not a setting we bring with us. We can see the seams, we can show you what the graph says, and we can hold whatever line your team agrees on. We do not get to pick it for you, and any consultancy that arrives with the answer already written has not read your code.

  • A.

    Four changes, in this order, and the bill usually goes down rather than up. Start from where the time is actually going, because on a Frontend repository it is rarely where the team assumes. The first pass in the audit measures four things: what a pull request costs end to end in wall-clock minutes and in runner minutes, which checks account for most of both, how much of that work was necessary for the change in question, and how long a pull request waits before its run even starts. That last number is the one that surprises people, because it is queueing rather than compute, and queueing does not degrade gently. When arrivals approach capacity the wait does not rise in proportion to the load, it climbs away from you, which is why a pipeline that felt fine last quarter feels broken this quarter without a single check having got slower. Then the changes. Order the checks by cost and determinism, cheapest and most certain first: types, lint, module boundaries, formatting, the bundle budget on the changed routes. Those are seconds, they catch a large share of agent output, and every one of them that fails early is a browser matrix you did not spend. Second, stop running everything on every change. Test impact analysis maps the test suite to the module graph, so a token edit runs what depends on tokens and a routing change runs what depends on routing, and the full suite runs on the merge path rather than on every push. On a Frontend codebase this is the single biggest lever, because the expensive checks are the ones with a browser in them. Third, the queue itself: batch and bisect instead of testing every pull request alone. A batch of four is roughly a quarter of the runs, and when a batch fails it is bisected automatically rather than thrown away, which costs a logarithmic number of extra runs and does not punish the innocent pull requests. Teams that do only this typically take a large bite out of the queue bill, and Mergify measured 94% of teams not doing it at all. Batch size should widen under load and narrow when the queue is quiet, which is what makes it survive a burst of agent pull requests arriving faster than CI can clear them. Fourth, caching and isolation that actually hold: a warm dependency and build cache keyed properly, and runs that do not contend for one shared environment. Three honest limits, because this is easy to oversell. Batching trades some precision in failure attribution for throughput, and it is the wrong trade below a certain merge volume, so we measure before switching it on. Bisection tells the truth only if the suite does, which means flake quarantine is a prerequisite rather than a nice-to-have, and it is the same flake work the test-quality gate already covers here. And a pipeline change cannot rescue a pull request that should not have been opened: 400-line scattered agent output is a specification problem upstream, which is what the structured specs are for. On cost, we report it the way we report agent spend, as cost per merged pull request read beside guard catch rate, because a pipeline that is cheap and merges nothing is not a saving. We build all of this on the CI you already run, with your runners and your billing. We are not a CI vendor, we do not resell one, and we do not move your pipeline to a platform of our choosing.

  • A.

    Fewer than the arithmetic suggests, and the way to keep the number small is to be precise about what each run actually needs to prove. Take the arithmetic seriously first, because it is what breaks shared staging. Twenty engineers each supervising three to five agents is sixty to a hundred concurrent branches wanting to be looked at, and a single shared environment serialises all of it: the queue for staging becomes the real merge queue, agents wait on humans who are waiting on other agents, and the first thing a team does under that pressure is start merging without checking, which is the outcome the whole factory exists to prevent. So the environment question is real. The answer is not one full stack per run. On a Frontend codebase most changes need to prove something about rendering, state, tokens, routing and interaction, and none of that requires your whole backend to be standing. A preview build of the Frontend against recorded or contract-generated API responses covers the majority of runs, costs close to nothing to spin up, and is deterministic, which matters more than realism for most checks: a visual regression against a live database is a flaky test with extra steps. What genuinely needs a full ephemeral environment is the smaller set of changes that cross the contract, touch auth, or depend on a real service behaving in a way a fixture cannot fake, and those get one, provisioned on demand and torn down when the pull request closes. The sequencing is the same as every other guard here. First an inventory rather than a build-out: which checks are running against a shared environment today, which of those actually needed one, and what the wait is costing in wall-clock time per pull request. On most codebases that report reallocates more capacity than buying more capacity would. Then the split is implemented, cheap preview by default and full environment by exception, with the exception routed on a rule rather than on someone remembering. Two limits stated plainly. Fixtures drift, and a contract-based preview is only as honest as the contract test that keeps it aligned, so that test is part of the work rather than an afterthought. And this is infrastructure we build on your platform, with your cloud account, your Kubernetes or your hosting provider, and your cost centre. We are not an environments vendor, we do not resell one, and if your platform team already has a preview environment story, we use it rather than replacing it.

  • A.

    Fewer than people fear, and the triage is a two-question test rather than a committee. Start by rejecting the two answers that get proposed first. Absorbing everything is absurd: a lot of what has been built is one analyst’s throwaway view of one quarter’s data, it did its job, and putting it through review would cost more than it saved. Absorbing nothing is how the current situation happened. So the test. First question, does it touch anything you would have to answer for: production data, customer-facing surfaces, credentials or a service that costs money when it is called. Second question, does anyone other than the author now depend on it, which in practice means it has a second user, a recurring meeting attached, or a decision made from its output. Neither yes is negotiable. One yes puts it on the sanctioned path, two makes it urgent, and no to both leaves it exactly where it is, which is a real outcome rather than a polite deferral, because a tool nobody depends on is allowed to break and allowed to be deleted. What the sanctioned path means concretely is deliberately narrow, because the temptation is to demand a rewrite and the rewrite is what kills the programme. The tool moves into the repository, keeps its shape, and picks up the four things it was missing: an identity boundary so it calls your services as a signed-in person with that person’s permissions rather than with a token pasted into a client bundle, an owner who is a named team, the seven guards on the way in, and a log so the next question about what it did has an answer. Most of that is mechanical and much of it is agent work with a human at the gate, which is the whole point of having a factory before you have this problem. Two things we do differently from what a governance programme usually looks like. The inventory is built with the people who built the tools, in the open, and it is not a hunt. If the first move is discovery software and a memo, everything gets quieter rather than fewer, and you have converted a visible estate into an invisible one. And what comes back from the triage is read as a roadmap, not a charge sheet: a cluster of six tools doing the same reporting job is a missing feature in your product, and the correct response is to build it once rather than to onboard six. On sequencing, this runs after the guards and the context are in place rather than before, for the same reason every other retrofit here does: the sanctioned path has to be genuinely fast on the day you ask people to use it, or the first person to try it tells everyone else not to bother. Our boundary is the same in every engagement: we build the path, the guards and the migration work. We are not a shadow-IT discovery product, we do not scan your network, we do not monitor employees, and we do not write your acceptable-use policy.

  • A.

    Because the thing making you slow is mostly not the writing, and the sanctioned path is aimed at the part that is. Be honest about the comparison first, since a pitch that pretends otherwise gets found out in week two. A person prompting an app builder gets something on screen in an afternoon, and no factory beats an afternoon at producing a screen. What they do not get, and what they discover between one and six months later, is anyone to call when it breaks, a way to change it safely once the author has moved teams, permissions that survive an audit, or any route from that screen into the product where the work actually belongs. So the sanctioned path is not competing on time-to-screen. It competes on time-to-merged, which is the number that has been quietly terrible and is the reason people left in the first place. That number is dominated by waiting: waiting for a Frontend engineer who is the only person who knows the design system, waiting for a review that is queued behind six others, waiting for a CI run that was sized for a smaller team, waiting for someone to say whether the thing is even allowed. The factory attacks each of those directly. Context and a skills library committed to the repo mean the agent produces something shaped like your codebase on the first attempt rather than the fourth. The seven guards decide mergeability before a human is asked, so review is spent on intent rather than on catching a missing empty state. Pipeline capacity is engineered rather than apologised for. And the roles work from earlier in this programme means a PM or a designer has a defined path in, not an exception someone has to approve. The result we aim for, and measure honestly, is a path where the boring 80% of an internal tool merges the same week and the author spends their attention on the part that is actually theirs. Three things keep this from being a slogan. We take the baseline before anything is installed, so the comparison is against your own numbers rather than a brochure, and it is read as time from idea to merged change per role, beside guard catch rate and review rejection rate, never throughput alone. We stage it: the first tools through are chosen because they are representative and unglamorous, not because they are important, since the point is to prove the path with something whose failure costs nothing. And we say plainly what does not get faster. Anything genuinely novel in your domain still needs a person who understands the domain, and no amount of infrastructure changes that. If the path does not beat the alternative on merged work within the first stage, the honest response is to fix the path, and that is the conversation we would rather have than a mandate that makes everyone quieter.

  • A.

    A guard, because this defect class is invisible to every check you already run and to the person reviewing the diff. Start with why it happens, since it is not carelessness. A coding agent writes the label it was asked for, in the language the prompt was written in, directly into the JSX, and the result compiles, passes types, passes tests and looks correct in the browser the author is looking at. There is nothing to see. The same is true of the three defects that travel with it. Layout sized to English, where German and Finnish routinely run 30 to 50% longer and a button that fits at 12 characters clips at 18. Physical direction in CSS, margin-left and text-align: left rather than margin-inline-start and text-align: start, because that is what the majority of the training data says, and it mirrors wrong the moment the app renders in Hebrew or Arabic. And sentences assembled by joining fragments, which is untranslatable in any language whose word order differs from yours, and which no translator ever gets the chance to fix because they only ever see the pieces. Every one of those ships green. The cost is not cosmetic. CSA Research’s long-running consumer study, 8,709 people across 29 countries, found 76% prefer to buy where the information is in their own language and 40% will not buy from a site in another language at all, which is the conversion rate of whichever locale quietly regressed this quarter. So it becomes a gate that runs on the diff, and it is deliberately cheap and deterministic, because the expensive version gets switched off. No user-visible literal outside the translation call in changed code. Every new key present and resolvable in the source locale, so a missing translation fails the run rather than rendering a raw key in production. A pseudo-locale build, the same strings padded 40% longer with accented characters and bracket markers, rendered in the component screenshots the pipeline already takes, which turns truncation and clipping into an ordinary visual diff and needs no translator and no budget. Physical-direction CSS rejected in new code. An RTL pass on the routes the change touched. Dates, numbers and currency through Intl rather than hand-formatted. Two things make it stick. It is ratcheted onto changed lines, so a repo with ten years of hardcoded strings does not go red on day one and instead stops getting worse while the existing debt is worked down deliberately. And the rules are in the context and the skills the agent reads before it writes, so the common case is that the agent produces the localized version first and the guard almost never has to fire. This is not an eighth guard. It rides inside the design system and accessibility guards for teams that ship more than one locale, and for teams that ship one it stays off. The boundary matters here: we build and operate the gate and we fix the code, we are not a translation vendor, we do not sell translation or run your TMS, and we do not choose your locales. RTL is not an edge case we read about, it is what our own work ships in.

  • A.

    Less than the review time it removes, but only if it is built as a cheap inner loop rather than as your existing end-to-end suite pointed at an agent, which is the mistake that makes this expensive and is worth naming first. The suite you already run is designed for a merge decision: full fixtures, real backends, every route, minutes per run. If an agent calls that on every iteration you have taken the most expensive thing in your pipeline and multiplied it by the number of attempts an agent makes, which is a lot, and the cost lands on your CI bill and on the queue everyone else is waiting in. So the inner loop is a different artifact. It renders the components the change touched, not the application. It runs against fixtures and recorded responses rather than a live stack, because the agent is asking whether its own change rendered correctly, not whether your integration works. It reads the accessibility tree first, which is text, small, deterministic and diffable, and only takes a screenshot when the change is genuinely visual. And it runs on the states worth checking rather than everything: loading, empty, error, offline, long content, narrow viewport, and right to left where the product ships it. In practice that is seconds against a component, and the agent runs it many times before anything reaches CI, which is the entire point, because a failure caught inside the agent’s own loop costs a retry and a failure caught in review costs a context switch for a senior engineer. Three things keep the cost honest. Storybook or whatever component workbench you already run is the fixture surface rather than a second thing to maintain, so the states are already written down and the loop consumes what your design system work produced anyway. Time, animation and anything non-deterministic are frozen, because a loop that fails intermittently gets disabled inside a week and takes the credibility of every other guard with it. And the browser is committed to the repository as configuration, so every agent and every engineer gets the same one, rather than the loop existing only on the machine of whoever set it up. On sequencing, this goes in early, before the roles work and before any fleet, for a reason worth stating: parallel agents multiply exactly the thing this removes, so turning on a fleet before the agents can check their own work is how a pipeline gets flooded with plausible pull requests nobody has time to read. We build and operate this inside your pipeline with the tooling you already run. We are not a testing vendor, we do not sell you a visual regression product, and we do not sell QA headcount.

  • A.

    No, and the difference is which question is being asked and when. Visual regression is a merge-time check with an owner: it compares the rendered result against an approved baseline and asks a human to accept or reject the difference. It is genuinely valuable, we install it as part of the design system guard, and nothing here replaces it. The agent loop is asking something else and asking it earlier. It is not comparing against a baseline, because at the moment the agent is iterating there is no approved baseline for a component that did not exist twenty seconds ago. It is asking whether what the agent just produced is coherent at all: does the interactive element have an accessible name, is the control reachable, did the error state render anything, does the text still fit at the longest string, did the layout survive a narrow viewport. Those are properties rather than comparisons, which is why they work on new code where a baseline check has nothing to compare to, and it is why the accessibility tree is the primary read rather than pixels. There is also a failure mode specific to this pairing that we design against explicitly, and it is the seventh wave’s snapshot rule pointed at a new target. If the same agent that changed a component is also allowed to approve the baseline that component is compared against, you have built a machine for agreeing with itself in writing, and the visual regression suite becomes a record of what the agent did rather than a check on it. So the rule is unchanged and absolute: a baseline is never accepted in the same run that changed the thing it depicts, and baseline approval stays a human decision with an owner. The two layers then do different jobs honestly. The agent loop is fast, property-based, runs many times, has no owner and blocks nothing, so it is allowed to be imperfect. Visual regression is slow, comparison-based, runs once, has an owner and blocks the merge, so it has to be trustworthy. Collapsing them into one thing is how teams end up with a slow inner loop and an untrustworthy gate, which is the worst of both. And the same honest limit applies to both: neither one knows whether the change was a good idea. They catch the obviously wrong, which is most of what an agent produces when it cannot see, and they leave the judgment where it belongs.

  • A.

    It starts by reporting, not by failing, and it starts on a list far shorter than the one you have. The reason is the same one that governs the license gate and the performance budget: a rule switched on at an ideal standard over a taxonomy that accumulated for six years goes red on every pull request in week one, and the team disables it by Thursday. So the first pass is an inventory that changes nothing. We take the events your codebase actually emits, which is rarely the list anyone thinks it is, and put it beside the events your dashboards, your experiments and your board deck actually read. Three groups fall out of that and each gets a different answer. The events nothing reads are the largest group and they get deleted, which is the cheapest win in the whole engagement, because dead instrumentation is code an agent will faithfully maintain and copy forward. The events something reads but nobody can explain get an owner or get deleted, and that decision belongs to your product and data people rather than to us. What is left is the small set the business steers by, and that is the only set the gate covers: usually somewhere between fifteen and forty events, the ones behind activation, the core job, conversion and retention. Those get a typed schema in the repository, so a renamed or dropped property fails at the call site, and they get an assertion inside the flows your pipeline already drives, so a refactor that silently detaches one goes red for the reason it actually went wrong. Then it ratchets: changed lines are held to the schema, untouched legacy is not, and the count of exceptions is a number we watch rather than a number we hide. Two things about the ordering that are worth stating because they cost money when they are wrong. This goes in after the design system, accessibility and test quality guards rather than before them, since it reuses the assertion surface those guards produced and there is no point building it twice. And the historical data does not get retrofitted. We do not go back and correct eighteen months of a broken funnel, because you cannot, and anyone offering to is reconstructing rather than measuring. What we can do is mark the date the event became trustworthy and make sure everyone reading the chart can see that line, which is a smaller and much more honest deliverable. We build and operate the gate inside your pipeline against the analytics stack you already run. We are not a data agency, we do not build your warehouse, we do not model your data or run your BI, and we do not pick your vendor.

  • A.

    It moves one specific part of it, and that part was already in engineering, which is the point of the answer. Be precise about the split, because conflating it is what leaves the layer unowned in the first place. Deciding what to measure is a product question. Defining what an event means, what its properties are and what a valid value looks like is a product and data question. Modelling it downstream, joining it, and building the reporting on top is a data question. None of those are ours and we do not take them. But the event itself is emitted by Frontend code, at a moment that only exists because a component rendered and a user interacted with it, and it breaks for the same reasons any other line of Frontend code breaks: somebody refactored around it. That has always been engineering work. The dbt Labs 2026 survey put ambiguous ownership at 41% of data practitioners as an ongoing challenge, and this is the seam where it usually lives: everyone agrees the numbers matter and nobody owns the twelve lines that produce them. What actually changes for your engineers is smaller than it sounds. They stop hand-writing event calls and start calling a typed function, which is less work rather than more, and it is the same move that made your design system cheaper to use than to bypass. Their pull requests fail earlier and for a legible reason instead of producing a data incident three weeks later that somebody else has to trace back to their commit. And their coding agents get the schema as context, which matters more than the gate does: an agent that can read the event definitions writes the correct call the first time, and an agent that cannot invents a plausible one. Be honest about what does not improve. Nothing here makes a badly designed event good, and nothing here settles an argument about which metric the company should care about, which is the argument most often mistaken for a tooling problem. Two separations we hold in writing, because they get blurred in exactly this conversation. Delivery measurement is whether your investment in AI-assisted engineering paid off, read on the merge side against a baseline taken in the audit. Release confirmation is whether the change you just shipped is safe to keep, read from field data on the routes that moved. This is the layer both of those read from, which is why we install it early and why we will not quote either of them on a client whose measurement layer is unverified.

  • A.

    With an inventory of what your application actually calls, which is always a longer list than the architecture diagram suggests and is usually the most useful artifact of the first fortnight on its own. Nobody starts from a complete set of specifications, and a gate that requires one before it does anything is a project that never ships. So we sort the boundary into three groups and each gets a different answer. For the services that already publish a contract, the work is small and mostly mechanical: generate the types and the mocks from that contract rather than hand-maintaining either, and fail the build on a consumer-breaking difference between the version in the pull request and the version the app was built against. Severity classification matters more than people expect here, because a gate that treats an added optional field the same as a removed one is a gate that fires constantly for no reason and gets switched off in a month. Added optional field, no action. Removed field, renamed field, narrowed enum, a type that changed underneath, loosened nullability on something you render without a guard: those stop the run. For the internal services with no spec, we do not write one by hand, because a hand-written description of somebody else’s behaviour is a second thing to keep true and it never stays true. We record the real traffic your application already makes against them in a test environment and generate the contract from that, which produces something honest about what is actually happening rather than aspirational about what should be. It also tends to surface the first round of findings by itself, because a recorded contract makes visible the three endpoints that return a different shape on Sundays. Where the owning team is willing, that recording becomes a consumer contract they can run in their own pipeline, and that is the point at which this stops being a Frontend defence and becomes a genuinely cheaper way for two teams to work. Where they are not willing yet, it still protects you, and we do not make the engagement depend on another team’s roadmap. For the vendors, which is the group everyone worries about and the group with the least available leverage, the answer is not a test in someone else’s CI. It is a recorded contract plus a scheduled check that runs against their sandbox or a low-cost real call, so a shape that moved is a ticket on a Tuesday morning rather than an incident on a Saturday night. Add a narrow runtime validation at exactly those boundaries, at the edges only and never through your whole app, so an unexpected payload from a third party renders a designed state instead of a stack trace. Then it ratchets, the same sequencing rule the performance budget, the license gate and the boundary rules already carry: changed lines are held to the contract, untouched legacy is not, and the exception count is a number we report rather than hide. Two things about ordering, because they cost money when they are wrong. This goes in after the test quality guard rather than before it, since it reuses that assertion surface and there is no point building it twice. And do not start with the vendor with the worst reputation, start with the boundary that broke most recently, because the fastest way to keep a new guard alive is for its first catch to be something the team already remembers losing a day to. We build and operate this inside your pipeline, against your specs and your tooling. We are not an API management vendor, we do not sell or run a gateway, and we do not take over your backend’s contract.

  • A.

    No, and the difference is the difference between a photograph and a smoke alarm. Generated types are genuinely good practice and if you have them you are ahead of most teams, but they are a snapshot taken at the moment somebody ran the generator, and every failure in this category happens after that moment. Ask the specific question: on the day the shape changes upstream, what fails, and does anyone find out before a customer does? With generation alone, usually one of three things happens and none of them is a failure. Nobody re-runs the generator, so your types describe a server that no longer exists and everything compiles perfectly against a fiction. Or the generator runs in the build and the types silently update, so the field you render disappears from the type and, if you touch it through anything less strict than a direct property access, still compiles. Or the types update, the build does break, and an engineer or an agent under time pressure widens the type or adds a non-null assertion to get moving again, which is the fix that makes the next occurrence invisible. That third one is the common case in an agent-heavy repository, because agents conform: they resolve the contradiction in front of them rather than escalating it. A gate is a different artifact from a generator in four ways, and each one closes one of those paths. It diffs the contract rather than the code, so the pull request that consumes a changed spec is compared against the spec the application was built against, and a consumer-breaking change is a build failure with a name rather than a type that quietly moved. It classifies severity, so the signal is legible instead of constant. It generates the mocks and fixtures from the same source, which is the part that catches most teams by surprise, because the reason the suite stayed green through a real break is almost always that the fixture was written by hand in 2024 and has been faithfully asserting the old shape ever since. And it records the fields you actually read, which no generator does and which is the only way a provider can distinguish a field that is safe to delete from one that is load-bearing for a screen they have never seen. There is also a limitation a generator inherits that is worth saying out loud, because it is where teams put too much faith: generated types are exactly as true as the specification they came from, and specifications drift from implementations, particularly for error responses, particularly for anything hand-written. A spec that says a field is always present is a claim, and if the service omits it under a condition nobody documented then your types are confidently wrong and the compiler is agreeing with them. That is why the recorded traffic matters as a cross-check, and why runtime validation stays at the boundary even in a well-specified system. And the same honest limit applies here as everywhere else: a green contract gate tells you the shape matches. It does not tell you the value means what you think it means, which is a question about your product rather than about your pipeline, and no gate we build will ever answer it.

  • A.

    You have half of it, and it is the half that tells you something is wrong. What is missing is the half that lets somebody read the thing that broke, and those are separate properties that get bought under one word. Observability is about signal: an error arrived, a metric moved, a trace exists. Debuggability is about the artifact: when the signal arrives, is what it points at legible to a person who did not write it, at speed, at night. You can have excellent observability over an unreadable artifact, and that is the common case on the Frontend right now, because the tooling is bought once and the four things that make its output useful are decided per release and quietly drift. Here is what that looks like concretely, and it is worth checking rather than assuming, because every team we have asked believed they were covered and roughly half were not. Open the last three Frontend errors in whatever you run. Is the stack symbolicated, or does it name a function called “t” inside a bundle hash. If it is minified, source maps are not being uploaded for that release, which is usually a build step that broke silently months ago and that nobody noticed because nobody reads Frontend stack traces until the night they need to. Does the error carry the release and the commit it came from. If it does not, there is no path from the failure to the diff that caused it, and the first twenty minutes of every incident are spent reconstructing that by hand from deploy timestamps. Does the client event share an identifier with the server-side trace for the same interaction. If not, you have two accurate accounts of one event and no way to join them, which is the specific reason Frontend incidents get misattributed to the backend and back again for an hour. And when a component throws, does the user get a designed state or a blank region. A blank region produces no error volume worth alerting on, so the failure is silent by construction. There is also a defect class that only shows up in agent-heavy repositories and that no observability product will ever surface, because from its point of view nothing happened: the swallowed error. An agent asked to make a failing path stop failing will often catch the exception and return null or an empty array, which is locally reasonable, passes review, satisfies the type checker and makes the test green. It also deletes the signal. The screen renders empty instead of throwing, so your tooling reports perfect health while a customer sees nothing, and this is the single most common way an AI-assisted codebase becomes quieter and less trustworthy at the same time. That one is caught in the diff, on changed lines, by requiring a caught error to be handled or reported and never silently discarded. So what we install is not another tool. It is the configuration and the assertions that make the tools you already pay for produce something a stranger can act on, committed to your repository so they cannot drift back. We build and operate that inside your pipeline. We do not join your on-call rotation, we do not sell an observability product, and if your existing vendor covers a piece of this properly we will tell you and leave it alone.

  • A.

    The team that owns the surface, which is almost never the person who merged, and getting that separation right in writing is a precondition of the roles work rather than a consequence of it. The instinct is to page the author, and it is wrong for a reason that predates AI: authorship and ownership have never been the same thing, and paging by authorship simply punishes whoever touched a file most recently. What is genuinely new is that authorship has also stopped being informative. When four different tools can produce a branch, the commit author records who ran the agent, not who understands the result, so git blame now points at a person who may have read the diff carefully and still holds no more context than you do. Building an escalation path on that is building it on noise. So ownership is structural. It follows the module boundaries the codebase already enforces, expressed as code ownership over directories rather than over commits, which means a surface has a named owning team from the moment it exists and the answer to “who do we call” is a property of the path in the stack trace. That is the same boundary work the factory installs for other reasons, and this is one of the places it pays for itself twice. Then the split, which we write down explicitly with every client because ambiguity here is what makes non-engineers stop shipping. The author owns the intent: what the change was for, what it was supposed to do, and answering questions about it during business hours. The owning team owns the surface: its production behaviour, its alerts, its rotation, and the decision to roll back. A PM who merges a copy change on a settings page does not go on call, and any programme that implies otherwise will end with PMs not merging anything, which is the outcome you were trying to escape. What we do ask of the author is smaller and enforceable: the change carries its own reversal path. On the Frontend that means exposure is decoupled from deployment, so the fix for a bad change is a flag flip by whoever is awake rather than a redeploy requiring the author to be found. That is the release-side work, and it is why we install it before we widen the set of people allowed to merge, not after. Two honest limits. Structural ownership is only as good as your module boundaries, so in a codebase where everything imports everything this produces a single owning team called “everyone”, and fixing that is boundary work that takes a quarter rather than a configuration change. And none of this reduces the number of people who need to understand the system. It makes the routing correct, which is worth a great deal at 02:00 and is not the same as making the system simpler. Our boundary is unchanged: we build the ownership model, the boundaries and the release path with you, we do not staff your rotation, and we do not write your escalation policy.

  • A.

    Almost nothing, if it is built properly, and that is the point rather than a concession. The gate exists so the team knows what it is allowed to depend on, not so that somebody is forbidden from using this year’s CSS, and the distinction between depending on a feature and using it is the whole design. Start with the target, because every team we have asked had one in somebody’s head and none had one in the repository. It comes from your own analytics rather than from a default, and it is almost always older than the room believes. Look at the engines and versions that actually reach the product, weighted by the thing you care about rather than by session count, since a browser carrying two percent of sessions and eleven percent of revenue is not a two percent browser. Three parts of the tail are worth naming because they are the parts analytics under-reports. On iOS the rendering engine has in practice tracked the operating system version, so your Safari tail is a function of device age rather than of user preference and it does not respond to anything you do. Enterprise customers pin browsers, so in a business product the oldest engine you serve often belongs to your largest account. And embedded WebViews inside partner or vendor applications are the group nobody has clean data on and the group that generates the strangest bug reports. Then the target becomes one line rather than a paragraph in a wiki. Baseline made it machine-readable and Browserslist reads those queries natively, so baseline widely available, a Baseline year set, or a query you derive from your own numbers is a single config that the bundler, the transpiler, the prefixer and the linters all read, which is the first time most codebases have one answer to this question instead of four. After that the gate classifies rather than forbids, and the classification is what decides whether it survives past week one. A feature used as an enhancement is allowed and nothing happens: it sits behind a feature query or a real detection, and the browser that lacks it renders something acceptable rather than something broken. That is most of what an agent writes, which is why this gate is far quieter than it sounds. A hard dependency on something outside the target with no fallback is what stops the run: layout that collapses rather than degrades, an interaction that only exists if the API exists, a form that cannot be submitted. And a feature inside the target that behaves differently in one engine is not a lint problem at all, so it is routed to the grid rather than pretended about. On tooling, name it plainly because it is unglamorous and already exists: the Baseline threshold is enforced on CSS through the ESLint CSS plugin’s baseline rule, on HTML through the equivalent rule in the HTML plugin, and Stylelint reads the same Browserslist config through a browser compatibility plugin, so there is one target and several enforcers rather than several targets. For JavaScript the same config drives the transpile, which is where teams get caught: unsupported syntax gets compiled down and disappears as a problem, unsupported APIs do not, and an agent reaching for a new platform API is writing a runtime failure that every build tool will cheerfully ship. Then it ratchets, the same sequencing that governs the license gate, the performance budget and the boundary rules: changed lines are held to the target, untouched legacy is not, and the exception count is a number we report rather than hide. The larger half of the value is not the gate. It is that the target is now a file the coding agent reads, so it proposes what you can ship instead of what the documentation showcased, and a class of pull request stops being written at all. This goes in early because it is configuration rather than infrastructure and it makes every later guard’s output smaller. Two honest limits. Deciding which browser to drop is a business decision with a revenue number attached and it belongs to your product people rather than to us, we only make the cost of each answer visible. And a rule about syntax cannot catch a feature that is supported everywhere and behaves differently in one place. We build and operate the target and the gate inside your pipeline, against your analytics and your tooling. We are not a browser testing vendor, we do not sell or run a device grid, and we do not pick your testing provider.

  • A.

    Because a grid is a sample and a target is a rule, and this category of failure is not sampled well by anything. A grid answers a narrow question honestly: did the routes somebody thought to write tests for behave correctly in the browsers somebody thought to buy, on the day the job ran. That is worth having and we do not take it out. But four gaps sit between that answer and the failure you are actually worried about, and each one is structural rather than a matter of running the grid harder. The first is granularity. Coverage is per-route and the defect is per-declaration. A new component uses one property that is not in your target, it ships on a settings page nobody wrote an end-to-end test for, and the grid is silent because the grid was never pointed there. On the Frontend the failure is also frequently visual rather than functional, so even a passing test on the right route can pass while the layout is wrong, since assertions check behaviour and the parser silently dropping a line changes appearance without changing behaviour. The second is economics, and it is the one that actually decides outcomes. A grid run costs minutes and money, so it gets trimmed, and under agent volume it is the first thing trimmed: the matrix quietly narrows to Chrome plus one, on the main branch only, then nightly. That is not a discipline failure, it is what any expensive late check does when the number of changes triples. A lint rule reading a config costs milliseconds and cannot be economised away. The third is the tail. The versions a grid offers are the recent ones, and your exposure is old ones, on devices that stopped updating and fleets that will not. The browser you most need to know about is the one hardest to rent. The fourth is where the feedback lands. A screenshot difference twenty minutes later, attributed to a route rather than to a line, is not something an agent can act on and is barely something a person can act on without an afternoon. A lint failure on the changed line names the feature, names the target and names the fallback, which is a fix rather than an investigation. That last point is the one to press, because it is the whole difference in an agent-heavy repository. A test tells a human afterwards. A config tells the agent beforehand. The agent that can read the target writes the supported thing the first time, and no amount of downstream testing recovers the cycle you spend when it does not. So keep the grid, shrink it, and point it at what only it can see: behavioural differences inside your target, real input and rendering rather than syntax, and the two or three flows that carry the revenue. It stops being the thing that catches new features you should not have used, which it was never good at, and becomes the thing that catches an engine behaving differently on code you are fully entitled to write, which nothing else can do. One honest limit worth stating in both directions: neither replaces the other. A team with an excellent grid and no target still ships new-feature failures on untested routes, and a team with a target and no grid still gets surprised by an engine that supports the feature and implements it differently.

  • A.

    That your interface still agrees with them, which is a different question from whether they are enforced, and it is the question nothing in your pipeline currently asks. Start by separating the two jobs, because most of the confusion in this area comes from collapsing them. Refusing a request is the security decision and it belongs on the server, we are not proposing to move it and any vendor who does is selling you a vulnerability. Deciding what to render is a product decision and it belongs to the Frontend: which controls exist, which are disabled, what a person sees instead of the thing they cannot do. The defect is never in either one alone, it is in the gap between them, and the gap has no owner today because each side reasonably assumes the other has it. So the gate checks the agreement. Four pieces, in the order we install them. First, the capability layer. Permission-dependent rendering stops asking about identity and starts asking about capability: not whether the user is an admin but whether this user may refund this invoice. One typed module answers those questions, everything else consumes it, and a boundary rule fails the run when a role name, a plan tier or a seat type appears as a string comparison anywhere outside it. That rule is the entire retrofit for most codebases, because it converts an invisible, scattered, untestable concern into one module with a surface you can point a test at. Second, the capability list is generated from the server rather than hand-maintained. This is the nineteenth wave’s contract rule applied to policy instead of to shape: a hand-written copy of somebody else’s rules is a second thing to keep true and it never stays true. Where a machine-readable policy exists, the client list is generated from it and a drift check fails when they diverge. Where none exists, and on most codebases that is at least some of the surface, we record the real behaviour from the endpoints and generate from that, which is honest about what is actually happening rather than aspirational about what should be. Third, and this is the assertion that makes the gate worth having, protected actions are asserted in both directions. For a role without the capability the control must be absent or disabled, and the request must be refused when it is issued anyway. One without the other is the failure this whole gate exists to prevent, because a UI-only check reads as protection to every reviewer who sees it and protects nothing. Fourth, coverage is enforced structurally rather than by diligence: a new route or a new protected action registered without an entry in the access map stops the run. Like every retrofit here it begins as an inventory that reports rather than fails, and then ratchets onto changed lines, the same sequencing the license gate, the performance budget and the boundary rules already use, because a rule switched on at an ideal standard across six years of screens gets disabled by Thursday. What this changes for agents is larger than the gate itself. The capability list is context, so an agent writing a new screen reads what the capabilities are and asks for the right one instead of pattern-matching the check from the component next door, and a class of pull request stops being written. Two honest limits, stated before the work starts. This proves your interface agrees with the policy you declared, and it can never tell you the declared policy is the one you intended, which is a product and security decision that stays with you. And it does not close an open endpoint: when the assertion finds that the server answers a request it should refuse, the gate has done its job by making that visible, and fixing it is backend work. We build and operate the gate inside your pipeline against your own policy and tooling. We are not a security auditor, we do not run penetration tests, we do not design your permission model, and we do not certify anyone. The separate question of what an AI agent acting for one of your users is allowed to do in your product is Frontend AI work rather than a merge gate, and it is answered on that page.

  • A.

    No, and if it did we would not propose it, because the combinatorial version is exactly the guard that gets deleted in the second month. The trick is that fixtures are capability-shaped rather than role-shaped, and the two counts are nothing like each other. A role is a bundle of capabilities, but a given surface almost never reads the bundle. A refund button reads one capability. An invoice page reads perhaps three. So the fixtures for that surface are the states it can actually be in, which is usually allowed, denied, and denied with a path forward, and not the forty roles times six tiers that would exist if you enumerated identities. Multiply that out across a real product and you get a few hundred small rendered states rather than tens of thousands, they live in the component workbench your team already runs, and they are generated from the capability list rather than typed out by hand, so adding a role does not add a fixture at all. The plan tier is worth calling out separately because teams model it as a second permission system and it behaves like one: entitlement is a capability like any other, the surface asks whether this account may use the feature, and the difference is only in what the denied state says, since a denied capability tells the user to ask an admin and a denied entitlement tells them what the plan does not include. Rendering an upsell into a permission failure is the standard mistake and it is worth naming, because a viewer who is told to upgrade in order to see something their admin simply has not granted them is being lied to by your interface. On what it costs and how we sequence it. The audit measures it before anything is installed rather than estimating it, and the shape is consistent across the codebases we have looked at: the capability layer itself is a day or two of work, the retrofit is concentrated in a small number of shared surfaces, usually a navigation component, a table of actions and two or three settings screens, and the long tail of components turn out to read no capability at all and need nothing. The migration is codemod-shaped for the mechanical part, which is finding the role comparisons, and genuinely manual for the ambiguous part, which is the handful of places where somebody encoded a rule in the client that exists nowhere on the server and nobody remembers whether it was deliberate. Those get surfaced as decisions for your team rather than resolved by us. It goes in after the guards and the context are running, because it is cheaper once the boundary rules exist and it compounds slower than they do. And it never becomes a reason to simplify your permission model: how many roles you have is a product decision with customers attached, we make the cost of each one visible and we do not lobby for fewer. Two honest limits. The exception path stays first-class and logged, because there will be surfaces where the correct answer really is a bespoke check, and a rising exception count means the capability model is wrong rather than the team being lazy. And no gate makes an untested role tested: this tells you the interface matches the policy on the states you declared, so a state nobody declared is still a state nobody has looked at, which is why the inventory comes first and why we report what it does not cover.

  • A.

    More than you would expect, because the thing you gate is the policy rather than the payload. The mistake is to imagine a CI job trying to read a script that does not exist yet. What actually gets enforced is the envelope that script has to fit inside, and the envelope is code in your repository. Four pieces, in the order we install them, and the first one changes the conversation on its own. Start with an inventory that fails nothing. We record what your pages actually load, in production, from real sessions rather than from a local run, and put it beside the list your team believes is there. Those two lists have never matched in any codebase we have looked at, and the gap is not sinister, it is turnover: a pixel for a campaign that ended, an A/B tool nobody has logged into since the person who bought it left, a vendor that was acquired and now resolves somewhere else. Every entry gets an owner and a written justification or it gets removed, which is PCI DSS 6.4.3 applied outside the payment page, and it is the cheapest week in the whole engagement because most of what it finds is deletion rather than work. Second, the allowlist becomes a build artifact. A content security policy is not a header somebody pasted once, it is generated from that inventory, checked into the repository, reviewed like any other change, and reported on before it is enforced, so the first thing it produces is evidence rather than an outage. Adding a vendor becomes a pull request against a list, which takes minutes, and this is the only step where anyone waits. Third, integrity and origin where the vendor supports it, which is subresource integrity on a pinned version rather than a live URL that can change under you. Where the vendor refuses to pin, and plenty of tag vendors do, that is not a gate failure, it is a documented exception with a name against it and a number we report rather than hide. Fourth, and this is the part teams skip, the budget. Third-party bytes and third-party main-thread time get their own line in the performance budget rather than being absorbed into the total, because a team that budgets only its own bundle has optimized the half it controls while the other half grew. On the consent side, the check is behavioural rather than declarative: your pipeline already drives your critical flows, so it can load a page fresh, decline everything, and assert that nothing in the tracking category fired, which is the one thing a screenshot of a banner will never tell you. Two honest limits, stated before the work starts. A policy stops a script from loading, it does not audit what a script you allowed then does, so an approved vendor remains a trust decision that belongs to your team. And this does not make you compliant with anything: we are not a privacy law firm, we give no legal advice, we do not certify anyone, and where the law is involved your counsel sets the policy and we build the mechanism that makes it true in the browser. We are also not a consent-platform vendor, we do not sell one and we do not pick yours.

  • A.

    It would, if we gated the tags, so we do not. We gate the vendors, and the difference between those two is the whole design. A growth team does not ship a hundred new companies a quarter, it ships a hundred configurations of the four or five vendors it already uses: a new event, a new audience, a new trigger, a new page. None of that touches the allowlist and none of it waits for anybody. What does touch the allowlist is a genuinely new domain executing code in your product, which is a real decision with a security and performance cost attached, and which happens rarely enough that a pull request reviewed the same day is not a queue by any honest definition. If it turns out your growth team really is adding a new vendor every week, the gate has just told you something more valuable than it cost, and that conversation belongs to your team rather than to us. There is a second half to this that matters more for the relationship than the mechanics. The factory claim is that everybody in your organization ships production Frontend, and the tag manager is the one place where that already happens, without a gate, and where nobody in engineering wanted to look at it. Treating it as shadow IT to be shut down would contradict the thing we sell. So the design goal is that a growth engineer keeps their speed and gains a rollback: the change is visible in the same place every other production change is visible, it is attributable to a person, it can be reverted by anybody rather than only by whoever has the login, and it shows up in your release timeline so the next incident review does not spend forty minutes discovering that nothing was deployed that day. On sequencing and cost, because both are smaller than this sounds. It goes in after the security and performance guards rather than beside them, since it reuses the budget surface and the flow assertions those produced. The inventory is days rather than weeks. The policy runs in report-only for a full traffic cycle before it enforces anything, which is non-negotiable, because a policy switched to enforcing on a Friday against a list built from a staging environment is how a team ends up with a broken checkout and a permanent grudge against the idea. And it ratchets the way every other retrofit here does: new vendors are held to the policy, the existing tail is inventoried and exempted with owners, and the exception count is a number we report rather than hide. One honest limit. If your organization genuinely has no owner for the tag surface, this gate will not create one, it will make the absence unmistakable, and deciding who holds it is a decision for your marketing and engineering leadership rather than for us.

  • A.

    You do not, and a gate that claims it can is the gate your team deletes in the second month. That is not a hedge, it is the design. Two components can be identical today and still be two components, because they belong to features that will change for different reasons, and collapsing them into a shared abstraction couples two roadmaps that had no business being coupled. Duplication is cheaper than the wrong abstraction, that has been true for longer than any of these tools have existed, and a check that ignores it will be right often enough to be trusted and wrong often enough to be hated. So the machine does the part machines are good at and stops. It detects, it names, and it hands over. In practice that is three separate things and only one of them ever fails a build. The first is discovery, and it is the half that changes behaviour before any gate exists: a registry generated from your code rather than maintained by hand, with the real components, hooks and utilities, their props, their states and where they are already used, served to the agent before it writes. Most of what we would otherwise catch at merge time simply stops being written, because the agent was never guessing. The second is detection on changed lines only, in ratchet mode, the same way every other retrofit here works: a new component or hook that is a structural near-duplicate of one that exists gets flagged with the name and path of the thing it resembles, so the reviewer is answering a specific question rather than being asked to notice something. The third is the decision, and it belongs to a person on your team, never to us and never to the tool. An intentional duplicate is a legitimate answer, it is recorded with a one-line reason next to the code, and it stops being raised again. The number that matters after that is not how many duplicates were blocked, it is how many exceptions were taken and whether that count is rising, because a rising exception rate means the check is miscalibrated for your codebase and we tune it or we turn that rule off. On cost and sequencing, since both are smaller than this sounds. The registry is generated, so it is days rather than weeks and it does not rot, which is the entire reason we do not write it by hand. Detection goes on after the design-system and test guards are running, because it reuses the same changed-lines surface they produced. And it is deliberately quiet at the start: the first cycle reports without failing anything, so your team sees what it would have blocked before it can block anything. Two honest limits. This slows the rate at which duplication is created and does not remove what is already there, which is the same ratchet the AI-debt answer describes and it pays down only where you are already working. And structural similarity is not semantic equivalence: two functions that do genuinely different things in similar shapes will occasionally be flagged, which is exactly why a human holds the decision and why we measure how often that happens.

  • A.

    It is the neighbouring guard, and the difference between the two is the reason a team with an excellent design system still ends up with four buttons. Your design-system guard asks whether the new thing is built correctly: the right tokens, no raw hex, on-scale spacing, an accessible name, the states covered in the workbench. It is a conformance check, and it passes a second button that is beautifully built. This asks a different question, which is whether the new thing should exist at all, and no amount of token discipline answers it. That is the gap the published numbers land in. When cross-file function calls fall 35% and refactoring line moves fall 70% while duplication rises 81%, none of that is a styling failure. Every one of those duplicates could be perfectly on-brand. So the two checks sit side by side and cover different halves of the same file, and there is no eighth guard added to the seven: this rides inside the design-system lane because that is where the component question already lives, and the reuse trend is reported beside guard catch rate rather than as its own dashboard. Three pieces of it are worth naming because they are the ones teams do not have. Deletion is part of done. A change that introduces a replacement names what it replaces and carries a removal date for the old path, because the reason your library has four buttons is almost never that someone added a fourth, it is that nobody was ever accountable for removing the third. The same rule catches the quieter version, which is a component that survives with no remaining consumer, a route nobody links to, a flag permanently on with a dead branch behind it. Error-masking is a duplication problem, not only a debugging one, and it is why that 47% rise belongs in this answer rather than in the on-call one: an empty catch is the most common way a second implementation hides that it disagrees with the first, so a caught error on changed lines is handled or reported and never swallowed into a null. And the reporting is a trend rather than an event, because you cannot manage this as a list of incidents. What we hand your team monthly is reuse rate, duplicate rate and the exception count, read next to guard catch rate, so you can see whether the codebase is getting easier or harder for the next agent to work in. Two boundaries, in the same shape as the security and performance ones. We are not a code-quality analytics vendor, we do not sell you a score or a dashboard subscription, and everything we install is committed to your repository and runs without us. And we do not run a cleanup sprint: remediation rides your roadmap, the guards hold the line on what you touch, and we say so before the engagement starts rather than after.

  • A.

    By making them fail. That is the whole answer and everything else is mechanics. A context file rots because it is the one artifact in the repository that cannot be wrong in a way anything notices: no type checks it, no test exercises it, no reviewer is assigned to it, and the only consumer is a machine that assumes it is true. Give it an assertion and it stops being prose, and it starts behaving like the rest of your codebase. In practice the work splits three ways. Generate everything derivable, which is more of the file than teams expect. Build and test commands read from the scripts that actually exist. The directory map derived from the tree rather than typed. Module boundaries emitted from the same rules the boundary lint holds, so the file and the enforcement cannot disagree. The component and hook registry generated from the code, which is the same generated registry the reuse work already produces, so this costs nothing extra once that is running. A generated line cannot go stale, because regenerating it is what the check does. Then assert what cannot be generated, and the trick is writing it so a machine can check it in the first place. A claim like we use the repository pattern for data access is unfalsifiable prose and it will be wrong within two quarters with nothing to show for it. A claim like data access goes through src/data and nothing else imports the client directly is a rule, and there is a lint rule that holds it, so the sentence in the file and the rule in CI are one thing stated twice. Where a claim genuinely cannot be reduced to a rule, it carries an owner and a re-verification date and expires loudly rather than quietly. Then keep it moving with the code. A pull request that renames a script, moves a directory, retires a pattern or removes a component and does not touch the context that names it is incomplete, which is the same rule as removing what you replaced, applied to the file that describes it. The context file gets an owner in CODEOWNERS derived from the boundaries it describes, so the people whose code it is about are the people who review a change to it. On sequencing and cost, because this is one of the cheaper things we install. The checks go into the CI run the guards already use, so there is no eighth guard, no new pipeline and no context dashboard. The first cycle reports without failing anything, the same report-only discipline the third-party script policy gets, so your team sees how much of the file is already false before anything blocks a merge. That first report is usually the most useful artifact of the whole exercise and it tends to be uncomfortable. Two honest limits and one boundary. An assertion proves a line is still true, never that it earns its place, which is a separate question with a separate answer on this page and a different finding behind it. And none of this makes a convention correct, it makes the file agree with what your code actually does, so a bad convention becomes a consistently applied bad convention until a person changes it. We are not a documentation vendor, we do not sell a context product or a subscription, and every file, generator and check is committed to your repository and runs without us.

  • A.

    You are describing the most common state there is, and it has a name. The June 2026 study that cataloged configuration problems in agent files looked at 100 popular open-source projects carrying an AGENTS.md or a CLAUDE.md, found at least one problem in 91 of them, and called this one init fossilization: a file the tool generated on day one, never reviewed, treated ever since as the configuration. It sits alongside five other named problems in that catalog and three of them decide your first week. Lint leakage, where the file restates rules your linter already enforces, which spends context tokens on something that cannot be violated anyway. Skill leakage, where a rarely used tool or procedure lives in the file that loads in every single session instead of in something loaded on demand. And conflicting instructions, where two directives contradict each other and the agent picks one, differently, each time. Start by deleting, not by writing, and the order matters because it is the cheapest sequence. First, remove everything an automated check already enforces. If your formatter forbids it, the sentence about it is dead weight in every session for the rest of the project. Second, move the rarely used out. A procedure used once a quarter belongs in a skill the agent loads when it is relevant, not in the file that is always loaded. Third, find the contradictions, which is a mechanical read rather than a judgement call, and resolve each one to a single statement. What is left after those three passes is usually a fraction of what you had, and it is the part that was carrying the value: commands, invariants, and the things that genuinely cannot be discovered by reading the code. Only then is it worth generating and asserting, because there is no point building a check around a paragraph you are about to delete. Now the part people skip. The reason it fossilized is that nobody owned it, and if that does not change you will run this exercise again in a year. So the file gets an owner, it changes in the same pull request as the code it describes, and the checks make a false line visible on the day it becomes false rather than on the day someone finally reads the whole thing. Two things we do not say. We do not tell anyone to throw the file away and start clean, because the surviving lines were usually written by somebody who knew something real, and a regenerated file is how you get back to where you started. And we do not claim a number for what this recovers. The published work here measures what is in these files and what is wrong with them, not what fixing them buys a specific team, so what we commit to is that the file stops being able to lie to your agents without anybody knowing, which is a smaller and more defensible claim than the one you will hear elsewhere.

  • A.

    It looks like two cycles of recording before anything is denied, and the order is the whole trick. Every team that has tried this the other way round has the same story: somebody wrote an allowlist from memory on a Monday, the build failed on a transitive fetch nobody knew about on Thursday, and the policy was switched off on Friday and never came back. So the first cycle blocks nothing. The substrate records every outbound connection an agent run makes, by exact host, with the run and the diff it produced attached. What comes out of that is the artifact your security team has never had, which is the real list: your registry, your registry’s CDN, the two font hosts somebody added in 2022, your error tracker, the design tool API, the preview environment, the four hosts your own build tooling calls at install time, and reliably a handful nobody can explain. Explaining those is usually the highest-value hour of the whole engagement and it has nothing to do with agents. Then the allowlist is generated from that record rather than authored, which is the same rule the context files get: a list a person maintains by hand drifts, a list derived from what your build actually resolves cannot. Exact hosts, not wildcards, and that distinction is the finding rather than a preference. A wildcard on a code host is a wildcard on anything anybody can host there, which is precisely how the published sandbox bypasses worked and precisely how the AISI agent reached the open internet it had been granted. Enforcement then goes on in the order that keeps it survivable. Deny by default in the agent’s run substrate, not in the agent’s own settings, because a control the agent can read is a control the agent can be talked into changing and because the vendors themselves have shipped bypasses of their own sandboxes. Installs route through a proxy so the entire package path collapses into one observed destination, which is where the provenance checks already live. The browser the agent drives to verify its work runs inside the same perimeter, and this is the one people miss: verification is the largest hole in an otherwise tight policy, because a browser will fetch whatever a page tells it to. And a request to a host outside the list fails loudly with the host named, so the fix is a one-line addition with a reason recorded rather than an afternoon of guessing. After that it is a diff. An agent run that contacts a host no previous run for that repo has ever contacted is surfaced on the pull request as a reviewable line, which is how this stays useful in month six instead of becoming a log nobody opens. Three honest things. This is not a new guard and there is no eighth one: it sits in the security gate’s lane and runs before the merge decision rather than inside it, the same place the install-time checks sit. An allowlist reduces blast radius and is not containment, which we say every time, because a permitted destination can carry anything and a recorded connection tells you where a run went and never what was in it. And the value is time to notice, not prevention. The published incident took four days to surface inside an organization built to run exactly these experiments. We build and operate this inside your pipeline with your tooling and your network policy, it is committed to your repository, and it runs without us. We are not a security vendor, we do not run a threat intelligence feed, we do not do incident response, and we do not certify anything as contained.

  • A.

    Yes, and it is the most common version of this we walk into. The reason it happens is reasonable: the agent needed to run the build, the build already had credentials, so the agent got the build’s identity. What that quietly grants is everything the pipeline was ever trusted to do, to a process whose next action is decided by a model reading text that arrived from outside your organization. Frontend CI is where this bites hardest, because of what those credentials are. They are not read credentials against a database behind your VPC. They are deploy tokens, CDN purge keys, registry publish tokens, analytics and error-tracking write keys, and a design tool token. Every one of them writes to the public internet, and several of them write to your users’ browsers. A backend threat model built around data exfiltration does not cover a credential whose whole purpose is publishing. Three changes, in the order we make them. Split the identity first. The agent gets its own principal, never the pipeline’s, so that what it may do is a decision somebody made rather than an inheritance, and so the audit trail distinguishes a run the agent did from a run your pipeline did. Then take publishing out of the agent’s reach entirely. An agent run does not need to deploy, purge a cache or publish a package in order to produce a mergeable change, and it should not be able to. Those actions move to a separate job that runs after the merge decision, triggered by the merge rather than by the agent, which is the same separation the release path already gives you. In practice this single change removes most of what a compromised run could actually do. Then make what is left short-lived and run-scoped: credentials minted per run, expiring with it, held by the substrate and injected at the point of use rather than sitting in the environment where anything the agent reads can print them. The related habit worth breaking is that agent output is treated as trusted input by the next stage. It is not. A change an agent produced is untrusted until the guards and a human have been through it, which is what the whole harness is for, and that principle extends to anything the run wrote outside the diff. Two limits, stated plainly. Scoping a credential reduces what a run can do and does not tell you what it did, which is why this answer and the egress record are two halves of one thing rather than alternatives. And there is a real cost: splitting identities and moving publishing out of the agent path is a week of unglamorous pipeline work that produces no visible feature, so it competes with your roadmap and we say so before the engagement rather than after. We do this inside your existing CI with your existing secret manager and identity provider. We are not a security vendor, we do not audit your pipeline, and we do not certify anything.

  • A.

    Yes, and the envelope is agreed before the first agent run, not negotiated after someone notices. That covers which model endpoints are allowed, what may leave your network, what an agent may read and write, which repos and branches are in scope, and what gets logged. Restricted and on-prem environments are in scope, and the harness is engine agnostic by design, so it works against a self-hosted or vendor-hosted model without rewriting the guards. Everything the factory adds is committed to your repository: the context files, the skills library, the guards, the review agent and the eval set. There is no Enpitech service in the path that stops working when we leave.

  • A.

    No, and the gap between those two sentences is where most security reviews stall without anyone naming it. Not training on your data is a promise about what a model learns. Not retaining your data is a promise about what a server keeps. A provider can honour the first one completely and still write your prompts and completions to an abuse-monitoring store for a fixed window, which is standard practice and usually disclosed, and which for a coding agent means your file contents and your diffs, not an abstraction of them. Zero retention is the stronger claim, and three things about it are worth checking rather than assuming. It is generally an enterprise-tier capability rather than a property of the product, so the tier you are on decides whether the sentence in the marketing copy describes your account. On several platforms the exclusion from training is opt-in, which means the default is the thing your review is trying to prevent and somebody has to have gone and switched it off, usually the person who created the account before anyone was watching. And it applies per surface rather than per vendor, so an organization can be at zero retention on the API and at the default on the desktop product, the IDE extension, the browser tool and the CI integration, all from the same vendor and all pointed at the same repository. What we do about it is unglamorous and it is the part that survives us. At the start of an engagement we write down, for every surface that touches the repository, which endpoint it calls, in which region, on which tier, what the retention setting is, whether training exclusion is default or opt-in, and where in a console or a config file that is set. Then wherever the platform allows it, that setting becomes committed configuration rather than a dashboard state, because a dashboard state is invisible until it is wrong and a config file is a diff with a reviewer on it. The version of this that fails is the one where a correct answer was given once, in a meeting, about an account that has since been upgraded, migrated and re-integrated twice. Two limits stated the same way every time. We are not auditors, we do not issue certifications and we do not sign your data processing agreements, so bring us the policy and the counsel and we will make the engineering match them. And a retention setting is a contractual promise rather than a technical control, which means it reduces exposure and does not remove it. Where a repository genuinely cannot leave your boundary, the answer is that it stays out of agent context, or the model runs inside your boundary, and not that a checkbox was ticked.

  • A.

    Usually yes, and that is the custodian nobody reviewed. The model provider gets a three-month procurement process. The tracing platform, the eval harness, the prompt observability tool and the error tracker get an API key pasted in by one engineer on a Tuesday because the pipeline needed to be debuggable, and every one of them is receiving the same content the provider sees: prompts that contain source files, completions that contain diffs, traces that contain both, and in a coding pipeline that is your repository arriving somewhere your security review never looked. There is a concrete reason to take this seriously rather than treat it as a hypothetical. In May 2026 the AI evaluation platform Braintrust detected unauthorized access to an AWS account holding customer API keys and told customers to revoke and regenerate every key stored with it. Two facts belong with that story every time it is told: what was reached was credentials rather than customer source code, and one customer was confirmed directly affected. We cite it for its structure, not its body count. An eval platform sits in the middle of a coding pipeline, holds the content and often the keys to the provider as well, and is chosen on developer experience rather than on custody. The fix is ordinary engineering and it is cheap when it is done at install time and expensive when it is done after a year of traces. Decide per tool whether it needs the payload at all, since a large share of what teams want from tracing is timing, cost, tool sequence, failure mode and outcome, none of which requires the file contents to be transmitted. Where the payload genuinely is needed, redact before the span leaves the process rather than after it arrives, so secrets and customer data never depend on the vendor’s controls. Give every one of these tools its own credential with its own scope and rotation, so revoking the eval platform does not mean rotating the provider key that half the org shares. Prefer the self-hosted option where the tool has a real one, which for this category is more often than people expect. And put every tool in the pipeline on the same sheet as the model provider, because a boundary that covers one custodian and not the other four is not a boundary, it is a preference. This is the same shape as the egress work and it is a different question. Egress records where a run went. This one asks who holds a copy of what it read and wrote, and under whose terms.

  • A.

    You do not record it on every line, because most lines carry no reason worth keeping and a repository that pretends otherwise is one nobody reads. Three tiers, and the whole method is deciding which tier a line is in at the moment it is written rather than a year later. The bottom tier is code that is simply what it is, and it gets nothing. The middle tier is a deliberate choice with an obvious alternative, a memoization boundary, a query key strategy, a decision to render on the server, and it gets one sentence in the commit that made it plus a line in the module’s own notes, so the reason lives next to the boundary rather than in a wiki with a different owner. The top tier is the one this is really about: code that exists because something broke, and removing it makes it break again. That tier does not get prose. It gets an executable invariant, which is a test named after the failure rather than after the function, asserting the behavior the line protects rather than the line itself. Focus returns to the trigger after the dialog closes. The live region announces once, not twice. The list does not scroll the page behind it on iOS. The request is not issued more than four times a second. Written that way the reason survives the refactor, because an agent that rewrites the implementation and keeps the behavior passes, and an agent that tidies the behavior away fails before a human is asked. The timing is the part teams get wrong and it is free to get right. The only moment the reason is both known and cheap is the pull request that fixed the bug, when somebody has just spent a day finding it. Six months later it costs an archaeology project, and after the person leaves it is gone. So the guard is not that every line has a test. It is that a fix for a reported defect does not merge without one, which is a rule your review already half enforces and which we make explicit. Underneath that sits the part the agent actually consumes. The impact surface is derived from the repository rather than authored: for a proposed change, which tests cover it, which components and routes depend on it, which invariants are in range. It is generated, so it cannot drift the way a hand-maintained rules file drifts, and it is handed to the agent before it writes rather than asserted after. There is a measured reason to prefer that order, and it is in the deep answer next to this one. Two limits we state every time. This is not a documentation program and we are not a documentation vendor: nothing here produces a document whose only reader is the person who wrote it. And an invariant proves a behavior still holds, never that it is still needed, so invariants get reviewed and retired like any other test, or the set becomes the next thing nobody trusts and the whole mechanism is back where it started.

  • A.

    It would not, and that is the finding rather than our opinion. The TDAD work published in March 2026 ran the experiment directly. Giving the agent a derived map of which tests a proposed change would affect, before it made the change, took test-level regressions from 6.08% to 1.82% and raised the share of issues actually resolved from 24% to 32%. Giving it test-driven-development instructions without that targeted context took regressions to 9.94%, which is worse than giving it nothing. The authors’ reading is the sentence to take into your next planning meeting: surfacing contextual information outperforms prescribing procedural workflows. A rule in a file competes for attention with everything else in the file. A fact about the change in front of it does not. The behavioral side of this is measured too. The May 2026 analysis of 20,574 coding-agent sessions across 1,639 repositories found constraint violations to be one of the seven recurring forms of misalignment, spanning collaboration style, implementation strategy and command execution, with agents rejecting narrow implementation constraints and expanding a deliberately minimal change into the larger workflow they judged correct, sometimes after repeated pushback in the same session. It also found that overall misalignment rates decline over time while constraint violations grow as a share of what remains. Instruction compliance is not a control surface, and every quarter you spend making the file more emphatic is a quarter spent on the one lever the data says is weakest. So the file keeps the job it is good at and loses the job it is bad at. Good: orientation, vocabulary, where things live, what this repository calls things, the commands that actually work. Bad: anything you need to be true, which moves out of prose and into a check. A rule that matters becomes a guard that fails a run, and a rule that does not matter enough to check is a rule you should delete, which is usually a third of the file and the reason the rest gets skimmed. Two things this is not, and both are answered separately above. It is not the file going stale, which is a maintenance problem we solve by generating everything derivable and asserting the rest in CI. And it is not the file being too large to navigate, which is a structure problem. This one is the file being read, understood and then not followed, which no amount of rewriting fixes. We build the checks, the derived context and the failure paths inside your pipeline, they are committed to your repository, and no eighth guard gets added to do it.

  • A.

    It moves the queue, yes, and that is the point: it moves it to the only place where the thing you are trying to catch is visible. Start from what is different about the failure. A branch-level check answers "is this change correct", and by the time you have agents in the repository that question is being answered well, because it is the question every guard was built for. The question nobody is answering is "is this change correct next to the other six that are about to land", and no amount of running the same checks harder on an isolated branch will reach it. So the integration stage is not a second copy of your pipeline. It is a short, specific list of checks that are only meaningful against a composed tree, and on a Frontend that list is unusually concrete. Does the design system now contain two components that render the same thing, which is the duplicate check run across the merged result rather than across one diff. Does a token resolve to a different value than either branch intended, because two branches edited the same scale and the winner is decided by import order. Does the router have two patterns matching one URL. Does a shared hook have a caller written against a contract that the same merge just changed, which the type checker will happily allow when the change was a widening. Does the accessibility guard still pass on pages that neither branch touched but both now compose, which is where stacking, focus order and live regions actually break. Is the route still inside the performance budget once every lazy chunk that arrived this cycle is counted together rather than one at a time. And does the contract gate still hold against the spec version the merged tree consumes. Every one of those is cheap to run and impossible to run early, which is exactly the profile of a check that belongs after admission rather than before it. Then the sequencing, which is what keeps it from becoming the bottleneck people fear. Pull requests are admitted in an order and tested against the tree they will actually produce, including the ones ahead of them, and the batching we already do for CI cost is the same mechanism: a batch of four is roughly a quarter of the runs and it is also the only artifact in your pipeline that contains four changes at once. When a batch fails it is bisected automatically rather than thrown away, so an innocent pull request is not punished for a neighbour. Three limits, stated the way we state the others. A queue buys correctness with latency, and there is a volume below which the latency costs more than the defects do, so the audit measures your merge rate before we switch anything on. Bisection only tells the truth if the suite does, which makes flake quarantine a prerequisite and not a follow-up, the same dependency the test-quality gate already has. And an integration check can tell you that two correct implementations of the same thing both landed. It cannot tell you which one your design system should keep. That is a human decision and we do not automate it away. No eighth guard is added here: this is the existing guard set evaluated at a second point in the pipeline, on the CI you already run.

  • A.

    Probably not, and the evidence usually cited for doing it is weaker than it looks, so it is worth being precise before you spend political capital on a mandate. The 2026 study of 33,596 agent-authored pull requests across 2,807 repositories did find a difference: replaying merges of pull request pairs, it measured textual conflicts in 41.7% of cross-agent pairs against 19.8% of pairs from the same agent. Taken alone that reads like an argument for a monoculture. Read the rest of the paper and it does not carry that weight. Cross-agent pairs were 0.5% of all the co-active pairs in the dataset, occurring in roughly 122 of the 2,807 repositories, so the higher rate rests on a small and unusual slice, and a repository running two vendors at once in 2026 is not a random repository. We quote the direction and we will not build you a plan on the number, which is the same rule we apply to every figure on this site. There is also a reason to expect the direction without needing the study, and it is the reason the mandate does not fix it. Two runs of the same agent on the same repository conflict less because they are reading the same context and converging on the same conventions, not because they share a vendor. That is a property of what the agent was given, and it is purchasable without a procurement decision. So the lever is the context, not the logo. One set of context files, one skills library, one component registry served over MCP, one guard set and one specification per unit of work, read by every agent in the building whatever its badge, and the convergence you were hoping to buy by standardising is the convergence you get. Two agents that both query the real component registry do not each invent a dialog. Two agents that both receive the same derived impact surface do not each pick a different place to put the same state. The harness is engine agnostic by design for exactly this reason, and it is also why we can say it plainly: the factory does not require you to run our preferred agent, and it does not stop working when you change one. Which you will. The standardisation argument also has a cost that nobody prices at the time. It puts your delivery on one vendor’s roadmap, pricing and availability, in a category where the leader has changed more than once a year, and it means the day you want to move, every habit and every piece of tooling moves with it. Where standardisation genuinely does earn its keep is narrower and worth doing: one place agents run, one identity and credential model per run, one telemetry stream so cost and outcome are comparable across tools, and one admission path into main. Standardise the surroundings and let the engines compete. The honest limit is that none of this makes concurrency free. The residual conflicts that survive shared context are the ones where two people genuinely asked for overlapping work, and that is a planning problem rather than a tooling one. We will tell you when what we are looking at is a planning problem, because a guard that gets pointed at one just becomes noise.

  • A.

    It means the pipeline stops accepting the word approval from anything that cannot be held to it, and the work is mostly plumbing rather than policy. Start with why the usual control dissolved. Separation of duties, or the four eyes principle if that is the phrase your auditor uses, was never really about two people, it was about two independent judgements, and it survived for decades on an accident of implementation: asking for a change and clearing it required two humans because there was no third option. Agents removed the accident. The same engineer can now open a run that writes the change, trigger a second run that reviews it, and merge on the strength of that review, and every step of it is recorded, attributed and green. Nothing was bypassed. The control simply has nobody in it. So the first change is vocabulary enforced by the system rather than agreed in a meeting. A machine review is a guard: it is a check that ran, it has a result, it belongs in the record, and it may block a merge. It is never an approval, and the pipeline refuses to count it as one, because an approval is a statement that a person is accountable for a judgement and a guard is a statement that a rule held. Teams conflate them because both render as a green tick in the same column, which is a user interface accident that has quietly become a governance one. Then the identity work, which is where most of the actual effort goes. Every agent run has its own principal, distinct from the person who started it and from the pipeline, which is the same split the egress and custody work already requires and is reused here rather than rebuilt. The requester of a run is recorded, and the merge check compares it against the approver: the identity that asked for a change cannot be the identity that clears it, which is a rule a machine can evaluate and a policy document cannot. Where a change class needs a human approval, the pipeline names which classes those are, checks that the approver is a person, and fails closed. Where it does not, it does not pretend, and the record says guards passed, no human approval required, which is a far more useful sentence to an auditor than a tick nobody can explain. Then the routing, because this only holds if the human approvals that remain are affordable. Guards run first and return a specific reason to the author, so a change that is going to be rejected never reaches a person. Changes are classified by what actually needs judgement rather than by size, which on a Frontend means a new component, a token change, a route, a change to copy a customer reads, anything touching an irreversible flow, and anything touching the design system. Those get a person by rule. A dependency bump with a passing contract test does not, and saying so out loud is what buys the attention for the ones that do. Three honest limits. This does not manufacture attention, and if the queue is bigger than the people then the answer is fewer pull requests or more reviewers, not a stricter rule. A rule that everybody routes around within a month is worse than no rule, so the classification is tuned against your actual merge history during the audit rather than copied from a framework. And we are not auditors, we do not certify anyone, and nothing here makes you compliant with anything. We build the controls, produce the evidence as a by-product, and hand both over with the rest of the factory.

  • A.

    On the published evidence it is mostly the second, and the value of the study is that it separates the two rather than asserting either. Habituation at the Gate followed 11,429 reviews from 400 repeat reviewers across seven months and found approval rates on agent-authored code rising from 30.1% to 36.8%, with a cumulative gap of 14.5 percentage points between reviewers in the first and the tenth decile of agent-review experience. If that were trust calibrating on evidence, the other numbers would move with it and they move against it. Inline comment volume fell 22% and review latency rose 3.5 times, which is the signature of less attention arriving later rather than of a reviewer who has learned where to look. The study also closes the three exits a team reaches for when it hears this. It is not the calendar, because the effect tracks how many agent pull requests that reviewer has personally seen rather than the date. It is not general leniency, because human-authored pull requests in the same repositories over the same period went the other way. And it is not the work getting easier, because controlling for pull request difficulty does not remove it. The authors call it reflexive habituation under a growing queue, and note it is the pattern you would expect from any alarm that mostly turns out fine. Take the finding seriously and it changes what you measure, because approval count is now known to be a corrupted metric and it is the one every dashboard shows. Four things we instrument instead, all of them derivable from data your forge already has. Review depth over reviewer tenure, which is the study run against your own repository and usually the first time anyone has looked. Escaped defect rate split by whether a change was human-approved, guard-cleared or both, which is the only number that tells you whether the approvals you are collecting are doing anything. Time-to-first-comment against queue length, because habituation is a load effect and it shows up as a load curve. And the share of merges where the approver was also the requester, which should be a rule rather than a metric and is worth measuring first because it is usually higher than anyone expects. Then the changes, and the useful ones are about load rather than about exhortation, since telling reviewers to try harder is the intervention the data most clearly rules out. Shrink what reaches a human: guards that fail with a specific reason, smaller changes because the specification was bounded, and a machine review that runs first and is recorded as a guard rather than as an approval. Rotate who reviews what, because the effect is per reviewer and per exposure, so a reviewer who sees every agent pull request in one area is the one it lands on hardest. Sample: a small share of already-approved agent merges get a second, deliberately slow read, which is how you keep a live reading of the drift rather than a memory of it. And make the high-consequence classes unskippable by rule rather than by attention. Two limits. Habituation is a human factors effect and we are engineers, not a research group: we install the measurement on your pipeline and report what it says, and we will not tell you we have solved a cognitive phenomenon. And we will not propose adding reviewers as the answer, because the whole premise of the factory is that the org you already have ships more, not that it grows.

  • A.

    Your senior Frontend engineers write them, and the engineer who wants nothing to do with it is usually the one we most want in the room, which is not a diplomatic answer but a practical one. Take the authorship question first, because getting it wrong is the most common way one of these installs fails. A guard encodes a standard, and the standards worth encoding are the ones already being enforced in your review comments, inconsistently, by four people who mostly agree. Nobody outside your team knows what they are. We can bring the shape of a guard, the CI wiring, the failure messages, the escape hatches and the experience of having done this before, and we cannot bring your answer to whether that new date picker should have existed, which token a warning surface uses, or what your empty states are supposed to do. So the first weeks of an install are largely extraction rather than construction: we read the last few months of review comments, which is the single richest source of tacit standards in any codebase because it is where they get stated out loud, we sit through reviews, and we write down the rule behind each recurring comment. Then each candidate rule goes back to the seniors in the only form that settles an argument, which is a run against your real merge history showing what it would have caught and what it would have blocked. That last number is the one that matters. A rule that would have blocked forty legitimate pull requests is not a standard, it is a preference, and finding that out on history costs nothing while finding it out in production costs the rule its credibility permanently. Now the refusenik, and it is worth separating two people who look identical in a meeting. The first has watched a tool rollout before, is being asked to absorb more review load, and reads this as another thing that will be done to them. That is a reasonable position and it dissolves on contact with the actual proposal, because the proposal is that their standards become the thing that blocks a merge rather than a comment somebody argues with. In practice the engineer who was most against it at the kickoff is frequently the one who ends up writing the most guards, for the obvious reason that they are the person with the strongest opinions about what good looks like, and those opinions have never had anywhere to go except a review thread. The second is a genuine objection about direction, usually some form of this makes it easier for people who should not be touching the Frontend to touch the Frontend, and that one is not resolved by process. We answer it with the sequence: the guards go in before the roles do, and we refuse the reverse order, so by the time a PM or a backend engineer opens a pull request the standard is already mechanical and the failure mode they are worried about is the one thing that cannot happen quietly. If that answer does not satisfy them, the install is still fine and the disagreement is real, but the person deciding it is your CTO rather than us. Two things we will not do. We will not run this as a transformation programme with a change-management track, because we are engineers and that is not our competence or our product. And we will not install guards over the objection of the people who have to live with them, because a rule the team routes around within a month is worse than no rule and we will have taken your money to make your pipeline noisier.

  • A.

    Load and outcomes, both baselined before anything is installed, and we will say up front which of them we expect to move and when. Trust is a genuine thing and a terrible instrument. It is self-reported, it lags the mechanism by months, it moves for reasons that have nothing to do with your pipeline, and the version of it that improves fastest is the one you least want, which is a team that stopped looking closely. So we report it never as a headline and at most as a survey question you own. Here is what we instrument instead, all of it derived from data your forge and CI already produce. Guard catch rate, split by guard, which is how much is being stopped before a person and by what. Review rejection rate on agent output, which should be visible and should fall, and which is the closest honest proxy for the almost-right problem. The share of pull requests that reach a human having already failed nothing, because that is the population your reviewers actually experience and the number that decides whether the install felt like anything. Review time per pull request, read beside merged volume and never instead of it, since review time per pull request falls trivially if everyone stops reading. Merged volume from outside the Frontend team, which is the claim the factory is actually making. And escaped defects, split by whether the change was guard-cleared, human-approved or both, because it is the only number that tells you whether the approvals you are collecting are doing anything. Alongside those, throughput read beside stability, which is DORA’s finding and not ours: their 2025 State of AI-assisted Software Development, published February 2026 off roughly 5,000 respondents, found AI acts as an amplifier, magnifying the strengths of organisations with a solid delivery foundation and the dysfunction of those without, lifting throughput while often costing stability where the foundation was thin. Reporting throughput alone in an AI rollout is how you get a quarter of good news followed by an incident review. Three things about the baseline, because it is the part most often skipped and the part that makes the rest meaningless. It is taken during the audit, before anything is installed, on your repository rather than on a benchmark. It is taken over enough history to survive one bad sprint. And we write down at the start which numbers we expect to move in the first month, which are quarter-scale, and which may never move, so that nobody gets to reinterpret a flat metric as a win afterwards. Two limits we hold to. No number we report about your delivery becomes an Enpitech marketing claim without a written case-study agreement from you, and we do not publish ratios in any case, because the figure is a property of your codebase rather than of your engineers and it does not transfer. And none of this measures whether the code was worth writing. A factory can tell you that what shipped met your standard and shipped faster than it used to; whether it was the right thing to build is a product question and it stays yours.

  • A.

    What the reviewer is reviewing, and it is a smaller change than it sounds because most of it is a reallocation rather than an addition. Today your senior opens a pull request and does two jobs at once. The first is mechanical: is the token right, does this component already exist, are the empty and error states handled, what does a keyboard user get, does this add three hundred kilobytes to the route. The second is the one only a person can do: was this the right change, does it fit the model the rest of the codebase holds, what happens to it in six months. The mechanical job is what agent volume multiplied, and it is also the entire job a guard can do. So the first move is to stop paying a senior to do it. Once the guards run before a human opens the diff, the review that remains is a review of the decision, and that is where the understanding problem becomes visible and fixable rather than just depressing. Three things we install alongside that, and all three are cheap. The author has to be able to explain the change, and the review asks them to. Not as a ceremony and not as a template field nobody reads, but as the actual first exchange on a non-trivial pull request: why this shape, what did you consider and reject, what would break. An engineer who cannot answer has not understood what they submitted, which is a finding rather than a failure, and it is the single highest-signal question available to you because it is the one an agent cannot answer on their behalf. The session that produced the change is attached to it, so the reviewer can see what was asked for and what came back. Reviewing a diff without the prompt that produced it is reviewing an answer without the question, and half the time the defect is in the instruction rather than the output. And rejection becomes the pairing moment rather than authoring. The traditional pair session had a senior watching somebody type, which is the part that is genuinely gone and is not coming back. The replacement is a senior and an engineer reading a rejection together, either from a guard or from production, because a failure the author owns is the most efficient teaching surface there has ever been and there are now considerably more of them. Two things not to do, both of which we see. Do not make juniors hand-write code as a training exercise while everybody else uses agents, because you will have trained them for a job nobody holds and taken away the tool they are actually going to be evaluated on. And do not respond to the understanding gap by routing all agent output to your seniors for closer reading, which is the instinctive move and which raises the load on the exact people you cannot afford to slow down. The correct direction is the opposite: fewer things reach a person, and the ones that do come with a human who can defend them. One limit, stated plainly. None of this is a substitute for somebody senior deciding that a particular engineer needs attention this quarter. We make the signal visible and the load survivable. Who gets coached is a management decision and it stays with you.

  • A.

    The half that was always the job, and it is now the only half, which is a better curriculum than the one it replaced rather than a thinner one. Be precise about what a guard actually holds. It holds standards: rules with an owner, a rationale and a deterministic answer. Which token a warning surface uses, which component already exists, what an empty state has to do, what this route is allowed to weigh, what a keyboard user gets, whether the copy went through the locale pipeline. Those were never the interesting part of being a senior engineer. They were the part that was expensive to transmit, because they lived in four people’s heads, got stated inconsistently in review comments, and took a new engineer a year to absorb by repeated collision. Writing them down does not remove them from the curriculum, it removes the year. What a guard cannot hold is judgment, and the list is longer than most teams expect once you write it out. Whether this is the right change at all. How to decompose a vague request into something an agent can execute and a reviewer can check, which is the skill that most determines output now and which almost nobody is taught. How to verify work you did not write, which is a genuine discipline with its own techniques and is not the same as reading it. How to read an unfamiliar codebase and hold a model of it. When the agent is confidently wrong and the tests agree with it. What to escalate. And the one the research names directly: what not to delegate. The ETH Zurich study behind our answer on the homepage found that seniors keep control through structured delegation, deciding deliberately what to hand over and what to keep, while juniors swing between over-reliance and avoidance because that boundary was never made explicit to them. It is teachable the moment somebody writes it down, and almost nobody has. So an install makes three of those concrete. The rules are written with rationales rather than as bare assertions, because a rule you can read the reasoning for teaches something and a rule that just fails does not. The specs are the artifact everyone works from, which makes decomposition the visible, reviewable, improvable skill rather than a private act inside somebody’s prompt window. And the delegation boundary is documented as part of the pipeline rather than left as folklore: what an agent may open unaccompanied, what needs a named human before it merges, what never leaves a person’s hands. Two honest limits, and the second one matters commercially so we would rather say it here than have you discover it. A factory raises the floor and shortens the path; it does not manufacture senior engineers, and anyone who tells you a pipeline produces judgment is selling you something. And the people side of this is a different service from ours on purpose. The factory is how your org ships. Where a team wants the delegation boundary, the verification discipline and the spec-writing actually taught rather than merely enforced, that is a training engagement on your own codebase, and it is worth being clear which of the two you are buying.

  • A.

    You can, and it is worth understanding exactly what you get, because it is the first thing every team tries and it solves the smaller half of the problem. A model reading a diff can produce an accurate summary of the diff. That is genuinely useful, it is better than an empty template, and it removes the category of description that claims work nobody did, which is the largest single inconsistency type in the published analysis. What it cannot do is the part that made the description worth having. It does not know why the change exists, which alternative was rejected, which of the three files was the actual fix and which two were tidying, what was deliberately left undone, or which constraint made the obvious approach wrong. It will write a fluent paragraph in place of all of that, and because it is fluent, nobody will notice the record is missing. You have replaced an unverified claim with a confident restatement, which reads better and carries less. So use it for what it is good at and put a guard in front of it. Derive the facts mechanically rather than by generation: the routes touched, the components added or changed, the tokens moved, the stories that changed, the bundle and accessibility deltas, all read out of the build you already run, where nothing has to be trusted because nothing was invented. Then require the author, human or the person who dispatched the agent, to supply the two sentences no tool can: what this was for, and what was consciously not done. Two sentences is not a bureaucratic burden, and the pull requests where somebody cannot write them are exactly the pull requests worth a longer look. Then check the whole thing against the diff, claims to changed surfaces and changed surfaces to claims, and fail the run on an unmapped claim or an unmentioned surface. The order matters: generate the derivable half, require the human half, verify the union. A summariser on its own skips straight to the middle and calls it done.

  • A.

    You would not, which is the property that makes it worth measuring rather than debating. A description that reads fine is the symptom, not the counter-evidence: the published work found that structured, well-presented descriptions get faster reviewer responses and higher merge rates independent of how the reviewer felt about them, so fluency and correctness are not correlated here in the direction anyone assumes. Run the measurement on your own history instead, because it is a weekend of work and it settles the argument with data from your repository rather than somebody else’s. Take the last few hundred merged pull requests. For each one, extract the claims from the description and the surfaces from the diff, and compute two numbers: the share of claims with no corresponding change, and the share of changed surfaces with no corresponding claim. The first is the misdirection rate and it is the one that misleads a reviewer. The second is the silent-payload rate and it is the one that lets a refactor, a dependency bump or a token change ride into a release nobody discussed. Then split both by author type, agent against human, and by change size, because the pattern usually concentrates in exactly one quadrant and the fix should go there first. Three supporting signals are cheap to collect at the same time. Time to first comment, because a description that misdirects tends to produce fast, confident approval rather than questions. Post-merge revert and follow-up-fix rate on the pull requests where the two sets disagreed. And the share of merges where the description mentions a user-visible behaviour, a loading state, an error state, an empty state, with no story, visual diff or test attached to back it up, which on a Frontend codebase is the highest-yield category of all. We run exactly this as part of the audit at the start of an engagement, on your real merge history, and the output is a number and a list rather than an opinion. If the numbers come back clean, we say so and you have bought one fewer guard, which has happened.

Didn't find yours?Ask us directly.