Skip to content
Conduit

mcp server

9lives-runner

Open-source Playwright tools for coding agents: local execution receipts, experimental fix confirmation and fault testing.

Quality-Max/9lives-runnercommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 17, 2026

9lives runner

npm version npm downloads CI License: Apache-2.0

Your coding agent proposes a fix. 9lives runs the test, compares the results, and records what its assertions caught. Keep your Playwright suite and inspect the evidence locally. No QualityMax account or hosted service required.

Quickstart · Runnable first example · Interactive demo · Website · Memes · Documentation · npm SDK · CLI releases

Inspect a real experiment

The demo leads with an application fix: the same reviewed test fails before the patch and passes after it. Experimental fix confirmation compares the two Git revisions. Three injected request faults then each cause an assertion failure. Inspect the patch, scroll the console, and download the evidence extracts.

ChapterWhat you can inspectEvidence type
A renamed buttonA broken locator and a verified repair with assertions preservedIllustrated walkthrough
A missing checkA green test that misses a required outcomeIllustrated walkthrough
Behind the agentObserved controls, bounded actions, and execution receiptsAlgorithm walkthrough
A real agent runSaved provider decisions and browser execution logsRecorded execution
Prove the fixBefore/after receipts and three caught faultsRecorded execution

The last experiment records seven Chromium executions on one synthetic profile app, captured on 13 October 2026. Opening the demo does not execute tests or call an agent. It works in light and dark themes and as a single offline HTML file. To execute the eight-chapter lab yourself, follow the release lab guide. The earlier Demo Bank locator repair is also reproducible.

In current source builds, run 9l doctor from the application project before the first scan (published v0.4.7 predates this command). It checks local prerequisites and gives repair commands without downloading browsers or loading project config. Use 9l doctor --sdk for SDK runs. See the setup diagnostics guide for limits and first-run steps.

From a failure to a checked fix

  1. Reproduce: run a reviewed Playwright spec with an assertion that fails on the broken app.
  2. Review: inspect your agent's proposed application patch or locator repair; preserve the intended behavior.
  3. Confirm: experimental 9l confirm / MCP confirm_finding runs the same reproduction on each Git revision in isolation.
  4. Challenge: experimental 9l prove injects supported fetch/XHR faults and reruns the test.

A passing receipt means the assertions passed and the execution report was validated. Confirmation shows that the test distinguishes the revisions. A caught fault means an assertion failed under that fault. None establishes full requirement coverage. See the confirmation and fault testing contracts.

Run your existing Playwright tests

Install the native CLI on macOS or Linux:

curl -fsSL https://9lives.run/install.sh | sh
export PATH="$HOME/.local/share/9lives-runner/bin:$PATH"
9l plan tests/checkout.spec.ts --format json
9l run tests/checkout.spec.ts --timeout 2m --attempts 1 --format json

Run from your project root and replace the path with an existing spec. Follow the quickstart for prerequisites, expected results and troubleshooting, or try the synthetic fault example.

Your project supplies its Playwright dependencies, browsers, configuration, and assertions. The SDK is optional. Native v0.4.7 binaries support macOS, Linux and Windows on x64 and ARM64. See Windows ZIP installation and the existing-project guide. Chromium is qualified; other browser engines are unqualified.

Connect the tools to a coding agent through native MCP. For Claude Code:

claude mcp add 9lives -- 9l mcp

The agent setup guide covers Codex, Claude, and the optional QA skill. Native tools expose execution, assessment, healing, page inspection, reproduction generation, and fix confirmation. qmax-code is the separate QA terminal that can run standalone or connect to QualityMax.

What is available

  • Local execution: plan, run, status, result, and cancel bound execution and record attributable terminal receipts.
  • Assessment: 9l assess advises on waits, skips, assertions, requirement mappings, and source provenance.
  • Page observations: 9l scan runs nine check categories; 9l inspect ranks controls and locators.
  • Optional SDK: named steps and bounded goals alongside explicit Playwright assertions. Goal completion is unverified.
  • Experimental: supported locator healing, revision confirmation, and fetch/XHR fault testing. The demo qualifies one synthetic app in Chromium.
  • Planned: independent behavioral verification, verified replay, and native mobile qualification.

Add the optional SDK

Install the published SDK in your Playwright project:

npm install --save-dev @9l/playwright@0.4.7 @playwright/test@1.64.0
npm exec playwright install chromium

Use Node 24 for the qualified runtime (Node 22 minimum) and Playwright 1.61.1 through 1.64.0; an existing project can keep its version in that range. On Linux, use npm exec playwright install --with-deps chromium for browser dependencies.

Install the Go CLI separately. With Go 1.25.13 or newer:

go install github.com/Quality-Max/9lives-runner/cmd/9l@latest
9l --version

Ensure Go's binary directory is on your PATH. Prebuilt CLI releases target macOS, Linux and Windows on amd64 and arm64, so their users do not need Go. See the download and checksum instructions for availability and platform selection. Windows ZIPs start with v0.2.0; earlier releases have macOS/Linux assets only. The npm package supplies the fixtures; it does not install the CLI or browsers.

Run with SDK steps

Keep your application's existing Playwright configuration and reviewed assertions. For an application serving a checkout page:

import {test, expect} from '@9l/playwright';

test('checkout confirms an order', async ({page, n9l}) => {
  await page.goto('http://localhost:3000/checkout');
  await n9l.step('place the order', async () => {
    await page.getByRole('button', {name: 'Place order'}).click();
    await expect(page.getByRole('status')).toHaveText('Order confirmed');
  });
});

Start the application, then run from the test project:

9l run tests/checkout.spec.ts --sdk --format json

For a complete runnable example that needs no application server or model, clone this repository and follow the local checkout demo. For an existing application, see the integration guide.

What the result establishes

The runner records a terminal outcome for every required test and validates SDK evidence against the owning run, job and attempt. Required failures, missing evidence, unexplained skips and interruption prevent an overall green result. Receipts persist under .9lives/receipts/; inspect them with 9l result <run-id> --format json.

A passing execution means the test's assertions passed and its report was validated. It does not prove that the assertions fully cover the requirements. Independent behavioral verification remains planned.

Check the page you changed

Before a coding agent calls a web change done, give it evidence from the page itself. 9l scan loads the page once in Chromium with the project's own Playwright and reports graded findings with reproduction steps and suggested fixes:

9l scan https://your-app.dev --format markdown
9l scan http://localhost:3000/ --allow-private-network --format json --out scan.json
9l scan http://localhost:3000/ --allow-private-network --baseline scan.json --fail-on-new
9l inspect http://localhost:3000/login --allow-private-network
CheckWhat it reports
consoleJavaScript errors, warnings and failed requests
linksBroken and redirecting links, up to --max-links
accessibilityMissing alt text, unlabelled controls, nameless interactive elements, heading structure
performanceCore Web Vitals LCP and CLS, plus TTFB and FCP load timings (INP, the third Core Web Vital, needs real interaction and is not measured)
seoTitle and meta description
security_headersCSP, HSTS, X-Content-Type-Options, Referrer-Policy
cookiesMissing Secure/HttpOnly/SameSite, third-party cookies, known trackers, tracking before consent
mixed_contentHTTP subresources and form actions on an HTTPS page
weightTransfer bytes, request count, render-blocking resources, oversized and uncompressed assets

The Markdown report opens with the grade and the categories to fix first:

Grade: 🔴 F (0 / 100) · 15 issues found

CategoryIssuesWorst
Console errors██████████ 4🔴 high
Accessibility████████░░ 3🔴 high
Security headers██████████ 4🟠 medium

--baseline compares against an earlier JSON result and reports new, fixed and unchanged findings, so a pipeline can fail only on regressions. 9l inspect returns the page's ranked locators (test id, role and label before text and position), each control's stability and a testability verdict. A page behind a login is checked with a Playwright storage-state file and --acknowledge-private-content. Loopback targets need --allow-private-network; other private addresses stay blocked. Scans are observations from one cold page load, not test results.

Coding agents get the same checks from 9l mcp as scan_url and inspect_page, plus generate_playwright_repro, which writes a spec for a finding that run_test executes and confirm_finding checks across a fix. These checks were previously the separate qmax-mcp npm server.

What you can do

CapabilityAvailable behaviorBoundary
Plan and runDiscover specs, inspect plans, bound concurrency and deadlinesRuns locally installed Playwright; no automatic tooling downloads
Inspect and cancelstatus, result, cancel, and terminal receiptsInterrupted runs are classified; automatic crash recovery is planned
SDK stepsn9l.step(...) with normal browser fixtures and assertionsOpt in with --sdk; existing execution stays available separately
Visual moderun --headed shows the browser, one job at a time by defaultLinux needs a display (xvfb-run -a on headless machines); slow motion comes from the project's launchOptions
Bounded goalsn9l.goal(...) over finite observed controlsCompletion is unverified; live model accuracy and cost are unqualified
Test assessmentassess and source/branch provenanceAdvisory static review; it does not establish executed assertion coverage
Fault proofExperimental prove: re-run a spec once per injected fetch/XHR fault and report which an assertion caughtNeeds @9l/playwright 0.1.1 (0.1.3 for the --faults opt-in kinds); a caught fault shows an assertion failed, not that it checks the right thing
Finding confirmationExperimental confirm: run a reproduction spec on the unfixed and fixed Git revisions, each in its own checkout, and report confirmed, not-reproduced, fix-ineffective or regressedCode under test must be started or imported from the checkout; confirmed shows the spec tells the revisions apart, not that it tests the finding
HealingOffline Tier 1 proposals and experimental native Tier 2 verificationPreserve assertions; verify candidates in isolation before application
Page checksscan: nine checks from one Chromium page load, baselines and --fail-on-new; inspect: ranked locators and testabilityObservations, not test results; one cold load, not field data; loopback needs explicit consent
ReproductionsMCP generate_playwright_repro writes a deterministic spec for a finding, URL or goalRuns nothing; review it, then run_test or confirm_finding

See the CLI reference, assessment guide, prove, confirm, native Tier 1 and native Tier 2. Verified replay and native mobile qualification remain subsequent milestones. Windows process ownership uses kill-on-close Job Objects; native Windows amd64 and arm64 CI checks Chromium execution and process-tree cleanup. Provider CLI shell integrations on Windows remain unqualified.

Add a bounded goal

await n9l.goal('Fill Name using name, then click Continue.', {
  params: {name: 'Fixture Person'}, maxActions: 3, timeoutMs: 30_000,
});
await expect(page.getByRole('heading', {name: 'Review'})).toBeVisible();

Choose --goal-provider anthropic or openai and configure its credential securely in Go's calling environment, or claude, codex or opencode to use that CLI's own subscription login without an API key. Offline --goal-script fixtures exercise the browser/engine contract without paid API calls. Purchase, deletion and outreach controls stop by default. See goal contracts.

Compatibility

ComponentQualifiedBoundary
@playwright/test1.61.1, 1.62.0, 1.62.1, 1.63.0, 1.64.0CI runs the unit, browser, assessment and packed-SDK checks on each. Later 1.x releases install (peer range >=1.61.1 <2) but are unqualified
9l assess matchersPlaywright 1.61.1 through 1.64.0The async matchers are identical across that range. A matcher outside it is reported as an unknown-matcher limit, not guessed
BrowserChromiumOther engines are unqualified
Node24 (22 minimum)
CLI0.4.7 on macOS, Linux and Windows, amd64 and arm64Provider CLI shell integrations on Windows are unqualified
SDK@9l/playwright 0.4.7, released with the CLIInstalling the SDK does not install the CLI or browsers

Keep your project's existing Playwright version if it is in the qualified range; upgrading is not required. To check a release locally, see the development guide.

Add it to your coding agent

The optional 9lives QA skill guides Codex and Claude through requirements, source provenance, assessment and executed results. Use the agent setup guide to add it to a project.

Adjacent QualityMax tools

ToolUse it for
qmax-mcpThe earlier standalone npm server for scans and inspection; its checks now ship in 9l scan, 9l inspect and 9l mcp, and its hosted-account proxy is not included
9lives PythonPython-only healing options, Cypress/Selenium adapters and watch/report commands
qualitymax-graderAn optional offline A–F hygiene score for a spec; its defect checks are now in 9l assess, and the grade is not a 9lives result or coverage evidence

These are separate distributions. Installing this runner or SDK does not install or configure them. The Python package also provides a 9l command; use an explicit executable path when both CLIs are installed.

Safety and honest limits

Test code executes with the local user's permissions. Use approved targets and explicitly pass required application environment keys with --pass-env. Goal parameter values stay in the browser worker; provider credentials stay in Go. Receipts omit page content and attachment bodies by default, and bound and sanitize diagnostics. Review the SDK evidence contract for identity, privacy, skip pins and failure handling.

Architecture

flowchart LR
  Specs[Playwright specs and assertions] --> Go[Go CLI: plan, budgets, scheduling]
  Go --> Worker[TypeScript SDK: fixtures and browser]
  Worker --> Browser[Local Playwright / Chromium]
  Browser --> Worker
  Worker --> Go
  Go --> Receipts[Validated terminal receipts]
  Go -. optional goal decisions .-> Provider[Configured model provider]

Go owns execution identity, cancellation and completeness. TypeScript owns browser handles and fixtures. The bounded 9l.engine/1 protocol joins them. See architecture decisions and the performance baseline, which separates runner overhead from Playwright and browser costs.

Support and responsible disclosure

Use GitHub Issues for non-sensitive usage and documentation questions. Report vulnerabilities privately using the security policy.

Development

npm ci
npm exec playwright install chromium
npm run demo
go test -race ./...
go vet ./...

The development guide lists SDK qualification, pinned Python compatibility checks and repository boundaries. See contributing before proposing changes.

Package and release metadata

The published @9l/playwright 0.4.7 and the Go CLI are separate distributions with one shared version: a single v<version> tag releases both. Binary archives include LICENSE, NOTICE and release-wide SHA-256 checksums. See the release runbook and changelog.

License

Apache-2.0. Third-party components retain their own licenses and notices. The SDK package and CLI archives include LICENSE and NOTICE.

↑↓ navigate openesc close