Doctrine

Agentic Shift-Left

Every team adopting AI-assisted development hits the same wall. Agents write features in minutes. They also write brittle tests, hard-code selectors that break on the next PR, and skip quality gates nobody enforces. The suite bloats, the flake rate climbs, and trust collapses.
The traditional shift-left response shifts the work left without shifting the worker. Agentic shift-left shifts both.

The Agentic Shift-Left
Lifecycle

Four stages. A human starts it, agents do the heavy lifting, a human confirms the result, and agents guard it going forward.

01
Human

Triage

A human reads the ticket, the PR, or the feature brief and makes the CX/revenue call: does this change affect something a customer would notice? This is the one decision the methodology refuses to automate. An agent can assess technical risk, but the question "will a customer care?" requires business context that lives outside the codebase.

02
Autonomous

Automate

Sub-agents own the work. The methodology decomposes test automation into roles that can be independently dispatched, each with isolated context and a schema-validated return contract. Independent journeys are dispatched in parallel; each journey runs through composer → reviewer cycles until approved.

03
Human + Harness

Confirm

The tests get tested. Every test must be proven to fail where the fix is absent (negative control). Adversarial probes challenge the tests themselves. The harness blocks QA sign-off until evidence exists. Coverage is a human responsibility: the QA engineer owns what must be covered.

04
Autonomous

Guard / Heal

Gated releases, layered verification. Self-repair establishes a baseline by running the failing scope three times, then classifies each failure from its own evidence — trace, console, network: fails every run, it's a deterministic failure (an app bug, filed with evidence; the test is left alone); passes sometimes, it's a flake (quarantined with evidence); mechanical drift, it's healed autonomously. Each test ends green, quarantined or explained.

Guard Layers

Once tests are committed, the methodology prescribes a layered, gate-first test architecture:

Regression
Runs in the go-live pipeline. A regression failure stops the release — regression is a gate, not an alarm.
Smoke
Targets individual features, pages, and components. Runs on every pull request. Speed is their contract.
E2E
Verifies complete user journeys. Every step happens in the browser — replicating the user's experience as closely as possible.
Self-Repair
Autonomous triage — app bugs, test drift, and flakes classified from evidence. Mechanical repairs apply themselves; semantic changes, such as re-baselining an assertion, return as operator-pending for a person to decide.

The Architectural
Foundation

A test that hard-codes CSS selectors is a test that breaks when a class name changes. An agent that writes tests with hard-coded selectors produces a suite that rots faster than it grows.

Separation of Concerns

The foundation is a three-layer separation. When a frontend redesign changes every data-testid in the application, zero test files change. Each layer is the single source of truth for its concern.

Test Code
Owns: Business intent
Changes when a requirement changes
Steps API
Owns: Interaction mechanics
Changes when the framework evolves
Page Repository
Owns: Selectors
Changes when the UI is redesigned

Tests Anyone Can Read

The Steps API is the interface between human intent and automated verification. A product owner can read the test and know what it checks. An agent can write it without knowing how click-interception retry works under the hood.

await steps.on('addToCartButton', 'ProductPage').click()
await steps.on('cartCount', 'CartDrawer').verifyText('1')

The framework manages stability (auto-wait visibility, scrollIntoView, click-interception detection with classified retry), logging (zero log lines in project test code), and selectors (resolved at runtime from the page repository).

Commit or
Discard

Tests are discardable by default. The verification work is still required. But committing to the permanent suite is a separate decision with a separate gate.

The agent proposes durable automation only when CX/revenue impact justifies permanent regression coverage. A human confirms the proposal. Without explicit confirmation, the test stays in the evidence bundle and is not committed to the repository.

Commit

High CX / revenue impact

A login-flow change that affects every user → permanent regression test joins the suite, guarded by pipelines going forward.

Discard

Verified, low impact

A tooltip copy fix → verify it, attach the evidence, discard the test. The suite stays lean; the evidence bundle stays complete.

The commit-or-discard gate prevents suite bloat — most test suites grow without bound and eventually collapse under their own maintenance weight.

Enforcement, Not
Instructions

The distinction between a methodology and a best-practices document is enforcement. On Claude Code a plugin adapter binds the five Achilles agents: tool and path scopes per agent, and 8 hooks that advise by default and deny only the irreversible. The main session is never bound. The sections below list what runs, what each part denies, and how to turn it off.

8 hooks ship with the package, in one TypeScript module under claude-code/ declared by claude-code/hooks.json. They run on Claude Code tool calls, agent spawns and turn completions for the five Achilles agents and pass every other session through. There is no activation ladder and no role kernel: an agent's definition under agents/ is its scope, and the adapter judges content, not identity.

Default posture is advice. A deny is reserved for the actions that cannot be undone or that put a false claim in front of other people. Every deny names the action to take and ends with a References: block of the methodology sections it enforces.

The 8 hooks

Hook
Event and effect
Denies
Bash judge
Bash tool call
One parsed-command model: advises on commit grammar and protected state paths; rewrites a missing playwright-cli -s=<slug> from the agent id.
git commit --no-verify / sign bypass; AI attribution trailers in a commit or PR body; k6 run over 1000 VUs, 3600 s, outside the allowlist or against production; git push --force; rm -rf outside the project; a spend-listed spec without its opt-in; a credential or PII shape written into a committed file
Pipeline ledger model
Write/Edit on the onboarding and perf ledgers, agent spawn, pane
Schema, transitions, reviewer cycles and per-phase deliverables as advice; the phase table in the pane; an integrity hash in the plugin store.
nothing
Sign-off
Tracker transition tools, gh pr create|ready
A verdict-shaped comment without a receipt is advised on.
A transition to done or a published PR without the reviewer-written receipt .achilles/adversarial-verification/<ticket>.json and an evidence bundle for that ticket; any sign-off while the bundle's HAR or console log holds a live credential
Dispatch discipline
Agent spawn
Brief preamble present, concurrency limits, a fresh reviewer per review, no grouping on a strict pass.
nothing
Return review
Agent turn complete
Validates the return against schemas/subagent-returns/<role>.schema.json, checks cited attestation paths exist, parses the judge verdict into the pane.
nothing
Spec hygiene
Write/Edit on specs, tests/**, the root Playwright config
Test ids on every added case, the import boundary, the evidence floor for a diagnosing agent, the factory content rules when a rule file exists.
nothing
Selector development
Write/Edit on frontend source by an author on a selector brief
The eight-step order shown as state; a revert reminder when a scope is left open.
An edit that is anything other than one added inert test attribute on one opening tag
Reporting
Turn complete, agent end
Archives each run's artifacts under .achilles/runs/, closes the agent's browser sessions, writes the run and perf summaries.
nothing

The 6 agents

Role scope is the enforcement for separation of duties. The orchestrator dispatches and keeps index-level state; it never writes a spec and never opens a browser session. The inspector drives the live app read-only and writes app context and evidence notes. The author writes under tests/** and the page repository, runs the suite and playwright-cli, and on a scaffold or selector brief gains the config files or one frontend file. The reviewer reads and runs; its only outputs are a verdict and a spill file, and it is a fresh dispatch per review. The reproducer takes one suspected defect and decides, without reading the suite or earlier reports, whether it is a bug; its verdict is what a defect filing and a sign-off need. The doc-writer edits docs/** and report files with no shell. The main session delegates a QA task with delegate_qa or /achilles <task>, keeps working, and receives the hand-back (DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, BLOCKED) in a turn of its own.

How to switch it off. ACHILLES_DISABLE=1 in the operator shell passes every event through for new sessions. Factory rules switch off by removing the rule file. Nothing inside a session can disable the adapter.

What it does not do. Scopes bound tools and paths, not content: an author can still write a bad test, and the review dispatch is what catches that. The Bash judge reads one command line, quote-aware, one level of sh -c; aliases, functions and scripts are not seen. The import-boundary check is a static floor, not a sandbox.

What a deny looks like

When the agent tries to transition a ticket without an evidence bundle:

❯ [BLOCKED] Sign-off refused — no evidence bundle for this ticket.

hook          sign-off
decision      deny
ticket        PROJ-1042

Do: run the verify-change workflow for PROJ-1042; the bundle under
tests/e2e/evidence/PROJ-1042-*/ and the reviewer receipt unlock the transition.
References: skills/achilles-orchestrator/workflows/verify-change.md

The Honest
Constraint

A methodology must be honest about what it cannot yet do.

The lifecycle works within the boundaries of the environment it runs against. When that environment is production — when every test hits a live database, real payment processors, and actual customer-facing state — the methodology must exclude its most critical flows.

Checkout. Registration. Payment. Password reset. Account deletion. These are the flows with the highest CX/revenue impact, and they are the flows that cannot be safely automated against a production environment.

The methodology covers these flows architecturally. Exercising them requires a fully controllable test environment — a faithful replica of production without live connections to payment processors, identity providers, or customer-facing state — and full control over test data: the ability to programmatically generate, seed, and clear it so every run starts from a known baseline.

Platform Coverage

The second constraint is platform. The element layer is already platform-agnostic by design: Element is an interface, WebElement is its Playwright implementation, and PlatformElement is the Appium/WebDriverIO implementation beside it. The page repository resolves the same named selector through UiSelector on Android and predicate strings on iOS.

What is not here yet is the rest of the lifecycle. The agent skills, the harness gates, and the self-repair driver all assume a Playwright browser session today. Mobile support is on the roadmap, not in the package. Until it lands, treat everything on this page as a doctrine for web applications — the methodology generalises, the tooling does not yet.

What Achilles Is Not

It is not a hosted runner: suites run on your machine or your CI. Enforcement exists on Claude Code only; pi loads the skills without it. It does not cover native mobile. It does not heal tests at runtime: achilles-self-repair works offline on a red suite. No benchmark of detection or flake rates is published. The limits that remain are listed in docs/harness/claude-code.md.

Why Not Just Prompt
Better?

AI test generators produce tests. Achilles enforces a methodology around them.

Prompt-driven testing

Ask your copilot to write Playwright tests. You get tests — with hard-coded selectors, no negative control, no evidence bundle, and no gate preventing a flaky test from merging. The agent follows instructions. Nothing enforces them in the session.

Achilles

The agent writes tests through a three-layer architecture that isolates selectors from logic. The adapter refuses ticket sign-off without an evidence bundle and a reviewer-written receipt, and a non-draft pull request without them. The methodology is the codebase, not a wiki page the agent never reads.

Getting
Started

Achilles runs on Playwright. If your stack uses Playwright, integration is additive — you don't rewrite existing tests.

Install the two npm packages, or claude plugin install achilles@achilles. The npm postinstall registers the plugin adapter in the project settings. Point the page repository at your application's selectors. Write new tests through the Steps API — existing Playwright tests continue to run unchanged alongside them.

Achilles 0.1.8 is a harness-neutral methodology with two thin adapters: on Claude Code the plugin registers 6 agents, 8 hooks, the delegate_qa tool and the /achilles command; on pi (pi install npm:@civitas-cerebrum/achilles) the skills load with the same delegate_qa tool, /achilles command and expert dispatch, each agent in its own pi process, and the Bash judge and secrets screen as guards. Harness specifics live in docs/harness/, never in the skills.

After install, the hooks act on the five Achilles agents and pass every other session through. Factory rules start only when you commit a rule file. Sign-off then requires an evidence bundle and a reviewer-written receipt. Remove a marketplace install with claude plugin uninstall achilles, or delete the plugin entry from the project settings. CLIs in the package: achilles-mutate, achilles-show, achilles-self-repair, achilles-scenario-lint, achilles-selector-evidence.

Built on
open source

Start with the flows you can control today. Both packages are public on npm and version-pinned.