artel-qa-lite
v0.1.1
Published
Artel QA Lite — agentic QA for web applications, installed as `artel`. The same product as metantel-cli: reads your source, tests in a real browser, writes a report a QA lead can act on.
Maintainers
Readme
Artel QA Lite
Agentic QA for web applications. It reads your source code, tests the running application in a real browser, and hands you a test plan and a report a QA lead can act on — with the evidence behind every verdict.
Install
npm install -g artel-qa-liteThen check the machine — it proves Claude Code and a browser actually work, and spends nothing:
artel doctorThis is Artel QA Lite installed as artel, the same product as
metantel-cli: every metantel command on this page
works as artel — artel plan --open, artel run --dry-run.
Requirements
| | |
|---|---|
| Node.js | 20 or newer — used only to install and launch; the product is a native binary |
| Claude Code | installed and signed in. Inspectors run on your own subscription |
| A Chromium | Google Chrome, Chromium, or npx playwright install chromium chromium-headless-shell |
| System | macOS 12+ (Apple Silicon or Intel) · Linux x64 / arm64 (glibc) · Windows 10/11 x64 |
npm installs one prebuilt binary for your platform. There is no postinstall script and nothing is downloaded at install or at run time.
Other ways to install
npx metantel-cli doctor # try it without installing
npm install --save-dev metantel-cli # pin it per project, run with npx metantel
npm install -g metantel-cli@latest # upgrade
npm uninstall -g metantel-cli # remove (your .metantel/ folders stay)Quick start
From the root of your application's repository, with the application running:
metantel init # writes .metantel/config.json — set app.url and auth
metantel plan --open # the test plan, generated from your source — free
metantel run --dry-run # the whole pipeline, nothing dispatched — free
metantel run --budget 5 # a real run, bounded to $5 of your Claude subscription
metantel report --open # the report (also written when the run finishes)A minimal .metantel/config.json:
{
"app": { "url": "http://localhost:3000", "name": "My application" },
"codebase": { "path": "." },
"auth": { "at": "/login", "username": "[email protected]", "password": "${QA_PASSWORD}" }
}${QA_PASSWORD} is read from the environment, so the password never has to be in the file.
metantel help lists every command; metantel <command> --help gives its options.
What you get
A test plan you did not write. metantel plan reads the repository — routes, views, components,
forms, translation catalogues — and writes test-plan.html: one scenario per thing a user can do,
with the page, how to get there, preconditions, procedure and pass condition. On a 200-page HR
system that is 151 scenarios covering 1,027 controls, generated in under a minute.
A walk before a word is spent. Before any inspector starts, the harness itself opens every page
it found, signs in, records which controls are really there, what reveals the hidden ones (a tab, an
"Add" button, a ?tab= link), which pages redirect and which are missing — and hands each inspector
those facts.
Verdicts the model does not get to write. An inspector says what it concludes and why; the harness measured what actually happened — the screen before and after, every request that left the browser, what the page announced. If the inspector says "saved" and nothing left the browser, the verdict is refuted, and the report says so in that sentence.
A report for a QA lead who has never seen us. report.html in every run: findings with severity,
where, expected, observed, steps to reproduce, evidence, confidence and the source file;
coverage by area; every control not reached with the reason in plain words; one test case per
control. Every number in it is derived from the run's own case file.
Reached 22% Assessed 14% Passed 103 Findings 13 (12 high · 1 low)
F-001 · High · Number Of Employees: nothing on the page changed and nothing left the browser
Where /admin/viewOrganizationGeneralInformation — Number Of Employees (Input field)
Expected Accepts input, shows it, and keeps it when the form is saved
Observed Entering a value had no effect the run could see
Evidence Screen: nothing on the screen changed after the action
Network: nothing left the browser — no request was made
Confidence Medium — judged on what the screen showed and what left the browserReached means somebody stood in front of the control. Assessed means a pass or a fail with evidence behind it. Both err low, and the report names the reason for every control not reached.
What it works on
Identification reads the source, with readers for Next.js, Nuxt, SvelteKit, React Router, Vue Router,
Angular, Django, Flask/FastAPI, Rails, Laravel, Symfony, Spring, ASP.NET, Express/Nest, Go routers
(chi, gin, echo, gorilla, net/http) and static HTML — and a floor under all of them: the running
application's own links. Translation catalogues in six formats, JSX in .js, Pug, Python form
classes and .NET display names are read so labels are the words a person sees.
The browser side is framework-neutral: it recognises a focusable div as the dropdown it is, names a
field by the label a person reads, clicks styled checkboxes through their label, operates custom
dropdowns and autocompletes (OXD, Ant, MUI, PrimeNG, Element, Fomantic…), and generates a valid file
of whatever type a file input accepts.
Private by construction
It runs entirely on your machine. Your source, credentials and results never leave it. The binary has no TLS library in it, so it cannot speak HTTPS to anyone; nothing calls a model we bill you for, and nothing phones home. An inspector is a model reading pages it does not control, so it is fenced:
- no shell, no file access, no web fetch — only the browser tools this binary serves
- only your application's origin (plus any
safety.allowed_originsyou list);file:,javascript:and foreign sites are refused - no page script unless you allow it, and a verdict filed after script ran is marked
- no uploads from your disk — the harness generates test files matching each file input
- your password is masked in every brief, report and log
- the console binds
127.0.0.1and refuses cross-site writes
Cost, measured: about $0.04–0.07 of your Claude subscription per control assessed. plan,
identify, sweep and run --dry-run are free.
Known limits
- OAuth / SSO / 2FA sign-in is not supported yet; password and passkey (WebAuthn) are.
- Pages that need a record to exist (an employee, a repository) are reached once an inspector has created one; the first walk reports them as needing that.
- Coverage numbers are honest, which means lower than a tool that counts "visited".
The bigger picture
Artel QA Lite is the free, local edition of Artel, Metantel's QA platform. The full suite adds a database channel as a third independent opinion, cross-run regression gates, per-role accounts, and the Datalake Intelligence Platform behind it. Everything Lite files is an open, append-only case file you keep. metantel.com
Licence: free for exploring the product and for QA testing of your own applications. No redistribution, derivative works or commercial use, including QA services for others; other usage, commercialisation and copyright restrictions apply — see the LICENSE file in this package. The reports and output it generates are yours. © 2026 JMV Metantel Pvt Ltd, Metantel and Trivikram Trishir Rao Padala. Licensing: [email protected]. Security reports: [email protected].
The complete user manual covers configuration, every command, reading the report, security, troubleshooting and FAQ.
User manual
Version 0.1 · for the metantel command line
Artel QA Lite reads your application's source code, drives the running application in a real browser, and writes a report a QA lead can act on. This manual covers everything a user needs: installing it, configuring a project, running it, reading what it produces, and what it will and will not do on your machine.
Contents
- How it works, in one page
- Requirements
- Install
- Set up a project
- The configuration file
- Your first session
- Commands
- The test plan
- Running
- The console
- The report
- Files a run leaves behind
- Cost and how to bound it
- Security and privacy
- Environment variables
- Troubleshooting
- Frequently asked questions
- Glossary
1. How it works, in one page
There are three stages, and they are deliberately separate.
Identify. The source is read — routes, views, components, forms, translation catalogues — and every control a user could act on is listed with the page it renders on: every field, button, link and piece of displayed text. This is the denominator: the number everything else is measured against. It comes from your code, not from what a crawler happened to bump into.
Walk, then inspect. Before anything is billed, the harness itself opens every page it found, signs in, and records which controls are really there, what reveals the hidden ones, which pages redirect and which are missing. Then inspectors — Claude Code sessions on your own subscription, working in a real browser — take the pages in bundles, exercise each control the way a user would, and say what they conclude.
Adjudicate. An inspector never writes its own verdict. While it worked, the harness measured what actually happened: the screen before and after, every request that left the browser, what the page announced. The verdict is made from those measurements. If an inspector says "saved" and nothing left the browser, the verdict is refuted, and the report says so in that sentence.
Everything lands in an append-only case file on your disk, and the report is derived from it.
2. Requirements
| | |
|---|---|
| Operating system | macOS 12+ (Apple Silicon or Intel), Linux x64/arm64 (glibc 2.35+, e.g. Ubuntu 22.04 / Debian 12), Windows 10/11 x64 |
| Node.js | 20 or newer — only to install and launch; the product is a native binary |
| Claude Code | installed and signed in (claude --version works). Inspectors run through it, on your subscription |
| A Chromium | Google Chrome, Chromium, or a Playwright browser (npx playwright install chromium chromium-headless-shell) |
| The application | running and reachable from this machine, with a test account |
| The source | a checkout of the application's repository on this machine |
Nothing is downloaded on install or at run time. metantel doctor tells you what is missing.
3. Install
npm install -g metantel-cli
metantel --version
metantel doctornpm installs the prebuilt binary for your platform (@metantel/cli-<platform>, pulled in
automatically) and a small launcher that runs it. There is no postinstall script and nothing is
downloaded at install or at run time. The same product is also published as artel-qa-lite, which
installs the command as artel; every metantel command in this manual works as artel.
doctor starts Claude Code, launches a browser, drives a page and reads it back, and runs every
rule in the binary. It ends with ok ready or a list of what would stop a run.
Other ways to install
| | |
|---|---|
| try it once | npx metantel-cli doctor |
| pin it per project | npm install --save-dev metantel-cli, then npx metantel run |
| in CI | npm install -g [email protected] — pin the version, and do not pass --omit=optional (the binary is the optional dependency) |
| upgrade | npm install -g metantel-cli@latest. Projects and runs are unaffected |
| uninstall | npm uninstall -g metantel-cli. Your .metantel/ directories stay; delete them if you want the runs gone |
Platforms built: macOS (Apple Silicon and Intel), Linux x64 and arm64 (glibc — Debian, Ubuntu, Fedora, RHEL; not Alpine/musl), Windows x64. On anything else the launcher says so by name.
4. Set up a project
From the root of the application's repository:
metantel initThis writes .metantel/config.json with a starter configuration and adds .metantel/runs/ to
.gitignore (runs contain screenshots and case files; they are not source). Edit the file: at
minimum app.url, and auth if the application has a sign-in.
Keep .metantel/config.json in version control if your team shares the setup; keep the password
out of it with ${VAR} — see the next section.
5. The configuration file
.metantel/config.json, found from the current directory upwards. metantel.json, artel.json
and .artel/config.json are also recognised, and every command takes an explicit path.
{
"app": {
"url": "http://localhost:3000",
"name": "My application",
"plugins": []
},
"codebase": {
"path": "."
},
"auth": {
"at": "/login",
"username": "[email protected]",
"password": "${QA_PASSWORD}"
},
"safety": {
"allowed_origins": [],
"page_script": false,
"upload_dirs": []
},
"accounts": {
"use": { "default": "admin" },
"catalogue": [],
"states": []
}
}app
| field | |
|---|---|
| url | The running application. Every route is resolved against it. It must be up before a run starts. |
| name | Used in reports and the console. |
| plugins | Optional. The extension slugs this deployment actually carries (for applications with an app store or plugin directory). Controls inside an extension you have not installed are then withheld with a reason instead of counted as failures. Leave it out and nothing is withheld — the safe direction. |
codebase
| field | |
|---|---|
| path | The application's source. Relative paths are relative to the project (the directory holding .metantel/). Without it there is no denominator. |
| mapFile | Optional override: a pre-built control map. Normally the map is built from path. |
auth
The harness signs in itself, once per inspector, before the inspector's first turn. Inspectors are never given the password and are told not to invent one.
| field | |
|---|---|
| at | The sign-in page, as a path or a full URL. Optional — many applications redirect there anyway. |
| username / email | Two names for the same field; use whichever the form calls it. |
| password | The password. Write "${QA_PASSWORD}" to read it from the environment; a reference to an unset variable is an error at start, not a failed sign-in later. |
| passkey | true for WebAuthn sign-in; the harness installs a virtual authenticator. Or { "rp_id": "…", "transport": "internal" }. |
| note | Free text shown to inspectors ("the dashboard loads after login; dismiss the tour"). |
Password and passkey sign-in are supported. OAuth, SSO and 2FA are not yet; an application behind them cannot be reached past the front door.
safety
Every inspector is a model reading pages it does not control, and a page can carry instructions. These fences are closed by default. Open one only when you know why.
| field | default | |
|---|---|---|
| allowed_origins | [] | Origins an inspector may open besides the application's own and its sign-in page — an identity provider, a payment page, a documentation site the app links to. "https://idp.example.com". |
| page_script | false | Allows browser_evaluate and browser_run_code_unsafe. Off, the tools are not even offered. On, every verdict filed after script ran is marked. |
| upload_dirs | [] | Directories an inspector may upload real files from. Off, the harness generates a valid test file of the type each file input accepts. |
accounts
Optional. For applications where different controls need different roles or states. catalogue
lists the accounts your own provisioning publishes; states lists named states an account can be
in; use.default names the one to start with. When empty, the single auth account is used for
everything.
.metantel/prefs.json
Run preferences, written by metantel init defaults and by the console's form. The command line
overrides them.
{ "headed": false, "lanes": 5, "max_waves": 10, "target": 70, "budget_usd": null, "model": null, "max_turns": 90 }.metantel/priority.json
What to test first. Written from the console or by hand.
{ "routes": ["/checkout", "/billing"], "controls": [], "tiers": ["write"], "note": "release blocker on checkout" }6. Your first session
A sensible first hour, spending nothing until the last step.
metantel doctor # everything this machine needs, proven
metantel init # then edit .metantel/config.json
metantel identify # what the source declares: controls, routes, how many were placed
metantel plan --open # the test plan, as a page
metantel sweep # the harness walks the application: what is really on each page
metantel run --dry-run # the whole pipeline, briefs written, nothing dispatched
metantel run --budget 5 # the first real run, bounded to five dollars of your subscription
metantel report --open # the report (it was also written when the run finished)Read identify before trusting anything else. It prints how many controls were found, how many
were placed on a page and how, and which routing conventions were recognised. A low placement
percentage means the report's denominator is a sliver of the application — fix that first (usually
by pointing codebase.path at the right directory).
7. Commands
Every command accepts --help (metantel run --help), and metantel help lists them all. Flags
take their value either way — --budget 5 or --budget=5. Paths in [config] are optional; the
config is otherwise found from the current directory upwards. A mistyped command is answered with
the one that was probably meant.
Exit codes: 0 the command did what was asked — a run that files findings still exits 0, the
findings are in the report; 1 a selftest rule failed; 2 it could not do what was asked — a
missing config, an unknown flag, a machine doctor says is not ready.
metantel init
Writes a starter .metantel/config.json and adds .metantel/runs/ to .gitignore. Refuses to
overwrite an existing file.
metantel doctor
Checks Claude Code, the headless browser, the windowed browser (two windows at once), every rule in the binary, and where runs will be written. Exit code is non-zero if anything would stop a run.
metantel selftest
Runs every rule in the binary offline, in about a second. No browser, no network.
metantel version · metantel --version
--version prints one line (metantel 0.1.1) for scripts; version adds the platform the binary
was built for.
metantel where [config]
Prints where this project's runs, caches and preferences live, before anything is written.
metantel identify [path] — --samples --json --out FILE
Identification only: no application, browser or model. Prints what the repository declares, how
many controls were named, placed and catalogued, and why not. --samples prints unnamed controls
as found; --json prints machine-readable counts and the route templates; --out writes the
catalogue.
metantel clusters [path] — --json
The solution-cluster catalogue: the general rules and the per-stack rules identification applies, what each solves, and which apply to this repository.
metantel plan [config] — --open --config PATH
Writes .metantel/test-plan.html and test-plan.md: one scenario per goal (page, how to get
there, preconditions, procedure, pass condition), plus the control checks outside any scenario.
Scenarios come from metantel goals; without goals the plan lists control checks only.
metantel goals [config] — --model M --route R --offline --refresh --fill --link --relink
Reads the codebase into goals: the things a user must be able to do on each page, with
preconditions. This is the one command that uses a stronger model by default (Sonnet), once per
codebase, cached against the source. --refresh re-reads everything; --fill re-reads only routes
that got nothing; --link works out which goals must be done before which.
metantel sweep [config] — --workers N --headed --json --route R
The harness walks every catalogued page without a model: which controls are on their page, what
reveals the hidden ones, which pages redirect or are missing, which framework and design system drew
the page. Every run does this first; run it alone to see the facts. --route limits it to routes
containing a string.
metantel run [config]
The main command. See Running.
| flag | default | |
|---|---|---|
| --lanes N | 5 | inspectors working at once |
| --budget USD | none | stop when this much of your subscription is spent |
| --target P | 70 | stop when this % of controls is assessed |
| --max-waves N | 10 | ceiling on waves |
| --model M | Haiku | the inspector model |
| --escalate-model M | Sonnet | the model for a job's last attempt (none to disable) |
| --max-attempts N | 3 | sessions a job may take before it is parked with its reason |
| --session-size N | 24 | controls one inspector session takes on, a page at a time |
| --max-turns N | 90 | how long one inspector session may work |
| --headed | off | watch in a browser window |
| --headless | on | force headless whatever prefs.json says |
| --dry-run | off | identify, walk, write the briefs, dispatch nothing |
| --auto | off | never stop to ask between waves (required without a terminal) |
| --no-sweep / --resweep | | skip the harness's walk, or force a fresh one |
metantel ui [config] — --port N --no-open
The local console. Binds 127.0.0.1 only. See The console.
metantel report [config] — --run ID --open --config PATH
Writes report.html and report.md into a run (the latest by default). Also done automatically
when a run finishes.
metantel mcp --lane ID --run ID --config PATH --store PATH
Serves the browser tool surface over MCP on stdio. Claude Code spawns this for each inspector; you can also attach it to your own agent.
8. The test plan
metantel plan produces a numbered plan before anything is spent:
TP-002 · Register a new OpenID Connect login provider
Page /admin/addAuthProvider
How to get there Admin > Configuration > OpenID Connect > Add
Preconditions Logged in as an Admin user; a provider name not already in use
Procedure Fill in Name, Url, Client Id and Client Secret with valid values and submit
Pass when The save completes without error and the new provider is listed afterward
Controls 4Scenarios are grouped by area of the application. Below them, control checks outside a scenario lists the controls no scenario names — they are still tested one by one in a run.
The plan is what a run will attempt. The report says what it found. Reviewing the plan with the team before the first run is the cheapest correction you can make.
9. Running
What happens
- Identify — from cache when the source has not changed.
- Walk — the harness opens every page (reused if walked in the last 12 hours;
--resweepforces it). - Board — controls are cut into jobs; goals decide what must be done before what.
- Waves — inspector sessions are dispatched in parallel, each taking a bundle of jobs on one or two pages. A session that finishes takes the next bundle. A wave ends when nothing is left to hand out.
- Between waves — pages that needed a record to exist (an employee, a repository) are walked again once an inspector has created one and they come onto the board.
- Stop — at the target, the budget, the wave ceiling, or when a wave converts nothing.
- Report — written into the run directory.
What you see
Artel QA Lite run r-20260913163000
· config …/.metantel/config.json (found here)
· app http://34.62.61.254/web/index.php
· map 1297 controls, from cache
· render 190 route(s) declared (symfony 190), 182 resolved to a view
· routes 96.5% of 1297 controls placed on a page
· catalogue 1031 controls on 170 routes
· sweep walked the application — 223 of 1031 controls seen on their page (21.6%)
· goals 227 across 94 route(s)
board: 290 jobs, 290 open
inspector-0: session 1 — 3 job(s), 27 control(s) on /admin/viewOrganizationGeneralInformation
…Each session prints what it settled and what it cost. Press Ctrl-C at any time: everything filed so
far is on disk, and the report can be written from it with metantel report.
Re-running
Each run is its own case file with its own verdicts. What carries over between runs is knowledge,
not results: where controls were found and what revealed them (ui-map.json), the walk of the
application (reused for 12 hours), the goals (until the source changes), and the identification
cache. A second run is therefore faster and reaches more, and its numbers are its own. Use
--budget and --target to size each run; metantel report --run <id> reads any past one.
10. The console
metantel uiOpens http://127.0.0.1:<port> in your browser: the stages of the current run animated from real
events, the board, findings as they are filed, coverage, and controls to start a run with the
preferences shown, set a priority, or stop a run the console started.
The console is local only. It binds the loopback address, refuses requests from other origins and hosts, and accepts writes only from its own page. It never computes coverage itself; it shows the numbers the run published.
11. The report
Every run writes report.html (self-contained, prints well) and report.md (paste into a ticket).
At a glance
| number | meaning | |---|---| | Controls | every field, button, link and label the source declares — the denominator | | Reached | somebody stood in front of it: an inspector, or the pre-run walk | | Assessed | a pass or a fail with evidence behind it | | Passed | behaved as its label says | | Findings | defects, with severity |
Both percentages err low. A control the harness could not reach counts against it.
Findings
Each finding carries: an id (F-001), severity (High / Medium / Low), a title in plain words,
Where (page and control), Expected, Observed, To reproduce (the steps the inspector
took, in a tester's words), Evidence (what the screen showed, what left the browser, screenshots
when taken), Confidence (and which channels it rests on), the inspector's note, and the source
file the control comes from.
Severity: High for a field or button that does not do its job or a save the server accepted without changing anything; Medium for a link or displayed text; Low for a control that only partly works.
Results, per control
Every internal verdict maps to one word a QA lead reads:
| result | meaning | |---|---| | Pass | it did what its label says, and the network agrees | | Pass (screen only) | the screen moved and the network was silent — fine for a client-side control, a flag for a save | | Fail | it did not — the screen said otherwise, the server disagreed, or nothing left the browser | | Inconclusive | the evidence does not settle it | | Blocked | the inspector could not put the application into the state the control needs | | Not shown | the inspector opened the page and did not find it | | Not tested | nobody exercised it | | Seen, not tested | the pre-run walk saw it on its page; no inspector reached it | | Not a control | declared in the source, not a control on the page — excluded from every count |
Not reached, and why
A table of every control nobody reached, grouped by reason: the page needs a record this account does not have; the page is not served by this deployment (404); the page sends this account back to sign-in; hidden until a state; not on the page in its default state; the run stopped first. This is the list to read when a number looks low.
Test cases
One case per control, grouped by page, with its result and the inspector's steps. Expand a page to read them.
Method
How the run was conducted, what was detected at runtime (framework, design system), which account was used, and whether a database was attached.
12. Files a run leaves behind
Everything is under the project's .metantel/. Nothing is written anywhere else in your repository.
.metantel/
config.json your configuration
prefs.json run preferences
priority.json what to test first
goals.json the goals read from the source (cached)
sweep.json the last walk of the application
ui-map.json where controls were found, across runs — makes the next run cheaper
test-plan.html/.md the plan
runs/<run-id>/
report.html/.md the report
summary.json numbers, cost, why it stopped
triage.json ranked findings; accusations with no evidence held back
catalog.json the denominator this run used
board.json the jobs
ledger.jsonl one row per verdict, append-only — the record of truth
actions.jsonl every browser action, in a tester's words
calls.jsonl every tool call, attributed to a lane and a control
progress.jsonl sessions, timings, spend
brief-*.md what each inspector session was told
evidence/ screenshots
uploads/ the test files the harness generated for file inputsledger.jsonl is append-only and the report is derived from it. If a report and a ledger ever
disagree, the ledger is right.
13. Cost and how to bound it
Inspectors run through your Claude Code subscription. Measured on real applications: about
$0.04–0.07 per control assessed with the default model. Identification, the plan, the walk and
--dry-run cost nothing.
--budget USDstops the run at that spend. The console shows spend as it happens.--target Pstops once that share of controls is assessed.--lanestrades speed for concurrent spend; five is a sensible default.metantel goalsuses Sonnet once per codebase (about $9 on a 200-page application) and is cached until the source changes.- Every summary line in the console and in
summary.jsonsays what was spent and which model answered.
14. Security and privacy
What leaves your machine. Only the prompts and tool results exchanged with Claude through Claude Code, under your subscription and Anthropic's terms. Metantel receives nothing: no source, no credentials, no results, no telemetry. The binary contains no TLS library and cannot make an HTTPS connection to anyone.
What an inspector can do. Only what the browser tools this binary serves allow:
- No shell, no file access, no web fetch. Claude Code's built-in tools are removed for inspectors.
- Only your application. An inspector may open the application's own origin, its sign-in page,
and
safety.allowed_origins.file:,javascript:,data:,chrome:and foreign sites are refused. A page that says "open this link" is not an instruction it can follow. - No page script unless
safety.page_scriptis on; a verdict filed after script ran is marked. - No files from your machine. File inputs receive a valid generated test file
(
artel-test-file.<ext>) of the type the input accepts.safety.upload_dirsopens a directory deliberately. - Credentials. The harness signs in; inspectors are never given the password and are told not to invent one. The configured password is masked in every brief, report, plan and log, even when the application's own repository quotes it (demo credentials in a CI file, say).
The console binds 127.0.0.1, refuses cross-origin requests and non-loopback hosts, and takes
writes only from its own page.
What the run does to your application. Inspectors create, edit and press things — that is the job. Point them at a staging or test deployment with a test account, not at production. Installer and upgrade routes are withheld from inspectors automatically.
Reporting a security issue: [email protected].
15. Environment variables
| variable | |
|---|---|
| METANTEL_CHROMIUM | path to a Chrome/Chromium binary to use instead of searching |
| PLAYWRIGHT_BROWSERS_PATH | a Playwright browser directory to search |
| METANTEL_CLAUDE_BIN | the Claude Code executable, if not claude on your PATH |
| METANTEL_BIN | (launcher) run a specific metantel binary — for a build of your own |
| ${NAME} in config | any of app.url, auth.username, auth.email, auth.password may reference the environment |
16. Troubleshooting
metantel: the binary for <platform> … is not installed. npm skipped the optional dependency
that carries the binary — usually because the install ran with --omit=optional / --no-optional,
or node_modules was copied from another operating system (a Mac's into a Linux container).
Reinstall on the machine that will run it: npm install -g metantel-cli.
metantel: there is no build for <platform> or this Linux uses musl libc. Builds exist for
macOS, glibc Linux (x64, arm64) and Windows x64. In a container, use a glibc base image such as
node:20-bookworm-slim rather than Alpine.
metantel doctor says x claude. Claude Code is not on your PATH or not signed in. Install it,
run claude once interactively to sign in, or set METANTEL_CLAUDE_BIN.
x browser … no Chromium found. Install one: npx playwright install chromium
chromium-headless-shell, or point METANTEL_CHROMIUM at Chrome. Nothing is downloaded for you.
nothing to test / very low placement in identify. codebase.path points at the wrong
directory, or the application uses a routing convention identification does not read yet. metantel
identify names the conventions it recognised; metantel sweep and a run still work from the
application's own links, with a smaller denominator.
Every page comes back signed-out or blocked. The front door did not open. Check auth.at,
the username field name (username vs email), and that the test account works in a normal
browser. metantel sweep --route login --headed shows what the harness sees.
A run stopped after one wave. Without a terminal (CI, the console) pass --auto; otherwise the
question "buy another wave?" reads end-of-file and stops. The console always passes it.
the application did not serve a single page to the sweep. The application is down or
unreachable from this machine. Nothing was saved; start the application and rerun.
Rate limits. The run reads Claude Code's own rate-limit events and waits; the console shows it. Long stalls on a laptop are usually the machine sleeping — the run keeps a wake lock while on mains power.
A finding looks wrong. Open the control's row in ledger.jsonl: every verdict carries the
evidence it rests on, what the inspector claimed, and whether the harness overruled it. The report
holds back accusations with nothing behind them and counts them separately.
Windows. Use PowerShell or Git Bash. Paths in config.json may use forward slashes.
17. Frequently asked questions
Does it need access to my database? No. Lite verifies on the screen and the network; a write is proven by the server accepting it and the application reading it back. A database channel is part of the full Artel suite.
Can it test an application behind Google / Okta / SSO? Not yet. Password and passkey sign-in are
supported. If an internal identity provider is on a separate origin, add it to
safety.allowed_origins — but the sign-in itself must be password or passkey.
Will it make changes to my application's data? Yes, in the test deployment you point it at: creating, editing and saving things is how a control is tested. Use a disposable environment and account.
Can I run it in CI? Yes: metantel run --auto --budget 10 --dry-run in a pipeline is free and
proves the setup; drop --dry-run to run for real. Exit codes are non-zero when the run could not
start. Linux x64/arm64 binaries are published for this; use a glibc image, pin the version, and keep
optional dependencies on.
Does it support my framework? Identification reads the source of most web stacks (see What it works on in the README). Where a convention is unknown, the application's own links are used. The browser side is framework-neutral.
Why is coverage lower than tool X reports? Because reached and assessed here mean what they say. A control counts only when someone stood in front of it, and only counts as assessed with a pass or fail and evidence. Visiting a page is not testing it.
Where does the model run? Through Claude Code, on your subscription. Choose the model with
--model; the default is the cheapest capable one.
Can I see what an inspector was told? Yes — brief-*.md in the run directory, one per session,
with the configured password masked.
18. Glossary
| term | |
|---|---|
| control | anything a user can act on or must be able to see: a field, button, link, checkbox, dropdown, or displayed text |
| catalogue | the list of controls with the page each renders on — the denominator |
| route / page | a URL the application serves; [name] marks a parameter (/orders/[id]) |
| walk (sweep) | the harness opening every page without a model, before a run |
| goal | something a user must be able to do on a page, with its preconditions, read from the source |
| brief | what an inspector session is told: the pages, the controls, the facts from the walk |
| inspector / lane | one Claude Code session driving the browser through the harness's tools |
| wave | one round of dispatching sessions until nothing is left to hand out |
| verdict | the harness's ruling on one control, from measured evidence; the inspector's claim is recorded beside it |
| assessed | a pass or fail with evidence; not "visited", not "attempted" |
| reached | an inspector or the walk stood in front of the control |
| finding | a verdict that says the application is broken, ranked by severity |
| case file | the run directory: ledger, evidence, briefs, report |
Artel QA Lite is the free, local edition of Artel by Metantel. [email protected]
