Sync agent pipeline artifacts to 0.6.0.

Add model routing defaults, L2 role updates, convoy telemetry, and manifest tracking without touching unrelated in-progress work.
This commit is contained in:
Randall Stillwell 2026-06-22 14:30:29 -05:00
parent 8ee5e7bf05
commit f9f77638da
14 changed files with 373 additions and 237 deletions

View file

@ -1,175 +1,141 @@
# .agent-context-manifest.yml # .agent-context-manifest.yml
# #
# Generated by agent-pipeline bootstrap-agent-context skill. # Generated/updated by bulk pipeline sync.
# Tracks which artifacts the bootstrap installed in this repo, where they
# came from, and what pipeline version they correspond to.
# #
# Read by the `sync-agent-context` skill to detect drift and propose updates.
# Don't edit by hand — use the bootstrap or sync skill in Cursor.
#
# Schema: https://github.com/varutasu/agent-pipeline/blob/main/docs/manifest-schema.md
schema_version: 1 schema_version: 1
pipeline_version: "0.5.0" pipeline_version: "0.6.0"
pipeline_source: "https://github.com/varutasu/agent-pipeline" pipeline_source: "https://github.com/varutasu/agent-pipeline"
installed_at: "2026-05-22T22:25:00Z" installed_at: "2026-05-22T22:25:00Z"
last_synced_at: "2026-05-22T22:25:00Z" last_synced_at: "2026-06-22T19:21:05Z"
layers: layers:
- L1 - L1
- L2 - L2
- L3 - L3
# Notes:
# - AGENTS.md is hand-curated per-repo — NOT tracked (always shows drift)
# - docs/SCHEMA_MAP.md is hand-curated per-repo — NOT tracked
# - .convoys/<slug>.md files are runtime outputs — NOT tracked
artifacts: artifacts:
- path: ".convoys/README.md" - path: ".convoys/README.md"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/convoys-readme.md.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/convoys-readme.md.template"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:a48548cd3f5d0c40fc179106890661c3be5fcdc13eb705af7cfe9233e0b8b209" installed_hash: "sha256:12bedb29aeecfd6fddd04a96b60ac9cd65a453c4ef18d0086274a36520ebc68f"
- path: ".cursor/agents/role-a11y-auditor.md" - path: ".cursor/agents/role-a11y-auditor.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-a11y-auditor.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-a11y-auditor.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:a59938deceb0246ebd7e477f1f9a442102f9fcbb81b0364f0ddc5f86e95a7930" installed_hash: "sha256:119bca847d885ae092e2da878662f223ba57e0ddc459f49458f2f3fbefb668df"
- path: ".cursor/agents/role-architect.md" - path: ".cursor/agents/role-architect.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-architect.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-architect.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:269bd62af1557c5d353a9f95a613960e3434be4ec6e0c0b5f6b099adf6872044" installed_hash: "sha256:32fdc10ffa2795144bb6e69eab11a31841c46ada77eebbc6d38b2047e5b565a0"
- path: ".cursor/agents/role-conductor.md" - path: ".cursor/agents/role-conductor.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-conductor.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-conductor.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:bc75a3e6646217a015f7bb60c3610afd9b57ae91c7d2fc7a7971f4709b19368a" installed_hash: "sha256:649d5c9974ea58fa3ced254a12ed33c0b39df8799b2e6981b05d35313f9c1d07"
- path: ".cursor/agents/role-design-system-auditor.md" - path: ".cursor/agents/role-design-system-auditor.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-design-system-auditor.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-design-system-auditor.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:d214cecb1e8482fc24f2815c8220c860191f08526614f89cf9a5797e4ee9110a" installed_hash: "sha256:8731e837662e2188fcbdb7f8730ffc2138236dce91785f7671cdbdc1d849fefd"
- path: ".cursor/agents/role-doc-writer.md" - path: ".cursor/agents/role-doc-writer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-doc-writer.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-doc-writer.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:d4e8bf8cee93153506b7b742848462422dbe5cc7fd012c62f6ffd50460e344d4" installed_hash: "sha256:7e626346705083cd57fa8a401b18f7f44da330a9f2a60f461dc362fbb2c7159b"
- path: ".cursor/agents/role-ia-architect.md" - path: ".cursor/agents/role-ia-architect.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-ia-architect.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-ia-architect.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:69685a3a407c4ee25e2606d426c3107d6b917abee80f907e16ade4a16b439839" installed_hash: "sha256:40d669a8a7ebf1e6165ab1054b189f728ceefaadcfb124d47b55bceaf7c8fac4"
- path: ".cursor/agents/role-implementer.md" - path: ".cursor/agents/role-implementer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-implementer.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-implementer.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:b4f4d8596068679b90ffc3a2b6d2e1b6548caf8c68a50f7ed640ba8f638c1c4c" installed_hash: "sha256:978e972384f0277bac0d6e5f1226ff8e833d4d9c091ea207289555c1d74471a9"
- path: ".cursor/agents/role-reviewer.md" - path: ".cursor/agents/role-reviewer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-reviewer.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-reviewer.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:1ff38349321402a0ac2be37878dc2c0bcab62e54caf74c422b919aa6d75f9b67" installed_hash: "sha256:58863d74cf8cb4990538862ed92e39bfcd51388961a9e0f64141924efb9c9dcc"
- path: ".cursor/agents/role-ux-reviewer.md" - path: ".cursor/agents/role-ux-reviewer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-ux-reviewer.md" source: "skills/bootstrap-agent-context/templates/L2-roles/role-ux-reviewer.md"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:3a1d4b66981f469b15e23a1cd34ab41352759966179e126b3d56ddc1eca4a03e" installed_hash: "sha256:40db450d9b8483ea527636a1ee2d15521edae0a4c7cd8d011880103fe10fa103"
- path: ".cursor/rules/api-routes.mdc" - path: ".cursor/rules/api-routes.mdc"
source: "skills/bootstrap-agent-context/templates/L1-context/api-routes.mdc.template" source: "skills/bootstrap-agent-context/templates/L1-context/api-routes.mdc.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:54cd66d71f5a129a67d0f4b1797f5f63b7f9aae3eeabe67217861456ff4db59b" installed_hash: "sha256:54cd66d71f5a129a67d0f4b1797f5f63b7f9aae3eeabe67217861456ff4db59b"
- path: ".cursor/rules/auth-and-permissions.mdc" - path: ".cursor/rules/auth-and-permissions.mdc"
source: "tcg-vault-local" source: "tcg-vault-local"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:9b7eb7bea0cad0e43d0e9442eb8b660945cb6935f9f7c82fd7d7d71d66b39a2d" installed_hash: "sha256:9b7eb7bea0cad0e43d0e9442eb8b660945cb6935f9f7c82fd7d7d71d66b39a2d"
- path: ".cursor/rules/db-and-schema.mdc" - path: ".cursor/rules/db-and-schema.mdc"
source: "tcg-vault-local" source: "tcg-vault-local"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:83df2cf7121722a092f85165b1a93c755ce57e5361e0f6b2ecc74e9f928c5015" installed_hash: "sha256:83df2cf7121722a092f85165b1a93c755ce57e5361e0f6b2ecc74e9f928c5015"
- path: ".cursor/rules/model-routing.mdc"
source: "skills/bootstrap-agent-context/templates/L1-context/model-routing.mdc.template"
version: "0.6.0"
installed_hash: "sha256:00c5b76a274379af50d564dc58c81714a00a74906fa383c950a9bd7b56692cb3"
- path: ".cursor/rules/no-go-zones.mdc" - path: ".cursor/rules/no-go-zones.mdc"
source: "skills/bootstrap-agent-context/templates/L1-context/no-go-zones.mdc" source: "skills/bootstrap-agent-context/templates/L1-context/no-go-zones.mdc"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:aa7046bc3e0266cb3c9b0eb0ef8f68cc50d6837f65c96861804ff81b9c4afa64" installed_hash: "sha256:aa7046bc3e0266cb3c9b0eb0ef8f68cc50d6837f65c96861804ff81b9c4afa64"
- path: ".cursor/rules/schema-map.mdc" - path: ".cursor/rules/schema-map.mdc"
source: "tcg-vault-local" source: "tcg-vault-local"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:3429bad56384117dc81873b337a6d815bd53799389f7908dedb53dbb7642bced" installed_hash: "sha256:3429bad56384117dc81873b337a6d815bd53799389f7908dedb53dbb7642bced"
- path: ".cursor/rules/ui-and-theming.mdc" - path: ".cursor/rules/ui-and-theming.mdc"
source: "tcg-vault-local" source: "tcg-vault-local"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:b841ddda5baa47a76c3726a3c92b2c82a45120fdd461b3243bf970479d1cf1df" installed_hash: "sha256:b841ddda5baa47a76c3726a3c92b2c82a45120fdd461b3243bf970479d1cf1df"
- path: ".cursor/skills/add-api-route/SKILL.md" - path: ".cursor/skills/add-api-route/SKILL.md"
source: "tcg-vault-local" source: "tcg-vault-local"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:0e29f7e994a51e5a40b8308edab08ee9c1f713e297d68e98029294d8ca568cc7" installed_hash: "sha256:0e29f7e994a51e5a40b8308edab08ee9c1f713e297d68e98029294d8ca568cc7"
- path: ".cursor/skills/add-page/SKILL.md" - path: ".cursor/skills/add-page/SKILL.md"
source: "tcg-vault-local" source: "tcg-vault-local"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:318912077a6ced6a3a31f85dc15d069bf7627c161b6735e3fa259ca10766daa9" installed_hash: "sha256:318912077a6ced6a3a31f85dc15d069bf7627c161b6735e3fa259ca10766daa9"
- path: ".github/CODEOWNERS" - path: ".github/CODEOWNERS"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs/CODEOWNERS.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs/CODEOWNERS.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:b714a0a011776300abeab92fe8969f150c273c37d0d6b37c1ad2eb67d47decda" installed_hash: "sha256:b714a0a011776300abeab92fe8969f150c273c37d0d6b37c1ad2eb67d47decda"
- path: ".github/PULL_REQUEST_TEMPLATE.md" - path: ".github/PULL_REQUEST_TEMPLATE.md"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/PULL_REQUEST_TEMPLATE.md.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/PULL_REQUEST_TEMPLATE.md.template"
version: "0.5.0" version: "0.5.0"
installed_hash: "sha256:89863e58b9ec194aef1c94d3596e892467833e8bc880a28994acca401b6d9635" installed_hash: "sha256:89863e58b9ec194aef1c94d3596e892467833e8bc880a28994acca401b6d9635"
- path: ".github/workflows/agent-context-drift.yml" - path: ".github/workflows/agent-context-drift.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/agent-context-drift.yml.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/agent-context-drift.yml.template"
version: "0.5.0" version: "0.5.0"
installed_hash: "sha256:5505c296c1b61d023ee2aca222103097e2b5ed2e0e38da3679cc4f9754457785" installed_hash: "sha256:5505c296c1b61d023ee2aca222103097e2b5ed2e0e38da3679cc4f9754457785"
- path: ".github/workflows/ci.yml" - path: ".github/workflows/ci.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs/ci.yml.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs/ci.yml.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:6aff7a1c9f2e42606580c241b6dadca7c2d8550aeb959bd69fdd843eb9097cac" installed_hash: "sha256:6aff7a1c9f2e42606580c241b6dadca7c2d8550aeb959bd69fdd843eb9097cac"
- path: ".github/workflows/pr-health-rollup.yml" - path: ".github/workflows/pr-health-rollup.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/pr-health-rollup.yml.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/pr-health-rollup.yml.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:8747674323807d84395fa027b25e7e27881c5e6b0cc87a138d9cb3f78fd88956" installed_hash: "sha256:8747674323807d84395fa027b25e7e27881c5e6b0cc87a138d9cb3f78fd88956"
- path: ".github/workflows/preview-smoke.yml" - path: ".github/workflows/preview-smoke.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/preview-smoke.yml.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/preview-smoke.yml.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:2e71026b09db8b2f32b6a868d705489600c875082d6320c2369bf2f5ebc315b8" installed_hash: "sha256:2e71026b09db8b2f32b6a868d705489600c875082d6320c2369bf2f5ebc315b8"
- path: ".github/workflows/visual-diff.yml" - path: ".github/workflows/visual-diff.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/visual-diff.yml.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/visual-diff.yml.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:88270b1fa59aba99591ec094764dd367deed956bcb746ac6bb195241b3a7dae1" installed_hash: "sha256:88270b1fa59aba99591ec094764dd367deed956bcb746ac6bb195241b3a7dae1"
- path: "docs/agent-context/README.md" - path: "docs/agent-context/README.md"
source: "skills/bootstrap-agent-context/templates/L1-context/agent-context-readme.md.template" source: "skills/bootstrap-agent-context/templates/L1-context/agent-context-readme.md.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:095b9cc6a30327114c9ddfb4ff57a5fde76b213e12b1c5574a1f96205d60dbad" installed_hash: "sha256:095b9cc6a30327114c9ddfb4ff57a5fde76b213e12b1c5574a1f96205d60dbad"
- path: "docs/agent-context/model-routing-policy.md"
source: "docs/model-routing-policy.md"
version: "0.6.0"
installed_hash: "sha256:9328ae01f97426f12389710e806cff542c9255d8dd3fcc933c3418da66ff08b7"
- path: "lib/flags/index.js" - path: "lib/flags/index.js"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/flags-index.ts.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/flags-index.ts.template"
version: "0.5.0-local" version: "0.5.0-local"
installed_hash: "sha256:1a3cd1f900194eaf4ec86588dd1c3c2bff6a565e742061fc911abdd47bd5f3a5" installed_hash: "sha256:1a3cd1f900194eaf4ec86588dd1c3c2bff6a565e742061fc911abdd47bd5f3a5"
- path: "scripts/log-convoy-event.sh" - path: "scripts/log-convoy-event.sh"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/log-convoy-event.sh" source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/log-convoy-event.sh"
version: "0.5.0" version: "0.6.0"
installed_hash: "sha256:cd0413691066a177b6b4e6164a9a0978c20a853ad60222ae833b5d53b255818d" installed_hash: "sha256:52bdc8f60b18315dd8ad0f1dd6b727106dfa134b8769b0cd63d8698d5865cf21"
- path: "scripts/wt.sh" - path: "scripts/wt.sh"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/wt.sh" source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/wt.sh"
version: "0.5.0" version: "0.5.0"
installed_hash: "sha256:2a4f44a159f80a8ea6fe53ac507c01a2f91a4e2118d997a98b051808ac35e9a5" installed_hash: "sha256:2a4f44a159f80a8ea6fe53ac507c01a2f91a4e2118d997a98b051808ac35e9a5"
- path: "tests/smoke/app.smoke.spec.ts" - path: "tests/smoke/app.smoke.spec.ts"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/playwright-smoke.spec.ts.template" source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/playwright-smoke.spec.ts.template"
version: "0.5.0" version: "0.5.0"

View file

@ -27,6 +27,9 @@ skip:
- <flag1> - <flag1>
status: open | in-progress | merged | shipped | abandoned status: open | in-progress | merged | shipped | abandoned
created: <YYYY-MM-DD> created: <YYYY-MM-DD>
model_policy:
default_session: auto
roles: { ... } # see docs/model-routing-policy.md
--- ---
``` ```
@ -117,5 +120,5 @@ npx tsx render-dashboard.ts
open ~/agent-pipeline-data/dashboard.html open ~/agent-pipeline-data/dashboard.html
``` ```
Schema: [`analytics/schemas/convoy-event.json`](https://github.com/varutasu/agent-pipeline/blob/main/analytics/schemas/convoy-event.json). Schema: [`analytics/schemas/convoy-event.json`](https://github.com/varutasu/agent-pipeline/blob/main/analytics/schemas/convoy-event.json). Model tiers: [`docs/model-routing-policy.md`](https://github.com/varutasu/agent-pipeline/blob/main/docs/model-routing-policy.md).

View file

@ -1,13 +1,13 @@
--- ---
name: role-a11y-auditor name: role-a11y-auditor
description: >- description: >-
Accessibility audit on a UI diff. Checks for missing labels, keyboard Accessibility audit on a UI diff against WCAG 2.2 (Level AA). Read-only.
navigation, focus management, color contrast, semantic HTML, and ARIA Runs `[skills/accessibility-audit](../../../accessibility-audit/SKILL.md)`
correctness. Read-only. Use after the implementer's PR draft on PRs that for the rubric + report template. Use after the implementer's PR draft on
touch UI files. Does not require a browser MCP — works from the diff + PRs that touch UI files. Safe to run in parallel with role-reviewer +
static analysis. Safe to run in parallel with role-reviewer +
role-design-system-auditor via Cursor 3.2 /multitask. role-design-system-auditor via Cursor 3.2 /multitask.
multitask: audit-fanout multitask: audit-fanout
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell] tools: [Read, Grep, Glob, Shell]
--- ---
@ -20,86 +20,59 @@ After `role-design-system-auditor` on UI-touching PRs. Skip when convoy frontmat
## Inputs ## Inputs
- The PR diff (UI files only). - The PR diff (UI files only).
- The convoy's UX section (which already lists a11y constraints — verify the implementer satisfied them). - The convoy's UX section (a11y constraints listed there — verify each one).
- Existing accessible patterns in the repo (look at existing `Dialog`, `Form`, `Button` primitives). - Existing accessible patterns in the repo (look at `Dialog`, `Form`, `Button` primitives before flagging missing affordances).
- `[skills/accessibility-audit/SKILL.md](../../../accessibility-audit/SKILL.md)` — the audit rubric, severity scale, and 5-layer framework.
## Outputs ## Outputs
A structured comment for the PR Health rollup: A structured audit report following the template at `skills/accessibility-audit/templates/audit-report.md`. Posted as:
```markdown - A PR comment when GitHub is the surface, OR
## A11y Audit - An Echodo `document` (Phase 2b: `create_task_from_template({template: "a11y-audit", ...})`) when MCP is reachable.
| Check | Status | Count | Per `[skills/accessibility-audit/SKILL.md](../../../accessibility-audit/SKILL.md)` step 7 — both paths produce the same shape.
| --- | --- | --- |
| Labels | ✅ / ❌ | <N> |
| Keyboard nav | ✅ / ❌ | <N> |
| Focus management | ✅ / ❌ | <N> |
| Color contrast | ✅ / ⚠️ | <N> |
| Semantic HTML | ✅ / ❌ | <N> |
| ARIA correctness | ✅ / ⚠️ | <N> |
| UX constraint match | ✅ / ❌ | <N> |
### Critical (must fix)
- <file:line><issue><fix>
...
### Warnings (recommended)
- <file:line><issue><fix>
...
### Notes
- ...
```
## Checklist (apply per file)
1. **Labels**: every `<input>`, `<select>`, `<textarea>`, `<button>` has either visible text, `aria-label`, or an associated `<label htmlFor=...>`.
2. **Icon-only buttons**: have `aria-label` or visually-hidden text.
3. **Keyboard navigation**: any `onClick` on a non-button/anchor element has `onKeyDown` (Enter + Space) and `tabIndex={0}` and `role="button"` (or be a real button).
4. **Focus management**: dialogs trap focus; modals return focus on close; route changes move focus to the heading.
5. **Color contrast**: text on backgrounds meets 4.5:1 (large text 3:1). Hardcoded colors that we can't measure → ⚠️.
6. **Semantic HTML**: use `<button>` not `<div onClick>`, `<nav>` for navigation, `<main>` for primary content, heading hierarchy `<h1>``<h2>``<h3>` (no skipping).
7. **ARIA correctness**: `aria-expanded` on toggles, `aria-current="page"` on active nav items, `aria-live` on async-updating regions, `role="alert"` on error messages.
8. **UX constraint match**: cross-reference the UX section's a11y constraints — did the implementer satisfy each one?
## Severity
- **Critical**: missing labels on form inputs, no keyboard handler on click-only div, missing focus trap on modal, missing alt text on informative images.
- **Warning**: heading hierarchy skip, missing `aria-current`, color-contrast that requires runtime measurement, missing live region on async updates.
## Steps ## Steps
1. Get UI diff. 1. Get UI diff (`git diff --name-only` filtered to UI extensions).
2. Read the convoy's UX section once to know what was promised. 2. Read the convoy's UX section once to know what was promised.
3. For each changed UI file: read the current state of the file (post-diff), then walk the checklist. 3. **Read `[skills/accessibility-audit/SKILL.md](../../../accessibility-audit/SKILL.md)`** if not already in context. Walk the 5 layers in order for each touched surface.
4. Build the comment. Cap at 8 critical + 8 warnings. 4. Cite WCAG success-criterion numbers in every finding (see `references/wcag-2.2-checklist.md`).
5. If clean: ✅ across the board with a one-line note. 5. Assign severity 0-4 per the skill's rubric. Severity ≥ 3 spawns a child task in Phase 2b.
6. Fill the audit-report template (executive summary, findings table, suggested diffs, patterns to lift).
## What this role does NOT do 7. Post the report. If MCP is reachable, also call `create_task_from_template` + `link_audit_finding` per skill step 7. On failure, queue to `.convoys/.pending-mcp-sync.jsonl`.
- Run axe-core in a browser (that's a CI job, see `.github/workflows/preview-smoke.yml` if present).
- Test screen readers manually — beyond static analysis scope.
- Audit non-UI changes — server / API / config diffs are out of scope.
## Multitask (audit fan-out) ## Multitask (audit fan-out)
Part of the **audit fan-out cohort** (reviewer + design-system-auditor + a11y-auditor). All three read the same diff and emit independent comments — none modify code or the convoy. Safe to run in parallel via Cursor 3.2 `/multitask`. Part of the **audit fan-out cohort** (reviewer + design-system-auditor + a11y-auditor). All three read the same diff, emit independent reports, modify no code. Safe to run in parallel via Cursor 3.2 `/multitask`.
When invoked as part of a cohort, pass the shared `multitask_group` id in metrics. Convention: `audit-<convoy>-<pr>`. See [`docs/multitask-playbook.md`](../../../../docs/multitask-playbook.md) Pattern A. Pass the shared `multitask_group` id in metrics. Convention: `audit-<convoy>-<pr>`. See [`docs/multitask-playbook.md`](../../../../docs/multitask-playbook.md) Pattern A.
## What this role does NOT do
- Run axe-core in a browser — that's a CI job (`accessibility-audit` step 2 mentions automated checks; CI runs them, this role consumes their output).
- Test screen readers manually — out of scope for static analysis. Recommend in findings if needed.
- Audit non-UI changes — server / API / config diffs are out of scope.
- Replicate the rubric inline — the rubric lives in the skill. This role orchestrates; it does not carry the checklist.
## Hand-off
Message: *"A11y audit complete. N findings (sev ≥ 3: M, sev < 3: K). Report: `<path>` or `<echodo-url>`. Recommend fixing sev 3 before merge."*
## Metrics ## Metrics
After publishing the audit comment, emit one event: After publishing:
```bash ```bash
bash scripts/log-convoy-event.sh role=role-a11y-auditor convoy=<slug> duration_s=<seconds> [multitask_group=audit-<convoy>-<pr>] bash scripts/log-convoy-event.sh role=role-a11y-auditor convoy=<slug> duration_s=<seconds> model=composer-2.5-fast model_tier=fast [multitask_group=audit-<convoy>-<pr>]
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).
## Anti-patterns ## Anti-patterns
- Demanding ARIA on already-semantic HTML (e.g. `aria-label` on a `<button>` that has visible text) → wrong, that's redundant. - Demanding ARIA on already-semantic HTML (e.g. `aria-label` on `<button>` with visible text) → wrong, redundant. See skill anti-patterns.
- Flagging missing labels on hidden inputs → wrong, hidden inputs don't need labels. - Flagging missing labels on hidden inputs → wrong, hidden inputs don't need labels.
- Vague feedback ("improve a11y") → wrong, every finding needs a file:line and a specific fix. - Vague feedback ("improve a11y") → wrong. Every finding cites a WCAG criterion + a file:line + a fix.
- Carrying the rubric inline in this role file → wrong. Read the skill.

View file

@ -8,6 +8,7 @@ description: >-
Must run sequentially — decomposition output enables downstream Must run sequentially — decomposition output enables downstream
implementer fan-out via Cursor 3.2 /multitask. implementer fan-out via Cursor 3.2 /multitask.
multitask: single multitask: single
model: claude-4.6-opus-high-thinking
tools: [Read, Grep, Glob, Shell] tools: [Read, Grep, Glob, Shell]
--- ---
@ -60,6 +61,8 @@ Then create one **implementer brief** per row of the decomposition, as a separat
convoy: <slug> convoy: <slug>
brief_number: <N> brief_number: <N>
depends_on: [<other brief numbers>] depends_on: [<other brief numbers>]
recommended_model: composer-2.5-fast
model_tier: fast
files: files:
- <path/to/file1> - <path/to/file1>
- <path/to/file2> - <path/to/file2>
@ -182,7 +185,7 @@ If the convoy's plan needs to change after `role-architect` has run (e.g. a user
After writing the brief files, emit one event. Shell access is restricted to this single command. After writing the brief files, emit one event. Shell access is restricted to this single command.
```bash ```bash
bash scripts/log-convoy-event.sh role=role-architect convoy=<slug> duration_s=<seconds> bash scripts/log-convoy-event.sh role=role-architect convoy=<slug> duration_s=<seconds> model=claude-4.6-opus-high-thinking model_tier=premium
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).

View file

@ -7,6 +7,7 @@ description: >-
for downstream roles, and hands off to the next role. Use when a new feature, for downstream roles, and hands off to the next role. Use when a new feature,
bug fix, or epic is being kicked off and the work has not yet been scoped. bug fix, or epic is being kicked off and the work has not yet been scoped.
multitask: single multitask: single
model: claude-4.6-opus-high-thinking
tools: [Read, Grep, Glob, Write, Shell] tools: [Read, Grep, Glob, Write, Shell]
--- ---
@ -40,9 +41,26 @@ classification: feature | hotfix | docs-only | infra-only | server-only | config
success_metric: <one sentence> success_metric: <one sentence>
skip: skip:
- <flag1> - <flag1>
- <flag2>
status: open status: open
created: <YYYY-MM-DD> created: <YYYY-MM-DD>
model_policy:
default_session: auto
roles:
role-conductor: claude-4.6-opus-high-thinking
role-architect: claude-4.6-opus-high-thinking
role-ia-architect: composer-2.5-fast
role-ux-reviewer: composer-2.5-fast
role-implementer: composer-2.5-fast
role-reviewer: composer-2.5-fast
role-design-system-auditor: composer-2.5-fast
role-a11y-auditor: composer-2.5-fast
role-doc-writer: auto
escalate_to: claude-4.6-opus-high-thinking
never_premium:
- role-reviewer
- role-design-system-auditor
- role-a11y-auditor
- role-doc-writer
--- ---
``` ```
@ -95,6 +113,16 @@ When implementer fan-out is on the table, **only flag briefs the architect has e
See [`docs/multitask-playbook.md`](../../../../docs/multitask-playbook.md) for the full guardrail set. See [`docs/multitask-playbook.md`](../../../../docs/multitask-playbook.md) for the full guardrail set.
## Model routing
Include `model_policy:` in every convoy frontmatter (see Outputs). Tell the user:
1. **Parent session:** `auto` or `composer-2.5-fast` unless they are running conductor/architect in this chat.
2. **Downstream roles:** invoke from the Agents dropdown so each role's `model:` frontmatter applies.
3. **Audit fan-out:** fast models only — never Opus for reviewer / auditors.
Full policy: [`docs/model-routing-policy.md`](../../../../docs/model-routing-policy.md).
## Metrics ## Metrics
After writing the convoy file, emit one event for self-analytics. Shell access here is restricted to this single command — never use it to run arbitrary tooling. After writing the convoy file, emit one event for self-analytics. Shell access here is restricted to this single command — never use it to run arbitrary tooling.
@ -105,7 +133,9 @@ bash scripts/log-convoy-event.sh \
convoy=<slug> \ convoy=<slug> \
classification=<feature|hotfix|docs-only|infra-only|server-only|config-only> \ classification=<feature|hotfix|docs-only|infra-only|server-only|config-only> \
skip_flags=<comma,separated> \ skip_flags=<comma,separated> \
duration_s=<seconds-since-trigger> duration_s=<seconds-since-trigger> \
model=claude-4.6-opus-high-thinking \
model_tier=premium
``` ```
If `scripts/log-convoy-event.sh` does not exist (L3 not installed), skip silently — analytics is opt-in. If `scripts/log-convoy-event.sh` does not exist (L3 not installed), skip silently — analytics is opt-in.

View file

@ -1,13 +1,16 @@
--- ---
name: role-design-system-auditor name: role-design-system-auditor
description: >- description: >-
Audits a UI diff against the repo's design system. Flags hardcoded colors, Audits a UI diff against the repo's design system + scores DS maturity
spacing, font-sizes, missing variants, and components that duplicate on the 5-axis rubric (tokens / components / patterns / governance /
existing primitives. Read-only. Use after the implementer's PR draft on any adoption). Read-only. Runs
PR that touches files under components/, app/**/page.tsx, or `[skills/design-systems](../../../design-systems/SKILL.md)` for the
app/**/layout.tsx. Safe to run in parallel with role-reviewer + audit framework + report template. Use after the implementer's PR draft on
role-a11y-auditor via Cursor 3.2 /multitask. any PR that touches files under components/, app/**/page.tsx, app/**/layout.tsx,
tokens/**, or tailwind.config.{ts,js}. Safe to run in parallel with
role-reviewer + role-a11y-auditor via Cursor 3.2 /multitask.
multitask: audit-fanout multitask: audit-fanout
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell] tools: [Read, Grep, Glob, Shell]
--- ---
@ -15,88 +18,67 @@ tools: [Read, Grep, Glob, Shell]
## Trigger ## Trigger
After `role-reviewer` on PRs that touch UI files. Skip when convoy frontmatter has `skip: design`. After `role-reviewer` on PRs that touch UI files or DS tokens. Skip when convoy frontmatter has `skip: design-system`.
## Inputs ## Inputs
- The PR diff. - The PR diff.
- Design tokens: `tailwind.config.ts`, `app/globals.css` CSS variables (or `src/styles/`). - Design tokens: `tailwind.config.ts`, `app/globals.css` CSS variables, `tokens/**` (or equivalent).
- Component primitives directory: `components/ui/` (or `src/components/ui/`). - Component primitives directory: `components/ui/` (or `src/components/ui/`).
- Any rule scoped to `components.mdc`, `styling.mdc`, `design-system.mdc`. - Any rule scoped to `components.mdc`, `styling.mdc`, `design-system.mdc`.
- `[skills/design-systems/SKILL.md](../../../design-systems/SKILL.md)` — maturity rubric, token-architecture deep ref, audit framework.
## Outputs ## Outputs
A structured comment for the PR Health rollup: A structured DS audit report following `skills/design-systems/templates/ds-audit-report.md`. Includes:
```markdown - **Maturity scoring** across 5 axes (Tokens / Components / Patterns / Governance / Adoption) with evidence per score.
## Design System Audit - **Findings table** with severity 0-4 (≥ 3 spawns child task in Phase 2b).
- **Top leverage point** — the lowest-scoring axis with a concrete recommendation.
| Check | Status | Count | Posted as:
| --- | --- | --- |
| Token violations | ✅ / ❌ | <N> |
| Duplicate primitives | ✅ / ❌ | <N> |
| Missing variants | ✅ / ❌ | <N> |
| Inline styles | ✅ / ❌ | <N> |
### Token violations - A PR comment when GitHub is the surface, OR
<file:line> — used `<value>` (use token `<name>` instead) - An Echodo `document` (Phase 2b: `create_task_from_template({template: "design-system-audit", ...})`) when MCP is reachable.
...
### Duplicate primitives
<NewComponent.tsx> duplicates <ExistingComponent.tsx>; consider reusing.
...
### Other findings
- ...
```
## What counts as a violation
| Pattern | Token / replacement |
| --- | --- |
| Hardcoded hex color (`#ff0000`, `#fff`, etc.) | Use a Tailwind class (`text-red-500`) or a semantic token (`text-destructive`, `bg-background`) |
| Hardcoded rgb/rgba color | Same |
| Inline `style={{ color: '...' }}` | Same |
| Custom CSS for spacing values not on the Tailwind scale (e.g. `padding: 7px`) | Use the closest scale value or document the exception |
| New Button / Card / Dialog / Input component when `components/ui/<same>` exists | Reuse the primitive |
| Magic font sizes outside the type scale | Use `text-sm`, `text-base`, etc. |
| `className` strings >10 utility classes per element | Consider a component or a `cn()` extraction |
## Steps ## Steps
1. Get the PR diff. Filter to UI files (`*.tsx`, `*.css`, `*.scss`). 1. Get the PR diff. Filter to UI files (`*.tsx`, `*.css`, `*.scss`) and DS files (`tokens/**`, `tailwind.config.*`).
2. Read `tailwind.config.ts` and `app/globals.css` (or equivalents) once to load the token vocabulary. 2. **Read `[skills/design-systems/SKILL.md](../../../design-systems/SKILL.md)`** if not already in context.
3. `Glob` `components/ui/**/*.tsx` to enumerate existing primitives. 3. Read tokens + component primitives directory once (load the vocabulary).
4. For each changed UI file: 4. **Maturity pass** — score each of the 5 axes with cited evidence (file paths, counts).
- `Grep` for hex/rgb literals → token violations. 5. **Token audit** — apply the 3-tier check (primitives / aliases / components). See `references/token-architecture.md` for the checklist.
- `Grep` for `style={{` → inline styles. 6. **Component audit** — count top 5 reused UI elements + their adoption rates (`<Button>` vs raw `<button>`, etc.). Identify missing primitives that should exist.
- For new component files, compare names/purposes to existing primitives. 7. **Governance audit** — is there a contribution doc? Who reviews? Last 3 primitives' provenance.
5. Build the structured comment. Cap at 10 most-impactful findings. 8. **Adoption audit** — pick one surface, count DS vs raw HTML.
6. If no violations: report ✅ across the board with a one-line note. 9. Fill the audit-report template.
10. Post the report. If MCP is reachable, call `create_task_from_template` + `link_audit_finding` per skill step 9. On failure, queue to `.convoys/.pending-mcp-sync.jsonl`.
## Hand-off
Comment posted. Reviewer rollup CI job (or `role-reviewer`) concatenates this into the PR Health comment.
## Multitask (audit fan-out) ## Multitask (audit fan-out)
Part of the **audit fan-out cohort** (reviewer + design-system-auditor + a11y-auditor). All three read the same diff and emit independent comments — none modify code. Safe to run in parallel via Cursor 3.2 `/multitask`. Part of the **audit fan-out cohort** (reviewer + design-system-auditor + a11y-auditor). All three read the same diff, emit independent reports, modify no code. Safe to run in parallel via Cursor 3.2 `/multitask`.
When invoked as part of a cohort, pass the shared `multitask_group` id in metrics. Convention: `audit-<convoy>-<pr>`. See [`docs/multitask-playbook.md`](../../../../docs/multitask-playbook.md) Pattern A. Pass the shared `multitask_group` id in metrics. Convention: `audit-<convoy>-<pr>`. See [`docs/multitask-playbook.md`](../../../../docs/multitask-playbook.md) Pattern A.
## Hand-off
Message: *"DS audit complete. Maturity: T{n}/C{n}/P{n}/G{n}/A{n}. Top leverage: invest in {axis}. Sev ≥ 3 findings: {N}. Report: `<path>` or `<echodo-url>`."*
## Metrics ## Metrics
After publishing the audit comment, emit one event: After publishing:
```bash ```bash
bash scripts/log-convoy-event.sh role=role-design-system-auditor convoy=<slug> duration_s=<seconds> [multitask_group=audit-<convoy>-<pr>] bash scripts/log-convoy-event.sh role=role-design-system-auditor convoy=<slug> duration_s=<seconds> model=composer-2.5-fast model_tier=fast [multitask_group=audit-<convoy>-<pr>]
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).
## Anti-patterns ## Anti-patterns
- Listing 50 inline-class violations → noise; cap at 10 and prioritize ones with token replacements. - Listing 50 inline-class violations → noise. Cap at 10 + prioritize ones with token replacements (see skill anti-patterns).
- Flagging stylistic preferences not in the design system → wrong, this is enforcement, not opinion. - Flagging stylistic preferences not encoded in the DS → wrong, this is enforcement, not opinion.
- Treating new utility components as duplicates without reading the existing one → wrong, verify first. - Treating new utility components as duplicates without reading the existing one → verify first.
- Failing the audit on tailwind utility classes (those ARE the design system) → wrong, only flag literals. - Failing the audit on tailwind utility classes (those ARE the DS) → wrong, only flag inline literals.
- Carrying the maturity rubric inline in this role file → wrong. Read the skill.
- Scoring maturity without evidence → wrong. Every score cites file paths or counts.

View file

@ -7,6 +7,7 @@ description: >-
before prod promote (gate 3). Skip when convoy frontmatter has skip: docs. before prod promote (gate 3). Skip when convoy frontmatter has skip: docs.
Must run sequentially — writes a single docs PR. Must run sequentially — writes a single docs PR.
multitask: single multitask: single
model: auto
tools: [Read, Grep, Glob, Edit, Write, Shell] tools: [Read, Grep, Glob, Edit, Write, Shell]
--- ---
@ -70,7 +71,7 @@ Docs PR opened. User reviews and merges as the final step before the release PR
After producing the docs PR draft, emit one event with the convoy outcome: After producing the docs PR draft, emit one event with the convoy outcome:
```bash ```bash
bash scripts/log-convoy-event.sh role=role-doc-writer convoy=<slug> duration_s=<seconds> outcome=complete bash scripts/log-convoy-event.sh role=role-doc-writer convoy=<slug> duration_s=<seconds> outcome=complete model=auto model_tier=auto
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).

View file

@ -7,6 +7,7 @@ description: >-
classified the work as feature, hotfix (rare), or server-only with UI side classified the work as feature, hotfix (rare), or server-only with UI side
effects. Must run sequentially — output feeds role-ux-reviewer. effects. Must run sequentially — output feeds role-ux-reviewer.
multitask: single multitask: single
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell] tools: [Read, Grep, Glob, Shell]
--- ---
@ -55,7 +56,7 @@ Message the user. They run the next role.
After appending your IA section, emit one event. Shell access is restricted to this single command. After appending your IA section, emit one event. Shell access is restricted to this single command.
```bash ```bash
bash scripts/log-convoy-event.sh role=role-ia-architect convoy=<slug> duration_s=<seconds> bash scripts/log-convoy-event.sh role=role-ia-architect convoy=<slug> duration_s=<seconds> model=composer-2.5-fast model_tier=fast
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).

View file

@ -8,6 +8,7 @@ description: >-
run as a Cursor 3.2 /multitask fleet IFF their briefs declare empty run as a Cursor 3.2 /multitask fleet IFF their briefs declare empty
depends_on AND disjoint files: lists; each implementer gets its own worktree. depends_on AND disjoint files: lists; each implementer gets its own worktree.
multitask: per-brief multitask: per-brief
model: composer-2.5-fast
tools: [Read, Grep, Glob, Edit, Write, Shell] tools: [Read, Grep, Glob, Edit, Write, Shell]
--- ---
@ -86,7 +87,7 @@ The user reviews the PR draft, opens the PR via `gh` or Cursor's UI. Reviewer +
After producing the PR draft, emit one event: After producing the PR draft, emit one event:
```bash ```bash
bash scripts/log-convoy-event.sh role=role-implementer convoy=<slug> brief=<N> duration_s=<seconds> bash scripts/log-convoy-event.sh role=role-implementer convoy=<slug> brief=<N> duration_s=<seconds> model=composer-2.5-fast model_tier=fast
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).

View file

@ -8,6 +8,7 @@ description: >-
PR draft and before the human merges. Safe to run in parallel with PR draft and before the human merges. Safe to run in parallel with
role-design-system-auditor + role-a11y-auditor via Cursor 3.2 /multitask. role-design-system-auditor + role-a11y-auditor via Cursor 3.2 /multitask.
multitask: audit-fanout multitask: audit-fanout
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell] tools: [Read, Grep, Glob, Shell]
--- ---
@ -88,7 +89,7 @@ When invoked as part of a cohort, include the shared `multitask_group` id in the
After publishing the review comment, emit one event: After publishing the review comment, emit one event:
```bash ```bash
bash scripts/log-convoy-event.sh role=role-reviewer convoy=<slug> brief=<N> duration_s=<seconds> [multitask_group=audit-<convoy>-<pr>] bash scripts/log-convoy-event.sh role=role-reviewer convoy=<slug> brief=<N> duration_s=<seconds> model=composer-2.5-fast model_tier=fast [multitask_group=audit-<convoy>-<pr>]
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).

View file

@ -1,12 +1,16 @@
--- ---
name: role-ux-reviewer name: role-ux-reviewer
description: >- description: >-
UX / IX review pass against the existing design system. Identifies which UX / IX review pass against the existing design system + heuristic critique.
existing components and patterns to reuse, calls out anti-patterns to avoid, Identifies which existing components to reuse, calls out anti-patterns,
and lists a11y constraints that must be satisfied. Read-only. Use after lists a11y constraints, and (when invoked as a critique pass) runs the
IA Architect on any feature with UI changes. Must run sequentially — refines full 9-step design critique. Read-only. Uses
the IA section, feeds role-architect. `[skills/design-critique](../../../design-critique/SKILL.md)`
(and `[skills/ux-writing](../../../ux-writing/SKILL.md)` when wave 1c lands).
Use after IA Architect on any feature with UI changes. Sequential —
refines the IA section, feeds role-architect.
multitask: single multitask: single
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell] tools: [Read, Grep, Glob, Shell]
--- ---
@ -16,46 +20,57 @@ tools: [Read, Grep, Glob, Shell]
After `role-ia-architect` for any classification that includes UI work. Skip when convoy frontmatter has `skip: ux`. After `role-ia-architect` for any classification that includes UI work. Skip when convoy frontmatter has `skip: ux`.
Two invocation modes:
1. **Sequential UX-pass** (default) — appends a `## UX` section to the convoy file. Feeds the Architect. Lightweight.
2. **Critique pass** (on-request, or when the convoy's success metric is below target) — runs the full 9-step critique per `[skills/design-critique/SKILL.md](../../../design-critique/SKILL.md)` and posts a `design-critique` report.
## Inputs ## Inputs
- The convoy file (with the IA section appended by the previous role). - The convoy file (with the IA section appended).
- Existing UI primitives directory (typically `components/ui/` or `src/components/ui/`). - Existing UI primitives directory (`components/ui/` or equivalent).
- Design tokens (typically `tailwind.config.ts`, `app/globals.css` CSS variables). - Design tokens (`tailwind.config.ts`, `app/globals.css` CSS variables, or `tokens/**`).
- Any rule scoped to `components.mdc`, `styling.mdc`, or `design-system.mdc`. - Any rule scoped to `components.mdc`, `styling.mdc`, `design-system.mdc`.
- `[skills/design-critique/SKILL.md](../../../design-critique/SKILL.md)` — Nielsen 10 + UX laws + 9-step framework.
## Outputs ## Outputs
### Mode 1: Sequential UX-pass
Append a `## UX` section to the convoy file with: Append a `## UX` section to the convoy file with:
1. **Existing components to reuse** — bullet list of `<ComponentName>` (`path/to/file.tsx`) for each reusable primitive the screens need. Be specific — name the file. 1. **Existing components to reuse** — bullet list of `<ComponentName>` (`path/to/file.tsx`) for each reusable primitive the screens need. Name the file.
2. **Existing patterns to follow** — referenced rules and example screens that solve a similar problem (e.g. *"PostCard.tsx is the canonical card pattern; use the same Badge primitive there"*). 2. **Existing patterns to follow** — referenced rules and example screens that solve a similar problem.
3. **A11y constraints** — bullets enumerating: required ARIA labels, keyboard navigation paths, focus management, color-contrast requirements specific to this change. 3. **A11y constraints** — bullets enumerating required ARIA labels, keyboard navigation paths, focus management, color-contrast requirements specific to this change. Hand to `role-a11y-auditor`.
4. **Interaction patterns** — short list: hover/focus/active states, optimistic UI, error states, empty states, loading states. Mark each as `required` or `nice-to-have`. 4. **Interaction patterns** — short list with `required` / `nice-to-have` annotations: hover/focus/active states, optimistic UI, error states, empty states, loading states. Cite Nielsen heuristic # per pattern (`H1` for loading, `H9` for errors, etc.).
5. **Anti-patterns to avoid** — explicit list of what NOT to do (e.g. *"Don't add a new color outside the design tokens for the badge background"*). 5. **Anti-patterns to avoid** — explicit list of what NOT to do, with the violated heuristic in parens.
6. **Mobile / responsive notes** — if the change has UI, this section is mandatory. If headless/server-only, note that. 6. **Mobile / responsive notes** — mandatory if UI is touched.
### Mode 2: Critique pass
Full report following `skills/design-critique/templates/critique-report.md`. Posted as a PR comment OR Echodo `document` (Phase 2b: `create_task_from_template({template: "design-critique", ...})`). Severity ≥ 3 findings spawn child tasks.
## Steps ## Steps
1. Read the convoy file. Find the IA section. 1. Read the convoy file. Find the IA section.
2. For each screen in the IA inventory: 2. For each screen in the IA inventory:
- `Glob` for relevant existing components in `components/ui/` (or equivalent). - `Glob` for relevant existing components in `components/ui/`.
- Identify the closest existing pattern by reading 1-3 example files. - Identify the closest existing pattern by reading 1-3 example files.
3. Read the design tokens once (one Read of `tailwind.config.ts` or `app/globals.css`). 3. Read the design tokens once (single Read of `tailwind.config.ts` or `tokens/**`).
4. Author the UX section. Be opinionated. Pick one pattern, not three options. 4. **Mode 1 (default):** Author the UX section. Be opinionated. Pick one pattern, not three options. Cite specific Nielsen heuristics per pattern. Append section to convoy file. Print: *"UX pass complete. Reuse: <N> primitives. A11y constraints: <M>. Next role: role-architect."*
5. Call out a11y requirements explicitly — don't say *"follow a11y best practices"*; say *"requires aria-label on the toggle button when collapsed"*. 5. **Mode 2 (critique):** Read `[skills/design-critique/SKILL.md](../../../design-critique/SKILL.md)`. Walk the 9 steps in order. Fill the critique-report template. Post the report. If MCP is reachable, call `create_task_from_template` + `link_audit_finding` per skill step 7. Hand off with score + top-3 fixes.
6. Append section to convoy file.
7. Print: *"UX pass complete. Reuse: <N> primitives. A11y constraints: <M>. Next role: role-architect."*
## Hand-off ## Hand-off
Message the user. Mode 1: message the user.
Mode 2: message: *"UX critique complete. Score X/50. N sev-≥-3 findings. Top 3 fixes: ..."*
## Metrics ## Metrics
After appending your UX section, emit one event. Shell access is restricted to this single command. After completing:
```bash ```bash
bash scripts/log-convoy-event.sh role=role-ux-reviewer convoy=<slug> duration_s=<seconds> bash scripts/log-convoy-event.sh role=role-ux-reviewer convoy=<slug> duration_s=<seconds> model=composer-2.5-fast model_tier=fast
``` ```
Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed). Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed).
@ -63,6 +78,8 @@ Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed)
## Anti-patterns ## Anti-patterns
- Suggesting new components when an existing one fits → wrong, this role's job is reuse. - Suggesting new components when an existing one fits → wrong, this role's job is reuse.
- Vague a11y guidance ("follow WCAG") → wrong, list specific requirements. - Vague a11y guidance ("follow WCAG") → wrong, list specific requirements with WCAG numbers.
- Three alternatives — pick one → wrong, pick one with reasoning. - Three alternatives — pick one with reasoning.
- Designing the schema or API → wrong, that's Architect. - Designing the schema or API → wrong, that's Architect.
- Critiquing without citing a Nielsen heuristic or UX law → wrong (see `design-critique` anti-patterns). Every finding cites evidence.
- Carrying the 9-step critique framework inline in this role file → wrong. Read the skill.

View file

@ -0,0 +1,34 @@
---
description: Model tier defaults for the agent pipeline — Opus for planning only; fast models for build and audit
alwaysApply: true
---
# Model routing (cost-aware pipeline)
Cursor subagent roles in `.cursor/agents/role-*.md` declare a `model:` in frontmatter. **Invoke roles from the Agents dropdown** (or a fresh chat pinned to that role) so the configured model applies. Parent chats on Opus that spawn Task subagents may override role models — see `docs/model-routing-policy.md`.
## Default session model
- **Parent chat (ad hoc work):** `auto` or `composer-2.5-fast`.
- **Escalate to Opus** (`claude-4.6-opus-high-thinking`) only for conductor, architect, or after two failed implementer attempts on the same brief.
- **Never use Opus 4.7 / xhigh** for routine pipeline work unless leadership explicitly approves a spike.
## Per-role tiers (canonical)
| Tier | Roles | Model |
| --- | --- | --- |
| Premium | conductor, architect | `claude-4.6-opus-high-thinking` |
| Fast | ia-architect, ux-reviewer, implementer, reviewer, design-system-auditor, a11y-auditor | `composer-2.5-fast` |
| Auto | doc-writer | `auto` |
Read `model_policy:` from the convoy frontmatter when present; it overrides these defaults for that convoy.
## Context discipline (biggest cost lever)
- Implementers and auditors: read **only** the brief + files in `files:` — not the whole convoy, not `prisma/schema.prisma` unless listed.
- Audits: diff + brief only; no repo-wide grep sweeps.
- Stop and ask before any single chat exceeds ~5M tokens; start a fresh scoped chat instead.
## Metrics
After each role, log `model=` and `model_tier=` via `scripts/log-convoy-event.sh` (see each role's Metrics section).

View file

@ -0,0 +1,112 @@
# Model routing policy
Cost-aware defaults for the agent pipeline. Complements per-role `model:` frontmatter in `.cursor/agents/role-*.md` and the always-on `.cursor/rules/model-routing.mdc`.
## Goals
1. **Preserve quality** on planning and decomposition (conductor, architect).
2. **Cut token spend** on build, audit, and docs (fast/auto tiers).
3. **Make spend measurable** via convoy metrics (`model`, `model_tier`).
Validated on Trimble usage (JanJun 2026): ~72% of spend was Opus-tier; ~37% came from 346 sessions at 10M+ tokens. This policy targets both levers.
## What Cursor enforces vs recommends
| Mechanism | Enforced? | Notes |
| --- | --- | --- |
| `model:` in `.cursor/agents/role-*.md` | **Partial** | Applies when the role is invoked from the Agents UI |
| `model_policy:` in convoy frontmatter | Recommend | Conductor writes it; humans and roles should follow |
| `model-routing.mdc` | Recommend | Always-on nudge; ~45 lines |
| Parent chat model picker | User | Set `auto` or `composer-2.5-fast` for routine work |
| Settings → Agents → Subagents | Partial | Sets default for built-in explore-style subagents |
**Known limitation (Jun 2026):** parent agents spawning Task subagents can pass an explicit `model` that overrides role frontmatter. Mitigation: invoke audit/implementer roles directly; avoid "do everything in one Opus chat."
## Tier table
| Tier | `model_tier` value | Default model ID | Roles |
| --- | --- | --- | --- |
| Premium | `premium` | `claude-4.6-opus-high-thinking` | conductor, architect |
| Fast | `fast` | `composer-2.5-fast` | ia-architect, ux-reviewer, implementer, reviewer, design-system-auditor, a11y-auditor |
| Auto | `auto` | `auto` | doc-writer |
### Escalation (premium)
Escalate from fast → premium when:
- Running conductor or architect (always).
- Implementer failed lint/tests twice on the same brief.
- Security-sensitive change (auth, RLS, admin routes) and architect explicitly flags `recommended_model: claude-4.6-opus-high-thinking` on the brief.
Do **not** escalate for: docs-only, audit fan-out, changelog, or single-file hotfixes.
## Convoy `model_policy` block
The conductor writes this into `.convoys/<slug>.md` frontmatter:
```yaml
model_policy:
default_session: auto
roles:
role-conductor: claude-4.6-opus-high-thinking
role-architect: claude-4.6-opus-high-thinking
role-ia-architect: composer-2.5-fast
role-ux-reviewer: composer-2.5-fast
role-implementer: composer-2.5-fast
role-reviewer: composer-2.5-fast
role-design-system-auditor: composer-2.5-fast
role-a11y-auditor: composer-2.5-fast
role-doc-writer: auto
escalate_to: claude-4.6-opus-high-thinking
never_premium:
- role-reviewer
- role-design-system-auditor
- role-a11y-auditor
- role-doc-writer
```
Briefs may override with `recommended_model:` and `model_tier:` in frontmatter (set by architect).
## Multitask + cost
Audit fan-out saves **wall-clock**, not tokens, when all three auditors run on Opus. Run the cohort on **fast** models:
```
/multitask role-reviewer + role-design-system-auditor + role-a11y-auditor
```
Invoke each role from the Agents dropdown (or ensure subagent model is `composer-2.5-fast`). See [`multitask-playbook.md`](multitask-playbook.md).
## Metrics contract
Each role appends to `.convoys/.metrics.jsonl`:
```bash
bash scripts/log-convoy-event.sh \
role=role-implementer \
convoy=<slug> \
brief=<N> \
model=composer-2.5-fast \
model_tier=fast \
duration_s=<seconds>
```
Optional: `estimated_cost_usd=<from Cursor usage export>` for monthly rollups.
Aggregate:
```bash
cd ~/code/agent-pipeline/analytics
npx tsx analyze-convoys.ts <repo-paths...>
npx tsx render-dashboard.ts
```
Dashboard surfaces `events_by_model`, `events_by_model_tier`, and a warning when premium-tier events dominate fast-tier roles.
## Team checklist
- [ ] Parent chat default: `auto` or `composer-2.5-fast`
- [ ] L2 roles installed with `model:` frontmatter (re-bootstrap or sync)
- [ ] `model-routing.mdc` present (always-apply)
- [ ] Settings → Agents → Subagents → fast model for explore
- [ ] Monthly: export team usage CSV + run analytics dashboard

View file

@ -6,17 +6,21 @@
# #
# Usage: # Usage:
# bash scripts/log-convoy-event.sh role=role-conductor convoy=bookmark-badge \ # bash scripts/log-convoy-event.sh role=role-conductor convoy=bookmark-badge \
# classification=feature 'skip_flags=visual,smoke' duration_s=42 # classification=feature 'skip_flags=visual,smoke' duration_s=42 \
# model=claude-4.6-opus-high-thinking model_tier=premium
# #
# All args are key=value. Required: role, convoy. # All args are key=value. Required: role, convoy.
# Optional: brief, classification, skip_flags (comma-separated), duration_s, # Optional: brief, classification, skip_flags (comma-separated), duration_s,
# stack_class, outcome, multitask_group. # stack_class, outcome, multitask_group, model, model_tier,
# estimated_cost_usd.
# #
# multitask_group: cohort id when this role ran as part of a Cursor 3.2 # multitask_group: cohort id when this role ran as part of a Cursor 3.2
# /multitask fan-out (e.g. 'audit-bookmark-badge-PR123'). Events sharing # /multitask fan-out (e.g. 'audit-bookmark-badge-PR123'). Events sharing
# this id should be aggregated with max(duration_s), not sum, for wall-clock. # this id should be aggregated with max(duration_s), not sum, for wall-clock.
# See docs/multitask-playbook.md. # See docs/multitask-playbook.md.
# #
# model / model_tier: cost telemetry per docs/model-routing-policy.md.
#
# Privacy: this file is gitignored by default; events contain only metadata, # Privacy: this file is gitignored by default; events contain only metadata,
# no code or prompts. To opt-in to commit, remove `.convoys/.metrics.jsonl` # no code or prompts. To opt-in to commit, remove `.convoys/.metrics.jsonl`
# from your `.gitignore`. # from your `.gitignore`.
@ -41,27 +45,31 @@ mkdir -p "$REPO_ROOT/.convoys"
# Pull values out of args without using associative arrays (bash 3.2 compat) # Pull values out of args without using associative arrays (bash 3.2 compat)
ROLE=""; CONVOY=""; BRIEF=""; CLASSIFICATION="" ROLE=""; CONVOY=""; BRIEF=""; CLASSIFICATION=""
SKIP_FLAGS=""; DURATION_S=""; STACK_CLASS=""; OUTCOME=""; MULTITASK_GROUP="" SKIP_FLAGS=""; DURATION_S=""; STACK_CLASS=""; OUTCOME=""; MULTITASK_GROUP=""
MODEL=""; MODEL_TIER=""; ESTIMATED_COST_USD=""
for arg in "$@"; do for arg in "$@"; do
k="${arg%%=*}" k="${arg%%=*}"
v="${arg#*=}" v="${arg#*=}"
case "$k" in case "$k" in
role) ROLE="$v" ;; role) ROLE="$v" ;;
convoy) CONVOY="$v" ;; convoy) CONVOY="$v" ;;
brief) BRIEF="$v" ;; brief) BRIEF="$v" ;;
classification) CLASSIFICATION="$v" ;; classification) CLASSIFICATION="$v" ;;
skip_flags) SKIP_FLAGS="$v" ;; skip_flags) SKIP_FLAGS="$v" ;;
duration_s) DURATION_S="$v" ;; duration_s) DURATION_S="$v" ;;
stack_class) STACK_CLASS="$v" ;; stack_class) STACK_CLASS="$v" ;;
outcome) OUTCOME="$v" ;; outcome) OUTCOME="$v" ;;
multitask_group) MULTITASK_GROUP="$v" ;; multitask_group) MULTITASK_GROUP="$v" ;;
model) MODEL="$v" ;;
model_tier) MODEL_TIER="$v" ;;
estimated_cost_usd) ESTIMATED_COST_USD="$v" ;;
*) echo "log-convoy-event: ignoring unknown arg '$k'" >&2 ;; *) echo "log-convoy-event: ignoring unknown arg '$k'" >&2 ;;
esac esac
done done
if [ -z "$ROLE" ] || [ -z "$CONVOY" ]; then if [ -z "$ROLE" ] || [ -z "$CONVOY" ]; then
echo "log-convoy-event: role and convoy are required" >&2 echo "log-convoy-event: role and convoy are required" >&2
echo "Usage: $0 role=<role> convoy=<slug> [classification=...] [skip_flags=a,b] [duration_s=N] [brief=N] [stack_class=...] [outcome=...]" >&2 echo "Usage: $0 role=<role> convoy=<slug> [classification=...] [skip_flags=a,b] [duration_s=N] [brief=N] [model=...] [model_tier=fast|premium|auto] [estimated_cost_usd=N]" >&2
exit 1 exit 1
fi fi
@ -83,6 +91,10 @@ if "$DURATION_S": ev["duration_s"] = int("$DURATION_S")
if "$STACK_CLASS": ev["stack_class"] = "$STACK_CLASS" if "$STACK_CLASS": ev["stack_class"] = "$STACK_CLASS"
if "$OUTCOME": ev["outcome"] = "$OUTCOME" if "$OUTCOME": ev["outcome"] = "$OUTCOME"
if "$MULTITASK_GROUP": ev["multitask_group"] = "$MULTITASK_GROUP" if "$MULTITASK_GROUP": ev["multitask_group"] = "$MULTITASK_GROUP"
if "$MODEL": ev["model"] = "$MODEL"
if "$MODEL_TIER": ev["model_tier"] = "$MODEL_TIER"
if "$ESTIMATED_COST_USD":
ev["estimated_cost_usd"] = float("$ESTIMATED_COST_USD")
print(json.dumps(ev)) print(json.dumps(ev))
PY PY