ShiftLefter logo ShiftLefter

ShiftLefter

Quality as a dimension, not a phase.

A typed vocabulary for your app's behavior — your actors, your actions, your intents, defined once and shared by every human and every AI agent that touches your tests. Scenarios are validated against it before anything runs.

We don't heal your tests — we name what changed.

Failures arrive in your vocabulary — which actor, which intent, which step — not as a selector timeout.

Open source, actively developed — releases

Install

Java 11+ is the only requirement. No Clojure toolchain.

curl -fsSL https://raw.githubusercontent.com/SHIFT-LEFTER/shiftlefter/main/release/install.sh | bash
export PATH="$PWD/sl:$PATH"
sl --version

A real run report

Every sl run can write a self-contained HTML report — one file, no server, failures expanded. This one is real, failures and all.

ShiftLefter HTML run report — scenario results with expanded failure transcripts

In plain terms: a Cucumber-compatible Gherkin test runner — Clojure core, real browsers and SMS, JUnit XML and HTML reports for CI — with a type system for what your tests are allowed to say.

What ShiftLefter does

  • A vocabulary you own, enforced before anything runs. Your glossary declares who can act and what they can do. Every scenario is checked against it at bind time, so a typo'd actor dies with a suggestion — before a browser ever opens, not four minutes into a run. This is real output:
    SVO validation issues:
      ERROR: Unknown subject :user/alicce in step
             ":user/alicce fills {:id "password"} with 'SuperSecretPassword!'"
             at features/two-users.feature:6
             Known subjects: :user/alice, :user/bob
             Did you mean: :user/alice?
    
    1 binding issue(s) found. Cannot execute.  # exit 2 — no browser was harmed
  • Macro expansion, not steps-calling-steps. Define "the user logs in" as a Gherkin step sequence, and ShiftLefter expands it at compile time — the runner sees every step with full provenance. When the login flow changes, update one macro definition, not 47 scenarios. Non-developers can read and edit the macro file. The workflow reuse teams reach for Screenplay to get — without the shadow-SUT complexity.
  • Many actors, more than one interface. Each actor gets its own isolated session — :user/alice and :user/bob log in side by side without sharing state. Web runs on a pluggable WebDriver/Playwright backend; SMS is a first-class second interface, so a 2FA flow can span web and text in a single scenario.
  • A well-behaved CI citizen. --junit-xml writes results your CI ingests natively (verified against a real GitLab artifacts:reports:junit ingest). --tags @smoke runs the subset your MR pipeline needs. --max-parallel runs scenarios concurrently with byte-identical report output, and @serial marks the ones that must run alone. Results print live, per scenario, as they finish.
  • An agent front door. sl orient tells a coding agent — or you — what mode a project is in, what would fail, and what to read next. sl agent-doc serves the doctrine from inside the jar, and the step-vocabulary reference is generated from the registered steps, so it cannot drift from the code. Tests live in durable project artifacts — glossary, intents, config — not one-shot generated scripts.

Where it is, honestly

Solid today

  • Multi-actor browser driving — independent sessions with real isolation.
  • The typed vocabulary discipline — validated at bind time, with suggestions.
  • The sl CLI — run, format, dry-run, diagnose; JUnit XML, HTML, and EDN output; tag filtering; parallel scenarios.
  • Gherkin parsing & lossless formatting — 46/46 official Cucumber test files, usable as a CI formatting gate.

Building toward

  • The traceability graph — requirements ↔ use cases ↔ features ↔ the runs that prove them.
  • Semantic diffing of live pages — ships today as a dev/REPL preview (SIEVE), heading for the CLI.
  • Not just what changed — how, and what it puts at risk.
  • First-class fixtures and hooks, and brownfield suite migration.

The baton pass: agents write good end-to-end tests against this surface now; the same vocabulary is the foundation they'll use to map tests to requirements, use cases, and provenance. Adopt it for the left column; the right column is why the discipline compounds.

For AI agents

If you're an agent (or you brought one): install, then ask the tool itself.

curl -fsSL https://raw.githubusercontent.com/SHIFT-LEFTER/shiftlefter/main/release/install.sh | bash
./sl/sl orient        # where am I, what would fail, what to read next
./sl/sl agent-doc --list

The full agent surface is documented in docs/AGENT.md; the installer prints a breadcrumb stanza to paste into your AGENTS.md. A plain-text pointer lives at /llms.txt.

See the code, or say hello.