The failure mode
LOOP-02-frontend-a11y.md lists as a precondition:
ast-grep available; Playwright installed and able to launch a browser (Bash: npx playwright --version)
The live accessibility-tree interrogation is the loop's whole differentiator — it is explicitly the part static scanners miss. But a large share of real targets cannot satisfy that precondition on the first run: no dev server, a headless environment with no browser, a Playwright install that resolves but cannot launch Chromium, or a target that is a component library with nothing to serve.
Today the loop file does not say what happens then. An agent hitting this will improvise, and the two obvious improvisations are both bad: silently skip nodes 5–8 and report PASS on a partial audit, or halt the entire loop including the static analysis that would have worked fine.
What a good PR looks like
Decide the behavior and write it into the loop file — this is a # Failure Routing and # Exit Criteria change, not a new node:
- Classify the precondition failure under
PROTOCOL.md §4 (Dependency Failure is the likely home) and route it explicitly.
- Make the static half (nodes 1–4) still complete and produce an artifact.
- Make the outcome honest in the exit criteria. Per
PROTOCOL.md §12, FAIL-with-artifact beats a silent success — a run that never opened a browser must not be able to report the same verdict as one that did. A distinct terminal state, with the skipped nodes named in the artifact, is probably the right shape.
- Say in
# Preconditions how an operator can tell in advance which mode they will get.
Please keep the loop inside its declared branch-mutating risk class, and do not add an assumption about which dev-server command or framework the target uses.
Checks
python tools/validate_loops.py. If you can run the changed RUN PROMPT against a real frontend repo — ideally once with Playwright working and once without — put both outcomes in the PR.
The failure mode
LOOP-02-frontend-a11y.mdlists as a precondition:The live accessibility-tree interrogation is the loop's whole differentiator — it is explicitly the part static scanners miss. But a large share of real targets cannot satisfy that precondition on the first run: no dev server, a headless environment with no browser, a Playwright install that resolves but cannot launch Chromium, or a target that is a component library with nothing to serve.
Today the loop file does not say what happens then. An agent hitting this will improvise, and the two obvious improvisations are both bad: silently skip nodes 5–8 and report PASS on a partial audit, or halt the entire loop including the static analysis that would have worked fine.
What a good PR looks like
Decide the behavior and write it into the loop file — this is a
# Failure Routingand# Exit Criteriachange, not a new node:PROTOCOL.md§4 (Dependency Failure is the likely home) and route it explicitly.PROTOCOL.md§12,FAIL-with-artifactbeats a silent success — a run that never opened a browser must not be able to report the same verdict as one that did. A distinct terminal state, with the skipped nodes named in the artifact, is probably the right shape.# Preconditionshow an operator can tell in advance which mode they will get.Please keep the loop inside its declared
branch-mutatingrisk class, and do not add an assumption about which dev-server command or framework the target uses.Checks
python tools/validate_loops.py. If you can run the changedRUN PROMPTagainst a real frontend repo — ideally once with Playwright working and once without — put both outcomes in the PR.