qa-check — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited qa-check (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Run /qa-check on any web project to audit for Accessibility (WCAG 2.2 AA), Performance, and Code Quality issues. This skill auto-detects the tech stack and adapts its checks accordingly.
Use $ARGUMENTS to scope the audit to a specific directory or file pattern (e.g., /qa-check src/components/). If empty, audit the entire project.
Do NOT fix issues - only report them. Present findings as structured Markdown tables.
Before running any checks, detect the project's tech stack by scanning the working directory for marker files. Report what was detected before proceeding.
#### Detection Rules
Scan in this order. A project can match multiple stacks (e.g., WordPress with Node build tools).
| Stack | Marker Files |
|---|---|
| WordPress / PHP | wp-config.php, composer.json with "wordpress", style.css containing Theme Name:, functions.php, wp-content/ or content/ directory |
| Python | requirements.txt, pyproject.toml, setup.py, setup.cfg, Pipfile, manage.py (Django), app.py or wsgi.py (Flask) |
| Node / JS | package.json - then inspect for framework indicators: next (Next.js), express (Express), nuxt (Nuxt), @angular/core (Angular), react (React), vue (Vue), svelte (Svelte) |
| Static Web | *.html files in root or src/, *.css files, no backend markers detected |
#### Detection Output
Print a summary before running checks:
## Stack Detection
| Stack | Detected | Markers Found |
|---|---|---|
| WordPress/PHP | Yes/No | wp-config.php, style.css (Theme Name: ...) |
| Python | Yes/No | requirements.txt, manage.py |
| Node/JS | Yes/No | package.json (express, react) |
| Static Web | Yes/No | index.html, styles.css |Then determine which template/view files to scan:
*.php in theme directory, template-parts/, templates/, inc/templates/**/*.html, app/templates/**/*.html**/templates/**/*.html, **/templatetags/*.pypages/**/*.{js,jsx,tsx}, app/**/*.{js,jsx,tsx}, components/**/*.{js,jsx,tsx}views/**/*.{ejs,pug,hbs,html}, public/**/*.htmlsrc/**/*.{jsx,tsx,vue,svelte}*.html, src/**/*.htmlAlso scan: all *.css files, all *.js or *.ts files in source directories, config files (.env*, *.config.*).
Goal: Confirm output pages meet WCAG 2.2 AA requirements. These checks apply to all stacks - scan every file that produces HTML output.
| # | Check | What to Look For |
|---|---|---|
| 1 | Semantic HTML | <header>, <main>, <footer>, <nav> used correctly. Flag pages that use only <div> for major layout sections. |
| 2 | Image alt text | Every <img> must have an alt attribute. Empty alt="" is valid for decorative images. Flag any <img> with no alt at all. In PHP: check <?php echo img tags. In JSX: check <img components. |
| 3 | Form labels | Every <input>, <select>, <textarea> must have an associated <label> (via for/id pairing) or aria-label/aria-labelledby. Flag orphaned inputs. |
| 4 | Link accessible names | Every <a> must have visible text content, aria-label, or aria-labelledby. Flag empty links (icon-only without aria-label). Flag <a> with only an <img> child that lacks alt. |
| 5 | Heading hierarchy | No skipped heading levels (e.g., <h1> directly to <h3> without <h2>). Check across all templates that compose a full page. |
| 6 | Focus styles | Check CSS for :focus-visible or :focus rules. Flag any outline: none or outline: 0 that lacks a replacement visible focus indicator. |
| 7 | ARIA usage | Flag misuse patterns: role="button" on <a> without tabindex and keyboard handler, aria-hidden="true" on focusable elements, invalid ARIA roles, redundant ARIA (e.g., role="button" on <button>). |
| 8 | Colour contrast | Flag hardcoded colour combos that appear low-contrast. Check text colour against background colour where both are set in the same rule or element. This is heuristic - flag suspicious combos for manual review. |
| 9 | Language attribute | <html lang="..."> must be present in the root document. Flag if missing. |
| 10 | Viewport meta | <meta name="viewport"> must be present. Flag if it contains maximum-scale=1, user-scalable=no, or user-scalable=0 (these disable zoom). |
#### Stack-Specific A11y Checks
wp_nav_menu() outputs use <nav> wrapper. Check the_post_thumbnail() calls for alt text support. Check get_template_part() partials for orphaned interactive elements.<img> without alt prop. Check onClick on non-interactive elements (<div onClick>) without role, tabIndex, and onKeyDown. Check for autoFocus usage.v-html usage (potential a11y bypass - content may lack proper semantics). Check :alt bindings on images.Report: PASS / WARN / FAIL per check.
Goal: Identify performance issues. Checks are adapted per detected stack.
| # | Check | What to Look For |
|---|---|---|
| 1 | Image optimization | <img> tags should have width and height attributes (CLS prevention). Below-fold images should have loading="lazy". Flag large images without modern format alternatives (webp/avif). |
| 2 | Asset loading | Scripts should use defer, async, or type="module". Flag render-blocking <script> tags in <head> without these attributes. Flag render-blocking CSS that could be deferred. |
| 3 | Bundle size | Check for large vendor files in public/static directories. Flag unminified JS/CSS in production paths (files > 50KB without .min in the name). |
| 4 | N+1 queries | Flag loops that contain database queries - this is a heuristic check. Look for query calls (query, execute, cursor, fetchall, $wpdb->, Model.objects, select, find) inside for/foreach/while/map blocks. |
| 5 | Caching | Check for cache-control patterns in server config, middleware, or headers. Flag if no caching strategy is apparent. |
| 6 | External requests | Scan templates for third-party URLs (https:// to external domains) that could block rendering. Flag font services, analytics, and tracking pixels loaded synchronously. |
| 7 | DNS prefetch / preconnect | If external resources are used, check for <link rel="dns-prefetch"> or <link rel="preconnect"> hints. |
#### Stack-Specific Performance Checks
WordPress:
wp_enqueue_script() / wp_enqueue_style() usage vs raw <script> / <link> tags (should use enqueue system).query_posts() usage - should use WP_Query or get_posts() instead.wp_cache_get() / wp_cache_set() on expensive queries.wp_deregister_script('jquery') is used properly (common source of breakage).get_posts() / WP_Query calls without 'no_found_rows' => true when pagination isn't needed.Python (Flask/Django):
select_related() / prefetch_related() usage in Django views with related model access.@cache decorators on expensive view functions.Node/JS:
readFileSync, writeFileSync) in request handlers.node_modules files accidentally served to the client.compression middleware in Express.Report: PASS / WARN / FAIL per check.
Goal: Identify security issues, code smells, and quality problems. Checks are adapted per detected stack.
#### Security (All Stacks)
| # | Check | What to Look For | |
|---|---|---|---|
| 1 | SQL injection | String concatenation or f-strings in SQL queries. Must use parameterized queries / prepared statements. | |
| 2 | XSS (Cross-Site Scripting) | Unescaped user output in templates. Check for raw output: `\ | safe (Jinja2), {!! !!} (Blade), dangerouslySetInnerHTML (React), v-html (Vue), echo $var without esc_html()` (WP). |
| 3 | CSRF | State-changing routes (POST/PUT/DELETE) without CSRF token validation. Check for token presence in forms. | |
| 4 | Hardcoded secrets | API keys, passwords, tokens, connection strings in source files. Regex scan for patterns: password\s*=\s*['"], api_key\s*=\s*['"], secret\s*=\s*['"], sk_live_, AKIA, ghp_, Bearer\s+[A-Za-z0-9]. | |
| 5 | Environment files | Check .gitignore for .env patterns. Flag if .env files are not gitignored. Flag .env files that exist in the repo (committed secrets). |
#### Stack-Specific Security
WordPress / PHP:
$wpdb->prepare() must be used for all $wpdb->query() / $wpdb->get_results() calls with variables.esc_html(), esc_attr(), esc_url(), or wp_kses() as appropriate.wp_nonce_field() and handlers must verify with wp_verify_nonce() or check_admin_referer().sanitize_text_field(), absint(), sanitize_email(), etc.extract() usage (variable injection risk).eval(), assert(), preg_replace() with e modifier.Python:
eval(), exec(), or __import__() with user-controlled input.except: - must catch specific exceptions.pickle.loads() on untrusted data.DEBUG = True in production config.SECRET_KEY hardcoded in settings.Node / JS:
eval(), Function(), or child_process.exec() with user input.helmet or manual security headers in Express apps.cors configuration (not origin: '*' in production).--unhandled-rejections=none or missing error handlers.package.json for "engines" field (Node version pinning).npm audit issues if package-lock.json is present.#### General Code Quality
| # | Check | What to Look For |
|---|---|---|
| 6 | Error handling | Empty catch / except blocks that swallow errors silently. Bare try/except in Python. catch (e) {} in JS. catch (Exception $e) {} in PHP without logging. |
| 7 | Dead code | Unused imports (heuristic - check if imported name is used in the file). Unreachable code after return / break / continue / exit. Commented-out code blocks (> 5 consecutive commented lines). |
| 8 | Formatting consistency | Mixed tabs and spaces for indentation within the same file. Inconsistent naming (camelCase mixed with snake_case in the same file, not counting external API names). |
| 9 | Dependencies | Check lockfile age (if package-lock.json or Pipfile.lock or composer.lock is > 6 months old based on git log, warn). Flag deprecated packages if detectable from lockfile metadata. |
| 10 | TODO / FIXME / HACK | Scan for TODO, FIXME, HACK, XXX, TEMP comments. Report count and locations - these indicate known technical debt. |
Report: PASS / WARN / FAIL per check.
Present results as Markdown tables. Use this exact structure:
## QA Audit - <date>
### Stack Detection
| Stack | Detected | Markers Found |
|---|---|---|
| WordPress/PHP | Yes/No | ... |
| Python | Yes/No | ... |
| Node/JS | Yes/No | ... |
| Static Web | Yes/No | ... |
**Files scanned:** <count> files across <directories>
---
### Summary
| Pillar | Status | Pass | Warn | Fail |
|---|---|---|---|---|
| Accessibility | PASS/WARN/FAIL | <n> | <n> | <n> |
| Performance | PASS/WARN/FAIL | <n> | <n> | <n> |
| Code Quality | PASS/WARN/FAIL | <n> | <n> | <n> |
Overall pillar status: FAIL if any check is FAIL, WARN if any check is WARN, PASS otherwise.
---
### Findings
#### Pillar 1: Accessibility
| # | Check | Status | Detail |
|---|---|---|---|
| 1 | Semantic HTML | PASS/WARN/FAIL | ... |
| 2 | Image alt text | PASS/WARN/FAIL | ... |
| ... | | | |
#### Pillar 2: Performance
| # | Check | Status | Detail |
|---|---|---|---|
| 1 | Image optimization | PASS/WARN/FAIL | ... |
| 2 | Asset loading | PASS/WARN/FAIL | ... |
| ... | | | |
#### Pillar 3: Code Quality
| # | Check | Status | Detail |
|---|---|---|---|
| 1 | SQL injection | PASS/WARN/FAIL | ... |
| 2 | XSS | PASS/WARN/FAIL | ... |
| ... | | | |
---
### Action Items
Numbered list of issues requiring attention, ordered by severity:
1. **[FAIL]** <description> - `<file>:<line>`
2. **[FAIL]** <description> - `<file>:<line>`
3. **[WARN]** <description> - `<file>:<line>`
...CLAUDE.md or equivalent project config exists, use its rules for formatting/naming checks instead of generic defaults.node_modules/, vendor/, venv/, .venv/, __pycache__/, dist/, build/, .git/, or other dependency/build/cache directories.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.