---
name: qa
description: Quality-assurance testing for the Carlos Arias website (carlosarias.co). Use when summarising a QA run, triaging findings, deciding severity, or fixing an issue the QA agent found (broken link, dead image, form failure, SEO/meta gap, sitemap gap, missing alt text). Explains what the site's QA covers, how severe each kind of issue is, and the gotchas of testing this specific site.
---

# Skill: QA for carlosarias.co

The site is a **static Astro build** (content baked from `cja_projects` / `cja_changelog`
at build time) plus a small **PHP API** at `/api`. The only live runtime endpoints are
`POST /api/contact/submit` and `GET /api/health`; everything else is pre-rendered HTML. So
QA is HTTP-based: a crawler fetches pages and parses the served HTML — no browser, no JS
execution.

## What a QA run checks

| check_type | What it verifies | Default severity |
|---|---|---|
| `page` | Every route returns 200 with HTML | **error** if not 200 |
| `link` | Every internal `<a href>` resolves (200) | **error** |
| `image` | Every `<img src>` / og:image / icon loads | **error** |
| `external` | Off-site links (social, project `links.live`) reachable | **warning** |
| `form` | `/api/contact/submit` alive (honeypot probe → 200) + rejects bad input (→ 422) | error / warning |
| `health` | `/api/health` returns 200 and `db:"connected"` | **error** |
| `seo` | Each page has a `<title>` + meta description; canonical host is carlosarias.co; titles aren't duplicated | warning (error for wrong canonical host) |
| `sitemap` | Every route appears in `sitemap.xml` | **warning** |
| `a11y` | Images have `alt`; `<html lang>` is set | **warning** |

## Severity model

- **error** — the site is broken for a real visitor: a page/link/image 404s, the contact
  form or API is down, or canonical URLs point at the wrong host. Fix promptly.
- **warning** — degraded but working: a missing meta description, a page absent from the
  sitemap, missing alt text, or an external link that looks dead. Fix when convenient.
- **info** — notes, no action needed.

## Site-specific gotchas (important)

- **Contact form is honeypot-probed, never really submitted.** The form has a hidden
  `company` field; if it's filled, the server returns `200 {received}` and writes **nothing**.
  QA fills it on purpose so the "is the endpoint alive" probe leaves no `cja_contact` row and
  sends no email. A separate probe sends a too-short `message` to confirm validation returns
  422. Never treat these probes as real leads.
- **External links are warnings, not errors.** Sites like Instagram/LinkedIn frequently
  return 403/429 to bots or time out — that is not proof the link is broken. Only a clear
  404/410 or DNS failure is flagged, and only as a warning. Don't over-react.
- **Known sitemap gap:** `sitemap.xml` currently omits `/projects`, `/changelog`,
  `/services`, `/resume`, `/faq`. These will show as `sitemap` warnings until
  `app/src/pages/sitemap.xml.js` is updated to include them.
- **Duplicate titles** usually mean a page didn't set its own `<title>` and fell back to the
  site default in `BaseLayout.astro`. The fix is a page-specific title/description prop.
- **Static build:** a content fix (e.g. a project's broken `links.live`) lives in the DB
  (`cja_projects`) or a page's `.astro`, and only goes live after a rebuild — which the
  console handles. Don't expect a DB edit alone to change the live page.

## Fixing a finding

Each finding carries a `fix_hint` — a ready-made instruction. When the admin turns a finding
into a Web Designer fix task, that hint becomes the task prompt. When you (as the Web
Designer) act on it: make the smallest correct change on the named page, stay on-brand (see
the `brand` skill), and let the console build/publish. Prefer fixing the source of a bad link
(the nav/footer/component or the `cja_projects` `links` value) over patching one instance.

## Writing the run summary

When asked to summarise a run: 2–4 sentences, plain English, for the site owner. Lead with
overall health ("clean" / "a few warnings" / "N errors need attention"), name the most
important thing to fix first, and say whether anything is urgent (a down form or API, a 404
on a linked page). No preamble, no restating every finding.
