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
#
# Generated by agent-pipeline bootstrap-agent-context skill.
# Tracks which artifacts the bootstrap installed in this repo, where they
# came from, and what pipeline version they correspond to.
# Generated/updated by bulk pipeline sync.
#
# 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
pipeline_version: "0.5.0"
pipeline_version: "0.6.0"
pipeline_source: "https://github.com/varutasu/agent-pipeline"
installed_at: "2026-05-22T22:25:00Z"
last_synced_at: "2026-05-22T22:25:00Z"
last_synced_at: "2026-06-22T19:21:05Z"
layers:
- L1
- L2
- 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:
- path: ".convoys/README.md"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/convoys-readme.md.template"
version: "0.5.0"
installed_hash: "sha256:a48548cd3f5d0c40fc179106890661c3be5fcdc13eb705af7cfe9233e0b8b209"
version: "0.6.0"
installed_hash: "sha256:12bedb29aeecfd6fddd04a96b60ac9cd65a453c4ef18d0086274a36520ebc68f"
- path: ".cursor/agents/role-a11y-auditor.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-a11y-auditor.md"
version: "0.5.0"
installed_hash: "sha256:a59938deceb0246ebd7e477f1f9a442102f9fcbb81b0364f0ddc5f86e95a7930"
version: "0.6.0"
installed_hash: "sha256:119bca847d885ae092e2da878662f223ba57e0ddc459f49458f2f3fbefb668df"
- path: ".cursor/agents/role-architect.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-architect.md"
version: "0.5.0"
installed_hash: "sha256:269bd62af1557c5d353a9f95a613960e3434be4ec6e0c0b5f6b099adf6872044"
version: "0.6.0"
installed_hash: "sha256:32fdc10ffa2795144bb6e69eab11a31841c46ada77eebbc6d38b2047e5b565a0"
- path: ".cursor/agents/role-conductor.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-conductor.md"
version: "0.5.0"
installed_hash: "sha256:bc75a3e6646217a015f7bb60c3610afd9b57ae91c7d2fc7a7971f4709b19368a"
version: "0.6.0"
installed_hash: "sha256:649d5c9974ea58fa3ced254a12ed33c0b39df8799b2e6981b05d35313f9c1d07"
- path: ".cursor/agents/role-design-system-auditor.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-design-system-auditor.md"
version: "0.5.0"
installed_hash: "sha256:d214cecb1e8482fc24f2815c8220c860191f08526614f89cf9a5797e4ee9110a"
version: "0.6.0"
installed_hash: "sha256:8731e837662e2188fcbdb7f8730ffc2138236dce91785f7671cdbdc1d849fefd"
- path: ".cursor/agents/role-doc-writer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-doc-writer.md"
version: "0.5.0"
installed_hash: "sha256:d4e8bf8cee93153506b7b742848462422dbe5cc7fd012c62f6ffd50460e344d4"
version: "0.6.0"
installed_hash: "sha256:7e626346705083cd57fa8a401b18f7f44da330a9f2a60f461dc362fbb2c7159b"
- path: ".cursor/agents/role-ia-architect.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-ia-architect.md"
version: "0.5.0"
installed_hash: "sha256:69685a3a407c4ee25e2606d426c3107d6b917abee80f907e16ade4a16b439839"
version: "0.6.0"
installed_hash: "sha256:40d669a8a7ebf1e6165ab1054b189f728ceefaadcfb124d47b55bceaf7c8fac4"
- path: ".cursor/agents/role-implementer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-implementer.md"
version: "0.5.0"
installed_hash: "sha256:b4f4d8596068679b90ffc3a2b6d2e1b6548caf8c68a50f7ed640ba8f638c1c4c"
version: "0.6.0"
installed_hash: "sha256:978e972384f0277bac0d6e5f1226ff8e833d4d9c091ea207289555c1d74471a9"
- path: ".cursor/agents/role-reviewer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-reviewer.md"
version: "0.5.0"
installed_hash: "sha256:1ff38349321402a0ac2be37878dc2c0bcab62e54caf74c422b919aa6d75f9b67"
version: "0.6.0"
installed_hash: "sha256:58863d74cf8cb4990538862ed92e39bfcd51388961a9e0f64141924efb9c9dcc"
- path: ".cursor/agents/role-ux-reviewer.md"
source: "skills/bootstrap-agent-context/templates/L2-roles/role-ux-reviewer.md"
version: "0.5.0"
installed_hash: "sha256:3a1d4b66981f469b15e23a1cd34ab41352759966179e126b3d56ddc1eca4a03e"
version: "0.6.0"
installed_hash: "sha256:40db450d9b8483ea527636a1ee2d15521edae0a4c7cd8d011880103fe10fa103"
- path: ".cursor/rules/api-routes.mdc"
source: "skills/bootstrap-agent-context/templates/L1-context/api-routes.mdc.template"
version: "0.5.0-local"
installed_hash: "sha256:54cd66d71f5a129a67d0f4b1797f5f63b7f9aae3eeabe67217861456ff4db59b"
- path: ".cursor/rules/auth-and-permissions.mdc"
source: "tcg-vault-local"
version: "0.5.0-local"
installed_hash: "sha256:9b7eb7bea0cad0e43d0e9442eb8b660945cb6935f9f7c82fd7d7d71d66b39a2d"
- path: ".cursor/rules/db-and-schema.mdc"
source: "tcg-vault-local"
version: "0.5.0-local"
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"
source: "skills/bootstrap-agent-context/templates/L1-context/no-go-zones.mdc"
version: "0.5.0-local"
installed_hash: "sha256:aa7046bc3e0266cb3c9b0eb0ef8f68cc50d6837f65c96861804ff81b9c4afa64"
- path: ".cursor/rules/schema-map.mdc"
source: "tcg-vault-local"
version: "0.5.0-local"
installed_hash: "sha256:3429bad56384117dc81873b337a6d815bd53799389f7908dedb53dbb7642bced"
- path: ".cursor/rules/ui-and-theming.mdc"
source: "tcg-vault-local"
version: "0.5.0-local"
installed_hash: "sha256:b841ddda5baa47a76c3726a3c92b2c82a45120fdd461b3243bf970479d1cf1df"
- path: ".cursor/skills/add-api-route/SKILL.md"
source: "tcg-vault-local"
version: "0.5.0-local"
installed_hash: "sha256:0e29f7e994a51e5a40b8308edab08ee9c1f713e297d68e98029294d8ca568cc7"
- path: ".cursor/skills/add-page/SKILL.md"
source: "tcg-vault-local"
version: "0.5.0-local"
installed_hash: "sha256:318912077a6ced6a3a31f85dc15d069bf7627c161b6735e3fa259ca10766daa9"
- path: ".github/CODEOWNERS"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs/CODEOWNERS.template"
version: "0.5.0-local"
installed_hash: "sha256:b714a0a011776300abeab92fe8969f150c273c37d0d6b37c1ad2eb67d47decda"
- path: ".github/PULL_REQUEST_TEMPLATE.md"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/PULL_REQUEST_TEMPLATE.md.template"
version: "0.5.0"
installed_hash: "sha256:89863e58b9ec194aef1c94d3596e892467833e8bc880a28994acca401b6d9635"
- path: ".github/workflows/agent-context-drift.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/agent-context-drift.yml.template"
version: "0.5.0"
installed_hash: "sha256:5505c296c1b61d023ee2aca222103097e2b5ed2e0e38da3679cc4f9754457785"
- path: ".github/workflows/ci.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs/ci.yml.template"
version: "0.5.0-local"
installed_hash: "sha256:6aff7a1c9f2e42606580c241b6dadca7c2d8550aeb959bd69fdd843eb9097cac"
- path: ".github/workflows/pr-health-rollup.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/pr-health-rollup.yml.template"
version: "0.5.0-local"
installed_hash: "sha256:8747674323807d84395fa027b25e7e27881c5e6b0cc87a138d9cb3f78fd88956"
- path: ".github/workflows/preview-smoke.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/preview-smoke.yml.template"
version: "0.5.0-local"
installed_hash: "sha256:2e71026b09db8b2f32b6a868d705489600c875082d6320c2369bf2f5ebc315b8"
- path: ".github/workflows/visual-diff.yml"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/visual-diff.yml.template"
version: "0.5.0-local"
installed_hash: "sha256:88270b1fa59aba99591ec094764dd367deed956bcb746ac6bb195241b3a7dae1"
- path: "docs/agent-context/README.md"
source: "skills/bootstrap-agent-context/templates/L1-context/agent-context-readme.md.template"
version: "0.5.0-local"
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"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/flags-index.ts.template"
version: "0.5.0-local"
installed_hash: "sha256:1a3cd1f900194eaf4ec86588dd1c3c2bff6a565e742061fc911abdd47bd5f3a5"
- path: "scripts/log-convoy-event.sh"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/log-convoy-event.sh"
version: "0.5.0"
installed_hash: "sha256:cd0413691066a177b6b4e6164a9a0978c20a853ad60222ae833b5d53b255818d"
version: "0.6.0"
installed_hash: "sha256:52bdc8f60b18315dd8ad0f1dd6b727106dfa134b8769b0cd63d8698d5865cf21"
- path: "scripts/wt.sh"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/_common/wt.sh"
version: "0.5.0"
installed_hash: "sha256:2a4f44a159f80a8ea6fe53ac507c01a2f91a4e2118d997a98b051808ac35e9a5"
- path: "tests/smoke/app.smoke.spec.ts"
source: "skills/bootstrap-agent-context/templates/L3-pipeline/nextjs-prisma-vercel/playwright-smoke.spec.ts.template"
version: "0.5.0"

View file

@ -27,6 +27,9 @@ skip:
- <flag1>
status: open | in-progress | merged | shipped | abandoned
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
```
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
description: >-
Accessibility audit on a UI diff. Checks for missing labels, keyboard
navigation, focus management, color contrast, semantic HTML, and ARIA
correctness. Read-only. Use after the implementer's PR draft on PRs that
touch UI files. Does not require a browser MCP — works from the diff +
static analysis. Safe to run in parallel with role-reviewer +
Accessibility audit on a UI diff against WCAG 2.2 (Level AA). Read-only.
Runs `[skills/accessibility-audit](../../../accessibility-audit/SKILL.md)`
for the rubric + report template. Use after the implementer's PR draft on
PRs that touch UI files. Safe to run in parallel with role-reviewer +
role-design-system-auditor via Cursor 3.2 /multitask.
multitask: audit-fanout
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell]
---
@ -20,86 +20,59 @@ After `role-design-system-auditor` on UI-touching PRs. Skip when convoy frontmat
## Inputs
- The PR diff (UI files only).
- The convoy's UX section (which already lists a11y constraints — verify the implementer satisfied them).
- Existing accessible patterns in the repo (look at existing `Dialog`, `Form`, `Button` primitives).
- The convoy's UX section (a11y constraints listed there — verify each one).
- 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
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
## A11y Audit
- A PR comment when GitHub is the surface, OR
- An Echodo `document` (Phase 2b: `create_task_from_template({template: "a11y-audit", ...})`) when MCP is reachable.
| Check | Status | Count |
| --- | --- | --- |
| 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.
Per `[skills/accessibility-audit/SKILL.md](../../../accessibility-audit/SKILL.md)` step 7 — both paths produce the same shape.
## 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.
3. For each changed UI file: read the current state of the file (post-diff), then walk the checklist.
4. Build the comment. Cap at 8 critical + 8 warnings.
5. If clean: ✅ across the board with a one-line note.
## What this role does NOT do
- 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.
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. Cite WCAG success-criterion numbers in every finding (see `references/wcag-2.2-checklist.md`).
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).
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`.
## 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
After publishing the audit comment, emit one event:
After publishing:
```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).
## 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.
- 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
implementer fan-out via Cursor 3.2 /multitask.
multitask: single
model: claude-4.6-opus-high-thinking
tools: [Read, Grep, Glob, Shell]
---
@ -60,6 +61,8 @@ Then create one **implementer brief** per row of the decomposition, as a separat
convoy: <slug>
brief_number: <N>
depends_on: [<other brief numbers>]
recommended_model: composer-2.5-fast
model_tier: fast
files:
- <path/to/file1>
- <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.
```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).

View file

@ -7,6 +7,7 @@ description: >-
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.
multitask: single
model: claude-4.6-opus-high-thinking
tools: [Read, Grep, Glob, Write, Shell]
---
@ -40,9 +41,26 @@ classification: feature | hotfix | docs-only | infra-only | server-only | config
success_metric: <one sentence>
skip:
- <flag1>
- <flag2>
status: open
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.
## 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
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> \
classification=<feature|hotfix|docs-only|infra-only|server-only|config-only> \
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.

View file

@ -1,13 +1,16 @@
---
name: role-design-system-auditor
description: >-
Audits a UI diff against the repo's design system. Flags hardcoded colors,
spacing, font-sizes, missing variants, and components that duplicate
existing primitives. Read-only. Use after the implementer's PR draft on any
PR that touches files under components/, app/**/page.tsx, or
app/**/layout.tsx. Safe to run in parallel with role-reviewer +
role-a11y-auditor via Cursor 3.2 /multitask.
Audits a UI diff against the repo's design system + scores DS maturity
on the 5-axis rubric (tokens / components / patterns / governance /
adoption). Read-only. Runs
`[skills/design-systems](../../../design-systems/SKILL.md)` for the
audit framework + report template. Use after the implementer's PR draft on
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
model: composer-2.5-fast
tools: [Read, Grep, Glob, Shell]
---
@ -15,88 +18,67 @@ tools: [Read, Grep, Glob, Shell]
## 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
- 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/`).
- 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
A structured comment for the PR Health rollup:
A structured DS audit report following `skills/design-systems/templates/ds-audit-report.md`. Includes:
```markdown
## Design System Audit
- **Maturity scoring** across 5 axes (Tokens / Components / Patterns / Governance / Adoption) with evidence per score.
- **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 |
| --- | --- | --- |
| Token violations | ✅ / ❌ | <N> |
| Duplicate primitives | ✅ / ❌ | <N> |
| Missing variants | ✅ / ❌ | <N> |
| Inline styles | ✅ / ❌ | <N> |
Posted as:
### Token violations
<file:line> — used `<value>` (use token `<name>` instead)
...
### 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 |
- A PR comment when GitHub is the surface, OR
- An Echodo `document` (Phase 2b: `create_task_from_template({template: "design-system-audit", ...})`) when MCP is reachable.
## Steps
1. Get the PR diff. Filter to UI files (`*.tsx`, `*.css`, `*.scss`).
2. Read `tailwind.config.ts` and `app/globals.css` (or equivalents) once to load the token vocabulary.
3. `Glob` `components/ui/**/*.tsx` to enumerate existing primitives.
4. For each changed UI file:
- `Grep` for hex/rgb literals → token violations.
- `Grep` for `style={{` → inline styles.
- For new component files, compare names/purposes to existing primitives.
5. Build the structured comment. Cap at 10 most-impactful findings.
6. If no violations: report ✅ across the board with a one-line note.
## Hand-off
Comment posted. Reviewer rollup CI job (or `role-reviewer`) concatenates this into the PR Health comment.
1. Get the PR diff. Filter to UI files (`*.tsx`, `*.css`, `*.scss`) and DS files (`tokens/**`, `tailwind.config.*`).
2. **Read `[skills/design-systems/SKILL.md](../../../design-systems/SKILL.md)`** if not already in context.
3. Read tokens + component primitives directory once (load the vocabulary).
4. **Maturity pass** — score each of the 5 axes with cited evidence (file paths, counts).
5. **Token audit** — apply the 3-tier check (primitives / aliases / components). See `references/token-architecture.md` for the checklist.
6. **Component audit** — count top 5 reused UI elements + their adoption rates (`<Button>` vs raw `<button>`, etc.). Identify missing primitives that should exist.
7. **Governance audit** — is there a contribution doc? Who reviews? Last 3 primitives' provenance.
8. **Adoption audit** — pick one surface, count DS vs raw HTML.
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`.
## 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
After publishing the audit comment, emit one event:
After publishing:
```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).
## Anti-patterns
- Listing 50 inline-class violations → noise; cap at 10 and prioritize ones with token replacements.
- Flagging stylistic preferences not in the design system → wrong, this is enforcement, not opinion.
- Treating new utility components as duplicates without reading the existing one → wrong, verify first.
- Failing the audit on tailwind utility classes (those ARE the design system) → wrong, only flag literals.
- Listing 50 inline-class violations → noise. Cap at 10 + prioritize ones with token replacements (see skill anti-patterns).
- 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 → verify first.
- 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.
Must run sequentially — writes a single docs PR.
multitask: single
model: auto
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:
```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).

View file

@ -7,6 +7,7 @@ description: >-
classified the work as feature, hotfix (rare), or server-only with UI side
effects. Must run sequentially — output feeds role-ux-reviewer.
multitask: single
model: composer-2.5-fast
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.
```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).

View file

@ -8,6 +8,7 @@ description: >-
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.
multitask: per-brief
model: composer-2.5-fast
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:
```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).

View file

@ -8,6 +8,7 @@ description: >-
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.
multitask: audit-fanout
model: composer-2.5-fast
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:
```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).

View file

@ -1,12 +1,16 @@
---
name: role-ux-reviewer
description: >-
UX / IX review pass against the existing design system. Identifies which
existing components and patterns to reuse, calls out anti-patterns to avoid,
and lists a11y constraints that must be satisfied. Read-only. Use after
IA Architect on any feature with UI changes. Must run sequentially — refines
the IA section, feeds role-architect.
UX / IX review pass against the existing design system + heuristic critique.
Identifies which existing components to reuse, calls out anti-patterns,
lists a11y constraints, and (when invoked as a critique pass) runs the
full 9-step design critique. Read-only. Uses
`[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
model: composer-2.5-fast
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`.
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
- The convoy file (with the IA section appended by the previous role).
- Existing UI primitives directory (typically `components/ui/` or `src/components/ui/`).
- Design tokens (typically `tailwind.config.ts`, `app/globals.css` CSS variables).
- Any rule scoped to `components.mdc`, `styling.mdc`, or `design-system.mdc`.
- The convoy file (with the IA section appended).
- Existing UI primitives directory (`components/ui/` or equivalent).
- Design tokens (`tailwind.config.ts`, `app/globals.css` CSS variables, or `tokens/**`).
- 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
### Mode 1: Sequential UX-pass
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.
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"*).
3. **A11y constraints** — bullets enumerating: required ARIA labels, keyboard navigation paths, focus management, color-contrast requirements specific to this change.
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`.
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"*).
6. **Mobile / responsive notes** — if the change has UI, this section is mandatory. If headless/server-only, note that.
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.
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 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, with the violated heuristic in parens.
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
1. Read the convoy file. Find the IA section.
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.
3. Read the design tokens once (one Read of `tailwind.config.ts` or `app/globals.css`).
4. Author the UX section. Be opinionated. Pick one pattern, not three options.
5. Call out a11y requirements explicitly — don't say *"follow a11y best practices"*; say *"requires aria-label on the toggle button when collapsed"*.
6. Append section to convoy file.
7. Print: *"UX pass complete. Reuse: <N> primitives. A11y constraints: <M>. Next role: role-architect."*
3. Read the design tokens once (single Read of `tailwind.config.ts` or `tokens/**`).
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. **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.
## 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
After appending your UX section, emit one event. Shell access is restricted to this single command.
After completing:
```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).
@ -63,6 +78,8 @@ Skip silently if `scripts/log-convoy-event.sh` does not exist (L3 not installed)
## Anti-patterns
- Suggesting new components when an existing one fits → wrong, this role's job is reuse.
- Vague a11y guidance ("follow WCAG") → wrong, list specific requirements.
- Three alternatives — pick one → wrong, pick one with reasoning.
- Vague a11y guidance ("follow WCAG") → wrong, list specific requirements with WCAG numbers.
- Three alternatives — pick one with reasoning.
- 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:
# 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.
# 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 fan-out (e.g. 'audit-bookmark-badge-PR123'). Events sharing
# this id should be aggregated with max(duration_s), not sum, for wall-clock.
# 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,
# no code or prompts. To opt-in to commit, remove `.convoys/.metrics.jsonl`
# 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)
ROLE=""; CONVOY=""; BRIEF=""; CLASSIFICATION=""
SKIP_FLAGS=""; DURATION_S=""; STACK_CLASS=""; OUTCOME=""; MULTITASK_GROUP=""
MODEL=""; MODEL_TIER=""; ESTIMATED_COST_USD=""
for arg in "$@"; do
k="${arg%%=*}"
v="${arg#*=}"
case "$k" in
role) ROLE="$v" ;;
convoy) CONVOY="$v" ;;
brief) BRIEF="$v" ;;
classification) CLASSIFICATION="$v" ;;
skip_flags) SKIP_FLAGS="$v" ;;
duration_s) DURATION_S="$v" ;;
stack_class) STACK_CLASS="$v" ;;
outcome) OUTCOME="$v" ;;
multitask_group) MULTITASK_GROUP="$v" ;;
role) ROLE="$v" ;;
convoy) CONVOY="$v" ;;
brief) BRIEF="$v" ;;
classification) CLASSIFICATION="$v" ;;
skip_flags) SKIP_FLAGS="$v" ;;
duration_s) DURATION_S="$v" ;;
stack_class) STACK_CLASS="$v" ;;
outcome) OUTCOME="$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 ;;
esac
done
if [ -z "$ROLE" ] || [ -z "$CONVOY" ]; then
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
fi
@ -83,6 +91,10 @@ if "$DURATION_S": ev["duration_s"] = int("$DURATION_S")
if "$STACK_CLASS": ev["stack_class"] = "$STACK_CLASS"
if "$OUTCOME": ev["outcome"] = "$OUTCOME"
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))
PY