Closes GAP-05, GAP-08, and final verification gate.
- Linux ARM64 diagnostic (GAP-05): browser-engine-installer now probes
os.platform + os.arch on Linux aarch64 and checks a prioritized list
of system chromium locations (/usr/bin/chromium, chromium-browser,
google-chrome, google-chrome-stable, /snap/bin/chromium). When a
browser is found, the install result carries a PlatformHint with an
exact VIBIUM_BROWSER_PATH export the user can copy. When none exists,
the hint surfaces the `apt-get install chromium` remediation. Wired
into phase 09 so it prints after vibium install succeeds. 5 new tests.
- GAP-08: added explicit `vibium --headless viewport 1280 720` setup
steps to yaml tc006/tc007 so the eval runs are as deterministic in CI
as smoke-test.sh. Updated smoke-test.sh header to note the yaml is
the canonical spec and the bash script is its mirror (covers the F1
vibium-missing contract case the yaml can't express cleanly).
- Trust tier promoted 2 -> 3 now that (a) the eval is runnable via
CommandEvalRunner, (b) CI runs both unit tests + smoke gate, and
(c) all 11 dependent browser-using skills either reference qe-browser
or document their intentional Playwright fallback.
- ADR-091 status: Proposed -> Implemented (2026-04-21).
- v3-adrs.md index reflects 80 Implemented / 6 In Progress / 3 Proposed.
Verification: 643/643 tests pass across tests/unit/validation/,
tests/unit/init/, tests/unit/scripts/qe-browser-*.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes GAP-01, GAP-02, GAP-04 from the ADR-091 completion plan.
- Adds CommandEvalRunner (src/validation/command-eval-runner.ts) as a
sibling to ParallelEvalRunner. Detects shell-based eval suites by
shape (first test case has input.command), runs setup/main commands
sequentially, and evaluates exit_code, json_fields (dotted JSONPath),
severity_at_least (none < low < medium < high < critical), and
candidate_count_at_least assertions against script JSON envelopes.
- Wires aqe eval run to dispatch to CommandEvalRunner when the suite is
command-mode. LLM-prompt suites keep the pre-existing path unchanged.
- Activates .claude/skills/qe-browser/evals/qe-browser.yaml (status:
active, was design-spec) and removes the honesty note now that the
runner supports its structured assertions.
- Pins vibium@^26.3.18 via DEFAULT_VIBIUM_SPEC in browser-engine-
installer.ts so npm install -g can't silently upgrade past a version
we've verified against the 5 primitives + smoke tests.
- Drops qe-browser SKILL.md trust_tier from 3 to 2 pending eval
integration in CI; will re-promote once the full verification pass
runs green.
Tests: 31 new cases (pure helpers, runner integration with injected
runner, happy-path against the shipped qe-browser.yaml).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
H1: detectVibium reads stderr too, extracts semver
- Many Go CLIs (including some Vibium versions) write --version to stderr.
detectVibium used to read only stdout and silently report 'unknown',
polluting the init log with "vibium unknown (already installed)".
- Fix: read both streams, prefer stdout, extract bare semver via regex
so output is consistent regardless of where the binary printed it.
- Tests: 5 new regression tests covering stderr fallback, stdout
preference, verbose-format extraction, prerelease tags, fallback to
first whitespace token.
- Note: result.version is now bare semver (26.3.18) not v-prefixed.
Two pre-existing tests updated to match the new contract.
H2: instructions_in_html_comment dead-code regex
- TreeWalker(SHOW_COMMENT).textContent yields the inner text without
the <!-- --> delimiters, so the pattern that requires the literal
`<!--` prefix could never fire. Eval tc009 was passing only by
accident (ignore_previous_instructions fired on the same fixture).
- Fix: re-wrap each comment node in `<!-- ... -->` before adding to
the hidden bucket. Pattern can now actually match.
- Tests: 2 new regression tests asserting wrapped form fires AND
unwrapped form does NOT fire (the bug condition).
H4: e2e-flow-verifier frontmatter regression — INVALID FINDING
- Verified against `git show main:` — the skill always had minimal
frontmatter on main (just name + description + user-invocable: true)
and has no evals/, schemas/, or scripts/ directories. It is a
user-invocable runbook-style skill, not trust-tier-3 validated.
No metadata to restore. Marked closed-as-invalid.
H6: log-before-spawn for the 3-minute Vibium install
- spawnSync(npm install -g vibium) blocks the event loop for up to
3 minutes on a cold cache while Chrome for Testing downloads. The
user saw zero output and would Ctrl-C thinking init hung.
- Fix: pre-flight detect call (5s timeout) short-circuits when vibium
is already installed (the common case, no banner). When the install
is actually about to run, log a clear "this can take 1-3 minutes,
downloads Chrome for Testing lazily" message BEFORE the spawn.
H7: scoped scripts/package.json survives npm pack — VERIFIED
- `npm pack --dry-run` confirms both
.claude/skills/qe-browser/scripts/package.json (225B) AND
assets/skills/qe-browser/scripts/package.json (225B)
are included in the published tarball. The CommonJS override that
keeps the helper scripts loadable from an ESM project root will
survive `npm install` after publication. No fix needed.
H8: eval yaml uses unsupported runner fields
- The structured assertion fields I invented (exit_code, json_fields,
severity_at_least, candidate_count_at_least) are NOT understood by
src/validation/parallel-eval-runner.ts which expects must_contain
keyword matching. The yaml as written is unrunnable.
- Honest fix: relabel evals/qe-browser.yaml as `status: design-spec`
with a HONESTY NOTE explaining it's a specification, not a runnable
eval. Two paths to make it runnable documented (extend runner OR
rewrite as must_contain).
- Parallel artifact: scripts/smoke-test.sh — a runnable bash smoke
test against the same pinned httpbin.org fixtures. THIS is the
script that gates PR-reopen per ADR-091 Phase 3.
Bonus from B2/H5 already in Phase 1:
- assert.js now uses ?? instead of || for the `expected` field
Verification:
- 50/50 qe-browser tests pass (was 36 in initial PR; +14 regressions)
- 392/392 init tests pass (was 387; +5 from H1)
- npm run build: clean
- npm pack --dry-run: scoped package.json confirmed in tarball
- eslint on all touched source files: clean
- bash -n smoke-test.sh: syntax OK
Phase 3 (real Vibium smoke test) still gating PR reopen per ADR-091.
Branch intentionally not pushed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces a new AQE-owned browser automation skill layered over Vibium
(WebDriver BiDi, single 10MB Go binary) and migrates 11 browser-using QE
skills to use it instead of raw Playwright/Puppeteer.
qe-browser ships five helper scripts that add QE primitives Vibium doesn't
cover on its own: typed assertions (16 check kinds), batch execution,
pixel-diff against stored baselines, prompt-injection scanning, and
semantic intent scoring ported from gsd-browser (MIT/Apache). Each script
emits a structured JSON envelope matching schemas/output.json so hooks
and CI gates can parse results without stdout grep.
Vibium installs automatically during `aqe init` via a new graceful
browser-engine installer that shells out to `npm install -g vibium` and
reports `already-installed`, `installed`, `install-failed`, or
`npm-unavailable` without ever failing init.
Skills migrated to reference qe-browser:
a11y-ally, e2e-flow-verifier, qe-visual-accessibility,
security-visual-testing, visual-testing-advanced, testability-scoring,
compatibility-testing, accessibility-testing, localization-testing,
observability-testing-patterns, enterprise-integration-testing.
Ships 36 new unit tests (browser-engine-installer, assert, intent-score,
check-injection) with dependency-injected spawners to avoid touching real
processes. All 387 existing init tests still pass.
Eval harness uses pinned public fixtures (httpbin.org, Vibium docs at a
pinned tag) plus a local static server that wraps this repo's own skill
docs, per the "no synthetic fixtures" rule.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>