From fcf6282a29f1e2e340a0bd66a8d1101bdac6e646 Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Mon, 20 Jul 2026 09:49:44 -0700 Subject: [PATCH 1/9] Add preflight-learning-path skill for author pre-PR self-review. Mirrors the five-phase review coach so authors catch post-inline issues before opening a PR, with optional package fixes and a frontend data-testid walkthrough. --- .cursor/commands/preflight-learning-path.md | 35 ++ .cursor/learning-path-workflows/workflows.md | 1 + .../skills/preflight-learning-path/SKILL.md | 417 ++++++++++++++++++ .../preflight-learning-path/author-testing.md | 103 +++++ .../frontend-selector-pr.md | 90 ++++ .../reference-checks.md | 173 ++++++++ .cursor/skills/review-learning-path/SKILL.md | 2 +- .gitignore | 3 + AGENTS.md | 2 + CLAUDE.md | 3 + 10 files changed, 828 insertions(+), 1 deletion(-) create mode 100644 .cursor/commands/preflight-learning-path.md create mode 100644 .cursor/skills/preflight-learning-path/SKILL.md create mode 100644 .cursor/skills/preflight-learning-path/author-testing.md create mode 100644 .cursor/skills/preflight-learning-path/frontend-selector-pr.md create mode 100644 .cursor/skills/preflight-learning-path/reference-checks.md diff --git a/.cursor/commands/preflight-learning-path.md b/.cursor/commands/preflight-learning-path.md new file mode 100644 index 000000000..8f74d0251 --- /dev/null +++ b/.cursor/commands/preflight-learning-path.md @@ -0,0 +1,35 @@ +## Command: /preflight-learning-path + +Self-review a learning path package in `interactive-tutorials` **before** opening a PR. Walks you through **one phase at a time**. Same static and live checks as the five-phase [/review-learning-path-pr](review-learning-path-pr.md) coach, from the author side. + +When invoked, read and follow **[preflight-learning-path/SKILL.md](../skills/preflight-learning-path/SKILL.md)** in order. Never batch phases. + +LP packages are **single-repo** (`interactive-tutorials` only). Metadata lives in package `website.yaml`; the website repo is read-only for conversion ([PR #416](https://github.com/grafana/interactive-tutorials/pull/416)). Learning Hub criteria: [learning-hub-standards.md](../skills/review-learning-path/learning-hub-standards.md). + +### Setup you need + +- This repo checked out with your `{slug}-lj/` package +- **Playwright MCP** enabled in Cursor (for DOM checks) +- Access to `https://learn.grafana.net/` (Okta login in the Playwright browser when asked) +- Block Editor only if you choose a guided smoke walk later + +--- + +## First message to the author + +> I'll walk you through a preflight check on your learning path **one phase at a time**. I'll pause after each phase. Please don't skip ahead. +> +> | Phase | What happens | +> |---|---| +> | 0 | Identify your `{slug}-lj/` package + confirm Playwright MCP | +> | 1 | Static pass (audit + path / Learning Hub checks). Only real review-level issues | +> | 2 | Playwright DOM checks. Block Editor smoke is optional | +> | 3 | Readiness report + offer to fix | +> | 4 | Optional package fixes | +> | 5 | Optional frontend `data-testid` PR if a stable selector is missing | +> +> **Setup:** Playwright MCP should be on. You'll Okta-login in the Playwright browser for DOM checks. +> +> **Phase 0:** Share the path package (`{slug}-lj/` directory), or tell me to infer it from your current branch. + +Do not start Phase 1 until the author confirms the path directory. diff --git a/.cursor/learning-path-workflows/workflows.md b/.cursor/learning-path-workflows/workflows.md index 4b542aa25..12c4f4533 100644 --- a/.cursor/learning-path-workflows/workflows.md +++ b/.cursor/learning-path-workflows/workflows.md @@ -103,3 +103,4 @@ The learning path slug is mysql-data-source. | `/build-interactive-lj` | Existing milestone markdown in website repo (read-only source) | `content.json` + `manifest.json` + `website.yaml` files in interactive-tutorials | | `/create-learning-path` | Feature description (no existing markdown) | `content.json` + `manifest.json` + `website.yaml` files | | `/review-learning-path-pr` | Existing LP PR in `interactive-tutorials` (share PR URL/number) | Human-guided review: static workbook, Block Editor smoke test, chat-approved inline comments, submit | +| `/preflight-learning-path` | Local `{slug}-lj/` package before opening a PR | Author self-review: same static + Playwright checks as review, readiness report, optional fixes / frontend testid PR | diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md new file mode 100644 index 000000000..cb3becf1d --- /dev/null +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -0,0 +1,417 @@ +--- +name: preflight-learning-path +description: >- + Guide a learning path author through pre-PR self-review in interactive-tutorials. + Mirrors the five-phase /review-learning-path-pr coach from the author side: static + pass, Playwright DOM checks, readiness report, optional package fixes, and optional + frontend data-testid PR. Use when the user runs /preflight-learning-path. +--- + +# Preflight learning path (author self-review) + +Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the five-phase [review-learning-path](../review-learning-path/SKILL.md) coach, from your side: static pass, Playwright DOM, readiness, then optional fixes. + +**Terminology:** Say **learning path** or **path** in messages; use `{path_dir}` in agent notes. + +**Entry command:** [/preflight-learning-path](../../commands/preflight-learning-path.md) + +**Mirror skill:** [review-learning-path](../review-learning-path/SKILL.md) (five-phase coach on main only). Do **not** use any outdated review skill phases or Always-inline routing. + +**Do NOT read external reference files upfront.** Each phase loads its own references on demand. + +**Skill memory:** State lives in `.cursor/lp-preflight-state/` (gitignored). Phase 1 dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/`. See [Commit safety](#commit-safety). + +**Routing:** [reference-checks.md](reference-checks.md) · [author-testing.md](author-testing.md) · [frontend-selector-pr.md](frontend-selector-pr.md) · shared [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) · shared [review reference-checks](../review-learning-path/reference-checks.md) + +**Related:** [audit-guide](../audit-guide/SKILL.md) · [update-guide](../update-guide/SKILL.md) · [review-learning-path](../review-learning-path/SKILL.md) + +--- + +## Human-in-the-loop contract + +| You (agent) | Author (human) | +|---|---| +| Confirm path, run audit + path/LH checks | Confirm `{path_dir}`, reply at checkpoints | +| Surface **post-inline-only** findings in chat | Decide whether to fix now or open PR with notes | +| Required Playwright DOM check (live path) | Okta login in Playwright browser; reply `ready` | +| Optional Block Editor coaching | `already-tested` / `walk-me` / `skip-smoke` | +| Apply package fixes only when asked | Reply `fix` (or name findings) | +| Walk frontend testid PR when needed | Approve push / PR create | + +--- + +## Workflow overview + +``` +Input (path_dir or current branch) + │ + ├─ Phase 0: Identify path ───── path_dir, path_type, Playwright MCP prereq + │ + ├─ Phase 1: Static pass ─────── audit + path/LH checks → author findings (post-inline only) + │ + ├─ Phase 2: Live test ───────── Playwright DOM required; Block Editor opt-in + │ (skipped when static-only) + │ + ├─ Phase 3: Readiness ───────── readiness report + offer to fix + │ + ├─ Phase 4: Apply fixes ─────── optional package JSON / website.yaml edits + │ + └─ Phase 5: Frontend testid ─── optional upstream data-testid PR (when needed) +``` + +--- + +## Inputs + +- **Required**: `{path_dir}` ending in `-lj/` (for example `monitor-azure-resources-lj`). Infer from current branch if omitted; confirm if ambiguous. +- **Optional**: `website_slug` (`{path_dir}` minus `-lj`). Website repo is read-only for conversion ([PR #416](https://github.com/grafana/interactive-tutorials/pull/416)). +- **Optional**: `learn_host` (default `learn.grafana.net`). +- **Optional**: `waive_live_testing` via `static-only: ` at Phase 1 end. See [static-only preflight](reference-checks.md#static-only-preflight). + +--- + +## Prerequisites + +See [author-testing.md § Prerequisites](author-testing.md#prerequisites). Phase 0 verifies Playwright MCP for the live path. + +--- + +## Safety invariants + +1. **Do not modify** `content.json`, `manifest.json`, or `website.yaml` until Phase 4 (and only when the author requests fixes). +2. **Never commit** preflight artifacts (`.cursor/lp-preflight-state/` or audit-guide files under `{milestone}/assets/`). +3. **Surface only post-inline** findings in chat and readiness (same bar as review [comment-style](../review-learning-path/comment-style.md)). Never dump Internal/Discard nits. +4. **No em dashes** in author-facing chat, readiness text, or drafted PR bodies. Use periods, commas, or parentheses. +5. **One preflight run per path slug** (resume from state; do not fork duplicate state files). +6. **Never** plan companion website / `pathfinder_data` / shortcode work as package blockers. + +--- + +## Commit safety + +Same snapshot/cleanup rules as [review-learning-path § Commit safety](../review-learning-path/SKILL.md#commit-safety). + +| Artifact | Where | Mitigation | +|---|---|---| +| Findings, readiness, state JSON | `.cursor/lp-preflight-state/` | `.gitignore` | +| audit-guide reports | `{milestone}/assets/` | Snapshot before Phase 1; delete new files before Phase 1 checkpoint | +| Pre-existing package `assets/` | Author/migrate notes | Never delete paths listed in `pre_review_assets` | + +**Phase 1 snapshot:** `find {milestone}/assets -type f 2>/dev/null | sort` → store in state `pre_review_assets`. + +**Phase 1 cleanup (mandatory before checkpoint):** remove audit files not in the snapshot; verify `git status --porcelain -- {path_dir}` shows no untracked audit paths. + +Re-verify commit safety after Phase 1 before Phase 2. + +--- + +## How this skill runs + +1. Announce the phase (number and name), what you're doing, and why (2–3 sentences). +2. Do agent work (audit, CLI, Playwright, drafts). +3. Stop at the checkpoint: one message, one ask. **Do not advance** until the author replies. +4. **Never batch phases.** If they say "keep going," pause at the next checkpoint anyway. + +--- + +## Checkpoint format + +| Section | Content | +|---|---| +| **Header** | `Phase {n} complete` + one-line outcome | +| **Summary** | Up to 3 plain-language bullets. Post-inline only. No rule counts. | +| **Your turn** | Exactly one action | +| **Up next** | One sentence | + +**Reply keywords:** `yes` · `ready` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix` · `frontend` · `done` · `resume` / `start fresh` + +**Tone:** Casual and friendly. Address the author as **you**. Celebrate clean passes. No rule numbers, no Blocker/nit labels, no em dashes. + +--- + +## Resume + +If `.cursor/lp-preflight-state/{slug}.json` exists: + +> **Resume?** I have an in-progress preflight for `{path_dir}` (stopped after phase {phase}). +> +> Reply **resume** to pick up, or **start fresh** to begin again. + +--- + +## Phase 0: Identify path + +**Goal:** Confirm `{path_dir}`, `path_type`, milestones; verify Playwright MCP; init state. + +### Tell the author + +> **Phase 0 - Identify path** +> +> Share the learning path package directory (for example `monitor-azure-resources-lj`), or tell me to infer it from your current branch. +> +> **Setup reminder:** For the live path I need **Playwright MCP** in Cursor. You'll Okta-login in the Playwright browser when we get to DOM checks. Block Editor is optional later. + +### Agent steps + +1. Infer or confirm `{path_dir}` (directory ending in `-lj`). +2. Record branch and HEAD sha. +3. Infer `website_slug` = `{path_dir}` minus `-lj` when website repo is in workspace (read-only). +4. Infer `path_type`: `new`, `conversion`, or `update` per [path type](reference-checks.md#path-type). +5. List milestones from path `manifest.json` `milestones` and dirs under `{path_dir}/`. +6. **Verify Playwright MCP** (`user-playwright`). If unavailable on a live path: stop with setup help ([author-testing.md](author-testing.md#prerequisites)). Do not silently skip. +7. Write `.cursor/lp-preflight-state/{slug}.json` ([state schema](reference-checks.md#state-file-schema)). + +### Checkpoint + +> **Phase 0 complete** - `{path_dir}` on `{branch}` @ `{short_sha}`. +> +> - Path: `{path_dir}` ({M} milestones) +> - Type: `{path_type}` +> - Playwright MCP: ready *(or blocked: see setup)* +> +> **Your turn:** Reply **yes** if this looks right, or tell me what to change. +> +> **Up next:** Static pass (I won't edit your JSON unless you ask later). + +--- + +## Phase 1: Static pass + +**Goal:** Audit every milestone + path consistency + Learning Hub. Surface **post-inline** findings only in chat. + +Combines review Phase 1 checks. Author sees findings in chat (not a private workbook dump of nits). + +### Tell the author + +> **Phase 1 - Static pass** +> +> I'm reading each milestone and checking manifests, `website.yaml`, and Learning Hub structure. I'll only call out things a reviewer would comment on. + +### Agent steps + +1. Snapshot `pre_review_assets`; dispatch [audit-guide](../audit-guide/SKILL.md) per milestone (parallel OK). +2. Walk shared [review reference-checks](../review-learning-path/reference-checks.md) + [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md). +3. **Always scan** for framing-in-milestones, [section intro markdown that may number as a step](../review-learning-path/reference-checks.md#section-intro-markdown-numbered-as-step), and [false noops](../review-learning-path/reference-checks.md#noop-and-non-interactive-steps). +4. Run Pathfinder CLI `validate --packages {path_dir}` if available. +5. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing). Keep only **post inline** for author chat. Drop Internal/Discard entirely from chat. +6. Write `{slug}-findings.md` under `.cursor/lp-preflight-state/` (post-inline list + optional verify-live notes for Phase 2). Resume aid only; chat stays tiny. +7. Mandatory audit cleanup; verify `git status`. +8. Do not cite rule numbers or audit severity labels in chat. + +### Checkpoint + +> **Phase 1 complete** - static pass done. +> +> - {One plain sentence: clean, or a few things to fix} +> - **Fix before PR** (≤3 bullets, plain language; omit if none): +> - {e.g. first hands-on still depends on business-value} +> - {e.g. "You'll…" intros inside sections in create-dashboard} +> +> **Your turn:** Reply **yes** and your test stack (for example `learn.grafana.net shared`, `fresh Cloud stack`). +> +> Or **`static-only: `** to skip live testing (not for **new** / **conversion** interactive paths). See [static-only preflight](reference-checks.md#static-only-preflight). +> +> **Up next:** Playwright DOM checks *(or readiness if static-only)*. + +Record `stack_state`, or `waive_live_testing` + `static_only_reason`. + +**Reject** bare `static-only` and static-only on **new** / **conversion** with interactive milestones. + +--- + +## Phase 2: Live test + +**Goal:** Required Playwright DOM checks. Block Editor smoke test is **not forced**. + +Skipped when `waive_live_testing` is true → jump to Phase 3. + +Details: [author-testing.md](author-testing.md). + +### Setup (tell the author once) + +> **Phase 2 - Live test** +> +> I need the **Playwright** browser for DOM checks. Log into `{learn_host}` with Okta there, then reply **ready**. +> +> Stack: `{stack_state}` +> +> After DOM checks I'll ask whether you've already smoke-tested in Block Editor (optional). + +**Wait for:** `ready`. + +### Milestone scope + +| `path_type` | Scope | +|---|---| +| **new** / **conversion** | Every interactive milestone in path `milestones` | +| **update** | Touched interactive milestones first; full path on request | + +### Step A: Playwright DOM (required) + +For each milestone in scope (path order; skip prose-only / terminal): + +1. Derive start URL ([milestone start URL](../review-learning-path/reference-checks.md#milestone-start-url)). +2. Navigate; check each `reftarget`: exists / missing / below-fold / state-dependent. +3. Record in `playwright.{milestone-slug}`. +4. One-line DOM result in chat per milestone (or batch briefly if all clean). + +### Step B: Block Editor (opt-in, once) + +After Playwright: + +> Have you already smoke-tested this path in Block Editor (Show me / Do it)? +> +> Reply **`already-tested: `** if yes (stack + anything flaky). +> Reply **`walk-me`** for a guided per-milestone check now (local JSON import, not the PR review tool). +> Reply **`skip-smoke`** to continue without recording Block Editor evidence. + +| Reply | Behavior | Readiness | +|---|---|---| +| `already-tested: …` | Store dogfood evidence; no per-milestone loop | Can still be **Ready for PR** if Playwright clean and no post-inline blockers | +| `walk-me` | Guided loop: local import, `pass` / `fail step N` / `N/A`; ask about false step numbers | Same when scoped milestones pass or documented N/A | +| `skip-smoke` | Continue | Cap at **Open PR with notes**; say Block Editor was not recorded | + +### Checkpoint + +> **Phase 2 complete** - live checks done. +> +> - Playwright: [short summary] +> - Block Editor: already-tested / walked / skipped +> +> **Your turn:** Reply **yes** for the readiness report. +> +> **Up next:** Phase 3 - readiness + whether to fix anything. + +--- + +## Phase 3: Readiness + +**Goal:** Merge static + live into a readiness outcome; offer fixes. + +### Agent steps + +1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) and promote only post-inline items. +2. Apply [readiness gate](reference-checks.md#readiness-gate). +3. Write `{slug}-readiness.md` with outcome + [PR opener checklist](reference-checks.md#pr-opener-checklist). +4. In chat: numbered list of open post-inline findings (file path + short human fix ask). Zero findings is first-class. +5. Offer next steps casually: `fix`, `frontend` (missing stable selector), or `done`. + +### Checkpoint + +> **Phase 3 complete - {readiness outcome}** +> +> - [2–4 bullets: gate status, live summary, top remaining items] +> - Report: `.cursor/lp-preflight-state/{slug}-readiness.md` +> +> **Fix before PR:** +> 1. `{file}` - {short ask} +> 2. … +> +> *(or: Nothing you'd get a review comment for. Nice work.)* +> +> **Your turn:** Reply **show report**, **fix** (package edits), **frontend** (upstream testid PR), or **done** if you're opening the PR. +> +> **Up next:** Optional fixes, or you're clear to open a PR. + +--- + +## Phase 4: Apply package fixes (optional) + +**Goal:** Author-requested surgical edits. + +### Tell the author + +> **Phase 4 - Apply fixes** +> +> Tell me which findings to fix (or say **fix all**). I'll edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). + +### Agent steps + +1. Apply only requested findings. +2. Re-run Pathfinder CLI validate if content/manifests changed. +3. Suggest re-running Phase 2 Playwright for touched interactive milestones. +4. Do not commit unless the author explicitly asks. + +### Checkpoint + +> **Phase 4 complete** - applied {N} fix(es). +> +> **Your turn:** Reply **yes** to refresh readiness, **frontend** if you still need a testid upstream, or **done**. + +--- + +## Phase 5: Frontend selector PR (optional) + +**Goal:** When a stable selector is missing upstream, walk the author through a small `data-testid` PR. + +Follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [grafana/grafana-cmab-app#1795](https://github.com/grafana/grafana-cmab-app/pull/1795). + +### Checkpoint + +> **Phase 5 complete** - frontend PR {url} *(or deferred)*. +> +> **Your turn:** Reply **done** when you're ready to open the learning path PR (or wait on the testid merge). + +--- + +## Anti-patterns + +**Do not** + +- Edit package JSON before Phase 4 / without an explicit ask +- Leave audit artifacts in milestone `assets/` +- Commit `.cursor/lp-preflight-state/` +- Surface Internal/Discard nits in chat or readiness +- Use em dashes, rule numbers, or Blocker labels with the author +- Force a full Block Editor loop when they already dogfooded +- Recommend **Ready for PR** with open post-inline items +- Recommend **Ready for PR** on **new** / **conversion** interactive paths when Playwright was skipped +- Request website-repo changes (`pathfinder_data`, shortcodes) as package blockers +- Use the PR review tool as a substitute for local import (no PR yet) + +**Do** + +- Mirror five-phase review checklists and Learning Hub standards +- Keep chat tiny and friendly +- Dedupe findings by root cause +- Run CLI validate when available +- Offer Phase 4 / 5 after readiness + +--- + +## Generated files + +Write under `.cursor/lp-preflight-state/` (never commit): + +| File | Phase | Purpose | +|---|---|---| +| `{slug}.json` | 0+ | Machine state ([schema](reference-checks.md#state-file-schema)) | +| `{slug}-findings.md` | 1 | Post-inline findings + verify-live notes | +| `{slug}-readiness.md` | 3 | Readiness gate + PR opener checklist | +| `{slug}/audits/{milestone}/` | 1 (optional) | Copied audit reports before cleanup | + +Generated markdown frontmatter: + +```markdown +--- +disclaimer: Auto-generated by preflight-learning-path skill. Do not edit manually. +notice: To regenerate, re-run the skill from the relevant phase. +path_dir: {path_dir} +--- +``` + +--- + +## Deep references + +| Topic | Doc | +|---|---| +| Author routing + readiness | [reference-checks.md](reference-checks.md) | +| Prereqs + Playwright + optional smoke | [author-testing.md](author-testing.md) | +| Frontend testid PR | [frontend-selector-pr.md](frontend-selector-pr.md) | +| Shared static checklists + finding routing | [../review-learning-path/reference-checks.md](../review-learning-path/reference-checks.md) | +| Learning Hub structure | [../review-learning-path/learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) | +| Comment voice (post-inline bar) | [../review-learning-path/comment-style.md](../review-learning-path/comment-style.md) | +| Reviewer workflow (mirror) | [../review-learning-path/SKILL.md](../review-learning-path/SKILL.md) | +| `website.yaml` | [docs/website-yaml-reference.md](../../../docs/website-yaml-reference.md) | +| Single-repo LP workflows | [learning-path-workflows/workflows.md](../../learning-path-workflows/workflows.md) | diff --git a/.cursor/skills/preflight-learning-path/author-testing.md b/.cursor/skills/preflight-learning-path/author-testing.md new file mode 100644 index 000000000..a7f5507e2 --- /dev/null +++ b/.cursor/skills/preflight-learning-path/author-testing.md @@ -0,0 +1,103 @@ +# Author testing (preflight) + +Live-test helpers for [preflight-learning-path/SKILL.md](SKILL.md) Phase 2. + +Aligns with the five-phase [review-learning-path](../review-learning-path/SKILL.md) live path, lighter for authors: Playwright DOM is required; Block Editor is opt-in. + +--- + +## Prerequisites + +Confirm at Phase 0 / remind in the slash-command first message. + +| Need | Required when | Why | How to verify / fix | +|---|---|---|---| +| `interactive-tutorials` checkout with `{slug}-lj/` | Always | Package under test | Path on disk / current branch | +| **Playwright MCP** enabled (`user-playwright`) | Live path (default for new/conversion interactive) | Agent DOM checks | Phase 0: list or call Playwright MCP tools. If missing: enable Playwright MCP in Cursor settings, then re-run | +| Okta login in the **Playwright** browser to `{learn_host}` (default `learn.grafana.net`) | Before Playwright DOM loop | MCP cannot complete SAML alone | Phase 2: author logs in, replies `ready` | +| Pathfinder Block Editor on learn | Only if author chooses `walk-me` | Optional smoke coaching | `{learn_host}/plugins/grafana-pathfinder-app?dev=true` → **?** → Debug → Block Editor → import local JSON | +| Pathfinder CLI (`grafana-pathfinder-app` built locally) | Nice-to-have | `validate --packages` | Note if missing; do not abort preflight | +| `gh` auth + write access to the UI repo | Phase 5 only | Frontend testid PR | Check when entering Phase 5 | +| `website` repo in workspace | Optional (conversion) | Read-only legacy compare | Never write | + +Same Playwright + Okta role as [learning-path-workflows/workflows.md](../../learning-path-workflows/workflows.md) and `/create-learning-path`. + +### If Playwright MCP is missing + +Stop at Phase 0 (or before Phase 2) with friendly setup help. Do **not** silently skip DOM checks on new/conversion interactive paths. `static-only: ` only when [static-only rules](reference-checks.md#static-only-preflight) allow it. + +--- + +## Two browsers (live path) + +| Browser | Who | Purpose | +|---|---|---| +| **Playwright** (MCP) | Agent (+ author Okta login) | Required DOM existence checks | +| **Normal browser** | Author | Optional Block Editor (`walk-me` only) | + +DOM exists ≠ Show me / Do it works. Reviewers still run full Block Editor smoke on the PR. + +--- + +## Playwright DOM (required) + +After author replies `ready`: + +For each interactive milestone in scope (path order): + +1. Start URL: first `on-page:/path` in milestone blocks, else path manifest `startingLocation` (same as [review milestone start URL](../review-learning-path/reference-checks.md#milestone-start-url)). +2. Navigate on `{learn_host}`. +3. For each `reftarget`, record: `exists` / `missing` / `below-fold` / `state-dependent`. +4. One-line result in chat before moving on (or a short all-clear if clean). + +Respect [live testing prerequisites](../review-learning-path/reference-checks.md#live-testing-prerequisites-phase-2) (stack state, credential-gated UI). Prefer documenting stack gaps over false "missing selector" on the wrong stack. + +Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) when promoting findings after live results. + +--- + +## Block Editor (opt-in) + +Authors are expected to dogfood while writing. Do **not** force a per-milestone interrogation by default. + +### Prompt (once, after Playwright) + +> Have you already smoke-tested this path in Block Editor (Show me / Do it)? +> +> Reply **`already-tested: `** if yes (stack + anything flaky). +> Reply **`walk-me`** if you want a guided per-milestone check now. +> Reply **`skip-smoke`** to continue without recording Block Editor evidence. + +### Local import (`walk-me` only) + +No PR yet, so **do not** use the PR review tool. + +1. Open `{learn_host}/plugins/grafana-pathfinder-app?dev=true` in the normal browser. +2. **?** → Debug → **Block Editor**. +3. Import `{path_dir}/{milestone}/content.json` from the local checkout. +4. Open the derived start URL; run every **Show me** and **Do it**. + +### Guided loop prompts + +For each scoped milestone: + +> **Milestone {i} of {M}: `{milestone-id}`** +> +> Import the local `content.json`, open `{derived_start_url}`, run Show me / Do it. +> +> Also glance at the section step list for false step numbers (intro prose as step 1, or learner-action noops). +> +> **Your turn:** Reply **pass**, **fail step N - ** *what happened*, or **N/A - ** *reason*. + +Record in state `pathfinder.{milestone-slug}`. + +--- + +## Milestone scope + +| `path_type` | Scope | +|---|---| +| **new** / **conversion** | Every interactive milestone in path `milestones` | +| **update** | Touched interactive milestones first; full path on request | + +Skip terminal-only / external-CLI milestones for DOM and walk-me unless the author asks. diff --git a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md new file mode 100644 index 000000000..21cec2655 --- /dev/null +++ b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md @@ -0,0 +1,90 @@ +# Frontend selector PR (preflight Phase 5) + +Walk an author through adding a stable `data-testid` upstream when Pathfinder needs one and the DOM has no good selector. + +**Canonical example:** [grafana/grafana-cmab-app#1795](https://github.com/grafana/grafana-cmab-app/pull/1795) (Add `data-testid` selectors to Usage page components). + +Use that PR as the model for: + +- Small, uniform component changes (testids only) +- Plain kebab-case names matching the product area +- PR title/body that explains Pathfinder authoring needs stable selectors +- Friendly, low-ceremony tone + +Do not paste the whole #1795 diff. Link it and mirror the pattern. + +--- + +## When to enter Phase 5 + +Trigger when Phase 2 shows a step needs a durable selector and: + +- No `data-testid` / strong semantic attribute exists in the DOM, and +- The author wants an upstream fix (not only a justified `:contains()` fallback), and +- They reply **`frontend`** at Phase 3 (or ask during Phase 4) + +If live passed with a justified `:contains()` and no stable selector exists, that stays Internal in review terms. Offer Phase 5 as an optional improvement, not a Fix-before-PR demand, unless Playwright/walk-me failed on that step. + +--- + +## Walkthrough (checkpointed) + +### 1. Confirm the element + +From Playwright: URL, visible label, current weak selector, screenshot or DOM snippet if helpful. + +Propose a `data-testid` (plain kebab-case, product-area prefix, matching existing testids in that app when present). + +**Wait for:** author OK on the name (or edits). + +### 2. Locate owning source + +- Default core UI: `grafana/grafana` +- Plugin app pages (`/a/grafana-*-app/...`): that plugin repo (as #1795 did for CMAB) + +Use workspace clones or GitHub search. Do **not** invent file paths. + +**Wait for:** confirm repo + file(s). + +### 3. Draft the change + +- Minimal diff: add `data-testid` (and wire through component props if needed) +- Match local naming conventions +- Draft PR title + body in the style of #1795 (Pathfinder needs stable selectors; keep scope tight) +- **No em dashes** in the PR body + +Example body shape (adapt; do not copy blindly): + +```markdown +Hey folks, I was building a Pathfinder guide and noticed some UI elements lacked stable selector IDs. + +Adds `data-testid` attributes to {components} following the existing kebab-case naming on this page. These selectors are needed for interactive Pathfinder guides, which prefer `data-testid` over text or class-based targeting. + +Example pattern: https://github.com/grafana/grafana-cmab-app/pull/1795 +``` + +**Wait for:** author approval of the draft. + +### 4. Open the PR + +1. Confirm `gh` auth and write access +2. Create branch, commit, push (ask before push) +3. `gh pr create` with the approved title/body +4. Follow existing grafana org repo norms; do not change repo visibility + +Record `frontend_pr_url` in preflight state. + +### 5. Update the guide selector + +Update the milestone `reftarget` to the new testid **only after** the author confirms the frontend change is available on their test stack. + +Until then: keep a temporary justified fallback if needed, and note the upstream PR URL in readiness / Open PR with notes. + +--- + +## Anti-patterns + +- Giant refactors or drive-by UI changes in the testid PR +- Inventing component paths +- Updating guide JSON to a testid that is not on the test stack yet without saying so +- Treating a missing upstream testid as something to "fix" only inside `interactive-tutorials` when the DOM has no stable hook diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md new file mode 100644 index 000000000..e8d773cf6 --- /dev/null +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -0,0 +1,173 @@ +# Reference checks (preflight-learning-path) + +Author-side routing and readiness for [preflight-learning-path/SKILL.md](SKILL.md). + +**Shared checklists (source of truth):** [../review-learning-path/reference-checks.md](../review-learning-path/reference-checks.md) and [../review-learning-path/learning-hub-standards.md](../review-learning-path/learning-hub-standards.md). Run every checklist the five-phase review coach runs in Phase 1. + +**Publishing model (PR [#416](https://github.com/grafana/interactive-tutorials/pull/416)):** Single-repo packages in `interactive-tutorials`. Metadata in package `website.yaml`; prose in `content.json`. Website repo is read-only for conversion. Never plan companion website / `pathfinder_data` / shortcode work. + +**Voice bar:** Same as review [comment-style.md](../review-learning-path/comment-style.md). Author chat and readiness only include **post inline** items. No em dashes. + +--- + +## Finding severity (author) + +Map review [finding routing](../review-learning-path/reference-checks.md#finding-routing) 1:1: + +| Review tier | Author action | +|---|---| +| **Post inline** | **Fix before PR** (surface in chat + readiness) | +| **Internal** | Hide (do not mention in chat or readiness) | +| **Discard** | Hide | + +Do not invent an author-only softer bar. Do not surface "Polish / follow-up" lists. + +### Must surface (post-inline examples) + +Apply the same five-phase coach rules (cite shared reference-checks; do not soften): + +- Playwright / Block Editor runtime fail (when live failed or `walk-me` failed) +- **Framing milestones** in path `milestones`, or first hands-on `depends` on a framing ID (must be `depends: []`) +- **Fake steps in sections:** missing bookends outside the section; in-section intro markdown that numbers as a step (e.g. first child "You'll …") +- **False noops:** learner-action copy with `noop` and no `reftarget` +- Missing / broken required `website.yaml` identity; Learning Hub structure the author must change +- Path root / manifest `id` mismatch; Pathfinder CLI validate failure +- Secrets `doIt: true`; confirmed 404s; conversion prose only in legacy markdown +- Fragile / wrong selectors when live fails, or stable `data-testid` exists in DOM and the guide uses a weak selector + +### Never surface + +Wording polish, justified `:contains()` when live passed, CODEOWNERS reminders, audit noise, selector polish when live passed, landing screenshot notes, milestone-count guidelines. + +--- + +## Checklists to run (Phase 1) + +Apply every section from [../review-learning-path/reference-checks.md](../review-learning-path/reference-checks.md): + +- Milestone `content.json` checks +- Section intro markdown numbered as a step +- Framing milestones / framing vs not framing +- Path root `content.json` +- Learning Hub structure + [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) +- `website.yaml` +- Valid manifests (CLI) +- Targeting / recommender +- Supplementary content +- Legacy website source (conversion, read-only) +- noop and non-interactive steps +- CODEOWNERS (discard for author chat) + +Tag each finding; keep only post-inline for author-facing output. + +--- + +## Path type + +Infer from branch diff, directory age, and legacy website source. Record in `{slug}.json` → `path_type`. + +| Type | Signals | Live emphasis | +|---|---|---| +| **new** | New `{slug}-lj/`; no legacy website folder | Full Playwright; `website.yaml` + path root completeness | +| **conversion** | Built via `/build-interactive-lj`; prose-heavy | Legacy prose captured in package; Playwright full path | +| **update** | Changes existing package only | Touched interactive milestones first | + +--- + +## Static-only preflight + +`static-only: ` at Phase 1 end skips Phase 2. + +| Situation | Allowed? | +|---|---| +| **new** / **conversion** with interactive milestones | **No** | +| **update** touching only markdown / `website.yaml` | Yes, with reason | +| Practice run / no stack access | Yes, with reason (caps readiness) | + +Reject bare `static-only`. Record `waive_live_testing` + `static_only_reason`. + +When live was skipped or incomplete, readiness must include **Not live-tested** (interactive path `milestones` minus recorded Playwright results). Never recommend **Ready for PR** for new/conversion interactive when Playwright was waived. + +--- + +## Readiness gate + +Recommend **Ready for PR** only when all are true: + +1. Zero open **Fix before PR** (post-inline) items +2. Pathfinder CLI validate passed, or CLI unavailable was noted and no other blockers +3. Playwright: no unexplained **missing** selectors on claimed-tested milestones (or documented stack prerequisite) +4. Block Editor: `already-tested` or successful `walk-me` (not `skip-smoke`) for new/conversion interactive, **or** author accepts **Open PR with notes** +5. `git status` clean of audit-guide artifacts under `{path_dir}` +6. Not `waive_live_testing` on new/conversion interactive (or outcome is **Open PR with notes**) + +| Outcome | When | +|---|---| +| **Ready for PR** | Gate conditions met | +| **Fix then re-preflight** | Open post-inline items or Playwright/walk-me failures | +| **Open PR with notes** | Package mergeable but smoke skipped, or fresh-stack retest notes for the reviewer | + +--- + +## PR opener checklist + +Include in `{slug}-readiness.md`: + +- [ ] Path `{path_dir}` validates with Pathfinder CLI (or CLI unavailable noted) +- [ ] First hands-on milestone `depends: []` +- [ ] No framing IDs in path `manifest.json` `milestones` +- [ ] `schemaVersion: "1.1.0"` or omitted on milestone `content.json` +- [ ] Playwright DOM checked for scoped interactive milestones +- [ ] Block Editor: already-tested notes, walk-me results, or skip noted for reviewer +- [ ] Path and milestone `website.yaml` complete +- [ ] **Not live-tested** section in PR description if any interactive milestone skipped Playwright +- [ ] Single PR in `interactive-tutorials` only (no companion website PR) + +--- + +## State file schema + +Path: `.cursor/lp-preflight-state/{slug}.json` + +```json +{ + "path_dir": "monitor-azure-resources-lj", + "slug": "monitor-azure-resources-lj", + "website_slug": "monitor-azure-resources", + "path_type": "conversion", + "branch": "docs/my-path", + "head_commit": "abc123", + "learn_host": "learn.grafana.net", + "stack_state": "learn.grafana.net shared", + "waive_live_testing": false, + "static_only_reason": null, + "smoke_mode": null, + "smoke_notes": null, + "pre_review_assets": {}, + "phase": 3, + "status": "in_progress", + "readiness": null, + "playwright": {}, + "pathfinder": {}, + "frontend_pr_url": null +} +``` + +| Field | Notes | +|---|---| +| `smoke_mode` | `already-tested` \| `walk-me` \| `skip-smoke` \| null | +| `smoke_notes` | Author notes for already-tested / skip | +| `pathfinder` | Only when `walk-me`; keys = milestone slug | +| `playwright` | DOM results per milestone | +| `phase` | Integer 0–5 | +| `readiness` | `Ready for PR` \| `Fix then re-preflight` \| `Open PR with notes` | + +--- + +## Pathfinder CLI validate + +```bash +node {pathfinder-app}/dist/cli/cli/index.js validate --packages {path_dir} +``` + +CLI failure → Fix before PR. CLI missing → note in readiness; do not abort the whole preflight. diff --git a/.cursor/skills/review-learning-path/SKILL.md b/.cursor/skills/review-learning-path/SKILL.md index 459d29114..684e90417 100644 --- a/.cursor/skills/review-learning-path/SKILL.md +++ b/.cursor/skills/review-learning-path/SKILL.md @@ -23,7 +23,7 @@ Help a **human reviewer** work through a `{slug}-lj/` pull request in **five pha **Routing:** [reference-checks.md](reference-checks.md) · [comment-style.md](comment-style.md) · [learning-hub-standards.md](learning-hub-standards.md) · [github-review.md](github-review.md) -**Related:** [audit-guide](../audit-guide/SKILL.md) · [review-guide-pr.mdc](../../review-guide-pr.mdc) +**Related:** [audit-guide](../audit-guide/SKILL.md) · [review-guide-pr.mdc](../../review-guide-pr.mdc) · [preflight-learning-path](../preflight-learning-path/SKILL.md) (author pre-PR mirror) --- diff --git a/.gitignore b/.gitignore index 9d67068eb..fc0acbdf8 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,9 @@ scripts/.browser-session/ # LP PR review skill — local state (findings, review body, GraphQL IDs) .cursor/pr-review-state/ +# LP preflight skill - local state (findings, readiness report) +.cursor/lp-preflight-state/ + # audit-guide skill output — review-time artifacts; never commit (see review-learning-path SKILL.md) **/assets/audit-input.json **/assets/audit-report.md diff --git a/AGENTS.md b/AGENTS.md index 7eb80c276..c1c8ed29b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,6 +42,7 @@ Full reference documentation lives in `docs/`. AI-oriented references live in `. | Update/modify an existing guide | [update-guide](.cursor/skills/update-guide/SKILL.md) skill | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [best-practices.mdc](.cursor/best-practices.mdc), [review-guide-pr.mdc](.cursor/review-guide-pr.mdc) | | Review a guide PR | [review-guide-pr.mdc](.cursor/review-guide-pr.mdc) | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [best-practices.mdc](.cursor/best-practices.mdc), [edge-cases-and-troubleshooting.mdc](.cursor/edge-cases-and-troubleshooting.mdc), `docs/` | | Review a learning path PR | [/review-learning-path-pr](.cursor/commands/review-learning-path-pr.md) | [review-learning-path](.cursor/skills/review-learning-path/SKILL.md), [audit-guide](.cursor/skills/audit-guide/SKILL.md), [review-guide-pr.mdc](.cursor/review-guide-pr.mdc) | +| Preflight a learning path (before PR) | [/preflight-learning-path](.cursor/commands/preflight-learning-path.md) | [preflight-learning-path](.cursor/skills/preflight-learning-path/SKILL.md), [audit-guide](.cursor/skills/audit-guide/SKILL.md), [review-learning-path](.cursor/skills/review-learning-path/SKILL.md) | | Decision trees & code smells | [best-practices.mdc](.cursor/best-practices.mdc) | [authoring-guide.mdc](.cursor/authoring-guide.mdc), `docs/` | | Create new guide | `/new` command | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [complete-example-tutorial.mdc](.cursor/complete-example-tutorial.mdc) | | Validate guide | `/lint`, `/check`, `/attack` commands | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [best-practices.mdc](.cursor/best-practices.mdc) | @@ -82,4 +83,5 @@ Full reference documentation lives in `docs/`. AI-oriented references live in `. | [/check](.cursor/commands/check.md) | Check guide quality against best practices | | [/attack](.cursor/commands/attack.md) | Find issues by simulating confused users | | [/review-learning-path-pr](.cursor/commands/review-learning-path-pr.md) | Full learning path PR review (audit, consistency, Playwright, Pathfinder, GitHub submit) | +| [/preflight-learning-path](.cursor/commands/preflight-learning-path.md) | Author pre-PR self-review for a learning path (same checks as review, then optional fixes) | | [/build-interactive-lj](.cursor/commands/build-interactive-lj/README.md) | Multi-phase learning journey builder | diff --git a/CLAUDE.md b/CLAUDE.md index d37dbb087..7971ce87c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,6 +17,7 @@ When a doc here disagrees with the upstream schema, the schema wins. Authoritati | Update / modify an existing guide | [update-guide](.cursor/skills/update-guide/SKILL.md) skill | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [best-practices.mdc](.cursor/best-practices.mdc), [review-guide-pr.mdc](.cursor/review-guide-pr.mdc) | | Review a guide PR | [.cursor/review-guide-pr.mdc](.cursor/review-guide-pr.mdc) | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [best-practices.mdc](.cursor/best-practices.mdc), [edge-cases-and-troubleshooting.mdc](.cursor/edge-cases-and-troubleshooting.mdc) | | Review a learning path PR | [/review-learning-path-pr](.cursor/commands/review-learning-path-pr.md) | [review-learning-path](.cursor/skills/review-learning-path/SKILL.md), [audit-guide](.cursor/skills/audit-guide/SKILL.md) | +| Preflight a learning path (before PR) | [/preflight-learning-path](.cursor/commands/preflight-learning-path.md) | [preflight-learning-path](.cursor/skills/preflight-learning-path/SKILL.md), [audit-guide](.cursor/skills/audit-guide/SKILL.md), [review-learning-path](.cursor/skills/review-learning-path/SKILL.md) | | Decision trees & code smells | [.cursor/best-practices.mdc](.cursor/best-practices.mdc) | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [docs/](docs/) | | Create a new guide | [/new](.cursor/commands/new.md) command | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [complete-example-tutorial.mdc](.cursor/complete-example-tutorial.mdc) | | Validate a guide | [/lint](.cursor/commands/lint.md), [/check](.cursor/commands/check.md), [/attack](.cursor/commands/attack.md) | [authoring-guide.mdc](.cursor/authoring-guide.mdc), [best-practices.mdc](.cursor/best-practices.mdc) | @@ -45,6 +46,8 @@ Multi-phase workflow skills with their own `SKILL.md` files. Skills write interm - [.cursor/skills/audit-guide/](.cursor/skills/audit-guide/SKILL.md) — comprehensive read-only audit (structural + semantic + adversarial) producing one prioritised report - [.cursor/skills/update-guide/](.cursor/skills/update-guide/SKILL.md) — modify an existing guide with a planning checkpoint, review pass, and CLI-validated rollback - [.cursor/skills/migrate-guide/](.cursor/skills/migrate-guide/SKILL.md) — migrate a guide or learning path to the Pathfinder package format +- [.cursor/skills/review-learning-path/](.cursor/skills/review-learning-path/SKILL.md) — human-guided learning path PR review (five-phase coach) +- [.cursor/skills/preflight-learning-path/](.cursor/skills/preflight-learning-path/SKILL.md) — author pre-PR self-review for a learning path ## Shared Content From 269b90fc860d405613f5f7d7b3d5ea10e9def838 Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Mon, 20 Jul 2026 11:14:05 -0700 Subject: [PATCH 2/9] Offer to add Playwright MCP config when preflight detects it missing. Phase 0 now pairs manual Settings steps with an opt-in mcp.json write (or mcp_auth), so authors are not left with instructions-only when the agent can help. --- .cursor/commands/preflight-learning-path.md | 2 +- .../skills/preflight-learning-path/SKILL.md | 14 ++++--- .../preflight-learning-path/author-testing.md | 38 ++++++++++++++++++- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/.cursor/commands/preflight-learning-path.md b/.cursor/commands/preflight-learning-path.md index 8f74d0251..4161b7104 100644 --- a/.cursor/commands/preflight-learning-path.md +++ b/.cursor/commands/preflight-learning-path.md @@ -28,7 +28,7 @@ LP packages are **single-repo** (`interactive-tutorials` only). Metadata lives i > | 4 | Optional package fixes | > | 5 | Optional frontend `data-testid` PR if a stable selector is missing | > -> **Setup:** Playwright MCP should be on. You'll Okta-login in the Playwright browser for DOM checks. +> **Setup:** Playwright MCP should be on. If it isn't, I'll offer to add the config for you (or walk you through Settings). You'll Okta-login in the Playwright browser for DOM checks. > > **Phase 0:** Share the path package (`{slug}-lj/` directory), or tell me to infer it from your current branch. diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index cb3becf1d..63322fe18 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -123,7 +123,7 @@ Re-verify commit safety after Phase 1 before Phase 2. | **Your turn** | Exactly one action | | **Up next** | One sentence | -**Reply keywords:** `yes` · `ready` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix` · `frontend` · `done` · `resume` / `start fresh` +**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix` · `frontend` · `done` · `resume` / `start fresh` **Tone:** Casual and friendly. Address the author as **you**. Celebrate clean passes. No rule numbers, no Blocker/nit labels, no em dashes. @@ -158,21 +158,25 @@ If `.cursor/lp-preflight-state/{slug}.json` exists: 3. Infer `website_slug` = `{path_dir}` minus `-lj` when website repo is in workspace (read-only). 4. Infer `path_type`: `new`, `conversion`, or `update` per [path type](reference-checks.md#path-type). 5. List milestones from path `manifest.json` `milestones` and dirs under `{path_dir}/`. -6. **Verify Playwright MCP** (`user-playwright`). If unavailable on a live path: stop with setup help ([author-testing.md](author-testing.md#prerequisites)). Do not silently skip. +6. **Verify Playwright MCP** (`user-playwright`). If unavailable on a live path: stop per [If Playwright MCP is missing](author-testing.md#if-playwright-mcp-is-missing). Give manual setup steps **and** offer to help when possible (add `mcp.json` config on **add playwright mcp**, or `mcp_auth` if the server needs auth). Do not silently skip. Do not edit `mcp.json` until they agree. 7. Write `.cursor/lp-preflight-state/{slug}.json` ([state schema](reference-checks.md#state-file-schema)). -### Checkpoint +### Checkpoint (MCP ready) -> **Phase 0 complete** - `{path_dir}` on `{branch}` @ `{short_sha}`. +> **Phase 0 complete** - `{path_dir}` on `{branch}` @ `{short_sha}`. > > - Path: `{path_dir}` ({M} milestones) > - Type: `{path_type}` -> - Playwright MCP: ready *(or blocked: see setup)* +> - Playwright MCP: ready > > **Your turn:** Reply **yes** if this looks right, or tell me what to change. > > **Up next:** Static pass (I won't edit your JSON unless you ask later). +### Checkpoint (MCP blocked) + +Use the blocked shape in [author-testing.md](author-testing.md#if-playwright-mcp-is-missing). Still report path / type. **Your turn** must include the **add playwright mcp** offer (or auth offer) plus manual Settings steps. After they reload and MCP is ready, re-run the verify step and use the MCP-ready checkpoint. + --- ## Phase 1: Static pass diff --git a/.cursor/skills/preflight-learning-path/author-testing.md b/.cursor/skills/preflight-learning-path/author-testing.md index a7f5507e2..92f9569a3 100644 --- a/.cursor/skills/preflight-learning-path/author-testing.md +++ b/.cursor/skills/preflight-learning-path/author-testing.md @@ -13,7 +13,7 @@ Confirm at Phase 0 / remind in the slash-command first message. | Need | Required when | Why | How to verify / fix | |---|---|---|---| | `interactive-tutorials` checkout with `{slug}-lj/` | Always | Package under test | Path on disk / current branch | -| **Playwright MCP** enabled (`user-playwright`) | Live path (default for new/conversion interactive) | Agent DOM checks | Phase 0: list or call Playwright MCP tools. If missing: enable Playwright MCP in Cursor settings, then re-run | +| **Playwright MCP** enabled (`user-playwright`) | Live path (default for new/conversion interactive) | Agent DOM checks | Phase 0: list or call Playwright MCP tools. If missing: follow [If Playwright MCP is missing](#if-playwright-mcp-is-missing) | | Okta login in the **Playwright** browser to `{learn_host}` (default `learn.grafana.net`) | Before Playwright DOM loop | MCP cannot complete SAML alone | Phase 2: author logs in, replies `ready` | | Pathfinder Block Editor on learn | Only if author chooses `walk-me` | Optional smoke coaching | `{learn_host}/plugins/grafana-pathfinder-app?dev=true` → **?** → Debug → Block Editor → import local JSON | | Pathfinder CLI (`grafana-pathfinder-app` built locally) | Nice-to-have | `validate --packages` | Note if missing; do not abort preflight | @@ -24,7 +24,41 @@ Same Playwright + Okta role as [learning-path-workflows/workflows.md](../../lear ### If Playwright MCP is missing -Stop at Phase 0 (or before Phase 2) with friendly setup help. Do **not** silently skip DOM checks on new/conversion interactive paths. `static-only: ` only when [static-only rules](reference-checks.md#static-only-preflight) allow it. +Stop at Phase 0 (or before Phase 2). Do **not** silently skip DOM checks on new/conversion interactive paths. `static-only: ` only when [static-only rules](reference-checks.md#static-only-preflight) allow it. + +Diagnose which case applies, then offer help (manual steps always; agent action when possible): + +| Case | How you can tell | Offer | +|---|---|---| +| **Config missing** from `~/.cursor/mcp.json` (no `playwright` / `@playwright/mcp` entry) | Read `mcp.json`; server absent | Ask: **Want me to add the Playwright MCP config for you?** If yes, merge the block below into `mcp.json` (create the file if needed). Then ask them to reload MCP servers (Cursor Settings → MCP → refresh/reload, or restart the agent) and reply **ready** / **yes** so you recheck. | +| **Needs auth** (`needsAuth` / only `mcp_auth` tool) | `GetMcpTools` / server status | Ask: **Want me to start the Playwright MCP connect flow?** If yes, call `mcp_auth` for `user-playwright` (empty args), wait, recheck. | +| **Configured but toggled off** in Cursor Settings | Entry exists in `mcp.json`; tools still unavailable | Manual only: Settings → MCP → enable **Playwright**. Agent cannot flip that toggle. | +| **Errored / won't start** | Tools missing; logs or STATUS show install/runtime errors | Diagnose (`npx`, Node, network). Offer config fixes; author confirms reload. | + +Standard config to add when missing (do not overwrite unrelated servers): + +```json +{ + "mcpServers": { + "playwright": { + "command": "npx", + "args": ["@playwright/mcp@latest"] + } + } +} +``` + +**Blocked checkpoint shape (author-facing):** + +> Playwright MCP isn't available, so I can't run the live DOM checks on this path. +> +> **Manual setup:** Cursor Settings → MCP → enable **Playwright** (or add it if it's not listed), then reload. +> +> **Or:** reply **add playwright mcp** and I'll add the standard config to `~/.cursor/mcp.json` for you (you'll still need to reload MCP afterward). +> +> `static-only` isn't a fit for new/conversion interactive paths. + +Never edit `mcp.json` until the author agrees. Never claim MCP is ready until `GetMcpTools` for `user-playwright` shows usable browser tools. --- From 74df1c8787534e112fb32a3476971b1faf892435 Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Tue, 21 Jul 2026 14:32:22 -0700 Subject: [PATCH 3/9] Add adversarial claim-check to preflight Phase 1. Catch contradicted, unsupported, and overstated product facts against live docs before authors open a PR. --- .cursor/commands/preflight-learning-path.md | 2 +- .../skills/preflight-learning-path/SKILL.md | 31 +++-- .../preflight-learning-path/claim-check.md | 120 ++++++++++++++++++ .../reference-checks.md | 3 + 4 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 .cursor/skills/preflight-learning-path/claim-check.md diff --git a/.cursor/commands/preflight-learning-path.md b/.cursor/commands/preflight-learning-path.md index 4161b7104..d92c2e991 100644 --- a/.cursor/commands/preflight-learning-path.md +++ b/.cursor/commands/preflight-learning-path.md @@ -22,7 +22,7 @@ LP packages are **single-repo** (`interactive-tutorials` only). Metadata lives i > | Phase | What happens | > |---|---| > | 0 | Identify your `{slug}-lj/` package + confirm Playwright MCP | -> | 1 | Static pass (audit + path / Learning Hub checks). Only real review-level issues | +> | 1 | Static pass (audit + path / Learning Hub + claim-check). Only real review-level issues and contradicted/unsupported product facts | > | 2 | Playwright DOM checks. Block Editor smoke is optional | > | 3 | Readiness report + offer to fix | > | 4 | Optional package fixes | diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index 63322fe18..a2d7c6afa 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -3,8 +3,9 @@ name: preflight-learning-path description: >- Guide a learning path author through pre-PR self-review in interactive-tutorials. Mirrors the five-phase /review-learning-path-pr coach from the author side: static - pass, Playwright DOM checks, readiness report, optional package fixes, and optional - frontend data-testid PR. Use when the user runs /preflight-learning-path. + pass (including adversarial claim-check), Playwright DOM checks, readiness report, + optional package fixes, and optional frontend data-testid PR. Use when the user + runs /preflight-learning-path. --- # Preflight learning path (author self-review) @@ -21,7 +22,7 @@ Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the **Skill memory:** State lives in `.cursor/lp-preflight-state/` (gitignored). Phase 1 dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/`. See [Commit safety](#commit-safety). -**Routing:** [reference-checks.md](reference-checks.md) · [author-testing.md](author-testing.md) · [frontend-selector-pr.md](frontend-selector-pr.md) · shared [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) · shared [review reference-checks](../review-learning-path/reference-checks.md) +**Routing:** [reference-checks.md](reference-checks.md) · [claim-check.md](claim-check.md) · [author-testing.md](author-testing.md) · [frontend-selector-pr.md](frontend-selector-pr.md) · shared [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) · shared [review reference-checks](../review-learning-path/reference-checks.md) **Related:** [audit-guide](../audit-guide/SKILL.md) · [update-guide](../update-guide/SKILL.md) · [review-learning-path](../review-learning-path/SKILL.md) @@ -31,7 +32,7 @@ Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the | You (agent) | Author (human) | |---|---| -| Confirm path, run audit + path/LH checks | Confirm `{path_dir}`, reply at checkpoints | +| Confirm path, run audit + path/LH + claim-check | Confirm `{path_dir}`, reply at checkpoints | | Surface **post-inline-only** findings in chat | Decide whether to fix now or open PR with notes | | Required Playwright DOM check (live path) | Okta login in Playwright browser; reply `ready` | | Optional Block Editor coaching | `already-tested` / `walk-me` / `skip-smoke` | @@ -47,7 +48,7 @@ Input (path_dir or current branch) │ ├─ Phase 0: Identify path ───── path_dir, path_type, Playwright MCP prereq │ - ├─ Phase 1: Static pass ─────── audit + path/LH checks → author findings (post-inline only) + ├─ Phase 1: Static pass ─────── audit + path/LH + claim-check → author findings (post-inline only) │ ├─ Phase 2: Live test ───────── Playwright DOM required; Block Editor opt-in │ (skipped when static-only) @@ -93,7 +94,7 @@ Same snapshot/cleanup rules as [review-learning-path § Commit safety](../review | Artifact | Where | Mitigation | |---|---|---| -| Findings, readiness, state JSON | `.cursor/lp-preflight-state/` | `.gitignore` | +| Findings, claim-check, readiness, state JSON | `.cursor/lp-preflight-state/` | `.gitignore` | | audit-guide reports | `{milestone}/assets/` | Snapshot before Phase 1; delete new files before Phase 1 checkpoint | | Pre-existing package `assets/` | Author/migrate notes | Never delete paths listed in `pre_review_assets` | @@ -181,15 +182,15 @@ Use the blocked shape in [author-testing.md](author-testing.md#if-playwright-mcp ## Phase 1: Static pass -**Goal:** Audit every milestone + path consistency + Learning Hub. Surface **post-inline** findings only in chat. +**Goal:** Audit every milestone + path consistency + Learning Hub + adversarial claim-check. Surface **post-inline** findings only in chat. -Combines review Phase 1 checks. Author sees findings in chat (not a private workbook dump of nits). +Combines review Phase 1 checks plus [claim-check.md](claim-check.md). Author sees findings in chat (not a private workbook dump of nits). ### Tell the author > **Phase 1 - Static pass** > -> I'm reading each milestone and checking manifests, `website.yaml`, and Learning Hub structure. I'll only call out things a reviewer would comment on. +> I'm reading each milestone, checking manifests, `website.yaml`, and Learning Hub structure, then fact-checking product claims against live docs. I'll only call out things a reviewer would comment on (plus contradicted or unsupported product facts). ### Agent steps @@ -197,19 +198,21 @@ Combines review Phase 1 checks. Author sees findings in chat (not a private work 2. Walk shared [review reference-checks](../review-learning-path/reference-checks.md) + [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md). 3. **Always scan** for framing-in-milestones, [section intro markdown that may number as a step](../review-learning-path/reference-checks.md#section-intro-markdown-numbered-as-step), and [false noops](../review-learning-path/reference-checks.md#noop-and-non-interactive-steps). 4. Run Pathfinder CLI `validate --packages {path_dir}` if available. -5. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing). Keep only **post inline** for author chat. Drop Internal/Discard entirely from chat. -6. Write `{slug}-findings.md` under `.cursor/lp-preflight-state/` (post-inline list + optional verify-live notes for Phase 2). Resume aid only; chat stays tiny. -7. Mandatory audit cleanup; verify `git status`. -8. Do not cite rule numbers or audit severity labels in chat. +5. Run the [claim-check](claim-check.md) pass across path root + all milestone prose. Write `{slug}-claim-check.md` under `.cursor/lp-preflight-state/`. Route Contradicted / Unsupported / Overstated as **Fix before PR**. Do not edit package JSON here. +6. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing) plus claim-check MUST FIX. Keep only **post inline** for author chat. Drop Internal/Discard entirely from chat. +7. Write `{slug}-findings.md` under `.cursor/lp-preflight-state/` (post-inline list + optional verify-live notes for Phase 2). Resume aid only; chat stays tiny. +8. Mandatory audit cleanup; verify `git status`. +9. Do not cite rule numbers or audit severity labels in chat. ### Checkpoint > **Phase 1 complete** - static pass done. > > - {One plain sentence: clean, or a few things to fix} -> - **Fix before PR** (≤3 bullets, plain language; omit if none): +> - **Fix before PR** (≤3 bullets, plain language; omit if none; include claim-check MUST FIX when present): > - {e.g. first hands-on still depends on business-value} > - {e.g. "You'll…" intros inside sections in create-dashboard} +> - {e.g. claim check: contradicted alert count in business-value} > > **Your turn:** Reply **yes** and your test stack (for example `learn.grafana.net shared`, `fresh Cloud stack`). > diff --git a/.cursor/skills/preflight-learning-path/claim-check.md b/.cursor/skills/preflight-learning-path/claim-check.md new file mode 100644 index 000000000..af6a835f7 --- /dev/null +++ b/.cursor/skills/preflight-learning-path/claim-check.md @@ -0,0 +1,120 @@ +# Claim check (preflight) + +Adversarial factual check for Pathfinder learning path packages. Adapted from the Learning Hub claim-check skill (`learning-hub-claim-check`) and the MUST FIX bar in journey audit reports (for example intro-db-olly). Goal: catch AI-invented product facts before a PR, not Hugo slide structure. + +Run inside [preflight Phase 1](SKILL.md#phase-1-static-pass) after audit-guide and path/LH checks, before the Phase 1 checkpoint. + +**Independence:** Prefer a fresh agent pass that did not author the package prose. Default stance: unproven. A claim is flagged unless a source plainly supports it. + +--- + +## Scope (path package) + +Read all prose that learners see: + +- Path root `content.json` markdown blocks +- Every milestone `content.json` markdown (including framing dirs not in path `milestones`, if present) +- Interactive step `content` / tooltips that state product facts (skip pure click instructions) +- Path and milestone `website.yaml` `description` / CTA copy when it asserts product behavior + +Skip: pure navigation instructions ("Click **Save**"), structural Pathfinder rules, and restatements of UI chrome with no product claim. + +Website repo (when in workspace) is **read-only** for sources (`content/docs/...`). Do not require a companion website PR. + +--- + +## What counts as a claim + +Falsifiable statements about the product, including: + +- What a feature does or does not do +- Feature / product / alert / dashboard names +- Versions, defaults, limits, prerequisites, platform availability +- Absolutes and quantifiers (only, never, all, every, must, N dashboards, N alerts) +- Comparisons that rank or prescribe one Grafana capability over another + +### Not claims + +- "In this milestone you will…" framing +- UI click paths without a product assertion +- Learning Hub boilerplate that matches standards verbatim + +--- + +## Procedure + +1. Extract claims (batch by milestone; include path root). +2. For each claim, find a source: local `website` docs first, then WebFetch to live grafana.com docs. No source → **Unsupported**. +3. Open the source; quote the supporting or contradicting line. +4. Verdict (see below). Sweep phrase + category across the whole package so the same error is one finding with multiple locations. +5. Write `.cursor/lp-preflight-state/{slug}-claim-check.md` (gitignored). + +Do not edit package JSON during the claim check. Fixes wait for Phase 4 if the author asks. + +--- + +## Verdicts + +| Verdict | Meaning | Preflight routing | +|---|---|---| +| **Supported** | Source plainly states the claim | Hide (optional Supported list in the report only) | +| **Contradicted** | Source says something different | **Fix before PR** (post-inline) | +| **Unsupported** | No source, or source does not address it | **Fix before PR** (post-inline) | +| **Overstated** | Source supports a weaker version; claim adds absolute/superlative/framing | **Fix before PR** (post-inline) | +| **Author decides** | Product-truth call a human must make | Surface in readiness as open question; do not auto-edit | + +Only Contradicted / Unsupported / Overstated count toward the Phase 1 "Fix before PR" list (dedupe by root cause). Soft style nits stay out of chat. + +--- + +## Catches that matter (linter cannot) + +Same five classes as Learning Hub claim-check: + +1. Made-up facts +2. Invented terms / alert names / dashboard names +3. Overstatements (counts, "zero impact", "most/all/every") +4. Competitive or prescriptive framing without a source +5. Pre-GA / preview features taught as GA + +--- + +## Report format + +Write `.cursor/lp-preflight-state/{slug}-claim-check.md`: + +```markdown +--- +disclaimer: Auto-generated by preflight-learning-path claim-check. Do not edit manually. +path_dir: {path_dir} +--- + +# Claim check: {path_dir} + +**Claims checked: N | Supported: N | Contradicted: N | Unsupported: N | Overstated: N** + +## MUST FIX (Fix before PR) + +### Contradicted +1. `{file}` — {claim}. Source: {quote or URL}. Fix: {one line}. + +### Unsupported +… + +### Overstated +… + +## Author decides +… + +## Sources used +… +``` + +Mirror the ranking style of journey audit reports: MUST FIX first, then author-decides. Do not dump Supported claims into author chat. + +--- + +## Phase 1 chat + +After claim-check, merge MUST FIX items into the Phase 1 Fix-before-PR bullets (still ≤3 in chat; point to the full claim-check file for the rest). If none, say the claim check found no contradicted or unsupported product facts. diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md index e8d773cf6..a53da43ad 100644 --- a/.cursor/skills/preflight-learning-path/reference-checks.md +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -34,6 +34,7 @@ Apply the same five-phase coach rules (cite shared reference-checks; do not soft - Path root / manifest `id` mismatch; Pathfinder CLI validate failure - Secrets `doIt: true`; confirmed 404s; conversion prose only in legacy markdown - Fragile / wrong selectors when live fails, or stable `data-testid` exists in DOM and the guide uses a weak selector +- **Claim-check MUST FIX:** Contradicted, Unsupported, or Overstated product facts per [claim-check.md](claim-check.md) (made-up counts, invented names, docs contradictions) ### Never surface @@ -58,6 +59,8 @@ Apply every section from [../review-learning-path/reference-checks.md](../review - noop and non-interactive steps - CODEOWNERS (discard for author chat) +Then run [claim-check.md](claim-check.md) across path root + milestone prose. Route Contradicted / Unsupported / Overstated as Fix before PR. Hide Supported from chat. Author-decides items may appear in readiness as open questions. + Tag each finding; keep only post-inline for author-facing output. --- From 96f1deecc68f259214d33e376f193c2be22b28ea Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Wed, 22 Jul 2026 09:44:49 -0700 Subject: [PATCH 4/9] Make preflight Phase 3 findings clearer for authors. Drop the check primer, show what was checked, and offer fix all / fix N choices with plain-language context. --- .../skills/preflight-learning-path/SKILL.md | 73 +++++++++++++------ .../preflight-learning-path/claim-check.md | 8 +- .../frontend-selector-pr.md | 2 +- .../reference-checks.md | 21 +++++- 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index a2d7c6afa..86c9d5149 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -36,7 +36,7 @@ Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the | Surface **post-inline-only** findings in chat | Decide whether to fix now or open PR with notes | | Required Playwright DOM check (live path) | Okta login in Playwright browser; reply `ready` | | Optional Block Editor coaching | `already-tested` / `walk-me` / `skip-smoke` | -| Apply package fixes only when asked | Reply `fix` (or name findings) | +| Apply package fixes only when asked | Reply `fix all`, `fix N`, or a combo like `fix 1,3` | | Walk frontend testid PR when needed | Approve push / PR create | --- @@ -119,14 +119,17 @@ Re-verify commit safety after Phase 1 before Phase 2. | Section | Content | |---|---| -| **Header** | `Phase {n} complete` + one-line outcome | -| **Summary** | Up to 3 plain-language bullets. Post-inline only. No rule counts. | -| **Your turn** | Exactly one action | -| **Up next** | One sentence | +| **Header** | `Phase {n}` + short plain outcome (avoid jargon like "post-inline") | +| **What we checked** | Phase 3 (and readiness-style summaries): where findings came from, in plain language | +| **Findings** | Numbered list with enough context to act (what is wrong, why it matters, which file). No rule counts. | +| **Your turn** | Clear reply choices (including **fix all** / **fix N** when findings exist) | +| **Up next** | One sentence when useful | -**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix` · `frontend` · `done` · `resume` / `start fresh` +Do **not** open Phase 3 with a "What this check is" primer. Lead with the outcome, then **What we checked**, then the numbered findings. -**Tone:** Casual and friendly. Address the author as **you**. Celebrate clean passes. No rule numbers, no Blocker/nit labels, no em dashes. +**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` (any combo) · `frontend` · `done` · `resume` / `start fresh` + +**Tone:** Casual and friendly. Address the author as **you**. Celebrate clean passes. No rule numbers, no Blocker/nit labels, no em dashes. Prefer everyday words over skill jargon (say "copy fixes" not "post-inline"; say "product claims vs docs" not "claim-check MUST FIX"). --- @@ -293,48 +296,74 @@ After Playwright: ## Phase 3: Readiness -**Goal:** Merge static + live into a readiness outcome; offer fixes. +**Goal:** Merge static + live into a readiness outcome; offer numbered fix choices. + +Author chat shape: [Author-facing findings](reference-checks.md#author-facing-findings). ### Agent steps 1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) and promote only post-inline items. 2. Apply [readiness gate](reference-checks.md#readiness-gate). 3. Write `{slug}-readiness.md` with outcome + [PR opener checklist](reference-checks.md#pr-opener-checklist). -4. In chat: numbered list of open post-inline findings (file path + short human fix ask). Zero findings is first-class. -5. Offer next steps casually: `fix`, `frontend` (missing stable selector), or `done`. +4. In chat: follow the Phase 3 checkpoint template below. Number every open finding. Zero findings is first-class (skip the fix list and celebrate). +5. Map replies: `fix all` / `fix N` / `fix 1,3` → Phase 4; `frontend` → Phase 5; `show report` → paste or link readiness path; `done` → end with PR-opener notes. -### Checkpoint +### Checkpoint (when there are findings) -> **Phase 3 complete - {readiness outcome}** +Use a friendly outcome line (examples: "almost ready, with N copy fixes first" for Fix then re-preflight; "ready for PR" or "open PR with notes" when that is the gate). Do **not** say only the raw gate label with no context. + +> **Phase 3 - {friendly outcome}** +> +> **What we checked** +> - {e.g. Written product claims against live docs} +> - {e.g. Whether UI selectors exist on learn.grafana.net (shared stack)} +> - {e.g. Block Editor smoke: skipped / already-tested / walked} > -> - [2–4 bullets: gate status, live summary, top remaining items] -> - Report: `.cursor/lp-preflight-state/{slug}-readiness.md` +> **Please fix these {N}** ({short kind, e.g. product-fact issues in learner copy}) > -> **Fix before PR:** -> 1. `{file}` - {short ask} +> 1. {Plain problem}. {Why / better wording}. +> (`{file or dirs}`) > 2. … > -> *(or: Nothing you'd get a review comment for. Nice work.)* +> **Your turn** +> - **fix all** — I'll update all of them +> - **fix 1** / **fix 2** / **fix 3** — only that item +> - **fix 1,3** — any combo by number +> - **done** — open a PR and leave these for review +> - **show report** — longer write-up +> - **frontend** — only if we need an upstream `data-testid` (omit if not relevant) +> +> **Heads-up** *(optional, only when useful)* +> {Stack or testing note, e.g. provisioned data source is read-only} + +### Checkpoint (when clean) + +> **Phase 3 - {Ready for PR | Open PR with notes}** +> +> **What we checked** +> - … +> +> Nothing here that would draw a review comment on copy or selectors. Nice work. > -> **Your turn:** Reply **show report**, **fix** (package edits), **frontend** (upstream testid PR), or **done** if you're opening the PR. +> **Your turn:** Reply **done** if you're opening the PR, **show report** for the write-up, or **frontend** if you still need an upstream testid. > -> **Up next:** Optional fixes, or you're clear to open a PR. +> *(If Open PR with notes: say why in one line, e.g. Block Editor smoke was skipped.)* --- ## Phase 4: Apply package fixes (optional) -**Goal:** Author-requested surgical edits. +**Goal:** Author-requested surgical edits (`fix all` / `fix N` / numbered combos from Phase 3). ### Tell the author > **Phase 4 - Apply fixes** > -> Tell me which findings to fix (or say **fix all**). I'll edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). +> Working on {fix all | item N | items …}. I'll edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). ### Agent steps -1. Apply only requested findings. +1. Apply only the numbered findings the author requested. 2. Re-run Pathfinder CLI validate if content/manifests changed. 3. Suggest re-running Phase 2 Playwright for touched interactive milestones. 4. Do not commit unless the author explicitly asks. diff --git a/.cursor/skills/preflight-learning-path/claim-check.md b/.cursor/skills/preflight-learning-path/claim-check.md index af6a835f7..2b9d6465b 100644 --- a/.cursor/skills/preflight-learning-path/claim-check.md +++ b/.cursor/skills/preflight-learning-path/claim-check.md @@ -115,6 +115,10 @@ Mirror the ranking style of journey audit reports: MUST FIX first, then author-d --- -## Phase 1 chat +## Phase 1 / Phase 3 chat -After claim-check, merge MUST FIX items into the Phase 1 Fix-before-PR bullets (still ≤3 in chat; point to the full claim-check file for the rest). If none, say the claim check found no contradicted or unsupported product facts. +After claim-check, merge MUST FIX items into author findings (dedupe; ≤3 in Phase 1 chat). Use plain language (problem + why + file), not verdict labels like "Contradicted" in the author bullets. + +At **Phase 3**, list them as numbered items and offer **fix all** / **fix N** / combos per [Author-facing findings](reference-checks.md#author-facing-findings). Do not open with a "What this check is" primer. + +If none, say the claim check found no contradicted or unsupported product facts. diff --git a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md index 21cec2655..d3fa381a0 100644 --- a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md +++ b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md @@ -21,7 +21,7 @@ Trigger when Phase 2 shows a step needs a durable selector and: - No `data-testid` / strong semantic attribute exists in the DOM, and - The author wants an upstream fix (not only a justified `:contains()` fallback), and -- They reply **`frontend`** at Phase 3 (or ask during Phase 4) +- They reply **`frontend`** at Phase 3 (alongside **fix all** / **fix N** choices) or ask during Phase 4 If live passed with a justified `:contains()` and no stable selector exists, that stays Internal in review terms. Offer Phase 5 as an optional improvement, not a Fix-before-PR demand, unless Playwright/walk-me failed on that step. diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md index a53da43ad..9186fda47 100644 --- a/.cursor/skills/preflight-learning-path/reference-checks.md +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -6,7 +6,26 @@ Author-side routing and readiness for [preflight-learning-path/SKILL.md](SKILL.m **Publishing model (PR [#416](https://github.com/grafana/interactive-tutorials/pull/416)):** Single-repo packages in `interactive-tutorials`. Metadata in package `website.yaml`; prose in `content.json`. Website repo is read-only for conversion. Never plan companion website / `pathfinder_data` / shortcode work. -**Voice bar:** Same as review [comment-style.md](../review-learning-path/comment-style.md). Author chat and readiness only include **post inline** items. No em dashes. +**Voice bar:** Same as review [comment-style.md](../review-learning-path/comment-style.md). Author chat and readiness only include **post inline** items. No em dashes. Prefer everyday words in chat (see [Author-facing findings](#author-facing-findings)). + +--- + +## Author-facing findings + +Use this shape whenever you list Fix-before-PR items in chat (especially Phase 3). Do **not** open with a "What this check is" primer. + +1. **Friendly outcome line** (e.g. "almost ready, with 3 copy fixes first"). You may mention the gate label in the readiness file; chat can stay friendlier. +2. **What we checked** — short bullets naming the sources of truth in plain language (product claims vs docs, UI selectors on `{stack}`, Block Editor smoke choice). +3. **Numbered findings** — each item: plain problem, why it matters or better wording, then the file/dir in parentheses. Enough context that the author can decide without opening the skill. +4. **Your turn** — always offer: + - **fix all** + - **fix N** (and combos like **fix 1,3**) + - **done** (open PR / leave for review) + - **show report** + - **frontend** only when relevant +5. **Heads-up** — optional stack/testing notes (already-installed plugins, read-only provisioned sources, etc.). + +Keep Phase 1 lighter (short Fix-before-PR bullets + stack ask). Put the full numbered + fix-choice treatment at Phase 3 after live results land. --- From c59c66d2c5fcd4414dbb62b7514c97cb6697b5dd Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Wed, 22 Jul 2026 09:59:48 -0700 Subject: [PATCH 5/9] Fold Block Editor watch-fors into one line during walk-me. Keep fake step numbers in a short checklist instead of a separate setup step. --- .cursor/skills/preflight-learning-path/SKILL.md | 2 +- .../skills/preflight-learning-path/author-testing.md | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index 86c9d5149..fdba12b3c 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -278,7 +278,7 @@ After Playwright: | Reply | Behavior | Readiness | |---|---|---| | `already-tested: …` | Store dogfood evidence; no per-milestone loop | Can still be **Ready for PR** if Playwright clean and no post-inline blockers | -| `walk-me` | Guided loop: local import, `pass` / `fail step N` / `N/A`; ask about false step numbers | Same when scoped milestones pass or documented N/A | +| `walk-me` | Guided loop: local import, `pass` / `fail step N` / `N/A`; fold false-step checks into the short watch-for line | Same when scoped milestones pass or documented N/A | | `skip-smoke` | Continue | Cap at **Open PR with notes**; say Block Editor was not recorded | ### Checkpoint diff --git a/.cursor/skills/preflight-learning-path/author-testing.md b/.cursor/skills/preflight-learning-path/author-testing.md index 92f9569a3..e62df0dbf 100644 --- a/.cursor/skills/preflight-learning-path/author-testing.md +++ b/.cursor/skills/preflight-learning-path/author-testing.md @@ -117,11 +117,15 @@ For each scoped milestone: > **Milestone {i} of {M}: `{milestone-id}`** > -> Import the local `content.json`, open `{derived_start_url}`, run Show me / Do it. +> 1. Import the local `content.json` +> 2. Open `{derived_start_url}` +> 3. Run every **Show me** and **Do it** > -> Also glance at the section step list for false step numbers (intro prose as step 1, or learner-action noops). +> **While you run it, watch for:** wrong highlights, Do it that no-ops or errors, steps that never unlock, and fake step numbers (intro prose or "You'll…" lines counted as steps). > -> **Your turn:** Reply **pass**, **fail step N - ** *what happened*, or **N/A - ** *reason*. +> **Your turn:** Reply **pass**, **fail step N -** *what happened*, or **N/A -** *reason*. + +Do **not** give the fake-step-number glance its own numbered setup step. Keep it inside the short **While you run it, watch for** line. Record in state `pathfinder.{milestone-slug}`. From 7915368154006affcc134520e8105bb745cfc6bf Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Wed, 22 Jul 2026 15:08:40 -0700 Subject: [PATCH 6/9] Route missing-selector findings to frontend, not fix N. Only offer package fix choices when a guide edit can resolve the item; lead with frontend when live needs an upstream testid. --- .../skills/preflight-learning-path/SKILL.md | 34 +++++++++++-------- .../frontend-selector-pr.md | 6 ++-- .../reference-checks.md | 20 +++++++---- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index fdba12b3c..8070b458f 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -127,7 +127,7 @@ Re-verify commit safety after Phase 1 before Phase 2. Do **not** open Phase 3 with a "What this check is" primer. Lead with the outcome, then **What we checked**, then the numbered findings. -**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` (any combo) · `frontend` · `done` · `resume` / `start fresh` +**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` (package-fixable only) · `frontend` (needs-frontend / upstream testid) · `done` · `resume` / `start fresh` **Tone:** Casual and friendly. Address the author as **you**. Celebrate clean passes. No rule numbers, no Blocker/nit labels, no em dashes. Prefer everyday words over skill jargon (say "copy fixes" not "post-inline"; say "product claims vs docs" not "claim-check MUST FIX"). @@ -296,17 +296,17 @@ After Playwright: ## Phase 3: Readiness -**Goal:** Merge static + live into a readiness outcome; offer numbered fix choices. +**Goal:** Merge static + live into a readiness outcome; offer the right next action per finding kind. -Author chat shape: [Author-facing findings](reference-checks.md#author-facing-findings). +Author chat shape: [Author-facing findings](reference-checks.md#author-facing-findings) (package-fixable vs needs-frontend). ### Agent steps 1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) and promote only post-inline items. 2. Apply [readiness gate](reference-checks.md#readiness-gate). 3. Write `{slug}-readiness.md` with outcome + [PR opener checklist](reference-checks.md#pr-opener-checklist). -4. In chat: follow the Phase 3 checkpoint template below. Number every open finding. Zero findings is first-class (skip the fix list and celebrate). -5. Map replies: `fix all` / `fix N` / `fix 1,3` → Phase 4; `frontend` → Phase 5; `show report` → paste or link readiness path; `done` → end with PR-opener notes. +4. In chat: follow the Phase 3 checkpoint template below. Number every open finding. Mark each as package-fixable or needs-frontend. Zero findings is first-class (skip the fix list and celebrate). +5. Map replies: `fix all` / `fix N` / combos → Phase 4 **only for package-fixable items**; `frontend` → Phase 5 for needs-frontend items; `show report` → readiness path; `done` → end with PR-opener notes. If the author says **fix N** on a needs-frontend item, clarify that a guide edit alone will not add a `data-testid` and re-offer **frontend** (or a clearly labeled temporary selector workaround if they insist). ### Checkpoint (when there are findings) @@ -319,22 +319,24 @@ Use a friendly outcome line (examples: "almost ready, with N copy fixes first" f > - {e.g. Whether UI selectors exist on learn.grafana.net (shared stack)} > - {e.g. Block Editor smoke: skipped / already-tested / walked} > -> **Please fix these {N}** ({short kind, e.g. product-fact issues in learner copy}) +> **Please fix these {N}** ({short kind}) > > 1. {Plain problem}. {Why / better wording}. > (`{file or dirs}`) > 2. … > -> **Your turn** -> - **fix all** — I'll update all of them -> - **fix 1** / **fix 2** / **fix 3** — only that item -> - **fix 1,3** — any combo by number +> **Your turn** *(include only the lines that apply)* +> - **fix all** / **fix N** / **fix 1,3** — package edits for copy or guide JSON that we can fix here +> - **frontend** — upstream `data-testid` for item(s) {N} (live miss; no durable selector in the DOM) > - **done** — open a PR and leave these for review > - **show report** — longer write-up -> - **frontend** — only if we need an upstream `data-testid` (omit if not relevant) > > **Heads-up** *(optional, only when useful)* -> {Stack or testing note, e.g. provisioned data source is read-only} +> {Stack or testing note} + +When **every** open item needs-frontend, omit **fix all** / **fix N**. Lead **Your turn** with **frontend**. + +When the list mixes kinds, say which numbers **fix** covers vs **frontend** (see [Author-facing findings](reference-checks.md#author-facing-findings)). ### Checkpoint (when clean) @@ -345,15 +347,17 @@ Use a friendly outcome line (examples: "almost ready, with N copy fixes first" f > > Nothing here that would draw a review comment on copy or selectors. Nice work. > -> **Your turn:** Reply **done** if you're opening the PR, **show report** for the write-up, or **frontend** if you still need an upstream testid. +> **Your turn:** Reply **done** if you're opening the PR, or **show report** for the write-up. > > *(If Open PR with notes: say why in one line, e.g. Block Editor smoke was skipped.)* +> +> *(Optional **frontend** only if you want a proactive testid improvement when live already passed with a weak-but-working selector.)* --- ## Phase 4: Apply package fixes (optional) -**Goal:** Author-requested surgical edits (`fix all` / `fix N` / numbered combos from Phase 3). +**Goal:** Author-requested surgical edits (`fix all` / `fix N` / numbered combos) for **package-fixable** findings only. ### Tell the author @@ -363,7 +367,7 @@ Use a friendly outcome line (examples: "almost ready, with N copy fixes first" f ### Agent steps -1. Apply only the numbered findings the author requested. +1. Apply only the numbered **package-fixable** findings the author requested. Do not pretend a guide `reftarget` tweak solves a needs-frontend gap unless they explicitly asked for a temporary workaround. 2. Re-run Pathfinder CLI validate if content/manifests changed. 3. Suggest re-running Phase 2 Playwright for touched interactive milestones. 4. Do not commit unless the author explicitly asks. diff --git a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md index d3fa381a0..0f6eadb05 100644 --- a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md +++ b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md @@ -20,8 +20,10 @@ Do not paste the whole #1795 diff. Link it and mirror the pattern. Trigger when Phase 2 shows a step needs a durable selector and: - No `data-testid` / strong semantic attribute exists in the DOM, and -- The author wants an upstream fix (not only a justified `:contains()` fallback), and -- They reply **`frontend`** at Phase 3 (alongside **fix all** / **fix N** choices) or ask during Phase 4 +- Live Playwright or walk-me failed on that step (or the author wants a proactive testid anyway), and +- They reply **`frontend`** at Phase 3 or ask during Phase 4 + +At Phase 3, treat this as a **needs-frontend** finding: lead with **frontend**, not **fix N**. A package-only `reftarget` tweak is not the real fix. Only offer a temporary weak selector in the guide if the author explicitly asks, and label it as brittle. If live passed with a justified `:contains()` and no stable selector exists, that stays Internal in review terms. Offer Phase 5 as an optional improvement, not a Fix-before-PR demand, unless Playwright/walk-me failed on that step. diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md index 9186fda47..04407b9de 100644 --- a/.cursor/skills/preflight-learning-path/reference-checks.md +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -16,15 +16,23 @@ Use this shape whenever you list Fix-before-PR items in chat (especially Phase 3 1. **Friendly outcome line** (e.g. "almost ready, with 3 copy fixes first"). You may mention the gate label in the readiness file; chat can stay friendlier. 2. **What we checked** — short bullets naming the sources of truth in plain language (product claims vs docs, UI selectors on `{stack}`, Block Editor smoke choice). -3. **Numbered findings** — each item: plain problem, why it matters or better wording, then the file/dir in parentheses. Enough context that the author can decide without opening the skill. -4. **Your turn** — always offer: - - **fix all** - - **fix N** (and combos like **fix 1,3**) - - **done** (open PR / leave for review) +3. **Numbered findings** — each item: plain problem, why it matters or better wording, then the file/dir in parentheses. Enough context that the author can decide without opening the skill. Tag each item mentally as **package-fixable** or **needs-frontend** (see below). +4. **Your turn** — offer only actions that can resolve the open items: + - **fix all** / **fix N** / combos — only for **package-fixable** items (prose, manifest, `website.yaml`, guide `reftarget` when a better selector already exists in the DOM) + - **frontend** — when any open item **needs-frontend** (live failed; no durable `data-testid` / strong semantic selector in the DOM). Do **not** offer **fix N** for that item as if a guide edit alone is the real fix + - **done** — open PR / leave for review - **show report** - - **frontend** only when relevant 5. **Heads-up** — optional stack/testing notes (already-installed plugins, read-only provisioned sources, etc.). +### Package-fixable vs needs-frontend + +| Kind | Examples | Phase 3 offer | +|---|---|---| +| **Package-fixable** | Claim-check copy, framing/`depends`, fake in-section steps, false noops, wrong `reftarget` when a stable testid already exists in the DOM | **fix N** / **fix all** | +| **Needs-frontend** | Playwright or walk-me failed; element has no durable selector in the DOM | **frontend** (primary). Optional: clearly labeled **try temporary selector** only if the author asks for a brittle package workaround. Never present bare **fix N** as the main path for this kind | + +When the list mixes both kinds, number everything, but in **Your turn** say which numbers **fix** covers and that **frontend** covers the selector gap (e.g. "fix 2,3 for copy; **frontend** for item 1"). + Keep Phase 1 lighter (short Fix-before-PR bullets + stack ask). Put the full numbered + fix-choice treatment at Phase 3 after live results land. --- From 507f4e75fade9f42c663b2f576c1595631521034 Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Wed, 22 Jul 2026 15:18:48 -0700 Subject: [PATCH 7/9] Polish preflight skill voice and author-facing usability. Add a voice guide, plain-language phase copy, Phase 5 step checkpoints, and clearer fix vs frontend routing in chat. --- .cursor/commands/preflight-learning-path.md | 12 +- .../skills/preflight-learning-path/SKILL.md | 138 ++++++++++-------- .../preflight-learning-path/author-testing.md | 4 +- .../preflight-learning-path/claim-check.md | 24 ++- .../frontend-selector-pr.md | 53 ++++++- .../reference-checks.md | 10 +- 6 files changed, 153 insertions(+), 88 deletions(-) diff --git a/.cursor/commands/preflight-learning-path.md b/.cursor/commands/preflight-learning-path.md index d92c2e991..15968ce3d 100644 --- a/.cursor/commands/preflight-learning-path.md +++ b/.cursor/commands/preflight-learning-path.md @@ -21,12 +21,12 @@ LP packages are **single-repo** (`interactive-tutorials` only). Metadata lives i > > | Phase | What happens | > |---|---| -> | 0 | Identify your `{slug}-lj/` package + confirm Playwright MCP | -> | 1 | Static pass (audit + path / Learning Hub + claim-check). Only real review-level issues and contradicted/unsupported product facts | -> | 2 | Playwright DOM checks. Block Editor smoke is optional | -> | 3 | Readiness report + offer to fix | -> | 4 | Optional package fixes | -> | 5 | Optional frontend `data-testid` PR if a stable selector is missing | +> | 0 | Confirm your `{slug}-lj/` package and Playwright MCP | +> | 1 | Static pass: structure, Learning Hub, and product claims vs docs | +> | 2 | Playwright DOM checks (Block Editor smoke optional) | +> | 3 | Readiness summary and what to fix (if anything) | +> | 4 | Optional package edits | +> | 5 | Optional upstream `data-testid` PR if a stable selector is missing | > > **Setup:** Playwright MCP should be on. If it isn't, I'll offer to add the config for you (or walk you through Settings). You'll Okta-login in the Playwright browser for DOM checks. > diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index 8070b458f..848099039 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -10,13 +10,13 @@ description: >- # Preflight learning path (author self-review) -Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the five-phase [review-learning-path](../review-learning-path/SKILL.md) coach, from your side: static pass, Playwright DOM, readiness, then optional fixes. +Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the five-phase [review-learning-path](../review-learning-path/SKILL.md) coach, from the author side: static pass, live DOM checks, readiness, then optional fixes. -**Terminology:** Say **learning path** or **path** in messages; use `{path_dir}` in agent notes. +**Terminology:** Say **learning path** or **path** in author messages; use `{path_dir}` in agent notes. **Entry command:** [/preflight-learning-path](../../commands/preflight-learning-path.md) -**Mirror skill:** [review-learning-path](../review-learning-path/SKILL.md) (five-phase coach on main only). Do **not** use any outdated review skill phases or Always-inline routing. +**Mirror skill:** [review-learning-path](../review-learning-path/SKILL.md) (five-phase coach on main only). Do **not** use outdated review skill phases or Always-inline routing. **Do NOT read external reference files upfront.** Each phase loads its own references on demand. @@ -28,16 +28,34 @@ Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the --- +## Voice (author-facing) + +Write like a calm teammate helping someone ship, not like a linter report. + +| Do | Don't | +|---|---| +| Short sentences; plain words | Jargon in chat (`post-inline`, `MUST FIX`, rule numbers) | +| Say what is wrong, why it matters, which file | Dump severity labels or audit counts | +| Offer only actions that can resolve the item | Offer **fix N** when the real fix is upstream | +| Celebrate clean passes briefly | Hedge with "seems fine" / "maybe" | +| One checkpoint ask at a time | Batch phases or multiple asks | + +No em dashes in author chat, readiness text, or drafted PR bodies. Use periods, commas, or parentheses. + +Address the author as **you**. Prefer "copy fixes," "product claims vs docs," "UI selectors," "smoke test." + +--- + ## Human-in-the-loop contract | You (agent) | Author (human) | |---|---| -| Confirm path, run audit + path/LH + claim-check | Confirm `{path_dir}`, reply at checkpoints | -| Surface **post-inline-only** findings in chat | Decide whether to fix now or open PR with notes | -| Required Playwright DOM check (live path) | Okta login in Playwright browser; reply `ready` | +| Confirm path; run audit, path/LH checks, and claim-check | Confirm `{path_dir}`; reply at checkpoints | +| Surface only review-level findings in chat | Decide whether to fix now or open a PR with notes | +| Required Playwright DOM check (live path) | Okta login in the Playwright browser; reply `ready` | | Optional Block Editor coaching | `already-tested` / `walk-me` / `skip-smoke` | -| Apply package fixes only when asked | Reply `fix all`, `fix N`, or a combo like `fix 1,3` | -| Walk frontend testid PR when needed | Approve push / PR create | +| Apply package fixes only when asked | `fix all`, `fix N`, or a combo like `fix 1,3` (package-fixable only) | +| Walk frontend testid PR when needed | Reply `frontend`; approve push / PR create | --- @@ -46,14 +64,14 @@ Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the ``` Input (path_dir or current branch) │ - ├─ Phase 0: Identify path ───── path_dir, path_type, Playwright MCP prereq + ├─ Phase 0: Identify path ───── path_dir, path_type, Playwright MCP │ - ├─ Phase 1: Static pass ─────── audit + path/LH + claim-check → author findings (post-inline only) + ├─ Phase 1: Static pass ─────── audit + path/LH + claim-check → review-level findings only │ ├─ Phase 2: Live test ───────── Playwright DOM required; Block Editor opt-in │ (skipped when static-only) │ - ├─ Phase 3: Readiness ───────── readiness report + offer to fix + ├─ Phase 3: Readiness ───────── plain summary + numbered fixes + right next action │ ├─ Phase 4: Apply fixes ─────── optional package JSON / website.yaml edits │ @@ -79,10 +97,10 @@ See [author-testing.md § Prerequisites](author-testing.md#prerequisites). Phase ## Safety invariants -1. **Do not modify** `content.json`, `manifest.json`, or `website.yaml` until Phase 4 (and only when the author requests fixes). +1. **Do not modify** `content.json`, `manifest.json`, or `website.yaml` until Phase 4 (and only when the author requests package-fixable fixes). 2. **Never commit** preflight artifacts (`.cursor/lp-preflight-state/` or audit-guide files under `{milestone}/assets/`). -3. **Surface only post-inline** findings in chat and readiness (same bar as review [comment-style](../review-learning-path/comment-style.md)). Never dump Internal/Discard nits. -4. **No em dashes** in author-facing chat, readiness text, or drafted PR bodies. Use periods, commas, or parentheses. +3. **Surface only review-level** findings in chat and readiness (same bar as review [comment-style](../review-learning-path/comment-style.md)). Never dump Internal/Discard nits. +4. **No em dashes** in author-facing chat, readiness text, or drafted PR bodies. 5. **One preflight run per path slug** (resume from state; do not fork duplicate state files). 6. **Never** plan companion website / `pathfinder_data` / shortcode work as package blockers. @@ -108,9 +126,9 @@ Re-verify commit safety after Phase 1 before Phase 2. ## How this skill runs -1. Announce the phase (number and name), what you're doing, and why (2–3 sentences). +1. Announce the phase briefly (number, name, what you are about to do). Keep it to a few sentences; do not lecture. 2. Do agent work (audit, CLI, Playwright, drafts). -3. Stop at the checkpoint: one message, one ask. **Do not advance** until the author replies. +3. Stop at the checkpoint: one message, one clear ask. **Do not advance** until the author replies. 4. **Never batch phases.** If they say "keep going," pause at the next checkpoint anyway. --- @@ -119,17 +137,16 @@ Re-verify commit safety after Phase 1 before Phase 2. | Section | Content | |---|---| -| **Header** | `Phase {n}` + short plain outcome (avoid jargon like "post-inline") | -| **What we checked** | Phase 3 (and readiness-style summaries): where findings came from, in plain language | -| **Findings** | Numbered list with enough context to act (what is wrong, why it matters, which file). No rule counts. | -| **Your turn** | Clear reply choices (including **fix all** / **fix N** when findings exist) | +| **Header** | `Phase {n}` + short plain outcome | +| **What we checked** | Phase 3 (and similar summaries): where findings came from, in plain language | +| **Findings** | Numbered list: what is wrong, why it matters, which file. No rule counts. | +| **Your turn** | Only actions that can resolve open items | | **Up next** | One sentence when useful | +| **Heads-up** | Optional stack note | Do **not** open Phase 3 with a "What this check is" primer. Lead with the outcome, then **What we checked**, then the numbered findings. -**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` (package-fixable only) · `frontend` (needs-frontend / upstream testid) · `done` · `resume` / `start fresh` - -**Tone:** Casual and friendly. Address the author as **you**. Celebrate clean passes. No rule numbers, no Blocker/nit labels, no em dashes. Prefer everyday words over skill jargon (say "copy fixes" not "post-inline"; say "product claims vs docs" not "claim-check MUST FIX"). +**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` (package-fixable only) · `frontend` · `done` · `resume` / `start fresh` --- @@ -153,7 +170,7 @@ If `.cursor/lp-preflight-state/{slug}.json` exists: > > Share the learning path package directory (for example `monitor-azure-resources-lj`), or tell me to infer it from your current branch. > -> **Setup reminder:** For the live path I need **Playwright MCP** in Cursor. You'll Okta-login in the Playwright browser when we get to DOM checks. Block Editor is optional later. +> For live checks I need **Playwright MCP** in Cursor. You will Okta-login in the Playwright browser when we get there. Block Editor smoke is optional later. ### Agent steps @@ -175,7 +192,7 @@ If `.cursor/lp-preflight-state/{slug}.json` exists: > > **Your turn:** Reply **yes** if this looks right, or tell me what to change. > -> **Up next:** Static pass (I won't edit your JSON unless you ask later). +> **Up next:** Static pass (I will not edit your JSON unless you ask later). ### Checkpoint (MCP blocked) @@ -185,15 +202,15 @@ Use the blocked shape in [author-testing.md](author-testing.md#if-playwright-mcp ## Phase 1: Static pass -**Goal:** Audit every milestone + path consistency + Learning Hub + adversarial claim-check. Surface **post-inline** findings only in chat. +**Goal:** Audit every milestone + path consistency + Learning Hub + claim-check. Surface review-level findings only in chat. -Combines review Phase 1 checks plus [claim-check.md](claim-check.md). Author sees findings in chat (not a private workbook dump of nits). +Combines review Phase 1 checks plus [claim-check.md](claim-check.md). Keep chat short; put detail in state files. ### Tell the author > **Phase 1 - Static pass** > -> I'm reading each milestone, checking manifests, `website.yaml`, and Learning Hub structure, then fact-checking product claims against live docs. I'll only call out things a reviewer would comment on (plus contradicted or unsupported product facts). +> I am reading each milestone, checking manifests and Learning Hub structure, and fact-checking product claims against live docs. I will only call out issues a reviewer would likely ask you to change. ### Agent steps @@ -201,21 +218,21 @@ Combines review Phase 1 checks plus [claim-check.md](claim-check.md). Author see 2. Walk shared [review reference-checks](../review-learning-path/reference-checks.md) + [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md). 3. **Always scan** for framing-in-milestones, [section intro markdown that may number as a step](../review-learning-path/reference-checks.md#section-intro-markdown-numbered-as-step), and [false noops](../review-learning-path/reference-checks.md#noop-and-non-interactive-steps). 4. Run Pathfinder CLI `validate --packages {path_dir}` if available. -5. Run the [claim-check](claim-check.md) pass across path root + all milestone prose. Write `{slug}-claim-check.md` under `.cursor/lp-preflight-state/`. Route Contradicted / Unsupported / Overstated as **Fix before PR**. Do not edit package JSON here. -6. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing) plus claim-check MUST FIX. Keep only **post inline** for author chat. Drop Internal/Discard entirely from chat. -7. Write `{slug}-findings.md` under `.cursor/lp-preflight-state/` (post-inline list + optional verify-live notes for Phase 2). Resume aid only; chat stays tiny. +5. Run the [claim-check](claim-check.md) pass across path root + all milestone prose. Write `{slug}-claim-check.md` under `.cursor/lp-preflight-state/`. Route Contradicted / Unsupported / Overstated as Fix before PR. Do not edit package JSON here. +6. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing) plus claim-check MUST FIX. Keep only review-level items for author chat. Drop Internal/Discard entirely from chat. +7. Write `{slug}-findings.md` under `.cursor/lp-preflight-state/` (findings + optional verify-live notes for Phase 2). Resume aid only; chat stays short. 8. Mandatory audit cleanup; verify `git status`. 9. Do not cite rule numbers or audit severity labels in chat. ### Checkpoint -> **Phase 1 complete** - static pass done. +> **Phase 1 complete** - static pass done. > > - {One plain sentence: clean, or a few things to fix} -> - **Fix before PR** (≤3 bullets, plain language; omit if none; include claim-check MUST FIX when present): +> - **Fix before PR** (≤3 bullets, plain language; omit if none): > - {e.g. first hands-on still depends on business-value} > - {e.g. "You'll…" intros inside sections in create-dashboard} -> - {e.g. claim check: contradicted alert count in business-value} +> - {e.g. intro claims data never reaches Grafana Cloud; docs say queries run from the server} > > **Your turn:** Reply **yes** and your test stack (for example `learn.grafana.net shared`, `fresh Cloud stack`). > @@ -231,7 +248,7 @@ Record `stack_state`, or `waive_live_testing` + `static_only_reason`. ## Phase 2: Live test -**Goal:** Required Playwright DOM checks. Block Editor smoke test is **not forced**. +**Goal:** Required Playwright DOM checks. Block Editor smoke is optional. Skipped when `waive_live_testing` is true → jump to Phase 3. @@ -245,7 +262,7 @@ Details: [author-testing.md](author-testing.md). > > Stack: `{stack_state}` > -> After DOM checks I'll ask whether you've already smoke-tested in Block Editor (optional). +> After DOM checks I will ask whether you have already smoke-tested in Block Editor (optional). **Wait for:** `ready`. @@ -263,7 +280,7 @@ For each milestone in scope (path order; skip prose-only / terminal): 1. Derive start URL ([milestone start URL](../review-learning-path/reference-checks.md#milestone-start-url)). 2. Navigate; check each `reftarget`: exists / missing / below-fold / state-dependent. 3. Record in `playwright.{milestone-slug}`. -4. One-line DOM result in chat per milestone (or batch briefly if all clean). +4. One-line DOM result in chat per milestone (or a short all-clear if clean). Prefer documenting stack gaps over false "missing" on the wrong stack. ### Step B: Block Editor (opt-in, once) @@ -277,20 +294,20 @@ After Playwright: | Reply | Behavior | Readiness | |---|---|---| -| `already-tested: …` | Store dogfood evidence; no per-milestone loop | Can still be **Ready for PR** if Playwright clean and no post-inline blockers | -| `walk-me` | Guided loop: local import, `pass` / `fail step N` / `N/A`; fold false-step checks into the short watch-for line | Same when scoped milestones pass or documented N/A | +| `already-tested: …` | Store dogfood evidence; no per-milestone loop | Can still be **Ready for PR** if Playwright clean and no open blockers | +| `walk-me` | Guided loop per [author-testing.md](author-testing.md); fold watch-fors into one line | Same when scoped milestones pass or documented N/A | | `skip-smoke` | Continue | Cap at **Open PR with notes**; say Block Editor was not recorded | ### Checkpoint -> **Phase 2 complete** - live checks done. +> **Phase 2 complete** - live checks done. > -> - Playwright: [short summary] +> - Playwright: {short summary} > - Block Editor: already-tested / walked / skipped > > **Your turn:** Reply **yes** for the readiness report. > -> **Up next:** Phase 3 - readiness + whether to fix anything. +> **Up next:** Phase 3 - readiness and what to fix (if anything). --- @@ -302,7 +319,7 @@ Author chat shape: [Author-facing findings](reference-checks.md#author-facing-fi ### Agent steps -1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) and promote only post-inline items. +1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) and promote only review-level items. 2. Apply [readiness gate](reference-checks.md#readiness-gate). 3. Write `{slug}-readiness.md` with outcome + [PR opener checklist](reference-checks.md#pr-opener-checklist). 4. In chat: follow the Phase 3 checkpoint template below. Number every open finding. Mark each as package-fixable or needs-frontend. Zero findings is first-class (skip the fix list and celebrate). @@ -310,7 +327,7 @@ Author chat shape: [Author-facing findings](reference-checks.md#author-facing-fi ### Checkpoint (when there are findings) -Use a friendly outcome line (examples: "almost ready, with N copy fixes first" for Fix then re-preflight; "ready for PR" or "open PR with notes" when that is the gate). Do **not** say only the raw gate label with no context. +Use a friendly outcome line (examples: "almost ready, with N copy fixes first"; "almost ready, with 1 selector fix first"). Do **not** lead with only the raw gate label. > **Phase 3 - {friendly outcome}** > @@ -321,12 +338,12 @@ Use a friendly outcome line (examples: "almost ready, with N copy fixes first" f > > **Please fix these {N}** ({short kind}) > -> 1. {Plain problem}. {Why / better wording}. +> 1. {Plain problem}. {Why it matters or better wording}. > (`{file or dirs}`) > 2. … > > **Your turn** *(include only the lines that apply)* -> - **fix all** / **fix N** / **fix 1,3** — package edits for copy or guide JSON that we can fix here +> - **fix all** / **fix N** / **fix 1,3** — package edits for copy or guide JSON we can fix here > - **frontend** — upstream `data-testid` for item(s) {N} (live miss; no durable selector in the DOM) > - **done** — open a PR and leave these for review > - **show report** — longer write-up @@ -336,7 +353,7 @@ Use a friendly outcome line (examples: "almost ready, with N copy fixes first" f When **every** open item needs-frontend, omit **fix all** / **fix N**. Lead **Your turn** with **frontend**. -When the list mixes kinds, say which numbers **fix** covers vs **frontend** (see [Author-facing findings](reference-checks.md#author-facing-findings)). +When the list mixes kinds, say which numbers **fix** covers vs **frontend**. ### Checkpoint (when clean) @@ -347,7 +364,7 @@ When the list mixes kinds, say which numbers **fix** covers vs **frontend** (see > > Nothing here that would draw a review comment on copy or selectors. Nice work. > -> **Your turn:** Reply **done** if you're opening the PR, or **show report** for the write-up. +> **Your turn:** Reply **done** if you are opening the PR, or **show report** for the write-up. > > *(If Open PR with notes: say why in one line, e.g. Block Editor smoke was skipped.)* > @@ -357,13 +374,13 @@ When the list mixes kinds, say which numbers **fix** covers vs **frontend** (see ## Phase 4: Apply package fixes (optional) -**Goal:** Author-requested surgical edits (`fix all` / `fix N` / numbered combos) for **package-fixable** findings only. +**Goal:** Author-requested surgical edits for **package-fixable** findings only. ### Tell the author > **Phase 4 - Apply fixes** > -> Working on {fix all | item N | items …}. I'll edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). +> Working on {fix all | item N | items …}. I will edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). ### Agent steps @@ -374,7 +391,7 @@ When the list mixes kinds, say which numbers **fix** covers vs **frontend** (see ### Checkpoint -> **Phase 4 complete** - applied {N} fix(es). +> **Phase 4 complete** - applied {N} fix(es). > > **Your turn:** Reply **yes** to refresh readiness, **frontend** if you still need a testid upstream, or **done**. @@ -386,11 +403,13 @@ When the list mixes kinds, say which numbers **fix** covers vs **frontend** (see Follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [grafana/grafana-cmab-app#1795](https://github.com/grafana/grafana-cmab-app/pull/1795). +Use the step checkpoints in that doc (confirm name → confirm repo/files → approve draft → ask before push → update guide only after the testid is on the stack). + ### Checkpoint -> **Phase 5 complete** - frontend PR {url} *(or deferred)*. +> **Phase 5 complete** - frontend PR {url} *(or deferred)*. > -> **Your turn:** Reply **done** when you're ready to open the learning path PR (or wait on the testid merge). +> **Your turn:** Reply **done** when you are ready to open the learning path PR (or wait on the testid merge). --- @@ -404,7 +423,8 @@ Follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [g - Surface Internal/Discard nits in chat or readiness - Use em dashes, rule numbers, or Blocker labels with the author - Force a full Block Editor loop when they already dogfooded -- Recommend **Ready for PR** with open post-inline items +- Offer **fix N** as the main path for a needs-frontend finding +- Recommend **Ready for PR** with open review-level items - Recommend **Ready for PR** on **new** / **conversion** interactive paths when Playwright was skipped - Request website-repo changes (`pathfinder_data`, shortcodes) as package blockers - Use the PR review tool as a substitute for local import (no PR yet) @@ -412,10 +432,10 @@ Follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [g **Do** - Mirror five-phase review checklists and Learning Hub standards -- Keep chat tiny and friendly +- Keep chat short, clear, and friendly - Dedupe findings by root cause - Run CLI validate when available -- Offer Phase 4 / 5 after readiness +- Offer Phase 4 / 5 after readiness with the right action per finding kind --- @@ -426,7 +446,8 @@ Write under `.cursor/lp-preflight-state/` (never commit): | File | Phase | Purpose | |---|---|---| | `{slug}.json` | 0+ | Machine state ([schema](reference-checks.md#state-file-schema)) | -| `{slug}-findings.md` | 1 | Post-inline findings + verify-live notes | +| `{slug}-findings.md` | 1 | Findings + verify-live notes | +| `{slug}-claim-check.md` | 1 | Claim-check report | | `{slug}-readiness.md` | 3 | Readiness gate + PR opener checklist | | `{slug}/audits/{milestone}/` | 1 (optional) | Copied audit reports before cleanup | @@ -447,11 +468,12 @@ path_dir: {path_dir} | Topic | Doc | |---|---| | Author routing + readiness | [reference-checks.md](reference-checks.md) | +| Claim-check (product facts) | [claim-check.md](claim-check.md) | | Prereqs + Playwright + optional smoke | [author-testing.md](author-testing.md) | | Frontend testid PR | [frontend-selector-pr.md](frontend-selector-pr.md) | | Shared static checklists + finding routing | [../review-learning-path/reference-checks.md](../review-learning-path/reference-checks.md) | | Learning Hub structure | [../review-learning-path/learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) | -| Comment voice (post-inline bar) | [../review-learning-path/comment-style.md](../review-learning-path/comment-style.md) | +| Comment voice (review-level bar) | [../review-learning-path/comment-style.md](../review-learning-path/comment-style.md) | | Reviewer workflow (mirror) | [../review-learning-path/SKILL.md](../review-learning-path/SKILL.md) | | `website.yaml` | [docs/website-yaml-reference.md](../../../docs/website-yaml-reference.md) | | Single-repo LP workflows | [learning-path-workflows/workflows.md](../../learning-path-workflows/workflows.md) | diff --git a/.cursor/skills/preflight-learning-path/author-testing.md b/.cursor/skills/preflight-learning-path/author-testing.md index e62df0dbf..7c23d27d2 100644 --- a/.cursor/skills/preflight-learning-path/author-testing.md +++ b/.cursor/skills/preflight-learning-path/author-testing.md @@ -50,13 +50,13 @@ Standard config to add when missing (do not overwrite unrelated servers): **Blocked checkpoint shape (author-facing):** -> Playwright MCP isn't available, so I can't run the live DOM checks on this path. +> Playwright MCP isn't available, so I can't run the live DOM checks on this path yet. > > **Manual setup:** Cursor Settings → MCP → enable **Playwright** (or add it if it's not listed), then reload. > > **Or:** reply **add playwright mcp** and I'll add the standard config to `~/.cursor/mcp.json` for you (you'll still need to reload MCP afterward). > -> `static-only` isn't a fit for new/conversion interactive paths. +> Skipping live checks with `static-only` isn't a fit for new or conversion interactive paths. Never edit `mcp.json` until the author agrees. Never claim MCP is ready until `GetMcpTools` for `user-playwright` shows usable browser tools. diff --git a/.cursor/skills/preflight-learning-path/claim-check.md b/.cursor/skills/preflight-learning-path/claim-check.md index 2b9d6465b..1a17db8f0 100644 --- a/.cursor/skills/preflight-learning-path/claim-check.md +++ b/.cursor/skills/preflight-learning-path/claim-check.md @@ -1,6 +1,6 @@ # Claim check (preflight) -Adversarial factual check for Pathfinder learning path packages. Adapted from the Learning Hub claim-check skill (`learning-hub-claim-check`) and the MUST FIX bar in journey audit reports (for example intro-db-olly). Goal: catch AI-invented product facts before a PR, not Hugo slide structure. +Adversarial factual check for Pathfinder learning path packages. Adapted from the Learning Hub claim-check skill and the MUST FIX bar in journey audit reports. Goal: catch invented product facts before a PR, not Hugo slide structure. Run inside [preflight Phase 1](SKILL.md#phase-1-static-pass) after audit-guide and path/LH checks, before the Phase 1 checkpoint. @@ -58,22 +58,20 @@ Do not edit package JSON during the claim check. Fixes wait for Phase 4 if the a | Verdict | Meaning | Preflight routing | |---|---|---| | **Supported** | Source plainly states the claim | Hide (optional Supported list in the report only) | -| **Contradicted** | Source says something different | **Fix before PR** (post-inline) | -| **Unsupported** | No source, or source does not address it | **Fix before PR** (post-inline) | -| **Overstated** | Source supports a weaker version; claim adds absolute/superlative/framing | **Fix before PR** (post-inline) | -| **Author decides** | Product-truth call a human must make | Surface in readiness as open question; do not auto-edit | +| **Contradicted** | Source says something different | Fix before PR (review-level) | +| **Unsupported** | No source, or source does not address it | Fix before PR (review-level) | +| **Overstated** | Source supports a weaker version; claim adds absolute/superlative/framing | Fix before PR (review-level) | +| **Author decides** | Product-truth call a human must make | Optional open question in readiness; do not auto-edit | -Only Contradicted / Unsupported / Overstated count toward the Phase 1 "Fix before PR" list (dedupe by root cause). Soft style nits stay out of chat. +Only Contradicted / Unsupported / Overstated count toward Fix before PR (dedupe by root cause). Soft style nits stay out of chat. --- ## Catches that matter (linter cannot) -Same five classes as Learning Hub claim-check: - 1. Made-up facts 2. Invented terms / alert names / dashboard names -3. Overstatements (counts, "zero impact", "most/all/every") +3. Overstatements (counts, "zero impact," "most/all/every") 4. Competitive or prescriptive framing without a source 5. Pre-GA / preview features taught as GA @@ -96,7 +94,7 @@ path_dir: {path_dir} ## MUST FIX (Fix before PR) ### Contradicted -1. `{file}` — {claim}. Source: {quote or URL}. Fix: {one line}. +1. `{file}` - {claim}. Source: {quote or URL}. Fix: {one line}. ### Unsupported … @@ -111,14 +109,14 @@ path_dir: {path_dir} … ``` -Mirror the ranking style of journey audit reports: MUST FIX first, then author-decides. Do not dump Supported claims into author chat. +MUST FIX first, then author-decides. Do not dump Supported claims into author chat. No em dashes in the report body. --- ## Phase 1 / Phase 3 chat -After claim-check, merge MUST FIX items into author findings (dedupe; ≤3 in Phase 1 chat). Use plain language (problem + why + file), not verdict labels like "Contradicted" in the author bullets. +After claim-check, merge MUST FIX items into author findings (dedupe; ≤3 in Phase 1 chat). Use plain language (problem + why + file). Do **not** put verdict labels like "Contradicted" in author bullets. -At **Phase 3**, list them as numbered items and offer **fix all** / **fix N** / combos per [Author-facing findings](reference-checks.md#author-facing-findings). Do not open with a "What this check is" primer. +At **Phase 3**, list them as numbered **package-fixable** items and offer **fix all** / **fix N** / combos per [Author-facing findings](reference-checks.md#author-facing-findings). Do not open with a "What this check is" primer. If none, say the claim check found no contradicted or unsupported product facts. diff --git a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md index 0f6eadb05..adc127e66 100644 --- a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md +++ b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md @@ -11,7 +11,7 @@ Use that PR as the model for: - PR title/body that explains Pathfinder authoring needs stable selectors - Friendly, low-ceremony tone -Do not paste the whole #1795 diff. Link it and mirror the pattern. +Do not paste the whole #1795 diff. Link it and mirror the pattern. No em dashes in drafted PR bodies. --- @@ -31,12 +31,25 @@ If live passed with a justified `:contains()` and no stable selector exists, tha ## Walkthrough (checkpointed) +Announce **Phase 5 - frontend selector (step X of 5)** at each stop. One ask per message. + ### 1. Confirm the element From Playwright: URL, visible label, current weak selector, screenshot or DOM snippet if helpful. Propose a `data-testid` (plain kebab-case, product-area prefix, matching existing testids in that app when present). +> **Phase 5 - frontend selector (step 1 of 5)** +> +> **Element that failed live** +> - Page: {url or page name} +> - Control: {visible label} +> - Guide selector today: `{reftarget}` +> +> **Proposed `data-testid`:** `{proposed-name}` +> +> **Your turn:** Reply **yes** if that name is fine, or suggest a different kebab-case name. + **Wait for:** author OK on the name (or edits). ### 2. Locate owning source @@ -46,6 +59,14 @@ Propose a `data-testid` (plain kebab-case, product-area prefix, matching existin Use workspace clones or GitHub search. Do **not** invent file paths. +> **Phase 5 - frontend selector (step 2 of 5)** +> +> Best guess for owning source: `{repo}` ({why}). +> +> Next I will confirm the exact file(s). I will not invent paths. +> +> **Your turn:** Reply **yes** if `{repo}` looks right, or name a different repo. + **Wait for:** confirm repo + file(s). ### 3. Draft the change @@ -53,7 +74,6 @@ Use workspace clones or GitHub search. Do **not** invent file paths. - Minimal diff: add `data-testid` (and wire through component props if needed) - Match local naming conventions - Draft PR title + body in the style of #1795 (Pathfinder needs stable selectors; keep scope tight) -- **No em dashes** in the PR body Example body shape (adapt; do not copy blindly): @@ -65,16 +85,32 @@ Adds `data-testid` attributes to {components} following the existing kebab-case Example pattern: https://github.com/grafana/grafana-cmab-app/pull/1795 ``` +> **Phase 5 - frontend selector (step 3 of 5)** +> +> Draft change: add `{testid}` on {component summary}. Testids only; no behavior change. +> +> **Title:** {title} +> +> **Body:** (show draft) +> +> **Your turn:** Reply **yes** to approve, or say what to change. + **Wait for:** author approval of the draft. ### 4. Open the PR 1. Confirm `gh` auth and write access -2. Create branch, commit, push (ask before push) +2. Create branch, commit, push (**ask before push**) 3. `gh pr create` with the approved title/body 4. Follow existing grafana org repo norms; do not change repo visibility -Record `frontend_pr_url` in preflight state. +> **Phase 5 - frontend selector (step 4 of 5)** +> +> Ready to open the PR in `{repo}` with the approved title/body. +> +> **Your turn:** Reply **yes** to push and create the PR, or **hold** to stop here. + +Record `frontend_pr_url` in preflight state after create. ### 5. Update the guide selector @@ -82,6 +118,14 @@ Update the milestone `reftarget` to the new testid **only after** the author con Until then: keep a temporary justified fallback if needed, and note the upstream PR URL in readiness / Open PR with notes. +> **Phase 5 - frontend selector (step 5 of 5)** +> +> Frontend PR: {url} +> +> When `{testid}` is on your test stack, we can update `{milestone}` to `[data-testid="{testid}"]`. We should not change the guide before that lands. +> +> **Your turn:** Reply **update guide** when the testid is available, or **done** to leave the guide as-is for now. + --- ## Anti-patterns @@ -90,3 +134,4 @@ Until then: keep a temporary justified fallback if needed, and note the upstream - Inventing component paths - Updating guide JSON to a testid that is not on the test stack yet without saying so - Treating a missing upstream testid as something to "fix" only inside `interactive-tutorials` when the DOM has no stable hook +- Offering bare **fix N** at Phase 3 as if a guide edit adds the testid diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md index 04407b9de..b4b563a91 100644 --- a/.cursor/skills/preflight-learning-path/reference-checks.md +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -6,17 +6,17 @@ Author-side routing and readiness for [preflight-learning-path/SKILL.md](SKILL.m **Publishing model (PR [#416](https://github.com/grafana/interactive-tutorials/pull/416)):** Single-repo packages in `interactive-tutorials`. Metadata in package `website.yaml`; prose in `content.json`. Website repo is read-only for conversion. Never plan companion website / `pathfinder_data` / shortcode work. -**Voice bar:** Same as review [comment-style.md](../review-learning-path/comment-style.md). Author chat and readiness only include **post inline** items. No em dashes. Prefer everyday words in chat (see [Author-facing findings](#author-facing-findings)). +**Voice bar:** Same severity bar as review [comment-style.md](../review-learning-path/comment-style.md) (review-level only in chat). No em dashes. Prefer everyday words in chat (see [Author-facing findings](#author-facing-findings) and [Voice](SKILL.md#voice-author-facing)). --- ## Author-facing findings -Use this shape whenever you list Fix-before-PR items in chat (especially Phase 3). Do **not** open with a "What this check is" primer. +Use this shape whenever you list Fix-before-PR items in chat (especially Phase 3). Do **not** open with a "What this check is" primer. Match [Voice](SKILL.md#voice-author-facing). -1. **Friendly outcome line** (e.g. "almost ready, with 3 copy fixes first"). You may mention the gate label in the readiness file; chat can stay friendlier. -2. **What we checked** — short bullets naming the sources of truth in plain language (product claims vs docs, UI selectors on `{stack}`, Block Editor smoke choice). -3. **Numbered findings** — each item: plain problem, why it matters or better wording, then the file/dir in parentheses. Enough context that the author can decide without opening the skill. Tag each item mentally as **package-fixable** or **needs-frontend** (see below). +1. **Friendly outcome line** (e.g. "almost ready, with 3 copy fixes first"). Keep gate labels in the readiness file; chat can stay plainer. +2. **What we checked** — short bullets in plain language (product claims vs docs, UI selectors on `{stack}`, Block Editor smoke choice). +3. **Numbered findings** — each item: plain problem, why it matters or better wording, then the file/dir in parentheses. Enough context that the author can decide without opening the skill. Treat each item as **package-fixable** or **needs-frontend** (see below). 4. **Your turn** — offer only actions that can resolve the open items: - **fix all** / **fix N** / combos — only for **package-fixable** items (prose, manifest, `website.yaml`, guide `reftarget` when a better selector already exists in the DOM) - **frontend** — when any open item **needs-frontend** (live failed; no durable `data-testid` / strong semantic selector in the DOM). Do **not** offer **fix N** for that item as if a guide edit alone is the real fix From cef6ac5a9be096fbbfcbc8261fd7b4c338a6fb48 Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Mon, 27 Jul 2026 09:19:50 -0700 Subject: [PATCH 8/9] Collapse preflight to a hard author flow with clearer MCP help. Pause only for path/MCP blockers, Okta login, smoke choice, and one results menu. Diagnose configured-but-broken Playwright MCP, drop refresh-readiness jargon, and remind authors not to commit lp-preflight-state. Co-authored-by: Cursor --- .cursor/commands/preflight-learning-path.md | 27 +- .cursor/learning-path-workflows/workflows.md | 2 +- .../skills/preflight-learning-path/SKILL.md | 344 ++++++++---------- .../preflight-learning-path/author-testing.md | 37 +- .../preflight-learning-path/claim-check.md | 12 +- .../frontend-selector-pr.md | 26 +- .../reference-checks.md | 8 +- 7 files changed, 209 insertions(+), 247 deletions(-) diff --git a/.cursor/commands/preflight-learning-path.md b/.cursor/commands/preflight-learning-path.md index 15968ce3d..0d20fb898 100644 --- a/.cursor/commands/preflight-learning-path.md +++ b/.cursor/commands/preflight-learning-path.md @@ -1,8 +1,8 @@ ## Command: /preflight-learning-path -Self-review a learning path package in `interactive-tutorials` **before** opening a PR. Walks you through **one phase at a time**. Same static and live checks as the five-phase [/review-learning-path-pr](review-learning-path-pr.md) coach, from the author side. +Self-review a learning path package in `interactive-tutorials` **before** opening a PR. Same checks as [/review-learning-path-pr](review-learning-path-pr.md), from the author side, with fewer stop-and-type moments: the agent runs what it can, then pauses only when it needs you (login, smoke choice, results / fixes). -When invoked, read and follow **[preflight-learning-path/SKILL.md](../skills/preflight-learning-path/SKILL.md)** in order. Never batch phases. +When invoked, read and follow **[preflight-learning-path/SKILL.md](../skills/preflight-learning-path/SKILL.md)** in order. LP packages are **single-repo** (`interactive-tutorials` only). Metadata lives in package `website.yaml`; the website repo is read-only for conversion ([PR #416](https://github.com/grafana/interactive-tutorials/pull/416)). Learning Hub criteria: [learning-hub-standards.md](../skills/review-learning-path/learning-hub-standards.md). @@ -17,19 +17,20 @@ LP packages are **single-repo** (`interactive-tutorials` only). Metadata lives i ## First message to the author -> I'll walk you through a preflight check on your learning path **one phase at a time**. I'll pause after each phase. Please don't skip ahead. +> I'll preflight your learning path with as few interruptions as possible. I'll run the static checks on my own, then pause when I need you logged into Playwright, again for an optional Block Editor smoke choice, then once for results and fix options. > -> | Phase | What happens | +> | When I pause | Why | > |---|---| -> | 0 | Confirm your `{slug}-lj/` package and Playwright MCP | -> | 1 | Static pass: structure, Learning Hub, and product claims vs docs | -> | 2 | Playwright DOM checks (Block Editor smoke optional) | -> | 3 | Readiness summary and what to fix (if anything) | -> | 4 | Optional package edits | -> | 5 | Optional upstream `data-testid` PR if a stable selector is missing | +> | Path unclear | Confirm which `{slug}-lj/` package | +> | Playwright not ready | Fix or add MCP | +> | Before live DOM | Okta login + which stack | +> | After DOM | Smoke: already-tested / walk-me / skip | +> | Results | What to fix (if anything) | > -> **Setup:** Playwright MCP should be on. If it isn't, I'll offer to add the config for you (or walk you through Settings). You'll Okta-login in the Playwright browser for DOM checks. +> **Setup:** Playwright MCP should be on. If it is missing or broken, I'll help fix it. You'll Okta-login in the Playwright browser for DOM checks. > -> **Phase 0:** Share the path package (`{slug}-lj/` directory), or tell me to infer it from your current branch. +> Preflight reports stay under `.cursor/lp-preflight-state/` (gitignored). Don't force-add them to your PR. +> +> **To start:** Share the path package (`{slug}-lj/` directory), or tell me to infer it from your current branch. If you already named the path, I'll begin the static checks now. -Do not start Phase 1 until the author confirms the path directory. +If the path is already clear from the user message, skip asking and start identify + static immediately. diff --git a/.cursor/learning-path-workflows/workflows.md b/.cursor/learning-path-workflows/workflows.md index 12c4f4533..40182979c 100644 --- a/.cursor/learning-path-workflows/workflows.md +++ b/.cursor/learning-path-workflows/workflows.md @@ -103,4 +103,4 @@ The learning path slug is mysql-data-source. | `/build-interactive-lj` | Existing milestone markdown in website repo (read-only source) | `content.json` + `manifest.json` + `website.yaml` files in interactive-tutorials | | `/create-learning-path` | Feature description (no existing markdown) | `content.json` + `manifest.json` + `website.yaml` files | | `/review-learning-path-pr` | Existing LP PR in `interactive-tutorials` (share PR URL/number) | Human-guided review: static workbook, Block Editor smoke test, chat-approved inline comments, submit | -| `/preflight-learning-path` | Local `{slug}-lj/` package before opening a PR | Author self-review: same static + Playwright checks as review, readiness report, optional fixes / frontend testid PR | +| `/preflight-learning-path` | Local `{slug}-lj/` package before opening a PR | Author self-review with few pauses (login, smoke choice, results): same static + Playwright checks as review, readiness report, optional fixes / frontend testid PR | diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index 848099039..1413e5cc4 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -20,7 +20,7 @@ Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the **Do NOT read external reference files upfront.** Each phase loads its own references on demand. -**Skill memory:** State lives in `.cursor/lp-preflight-state/` (gitignored). Phase 1 dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/`. See [Commit safety](#commit-safety). +**Skill memory:** State lives in `.cursor/lp-preflight-state/` (gitignored; never commit). Phase 1 dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/`. See [Commit safety](#commit-safety). **Routing:** [reference-checks.md](reference-checks.md) · [claim-check.md](claim-check.md) · [author-testing.md](author-testing.md) · [frontend-selector-pr.md](frontend-selector-pr.md) · shared [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) · shared [review reference-checks](../review-learning-path/reference-checks.md) @@ -34,15 +34,33 @@ Write like a calm teammate helping someone ship, not like a linter report. | Do | Don't | |---|---| -| Short sentences; plain words | Jargon in chat (`post-inline`, `MUST FIX`, rule numbers) | +| Short sentences; plain words | Jargon in chat (`post-inline`, `MUST FIX`, "refresh readiness", rule numbers) | | Say what is wrong, why it matters, which file | Dump severity labels or audit counts | | Offer only actions that can resolve the item | Offer **fix N** when the real fix is upstream | | Celebrate clean passes briefly | Hedge with "seems fine" / "maybe" | -| One checkpoint ask at a time | Batch phases or multiple asks | +| Pause only when you truly need the author | Quiz them with "reply yes" between agent-only steps | No em dashes in author chat, readiness text, or drafted PR bodies. Use periods, commas, or parentheses. -Address the author as **you**. Prefer "copy fixes," "product claims vs docs," "UI selectors," "smoke test." +Address the author as **you**. Prefer "copy fixes," "product claims vs docs," "UI selectors," "smoke test," "ready / not-ready summary." + +--- + +## Author experience (hard flow) + +Do as much as you can without stopping. Authors should not confirm every internal phase. + +**Pause only for:** + +1. Path unclear (ambiguous / missing `{path_dir}`) +2. Playwright MCP blocked or broken (setup) +3. Okta / browser ready before DOM checks (and stack choice, unless already known) +4. Block Editor smoke choice (and walk-me replies if they choose guided smoke) +5. Results + fix menu (and later fix / frontend / done) + +**Do not** pause for "Phase 0 complete, reply yes" or "Phase 1 complete, reply yes" when the path is known and MCP is healthy. Run identify → static → then ask for login in one beat. + +Internal phase numbers (0–5) stay in state and agent notes. Author chat can say "checking your path," "live checks," "results" instead of a quiz board. --- @@ -50,12 +68,12 @@ Address the author as **you**. Prefer "copy fixes," "product claims vs docs," "U | You (agent) | Author (human) | |---|---| -| Confirm path; run audit, path/LH checks, and claim-check | Confirm `{path_dir}`; reply at checkpoints | -| Surface only review-level findings in chat | Decide whether to fix now or open a PR with notes | -| Required Playwright DOM check (live path) | Okta login in the Playwright browser; reply `ready` | -| Optional Block Editor coaching | `already-tested` / `walk-me` / `skip-smoke` | -| Apply package fixes only when asked | `fix all`, `fix N`, or a combo like `fix 1,3` (package-fixable only) | -| Walk frontend testid PR when needed | Reply `frontend`; approve push / PR create | +| Infer path when clear; confirm only if ambiguous | Share `{path_dir}` when asked | +| Run static + claim-check without a mid-stop | Wait or do other work | +| Open Playwright; ask when logged in | Okta in Playwright browser; reply when ready | +| Run DOM checks; then ask about smoke | `already-tested` / `walk-me` / `skip-smoke` | +| One results + fix menu | `fix all` / `fix N` / `frontend` / `done` / `show report` | +| Apply package or frontend fixes only when asked | Approve edits / push | --- @@ -64,18 +82,21 @@ Address the author as **you**. Prefer "copy fixes," "product claims vs docs," "U ``` Input (path_dir or current branch) │ - ├─ Phase 0: Identify path ───── path_dir, path_type, Playwright MCP + ├─ Identify + MCP check ─────── quiet unless path/MCP needs the author + │ + ├─ Static pass ─────────────── audit + path/LH + claim-check (no author yes) │ - ├─ Phase 1: Static pass ─────── audit + path/LH + claim-check → review-level findings only + ├─ PAUSE: login + stack ────── Playwright Okta; stack (or static-only if allowed) │ - ├─ Phase 2: Live test ───────── Playwright DOM required; Block Editor opt-in - │ (skipped when static-only) + ├─ Playwright DOM ──────────── required (unless static-only) │ - ├─ Phase 3: Readiness ───────── plain summary + numbered fixes + right next action + ├─ PAUSE: smoke choice ─────── already-tested / walk-me / skip-smoke │ - ├─ Phase 4: Apply fixes ─────── optional package JSON / website.yaml edits + ├─ Results + fix menu ──────── one readiness summary (former Phase 3) │ - └─ Phase 5: Frontend testid ─── optional upstream data-testid PR (when needed) + ├─ Optional package fixes ──── fix all / fix N + │ + └─ Optional frontend testid ── when needs-frontend ``` --- @@ -85,20 +106,20 @@ Input (path_dir or current branch) - **Required**: `{path_dir}` ending in `-lj/` (for example `monitor-azure-resources-lj`). Infer from current branch if omitted; confirm if ambiguous. - **Optional**: `website_slug` (`{path_dir}` minus `-lj`). Website repo is read-only for conversion ([PR #416](https://github.com/grafana/interactive-tutorials/pull/416)). - **Optional**: `learn_host` (default `learn.grafana.net`). -- **Optional**: `waive_live_testing` via `static-only: ` at Phase 1 end. See [static-only preflight](reference-checks.md#static-only-preflight). +- **Optional**: `waive_live_testing` via `static-only: ` at the login/stack pause. See [static-only preflight](reference-checks.md#static-only-preflight). --- ## Prerequisites -See [author-testing.md § Prerequisites](author-testing.md#prerequisites). Phase 0 verifies Playwright MCP for the live path. +See [author-testing.md § Prerequisites](author-testing.md#prerequisites). Identify verifies Playwright MCP before live checks. --- ## Safety invariants -1. **Do not modify** `content.json`, `manifest.json`, or `website.yaml` until Phase 4 (and only when the author requests package-fixable fixes). -2. **Never commit** preflight artifacts (`.cursor/lp-preflight-state/` or audit-guide files under `{milestone}/assets/`). +1. **Do not modify** `content.json`, `manifest.json`, or `website.yaml` until the author requests package-fixable fixes. +2. **Never commit** preflight artifacts (`.cursor/lp-preflight-state/` or audit-guide files under `{milestone}/assets/`). Remind the author once that reports are local and gitignored. 3. **Surface only review-level** findings in chat and readiness (same bar as review [comment-style](../review-learning-path/comment-style.md)). Never dump Internal/Discard nits. 4. **No em dashes** in author-facing chat, readiness text, or drafted PR bodies. 5. **One preflight run per path slug** (resume from state; do not fork duplicate state files). @@ -112,41 +133,41 @@ Same snapshot/cleanup rules as [review-learning-path § Commit safety](../review | Artifact | Where | Mitigation | |---|---|---| -| Findings, claim-check, readiness, state JSON | `.cursor/lp-preflight-state/` | `.gitignore` | -| audit-guide reports | `{milestone}/assets/` | Snapshot before Phase 1; delete new files before Phase 1 checkpoint | +| Findings, claim-check, readiness, state JSON | `.cursor/lp-preflight-state/` | `.gitignore` (must ship with this skill) | +| audit-guide reports | `{milestone}/assets/` | Snapshot before static; delete new files before login pause | | Pre-existing package `assets/` | Author/migrate notes | Never delete paths listed in `pre_review_assets` | -**Phase 1 snapshot:** `find {milestone}/assets -type f 2>/dev/null | sort` → store in state `pre_review_assets`. - -**Phase 1 cleanup (mandatory before checkpoint):** remove audit files not in the snapshot; verify `git status --porcelain -- {path_dir}` shows no untracked audit paths. +**Static snapshot:** `find {milestone}/assets -type f 2>/dev/null | sort` → store in state `pre_review_assets`. -Re-verify commit safety after Phase 1 before Phase 2. +**Static cleanup (mandatory before login pause):** remove audit files not in the snapshot; verify `git status --porcelain -- {path_dir}` shows no untracked audit paths. --- ## How this skill runs -1. Announce the phase briefly (number, name, what you are about to do). Keep it to a few sentences; do not lecture. -2. Do agent work (audit, CLI, Playwright, drafts). -3. Stop at the checkpoint: one message, one clear ask. **Do not advance** until the author replies. -4. **Never batch phases.** If they say "keep going," pause at the next checkpoint anyway. +1. Tell the author briefly what you are starting (path name when known). Do not lecture. +2. Run every agent-only step you can before the next real pause. +3. At a pause: one message, one clear ask. Plain language. **Do not advance** until they reply. +4. Do **not** invent extra "reply yes if this looks right" stops between agent-only work. +5. If they say "keep going" during a real pause (login / smoke / results), still honor that pause's need (e.g. you cannot DOM-check without login). --- -## Checkpoint format +## Results menu format (after live) | Section | Content | |---|---| -| **Header** | `Phase {n}` + short plain outcome | -| **What we checked** | Phase 3 (and similar summaries): where findings came from, in plain language | -| **Findings** | Numbered list: what is wrong, why it matters, which file. No rule counts. | +| **Header** | Friendly outcome (e.g. almost ready, with N copy fixes first) | +| **What we checked** | Plain bullets: claims vs docs, UI selectors, smoke choice | +| **Findings** | Numbered: what is wrong, why it matters, which file | | **Your turn** | Only actions that can resolve open items | -| **Up next** | One sentence when useful | -| **Heads-up** | Optional stack note | +| **Heads-up** | Optional stack note; gitignore reminder if useful | -Do **not** open Phase 3 with a "What this check is" primer. Lead with the outcome, then **What we checked**, then the numbered findings. +Do **not** open with a "What this check is" primer. -**Reply keywords:** `yes` · `ready` · `add playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` (package-fixable only) · `frontend` · `done` · `resume` / `start fresh` +**Useful replies:** `ready` · `add playwright mcp` · `fix playwright mcp` · `static-only: ` · `already-tested: ` · `walk-me` · `skip-smoke` · `pass` / `fail step N - …` / `N/A - …` · `show report` · `fix all` · `fix 1` / `fix 2` / `fix 3` · `fix 1,3` · `frontend` · `done` · `resume` / `start fresh` + +After package fixes, ask: **Want an updated ready / not-ready summary?** (not "refresh readiness"). --- @@ -154,23 +175,25 @@ Do **not** open Phase 3 with a "What this check is" primer. Lead with the outcom If `.cursor/lp-preflight-state/{slug}.json` exists: -> **Resume?** I have an in-progress preflight for `{path_dir}` (stopped after phase {phase}). +> **Resume?** I have an in-progress preflight for `{path_dir}` (stopped at {plain pause name}). > > Reply **resume** to pick up, or **start fresh** to begin again. --- -## Phase 0: Identify path +## Identify path + MCP (quiet unless blocked) **Goal:** Confirm `{path_dir}`, `path_type`, milestones; verify Playwright MCP; init state. -### Tell the author +### Author chat -> **Phase 0 - Identify path** -> -> Share the learning path package directory (for example `monitor-azure-resources-lj`), or tell me to infer it from your current branch. -> -> For live checks I need **Playwright MCP** in Cursor. You will Okta-login in the Playwright browser when we get there. Block Editor smoke is optional later. +If `{path_dir}` is missing or ambiguous: + +> Which learning path package should I preflight? Share the `{slug}-lj/` directory, or tell me to infer it from your current branch. + +If path is clear, say one short line (e.g. "Preflighting `{path_dir}`. Running the static checks now.") and continue. Do **not** ask them to confirm the path/type/MCP table when everything looks fine. + +Mention once (early, not every pause): reports land under `.cursor/lp-preflight-state/` and are gitignored; do not force-add them to a PR. ### Agent steps @@ -179,38 +202,16 @@ If `.cursor/lp-preflight-state/{slug}.json` exists: 3. Infer `website_slug` = `{path_dir}` minus `-lj` when website repo is in workspace (read-only). 4. Infer `path_type`: `new`, `conversion`, or `update` per [path type](reference-checks.md#path-type). 5. List milestones from path `manifest.json` `milestones` and dirs under `{path_dir}/`. -6. **Verify Playwright MCP** (`user-playwright`). If unavailable on a live path: stop per [If Playwright MCP is missing](author-testing.md#if-playwright-mcp-is-missing). Give manual setup steps **and** offer to help when possible (add `mcp.json` config on **add playwright mcp**, or `mcp_auth` if the server needs auth). Do not silently skip. Do not edit `mcp.json` until they agree. +6. **Verify Playwright MCP** (`user-playwright`). Cover missing, needs-auth, toggled-off, **and configured-but-broken** per [If Playwright MCP is missing or broken](author-testing.md#if-playwright-mcp-is-missing-or-broken). Do not silently skip. Do not edit `mcp.json` until they agree. 7. Write `.cursor/lp-preflight-state/{slug}.json` ([state schema](reference-checks.md#state-file-schema)). -### Checkpoint (MCP ready) - -> **Phase 0 complete** - `{path_dir}` on `{branch}` @ `{short_sha}`. -> -> - Path: `{path_dir}` ({M} milestones) -> - Type: `{path_type}` -> - Playwright MCP: ready -> -> **Your turn:** Reply **yes** if this looks right, or tell me what to change. -> -> **Up next:** Static pass (I will not edit your JSON unless you ask later). - -### Checkpoint (MCP blocked) - -Use the blocked shape in [author-testing.md](author-testing.md#if-playwright-mcp-is-missing). Still report path / type. **Your turn** must include the **add playwright mcp** offer (or auth offer) plus manual Settings steps. After they reload and MCP is ready, re-run the verify step and use the MCP-ready checkpoint. +If MCP is blocked, stop with the blocked shape in author-testing.md. Do not run live later until tools work. --- -## Phase 1: Static pass - -**Goal:** Audit every milestone + path consistency + Learning Hub + claim-check. Surface review-level findings only in chat. - -Combines review Phase 1 checks plus [claim-check.md](claim-check.md). Keep chat short; put detail in state files. +## Static pass (no author yes) -### Tell the author - -> **Phase 1 - Static pass** -> -> I am reading each milestone, checking manifests and Learning Hub structure, and fact-checking product claims against live docs. I will only call out issues a reviewer would likely ask you to change. +**Goal:** Audit every milestone + path consistency + Learning Hub + claim-check. Keep findings for the final results menu. ### Agent steps @@ -218,146 +219,120 @@ Combines review Phase 1 checks plus [claim-check.md](claim-check.md). Keep chat 2. Walk shared [review reference-checks](../review-learning-path/reference-checks.md) + [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md). 3. **Always scan** for framing-in-milestones, [section intro markdown that may number as a step](../review-learning-path/reference-checks.md#section-intro-markdown-numbered-as-step), and [false noops](../review-learning-path/reference-checks.md#noop-and-non-interactive-steps). 4. Run Pathfinder CLI `validate --packages {path_dir}` if available. -5. Run the [claim-check](claim-check.md) pass across path root + all milestone prose. Write `{slug}-claim-check.md` under `.cursor/lp-preflight-state/`. Route Contradicted / Unsupported / Overstated as Fix before PR. Do not edit package JSON here. -6. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing) plus claim-check MUST FIX. Keep only review-level items for author chat. Drop Internal/Discard entirely from chat. -7. Write `{slug}-findings.md` under `.cursor/lp-preflight-state/` (findings + optional verify-live notes for Phase 2). Resume aid only; chat stays short. +5. Run the [claim-check](claim-check.md) pass. Write `{slug}-claim-check.md`. Route Contradicted / Unsupported / Overstated as Fix before PR. Do not edit package JSON here. +6. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing). Keep only review-level items for later author chat. +7. Write `{slug}-findings.md` (findings + verify-live notes). 8. Mandatory audit cleanup; verify `git status`. 9. Do not cite rule numbers or audit severity labels in chat. -### Checkpoint +Then go straight to the login pause (unless `static-only` was already set). + +--- + +## PAUSE: Login + stack + +**Goal:** Author is logged into Playwright on `{learn_host}`; record stack (or allow static-only when rules permit). -> **Phase 1 complete** - static pass done. +> **Live checks next** > -> - {One plain sentence: clean, or a few things to fix} -> - **Fix before PR** (≤3 bullets, plain language; omit if none): -> - {e.g. first hands-on still depends on business-value} -> - {e.g. "You'll…" intros inside sections in create-dashboard} -> - {e.g. intro claims data never reaches Grafana Cloud; docs say queries run from the server} +> I need you logged into `{learn_host}` in the **Playwright** browser (Okta there). I can open it for you if it is not open yet. > -> **Your turn:** Reply **yes** and your test stack (for example `learn.grafana.net shared`, `fresh Cloud stack`). +> Also tell me which stack you are using (for example `learn.grafana.net shared`, `fresh Cloud stack`). > -> Or **`static-only: `** to skip live testing (not for **new** / **conversion** interactive paths). See [static-only preflight](reference-checks.md#static-only-preflight). +> Reply **ready** when the Playwright browser is logged in (include the stack in the same reply if you have not already). > -> **Up next:** Playwright DOM checks *(or readiness if static-only)*. +> Or **`static-only: `** to skip live testing (not for **new** / **conversion** interactive paths). + +**Wait for:** `ready` (+ stack), or allowed `static-only: `. Record `stack_state`, or `waive_live_testing` + `static_only_reason`. **Reject** bare `static-only` and static-only on **new** / **conversion** with interactive milestones. ---- +If static-only: skip Playwright + smoke; jump to results menu with **Not live-tested** notes. -## Phase 2: Live test - -**Goal:** Required Playwright DOM checks. Block Editor smoke is optional. +--- -Skipped when `waive_live_testing` is true → jump to Phase 3. +## Playwright DOM (no author yes between milestones) Details: [author-testing.md](author-testing.md). -### Setup (tell the author once) - -> **Phase 2 - Live test** -> -> I need the **Playwright** browser for DOM checks. Log into `{learn_host}` with Okta there, then reply **ready**. -> -> Stack: `{stack_state}` -> -> After DOM checks I will ask whether you have already smoke-tested in Block Editor (optional). - -**Wait for:** `ready`. - -### Milestone scope - | `path_type` | Scope | |---|---| | **new** / **conversion** | Every interactive milestone in path `milestones` | | **update** | Touched interactive milestones first; full path on request | -### Step A: Playwright DOM (required) - For each milestone in scope (path order; skip prose-only / terminal): 1. Derive start URL ([milestone start URL](../review-learning-path/reference-checks.md#milestone-start-url)). 2. Navigate; check each `reftarget`: exists / missing / below-fold / state-dependent. 3. Record in `playwright.{milestone-slug}`. -4. One-line DOM result in chat per milestone (or a short all-clear if clean). Prefer documenting stack gaps over false "missing" on the wrong stack. -### Step B: Block Editor (opt-in, once) +Keep chat quiet during the sweep (or a short progress line). Prefer documenting stack gaps over false "missing" on the wrong stack. + +Then go to the smoke pause. + +--- -After Playwright: +## PAUSE: Block Editor smoke > Have you already smoke-tested this path in Block Editor (Show me / Do it)? > -> Reply **`already-tested: `** if yes (stack + anything flaky). -> Reply **`walk-me`** for a guided per-milestone check now (local JSON import, not the PR review tool). -> Reply **`skip-smoke`** to continue without recording Block Editor evidence. +> - **`already-tested: `** if yes (stack + anything flaky) +> - **`walk-me`** for a guided per-milestone check now (local JSON import) +> - **`skip-smoke`** to continue without recording Block Editor evidence | Reply | Behavior | Readiness | |---|---|---| -| `already-tested: …` | Store dogfood evidence; no per-milestone loop | Can still be **Ready for PR** if Playwright clean and no open blockers | -| `walk-me` | Guided loop per [author-testing.md](author-testing.md); fold watch-fors into one line | Same when scoped milestones pass or documented N/A | -| `skip-smoke` | Continue | Cap at **Open PR with notes**; say Block Editor was not recorded | - -### Checkpoint +| `already-tested: …` | Store dogfood evidence | Can still be **Ready for PR** if Playwright clean and no open blockers | +| `walk-me` | Guided loop per [author-testing.md](author-testing.md) | Same when scoped milestones pass or documented N/A | +| `skip-smoke` | Continue | Cap at **Open PR with notes** | -> **Phase 2 complete** - live checks done. -> -> - Playwright: {short summary} -> - Block Editor: already-tested / walked / skipped -> -> **Your turn:** Reply **yes** for the readiness report. -> -> **Up next:** Phase 3 - readiness and what to fix (if anything). +After smoke (or walk-me finishes), build readiness and show the **results menu** once. --- -## Phase 3: Readiness - -**Goal:** Merge static + live into a readiness outcome; offer the right next action per finding kind. +## Results + fix menu -Author chat shape: [Author-facing findings](reference-checks.md#author-facing-findings) (package-fixable vs needs-frontend). +**Goal:** One readiness outcome; right next actions. Author chat shape: [Author-facing findings](reference-checks.md#author-facing-findings). ### Agent steps -1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree) and promote only review-level items. +1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree); promote only review-level items. 2. Apply [readiness gate](reference-checks.md#readiness-gate). 3. Write `{slug}-readiness.md` with outcome + [PR opener checklist](reference-checks.md#pr-opener-checklist). -4. In chat: follow the Phase 3 checkpoint template below. Number every open finding. Mark each as package-fixable or needs-frontend. Zero findings is first-class (skip the fix list and celebrate). -5. Map replies: `fix all` / `fix N` / combos → Phase 4 **only for package-fixable items**; `frontend` → Phase 5 for needs-frontend items; `show report` → readiness path; `done` → end with PR-opener notes. If the author says **fix N** on a needs-frontend item, clarify that a guide edit alone will not add a `data-testid` and re-offer **frontend** (or a clearly labeled temporary selector workaround if they insist). +4. Show the results menu below. Mark each finding package-fixable or needs-frontend. +5. Map replies: `fix all` / `fix N` → package fixes; `frontend` → frontend walkthrough; `show report` → readiness path; `done` → wrap with PR-opener notes. -### Checkpoint (when there are findings) +### When there are findings -Use a friendly outcome line (examples: "almost ready, with N copy fixes first"; "almost ready, with 1 selector fix first"). Do **not** lead with only the raw gate label. - -> **Phase 3 - {friendly outcome}** +> **{Friendly outcome}** > > **What we checked** -> - {e.g. Written product claims against live docs} -> - {e.g. Whether UI selectors exist on learn.grafana.net (shared stack)} -> - {e.g. Block Editor smoke: skipped / already-tested / walked} +> - {Product claims vs live docs} +> - {UI selectors on {stack}} +> - {Block Editor smoke: skipped / already-tested / walked} > > **Please fix these {N}** ({short kind}) > -> 1. {Plain problem}. {Why it matters or better wording}. +> 1. {Plain problem}. {Why / better wording}. > (`{file or dirs}`) > 2. … > -> **Your turn** *(include only the lines that apply)* -> - **fix all** / **fix N** / **fix 1,3** — package edits for copy or guide JSON we can fix here -> - **frontend** — upstream `data-testid` for item(s) {N} (live miss; no durable selector in the DOM) +> **Your turn** *(include only lines that apply)* +> - **fix all** / **fix N** / **fix 1,3** — package edits we can make here +> - **frontend** — upstream `data-testid` for item(s) {N} > - **done** — open a PR and leave these for review > - **show report** — longer write-up > -> **Heads-up** *(optional, only when useful)* -> {Stack or testing note} - -When **every** open item needs-frontend, omit **fix all** / **fix N**. Lead **Your turn** with **frontend**. +> **Heads-up** *(optional)* +> {Stack note. Remind once if needed: preflight reports are gitignored under `.cursor/lp-preflight-state/`.} -When the list mixes kinds, say which numbers **fix** covers vs **frontend**. +When every open item needs-frontend, omit **fix all** / **fix N**. Lead with **frontend**. -### Checkpoint (when clean) +### When clean -> **Phase 3 - {Ready for PR | Open PR with notes}** +> **{Ready for PR | Open PR with notes}** > > **What we checked** > - … @@ -367,47 +342,31 @@ When the list mixes kinds, say which numbers **fix** covers vs **frontend**. > **Your turn:** Reply **done** if you are opening the PR, or **show report** for the write-up. > > *(If Open PR with notes: say why in one line, e.g. Block Editor smoke was skipped.)* -> -> *(Optional **frontend** only if you want a proactive testid improvement when live already passed with a weak-but-working selector.)* --- -## Phase 4: Apply package fixes (optional) - -**Goal:** Author-requested surgical edits for **package-fixable** findings only. +## Package fixes (optional) -### Tell the author +**Goal:** Surgical edits for **package-fixable** findings only (`fix all` / `fix N`). -> **Phase 4 - Apply fixes** -> > Working on {fix all | item N | items …}. I will edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). -### Agent steps - -1. Apply only the numbered **package-fixable** findings the author requested. Do not pretend a guide `reftarget` tweak solves a needs-frontend gap unless they explicitly asked for a temporary workaround. +1. Apply only requested package-fixable findings. 2. Re-run Pathfinder CLI validate if content/manifests changed. -3. Suggest re-running Phase 2 Playwright for touched interactive milestones. +3. Suggest re-running Playwright for touched interactive milestones when relevant. 4. Do not commit unless the author explicitly asks. -### Checkpoint - -> **Phase 4 complete** - applied {N} fix(es). +> Applied {N} fix(es). > -> **Your turn:** Reply **yes** to refresh readiness, **frontend** if you still need a testid upstream, or **done**. +> **Your turn:** Want an **updated ready / not-ready summary**? Or reply **frontend** / **done**. --- -## Phase 5: Frontend selector PR (optional) - -**Goal:** When a stable selector is missing upstream, walk the author through a small `data-testid` PR. - -Follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [grafana/grafana-cmab-app#1795](https://github.com/grafana/grafana-cmab-app/pull/1795). +## Frontend selector PR (optional) -Use the step checkpoints in that doc (confirm name → confirm repo/files → approve draft → ask before push → update guide only after the testid is on the stack). +When a stable selector is missing upstream, follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [grafana/grafana-cmab-app#1795](https://github.com/grafana/grafana-cmab-app/pull/1795). -### Checkpoint - -> **Phase 5 complete** - frontend PR {url} *(or deferred)*. +> Frontend PR {url} *(or deferred)*. > > **Your turn:** Reply **done** when you are ready to open the learning path PR (or wait on the testid merge). @@ -417,46 +376,45 @@ Use the step checkpoints in that doc (confirm name → confirm repo/files → ap **Do not** -- Edit package JSON before Phase 4 / without an explicit ask +- Quiz the author between agent-only steps ("Phase N complete, reply yes") +- Edit package JSON without an explicit ask - Leave audit artifacts in milestone `assets/` - Commit `.cursor/lp-preflight-state/` - Surface Internal/Discard nits in chat or readiness -- Use em dashes, rule numbers, or Blocker labels with the author +- Use em dashes, rule numbers, Blocker labels, or "refresh readiness" - Force a full Block Editor loop when they already dogfooded - Offer **fix N** as the main path for a needs-frontend finding - Recommend **Ready for PR** with open review-level items - Recommend **Ready for PR** on **new** / **conversion** interactive paths when Playwright was skipped -- Request website-repo changes (`pathfinder_data`, shortcodes) as package blockers -- Use the PR review tool as a substitute for local import (no PR yet) +- Request website-repo changes as package blockers +- Use the PR review tool instead of local import (no PR yet) **Do** -- Mirror five-phase review checklists and Learning Hub standards +- Batch agent work; pause only for real human gates - Keep chat short, clear, and friendly - Dedupe findings by root cause - Run CLI validate when available -- Offer Phase 4 / 5 after readiness with the right action per finding kind +- Offer package vs frontend actions correctly after the results menu --- ## Generated files -Write under `.cursor/lp-preflight-state/` (never commit): - -| File | Phase | Purpose | -|---|---|---| -| `{slug}.json` | 0+ | Machine state ([schema](reference-checks.md#state-file-schema)) | -| `{slug}-findings.md` | 1 | Findings + verify-live notes | -| `{slug}-claim-check.md` | 1 | Claim-check report | -| `{slug}-readiness.md` | 3 | Readiness gate + PR opener checklist | -| `{slug}/audits/{milestone}/` | 1 (optional) | Copied audit reports before cleanup | +Write under `.cursor/lp-preflight-state/` (never commit; gitignored): -Generated markdown frontmatter: +| File | Purpose | +|---|---| +| `{slug}.json` | Machine state ([schema](reference-checks.md#state-file-schema)) | +| `{slug}-findings.md` | Findings + verify-live notes | +| `{slug}-claim-check.md` | Claim-check report | +| `{slug}-readiness.md` | Ready / not-ready summary + PR opener checklist | +| `{slug}/audits/{milestone}/` | Optional copied audit reports before cleanup | ```markdown --- disclaimer: Auto-generated by preflight-learning-path skill. Do not edit manually. -notice: To regenerate, re-run the skill from the relevant phase. +notice: To regenerate, re-run the skill from the relevant pause. path_dir: {path_dir} --- ``` diff --git a/.cursor/skills/preflight-learning-path/author-testing.md b/.cursor/skills/preflight-learning-path/author-testing.md index 7c23d27d2..29306658f 100644 --- a/.cursor/skills/preflight-learning-path/author-testing.md +++ b/.cursor/skills/preflight-learning-path/author-testing.md @@ -1,41 +1,42 @@ # Author testing (preflight) -Live-test helpers for [preflight-learning-path/SKILL.md](SKILL.md) Phase 2. +Live-test helpers for [preflight-learning-path/SKILL.md](SKILL.md). -Aligns with the five-phase [review-learning-path](../review-learning-path/SKILL.md) live path, lighter for authors: Playwright DOM is required; Block Editor is opt-in. +Aligns with the five-phase [review-learning-path](../review-learning-path/SKILL.md) live path, lighter for authors: Playwright DOM is required; Block Editor is opt-in. Fits the hard author flow: pause for login, then smoke choice; do not quiz between DOM milestones. --- ## Prerequisites -Confirm at Phase 0 / remind in the slash-command first message. +Confirm during identify (quietly unless blocked). Remind in the slash-command first message. | Need | Required when | Why | How to verify / fix | |---|---|---|---| | `interactive-tutorials` checkout with `{slug}-lj/` | Always | Package under test | Path on disk / current branch | -| **Playwright MCP** enabled (`user-playwright`) | Live path (default for new/conversion interactive) | Agent DOM checks | Phase 0: list or call Playwright MCP tools. If missing: follow [If Playwright MCP is missing](#if-playwright-mcp-is-missing) | -| Okta login in the **Playwright** browser to `{learn_host}` (default `learn.grafana.net`) | Before Playwright DOM loop | MCP cannot complete SAML alone | Phase 2: author logs in, replies `ready` | +| **Playwright MCP** enabled (`user-playwright`) | Live path (default for new/conversion interactive) | Agent DOM checks | Identify: list or call Playwright MCP tools. If missing or broken: follow [If Playwright MCP is missing or broken](#if-playwright-mcp-is-missing-or-broken) | +| Okta login in the **Playwright** browser to `{learn_host}` (default `learn.grafana.net`) | Before Playwright DOM loop | MCP cannot complete SAML alone | Login pause: author logs in, replies `ready` | | Pathfinder Block Editor on learn | Only if author chooses `walk-me` | Optional smoke coaching | `{learn_host}/plugins/grafana-pathfinder-app?dev=true` → **?** → Debug → Block Editor → import local JSON | | Pathfinder CLI (`grafana-pathfinder-app` built locally) | Nice-to-have | `validate --packages` | Note if missing; do not abort preflight | -| `gh` auth + write access to the UI repo | Phase 5 only | Frontend testid PR | Check when entering Phase 5 | +| `gh` auth + write access to the UI repo | Frontend walkthrough only | Frontend testid PR | Check when entering frontend steps | | `website` repo in workspace | Optional (conversion) | Read-only legacy compare | Never write | Same Playwright + Okta role as [learning-path-workflows/workflows.md](../../learning-path-workflows/workflows.md) and `/create-learning-path`. -### If Playwright MCP is missing +### If Playwright MCP is missing or broken -Stop at Phase 0 (or before Phase 2). Do **not** silently skip DOM checks on new/conversion interactive paths. `static-only: ` only when [static-only rules](reference-checks.md#static-only-preflight) allow it. +Stop before live DOM checks. Do **not** silently skip DOM checks on new/conversion interactive paths. `static-only: ` only when [static-only rules](reference-checks.md#static-only-preflight) allow it. Diagnose which case applies, then offer help (manual steps always; agent action when possible): | Case | How you can tell | Offer | |---|---|---| -| **Config missing** from `~/.cursor/mcp.json` (no `playwright` / `@playwright/mcp` entry) | Read `mcp.json`; server absent | Ask: **Want me to add the Playwright MCP config for you?** If yes, merge the block below into `mcp.json` (create the file if needed). Then ask them to reload MCP servers (Cursor Settings → MCP → refresh/reload, or restart the agent) and reply **ready** / **yes** so you recheck. | +| **Config missing** from `~/.cursor/mcp.json` (no `playwright` / `@playwright/mcp` entry) | Read `mcp.json`; server absent | Ask: **Want me to add the Playwright MCP config for you?** If yes, merge the standard block below into `mcp.json`. Then ask them to reload MCP and reply when ready so you recheck. | | **Needs auth** (`needsAuth` / only `mcp_auth` tool) | `GetMcpTools` / server status | Ask: **Want me to start the Playwright MCP connect flow?** If yes, call `mcp_auth` for `user-playwright` (empty args), wait, recheck. | | **Configured but toggled off** in Cursor Settings | Entry exists in `mcp.json`; tools still unavailable | Manual only: Settings → MCP → enable **Playwright**. Agent cannot flip that toggle. | -| **Errored / won't start** | Tools missing; logs or STATUS show install/runtime errors | Diagnose (`npx`, Node, network). Offer config fixes; author confirms reload. | +| **Configured but broken** | Entry exists; server shows error / tools fail / navigate fails. Common: custom CDP like `http://localhost:9222` with nothing listening | Explain the failure plainly. Offer to replace with the standard `npx @playwright/mcp@latest` block (reply **add playwright mcp** or **fix playwright mcp**). Warn that this overwrites a custom playwright entry; keep other servers. Then reload and recheck. | +| **Errored / won't start** | Tools missing; logs or STATUS show install/runtime errors | Diagnose (`npx`, Node, network). Offer the standard config; author confirms reload. | -Standard config to add when missing (do not overwrite unrelated servers): +Standard config to add or restore (do not overwrite unrelated servers; for **configured but broken**, replace only the `playwright` server entry after the author agrees): ```json { @@ -50,15 +51,17 @@ Standard config to add when missing (do not overwrite unrelated servers): **Blocked checkpoint shape (author-facing):** -> Playwright MCP isn't available, so I can't run the live DOM checks on this path yet. +> Playwright MCP isn't ready, so I can't run the live DOM checks on this path yet. > -> **Manual setup:** Cursor Settings → MCP → enable **Playwright** (or add it if it's not listed), then reload. +> **Manual setup:** Cursor Settings → MCP → enable **Playwright** (or fix / re-add it), then reload. > -> **Or:** reply **add playwright mcp** and I'll add the standard config to `~/.cursor/mcp.json` for you (you'll still need to reload MCP afterward). +> If Playwright is listed but broken (for example a CDP URL like `localhost:9222` with no browser listening), reply **fix playwright mcp** and I'll switch it to the standard `npx @playwright/mcp@latest` config. You'll still need to reload MCP afterward. +> +> **Or:** reply **add playwright mcp** if it is missing entirely. > > Skipping live checks with `static-only` isn't a fit for new or conversion interactive paths. -Never edit `mcp.json` until the author agrees. Never claim MCP is ready until `GetMcpTools` for `user-playwright` shows usable browser tools. +Never edit `mcp.json` until the author agrees. Never claim MCP is ready until `GetMcpTools` for `user-playwright` shows usable browser tools (and a quick navigate smoke succeeds when diagnosing "broken"). --- @@ -75,14 +78,14 @@ DOM exists ≠ Show me / Do it works. Reviewers still run full Block Editor smok ## Playwright DOM (required) -After author replies `ready`: +After author replies `ready` at the login pause: For each interactive milestone in scope (path order): 1. Start URL: first `on-page:/path` in milestone blocks, else path manifest `startingLocation` (same as [review milestone start URL](../review-learning-path/reference-checks.md#milestone-start-url)). 2. Navigate on `{learn_host}`. 3. For each `reftarget`, record: `exists` / `missing` / `below-fold` / `state-dependent`. -4. One-line result in chat before moving on (or a short all-clear if clean). +4. Do **not** stop for author confirmation between milestones. One short progress line is enough; save the summary for the results menu. Respect [live testing prerequisites](../review-learning-path/reference-checks.md#live-testing-prerequisites-phase-2) (stack state, credential-gated UI). Prefer documenting stack gaps over false "missing selector" on the wrong stack. diff --git a/.cursor/skills/preflight-learning-path/claim-check.md b/.cursor/skills/preflight-learning-path/claim-check.md index 1a17db8f0..7ecc4f8a3 100644 --- a/.cursor/skills/preflight-learning-path/claim-check.md +++ b/.cursor/skills/preflight-learning-path/claim-check.md @@ -2,7 +2,7 @@ Adversarial factual check for Pathfinder learning path packages. Adapted from the Learning Hub claim-check skill and the MUST FIX bar in journey audit reports. Goal: catch invented product facts before a PR, not Hugo slide structure. -Run inside [preflight Phase 1](SKILL.md#phase-1-static-pass) after audit-guide and path/LH checks, before the Phase 1 checkpoint. +Run during the [static pass](SKILL.md#static-pass-no-author-yes) after audit-guide and path/LH checks. Do not pause the author for a yes between static and login. **Independence:** Prefer a fresh agent pass that did not author the package prose. Default stance: unproven. A claim is flagged unless a source plainly supports it. @@ -49,7 +49,7 @@ Falsifiable statements about the product, including: 4. Verdict (see below). Sweep phrase + category across the whole package so the same error is one finding with multiple locations. 5. Write `.cursor/lp-preflight-state/{slug}-claim-check.md` (gitignored). -Do not edit package JSON during the claim check. Fixes wait for Phase 4 if the author asks. +Do not edit package JSON during the claim check. Fixes wait for the results menu if the author asks. --- @@ -113,10 +113,10 @@ MUST FIX first, then author-decides. Do not dump Supported claims into author ch --- -## Phase 1 / Phase 3 chat +## Author chat (results menu) -After claim-check, merge MUST FIX items into author findings (dedupe; ≤3 in Phase 1 chat). Use plain language (problem + why + file). Do **not** put verdict labels like "Contradicted" in author bullets. +After claim-check, merge MUST FIX items into the findings that feed the **one results menu** (dedupe). Use plain language (problem + why + file). Do **not** put verdict labels like "Contradicted" in author bullets. Do not open with a "What this check is" primer. -At **Phase 3**, list them as numbered **package-fixable** items and offer **fix all** / **fix N** / combos per [Author-facing findings](reference-checks.md#author-facing-findings). Do not open with a "What this check is" primer. +Offer **fix all** / **fix N** / combos for package-fixable claim items per [Author-facing findings](reference-checks.md#author-facing-findings). -If none, say the claim check found no contradicted or unsupported product facts. +If none, say the claim check found no contradicted or unsupported product facts (as part of What we checked / clean results). diff --git a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md index adc127e66..ee3480d25 100644 --- a/.cursor/skills/preflight-learning-path/frontend-selector-pr.md +++ b/.cursor/skills/preflight-learning-path/frontend-selector-pr.md @@ -1,4 +1,4 @@ -# Frontend selector PR (preflight Phase 5) +# Frontend selector PR (preflight) Walk an author through adding a stable `data-testid` upstream when Pathfinder needs one and the DOM has no good selector. @@ -15,23 +15,23 @@ Do not paste the whole #1795 diff. Link it and mirror the pattern. No em dashes --- -## When to enter Phase 5 +## When to enter -Trigger when Phase 2 shows a step needs a durable selector and: +Trigger when live checks show a step needs a durable selector and: - No `data-testid` / strong semantic attribute exists in the DOM, and - Live Playwright or walk-me failed on that step (or the author wants a proactive testid anyway), and -- They reply **`frontend`** at Phase 3 or ask during Phase 4 +- They reply **`frontend`** at the results menu or ask after package fixes -At Phase 3, treat this as a **needs-frontend** finding: lead with **frontend**, not **fix N**. A package-only `reftarget` tweak is not the real fix. Only offer a temporary weak selector in the guide if the author explicitly asks, and label it as brittle. +At the results menu, treat this as a **needs-frontend** finding: lead with **frontend**, not **fix N**. A package-only `reftarget` tweak is not the real fix. Only offer a temporary weak selector in the guide if the author explicitly asks, and label it as brittle. -If live passed with a justified `:contains()` and no stable selector exists, that stays Internal in review terms. Offer Phase 5 as an optional improvement, not a Fix-before-PR demand, unless Playwright/walk-me failed on that step. +If live passed with a justified `:contains()` and no stable selector exists, that stays Internal in review terms. Offer this walkthrough as an optional improvement, not a Fix-before-PR demand, unless Playwright/walk-me failed on that step. --- ## Walkthrough (checkpointed) -Announce **Phase 5 - frontend selector (step X of 5)** at each stop. One ask per message. +These pauses are intentional (author must approve name, repo, draft, push). Announce **Frontend selector (step X of 5)** at each stop. One ask per message. Do not call this "Phase 5" in author chat. ### 1. Confirm the element @@ -39,7 +39,7 @@ From Playwright: URL, visible label, current weak selector, screenshot or DOM sn Propose a `data-testid` (plain kebab-case, product-area prefix, matching existing testids in that app when present). -> **Phase 5 - frontend selector (step 1 of 5)** +> **Frontend selector (step 1 of 5)** > > **Element that failed live** > - Page: {url or page name} @@ -59,7 +59,7 @@ Propose a `data-testid` (plain kebab-case, product-area prefix, matching existin Use workspace clones or GitHub search. Do **not** invent file paths. -> **Phase 5 - frontend selector (step 2 of 5)** +> **Frontend selector (step 2 of 5)** > > Best guess for owning source: `{repo}` ({why}). > @@ -85,7 +85,7 @@ Adds `data-testid` attributes to {components} following the existing kebab-case Example pattern: https://github.com/grafana/grafana-cmab-app/pull/1795 ``` -> **Phase 5 - frontend selector (step 3 of 5)** +> **Frontend selector (step 3 of 5)** > > Draft change: add `{testid}` on {component summary}. Testids only; no behavior change. > @@ -104,7 +104,7 @@ Example pattern: https://github.com/grafana/grafana-cmab-app/pull/1795 3. `gh pr create` with the approved title/body 4. Follow existing grafana org repo norms; do not change repo visibility -> **Phase 5 - frontend selector (step 4 of 5)** +> **Frontend selector (step 4 of 5)** > > Ready to open the PR in `{repo}` with the approved title/body. > @@ -118,7 +118,7 @@ Update the milestone `reftarget` to the new testid **only after** the author con Until then: keep a temporary justified fallback if needed, and note the upstream PR URL in readiness / Open PR with notes. -> **Phase 5 - frontend selector (step 5 of 5)** +> **Frontend selector (step 5 of 5)** > > Frontend PR: {url} > @@ -134,4 +134,4 @@ Until then: keep a temporary justified fallback if needed, and note the upstream - Inventing component paths - Updating guide JSON to a testid that is not on the test stack yet without saying so - Treating a missing upstream testid as something to "fix" only inside `interactive-tutorials` when the DOM has no stable hook -- Offering bare **fix N** at Phase 3 as if a guide edit adds the testid +- Offering bare **fix N** at the results menu as if a guide edit adds the testid diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md index b4b563a91..386abc176 100644 --- a/.cursor/skills/preflight-learning-path/reference-checks.md +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -12,7 +12,7 @@ Author-side routing and readiness for [preflight-learning-path/SKILL.md](SKILL.m ## Author-facing findings -Use this shape whenever you list Fix-before-PR items in chat (especially Phase 3). Do **not** open with a "What this check is" primer. Match [Voice](SKILL.md#voice-author-facing). +Use this shape for the **one results menu** after live (or after allowed static-only). Do **not** open with a "What this check is" primer. Match [Voice](SKILL.md#voice-author-facing). 1. **Friendly outcome line** (e.g. "almost ready, with 3 copy fixes first"). Keep gate labels in the readiness file; chat can stay plainer. 2. **What we checked** — short bullets in plain language (product claims vs docs, UI selectors on `{stack}`, Block Editor smoke choice). @@ -26,14 +26,14 @@ Use this shape whenever you list Fix-before-PR items in chat (especially Phase 3 ### Package-fixable vs needs-frontend -| Kind | Examples | Phase 3 offer | +| Kind | Examples | Results menu offer | |---|---|---| | **Package-fixable** | Claim-check copy, framing/`depends`, fake in-section steps, false noops, wrong `reftarget` when a stable testid already exists in the DOM | **fix N** / **fix all** | | **Needs-frontend** | Playwright or walk-me failed; element has no durable selector in the DOM | **frontend** (primary). Optional: clearly labeled **try temporary selector** only if the author asks for a brittle package workaround. Never present bare **fix N** as the main path for this kind | When the list mixes both kinds, number everything, but in **Your turn** say which numbers **fix** covers and that **frontend** covers the selector gap (e.g. "fix 2,3 for copy; **frontend** for item 1"). -Keep Phase 1 lighter (short Fix-before-PR bullets + stack ask). Put the full numbered + fix-choice treatment at Phase 3 after live results land. +Keep the identify + static work quiet when the path is known. Put the full numbered + fix-choice treatment in the **one results menu** after live (or after allowed static-only). --- @@ -106,7 +106,7 @@ Infer from branch diff, directory age, and legacy website source. Record in `{sl ## Static-only preflight -`static-only: ` at Phase 1 end skips Phase 2. +`static-only: ` at the **login / stack pause** skips Playwright and smoke (jump to the results menu). | Situation | Allowed? | |---|---| From d4613396a51017d0e0e6e6bee7c22ecdd6e4362d Mon Sep 17 00:00:00 2001 From: Taylor Cole Date: Mon, 27 Jul 2026 11:25:49 -0700 Subject: [PATCH 9/9] Address moxious review: shared claim-check, checkpoints, static-only. Make claim-check the shared policy for review and preflight, persist named checkpoints for resume, make static-only rows exclusive with precedence, and fix the section-intro markdown anchor. Co-authored-by: Cursor --- .cursor/commands/preflight-learning-path.md | 2 +- .cursor/learning-path-workflows/workflows.md | 2 +- .../skills/preflight-learning-path/SKILL.md | 52 ++++--- .../preflight-learning-path/claim-check.md | 123 +--------------- .../reference-checks.md | 26 +++- .cursor/skills/review-learning-path/SKILL.md | 19 +-- .../review-learning-path/claim-check.md | 133 ++++++++++++++++++ .../review-learning-path/reference-checks.md | 15 +- AGENTS.md | 2 +- 9 files changed, 218 insertions(+), 156 deletions(-) create mode 100644 .cursor/skills/review-learning-path/claim-check.md diff --git a/.cursor/commands/preflight-learning-path.md b/.cursor/commands/preflight-learning-path.md index 0d20fb898..ad34a3aa7 100644 --- a/.cursor/commands/preflight-learning-path.md +++ b/.cursor/commands/preflight-learning-path.md @@ -1,6 +1,6 @@ ## Command: /preflight-learning-path -Self-review a learning path package in `interactive-tutorials` **before** opening a PR. Same checks as [/review-learning-path-pr](review-learning-path-pr.md), from the author side, with fewer stop-and-type moments: the agent runs what it can, then pauses only when it needs you (login, smoke choice, results / fixes). +Self-review a learning path package in `interactive-tutorials` **before** opening a PR. Mirrors [/review-learning-path-pr](review-learning-path-pr.md) (shared static checklists, shared claim-check, Playwright DOM) from the author side, with fewer stop-and-type moments: the agent runs what it can, then pauses only when it needs you (login, smoke choice, results / fixes). When invoked, read and follow **[preflight-learning-path/SKILL.md](../skills/preflight-learning-path/SKILL.md)** in order. diff --git a/.cursor/learning-path-workflows/workflows.md b/.cursor/learning-path-workflows/workflows.md index 40182979c..24be14b1a 100644 --- a/.cursor/learning-path-workflows/workflows.md +++ b/.cursor/learning-path-workflows/workflows.md @@ -103,4 +103,4 @@ The learning path slug is mysql-data-source. | `/build-interactive-lj` | Existing milestone markdown in website repo (read-only source) | `content.json` + `manifest.json` + `website.yaml` files in interactive-tutorials | | `/create-learning-path` | Feature description (no existing markdown) | `content.json` + `manifest.json` + `website.yaml` files | | `/review-learning-path-pr` | Existing LP PR in `interactive-tutorials` (share PR URL/number) | Human-guided review: static workbook, Block Editor smoke test, chat-approved inline comments, submit | -| `/preflight-learning-path` | Local `{slug}-lj/` package before opening a PR | Author self-review with few pauses (login, smoke choice, results): same static + Playwright checks as review, readiness report, optional fixes / frontend testid PR | +| `/preflight-learning-path` | Local `{slug}-lj/` package before opening a PR | Author self-review with few pauses (login, smoke choice, results): mirrors review static + Playwright checks and shared claim-check, readiness report, optional fixes / frontend testid PR | diff --git a/.cursor/skills/preflight-learning-path/SKILL.md b/.cursor/skills/preflight-learning-path/SKILL.md index 1413e5cc4..f3c3fa539 100644 --- a/.cursor/skills/preflight-learning-path/SKILL.md +++ b/.cursor/skills/preflight-learning-path/SKILL.md @@ -2,27 +2,26 @@ name: preflight-learning-path description: >- Guide a learning path author through pre-PR self-review in interactive-tutorials. - Mirrors the five-phase /review-learning-path-pr coach from the author side: static - pass (including adversarial claim-check), Playwright DOM checks, readiness report, - optional package fixes, and optional frontend data-testid PR. Use when the user - runs /preflight-learning-path. + Mirrors /review-learning-path-pr (shared static checklists, shared claim-check, + Playwright DOM, readiness) from the author side, then optional package fixes and + optional frontend data-testid PR. Use when the user runs /preflight-learning-path. --- # Preflight learning path (author self-review) -Walk through a `{slug}-lj/` package **before you open a PR**. Same checks as the five-phase [review-learning-path](../review-learning-path/SKILL.md) coach, from the author side: static pass, live DOM checks, readiness, then optional fixes. +Walk through a `{slug}-lj/` package **before you open a PR**. Mirrors [review-learning-path](../review-learning-path/SKILL.md): shared static checklists, shared [claim-check](../review-learning-path/claim-check.md), Playwright DOM, then readiness and optional fixes. Author flow batches agent work and pauses only at real human gates (not a five-stop quiz). **Terminology:** Say **learning path** or **path** in author messages; use `{path_dir}` in agent notes. **Entry command:** [/preflight-learning-path](../../commands/preflight-learning-path.md) -**Mirror skill:** [review-learning-path](../review-learning-path/SKILL.md) (five-phase coach on main only). Do **not** use outdated review skill phases or Always-inline routing. +**Mirror skill:** [review-learning-path](../review-learning-path/SKILL.md). Shared claim policy lives under the review skill so both callers cannot drift. -**Do NOT read external reference files upfront.** Each phase loads its own references on demand. +**Do NOT read external reference files upfront.** Each step loads its own references on demand. -**Skill memory:** State lives in `.cursor/lp-preflight-state/` (gitignored; never commit). Phase 1 dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/`. See [Commit safety](#commit-safety). +**Skill memory:** State lives in `.cursor/lp-preflight-state/` (gitignored; never commit). Static pass dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/`. See [Commit safety](#commit-safety). -**Routing:** [reference-checks.md](reference-checks.md) · [claim-check.md](claim-check.md) · [author-testing.md](author-testing.md) · [frontend-selector-pr.md](frontend-selector-pr.md) · shared [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) · shared [review reference-checks](../review-learning-path/reference-checks.md) +**Routing:** [reference-checks.md](reference-checks.md) · [claim-check.md](claim-check.md) (pointer) · [author-testing.md](author-testing.md) · [frontend-selector-pr.md](frontend-selector-pr.md) · shared [claim-check](../review-learning-path/claim-check.md) · shared [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md) · shared [review reference-checks](../review-learning-path/reference-checks.md) **Related:** [audit-guide](../audit-guide/SKILL.md) · [update-guide](../update-guide/SKILL.md) · [review-learning-path](../review-learning-path/SKILL.md) @@ -60,7 +59,7 @@ Do as much as you can without stopping. Authors should not confirm every interna **Do not** pause for "Phase 0 complete, reply yes" or "Phase 1 complete, reply yes" when the path is known and MCP is healthy. Run identify → static → then ask for login in one beat. -Internal phase numbers (0–5) stay in state and agent notes. Author chat can say "checking your path," "live checks," "results" instead of a quiz board. +Internal **checkpoint** names (see [state schema](reference-checks.md#state-file-schema)) stay in state and agent notes. Author chat can say "checking your path," "live checks," "results" instead of a quiz board. --- @@ -175,16 +174,20 @@ After package fixes, ask: **Want an updated ready / not-ready summary?** (not "r If `.cursor/lp-preflight-state/{slug}.json` exists: -> **Resume?** I have an in-progress preflight for `{path_dir}` (stopped at {plain pause name}). +> **Resume?** I have an in-progress preflight for `{path_dir}` (stopped at **`{checkpoint}`**). > > Reply **resume** to pick up, or **start fresh** to begin again. +On resume, read `checkpoint` + `status` from state and continue from that gate. Do not invent a numeric phase. + --- ## Identify path + MCP (quiet unless blocked) **Goal:** Confirm `{path_dir}`, `path_type`, milestones; verify Playwright MCP; init state. +**Persist:** After init (or when blocked on MCP), set `checkpoint` to `identify` (still blocked) or `login` (ready for login pause). Set `status: in_progress`. + ### Author chat If `{path_dir}` is missing or ambiguous: @@ -205,7 +208,7 @@ Mention once (early, not every pause): reports land under `.cursor/lp-preflight- 6. **Verify Playwright MCP** (`user-playwright`). Cover missing, needs-auth, toggled-off, **and configured-but-broken** per [If Playwright MCP is missing or broken](author-testing.md#if-playwright-mcp-is-missing-or-broken). Do not silently skip. Do not edit `mcp.json` until they agree. 7. Write `.cursor/lp-preflight-state/{slug}.json` ([state schema](reference-checks.md#state-file-schema)). -If MCP is blocked, stop with the blocked shape in author-testing.md. Do not run live later until tools work. +If MCP is blocked, stop with the blocked shape in author-testing.md (`checkpoint: identify`). Do not run live later until tools work. --- @@ -213,13 +216,15 @@ If MCP is blocked, stop with the blocked shape in author-testing.md. Do not run **Goal:** Audit every milestone + path consistency + Learning Hub + claim-check. Keep findings for the final results menu. +**Persist:** Keep `checkpoint: login` while static runs (next human gate). Do not invent a separate author-facing "static done" pause. + ### Agent steps 1. Snapshot `pre_review_assets`; dispatch [audit-guide](../audit-guide/SKILL.md) per milestone (parallel OK). 2. Walk shared [review reference-checks](../review-learning-path/reference-checks.md) + [learning-hub-standards.md](../review-learning-path/learning-hub-standards.md). -3. **Always scan** for framing-in-milestones, [section intro markdown that may number as a step](../review-learning-path/reference-checks.md#section-intro-markdown-numbered-as-step), and [false noops](../review-learning-path/reference-checks.md#noop-and-non-interactive-steps). +3. **Always scan** for framing-in-milestones, [section intro markdown that may number as a step](../review-learning-path/reference-checks.md#section-intro-markdown-numbered-as-a-step), and [false noops](../review-learning-path/reference-checks.md#noop-and-non-interactive-steps). 4. Run Pathfinder CLI `validate --packages {path_dir}` if available. -5. Run the [claim-check](claim-check.md) pass. Write `{slug}-claim-check.md`. Route Contradicted / Unsupported / Overstated as Fix before PR. Do not edit package JSON here. +5. Run the shared [claim-check](../review-learning-path/claim-check.md) pass (preflight pointer: [claim-check.md](claim-check.md)). Write `{slug}-claim-check.md`. Route Contradicted / Unsupported / Overstated as Fix before PR. Do not edit package JSON here. 6. Tag findings with review [finding routing](../review-learning-path/reference-checks.md#finding-routing). Keep only review-level items for later author chat. 7. Write `{slug}-findings.md` (findings + verify-live notes). 8. Mandatory audit cleanup; verify `git status`. @@ -233,6 +238,8 @@ Then go straight to the login pause (unless `static-only` was already set). **Goal:** Author is logged into Playwright on `{learn_host}`; record stack (or allow static-only when rules permit). +**Persist:** Before asking, `checkpoint: login`. After `ready`, set `checkpoint: dom`. After allowed `static-only`, set `checkpoint: results` and `waive_live_testing`. + > **Live checks next** > > I need you logged into `{learn_host}` in the **Playwright** browser (Okta there). I can open it for you if it is not open yet. @@ -247,7 +254,7 @@ Then go straight to the login pause (unless `static-only` was already set). Record `stack_state`, or `waive_live_testing` + `static_only_reason`. -**Reject** bare `static-only` and static-only on **new** / **conversion** with interactive milestones. +**Reject** bare `static-only` and static-only on **new** / **conversion** with interactive milestones. Precedence: [static-only preflight](reference-checks.md#static-only-preflight). If static-only: skip Playwright + smoke; jump to results menu with **Not live-tested** notes. @@ -257,6 +264,8 @@ If static-only: skip Playwright + smoke; jump to results menu with **Not live-te Details: [author-testing.md](author-testing.md). +**Persist:** `checkpoint: dom` while sweeping; set `checkpoint: smoke` when DOM is done (before the smoke ask). + | `path_type` | Scope | |---|---| | **new** / **conversion** | Every interactive milestone in path `milestones` | @@ -276,6 +285,8 @@ Then go to the smoke pause. ## PAUSE: Block Editor smoke +**Persist:** Before asking, `checkpoint: smoke`. After the author replies, set `checkpoint: results` (or stay on `smoke` during walk-me until scoped milestones finish). + > Have you already smoke-tested this path in Block Editor (Show me / Do it)? > > - **`already-tested: `** if yes (stack + anything flaky) @@ -296,6 +307,8 @@ After smoke (or walk-me finishes), build readiness and show the **results menu** **Goal:** One readiness outcome; right next actions. Author chat shape: [Author-facing findings](reference-checks.md#author-facing-findings). +**Persist:** `checkpoint: results` when showing the menu. On `fix all` / `fix N` → `checkpoint: package_fixes`. On `frontend` → `checkpoint: frontend`. On `done` → `status: complete`, keep `checkpoint: results` (or `frontend` if that was last). + ### Agent steps 1. Apply [selector decision tree](../review-learning-path/reference-checks.md#selector-decision-tree); promote only review-level items. @@ -349,6 +362,8 @@ When every open item needs-frontend, omit **fix all** / **fix N**. Lead with **f **Goal:** Surgical edits for **package-fixable** findings only (`fix all` / `fix N`). +**Persist:** `checkpoint: package_fixes` while editing; return to `checkpoint: results` after offering an updated summary. + > Working on {fix all | item N | items …}. I will edit `content.json` / `manifest.json` / `website.yaml` only, same discipline as [update-guide](../update-guide/SKILL.md). 1. Apply only requested package-fixable findings. @@ -366,6 +381,8 @@ When every open item needs-frontend, omit **fix all** / **fix N**. Lead with **f When a stable selector is missing upstream, follow [frontend-selector-pr.md](frontend-selector-pr.md). Canonical example: [grafana/grafana-cmab-app#1795](https://github.com/grafana/grafana-cmab-app/pull/1795). +**Persist:** `checkpoint: frontend` for the whole walkthrough. + > Frontend PR {url} *(or deferred)*. > > **Your turn:** Reply **done** when you are ready to open the learning path PR (or wait on the testid merge). @@ -388,14 +405,17 @@ When a stable selector is missing upstream, follow [frontend-selector-pr.md](fro - Recommend **Ready for PR** on **new** / **conversion** interactive paths when Playwright was skipped - Request website-repo changes as package blockers - Use the PR review tool instead of local import (no PR yet) +- Leave `checkpoint` stale across gates (resume depends on it) **Do** - Batch agent work; pause only for real human gates +- Persist named `checkpoint` after each gate - Keep chat short, clear, and friendly - Dedupe findings by root cause - Run CLI validate when available - Offer package vs frontend actions correctly after the results menu +- Run the shared claim-check (same policy as review) --- @@ -426,7 +446,7 @@ path_dir: {path_dir} | Topic | Doc | |---|---| | Author routing + readiness | [reference-checks.md](reference-checks.md) | -| Claim-check (product facts) | [claim-check.md](claim-check.md) | +| Claim-check (product facts) | [../review-learning-path/claim-check.md](../review-learning-path/claim-check.md) (pointer: [claim-check.md](claim-check.md)) | | Prereqs + Playwright + optional smoke | [author-testing.md](author-testing.md) | | Frontend testid PR | [frontend-selector-pr.md](frontend-selector-pr.md) | | Shared static checklists + finding routing | [../review-learning-path/reference-checks.md](../review-learning-path/reference-checks.md) | diff --git a/.cursor/skills/preflight-learning-path/claim-check.md b/.cursor/skills/preflight-learning-path/claim-check.md index 7ecc4f8a3..175874c72 100644 --- a/.cursor/skills/preflight-learning-path/claim-check.md +++ b/.cursor/skills/preflight-learning-path/claim-check.md @@ -1,122 +1,7 @@ -# Claim check (preflight) +# Claim check (preflight pointer) -Adversarial factual check for Pathfinder learning path packages. Adapted from the Learning Hub claim-check skill and the MUST FIX bar in journey audit reports. Goal: catch invented product facts before a PR, not Hugo slide structure. +**Canonical policy:** [../review-learning-path/claim-check.md](../review-learning-path/claim-check.md) -Run during the [static pass](SKILL.md#static-pass-no-author-yes) after audit-guide and path/LH checks. Do not pause the author for a yes between static and login. +Shared by `/preflight-learning-path` and `/review-learning-path-pr`. Do not maintain a second verdict table here. -**Independence:** Prefer a fresh agent pass that did not author the package prose. Default stance: unproven. A claim is flagged unless a source plainly supports it. - ---- - -## Scope (path package) - -Read all prose that learners see: - -- Path root `content.json` markdown blocks -- Every milestone `content.json` markdown (including framing dirs not in path `milestones`, if present) -- Interactive step `content` / tooltips that state product facts (skip pure click instructions) -- Path and milestone `website.yaml` `description` / CTA copy when it asserts product behavior - -Skip: pure navigation instructions ("Click **Save**"), structural Pathfinder rules, and restatements of UI chrome with no product claim. - -Website repo (when in workspace) is **read-only** for sources (`content/docs/...`). Do not require a companion website PR. - ---- - -## What counts as a claim - -Falsifiable statements about the product, including: - -- What a feature does or does not do -- Feature / product / alert / dashboard names -- Versions, defaults, limits, prerequisites, platform availability -- Absolutes and quantifiers (only, never, all, every, must, N dashboards, N alerts) -- Comparisons that rank or prescribe one Grafana capability over another - -### Not claims - -- "In this milestone you will…" framing -- UI click paths without a product assertion -- Learning Hub boilerplate that matches standards verbatim - ---- - -## Procedure - -1. Extract claims (batch by milestone; include path root). -2. For each claim, find a source: local `website` docs first, then WebFetch to live grafana.com docs. No source → **Unsupported**. -3. Open the source; quote the supporting or contradicting line. -4. Verdict (see below). Sweep phrase + category across the whole package so the same error is one finding with multiple locations. -5. Write `.cursor/lp-preflight-state/{slug}-claim-check.md` (gitignored). - -Do not edit package JSON during the claim check. Fixes wait for the results menu if the author asks. - ---- - -## Verdicts - -| Verdict | Meaning | Preflight routing | -|---|---|---| -| **Supported** | Source plainly states the claim | Hide (optional Supported list in the report only) | -| **Contradicted** | Source says something different | Fix before PR (review-level) | -| **Unsupported** | No source, or source does not address it | Fix before PR (review-level) | -| **Overstated** | Source supports a weaker version; claim adds absolute/superlative/framing | Fix before PR (review-level) | -| **Author decides** | Product-truth call a human must make | Optional open question in readiness; do not auto-edit | - -Only Contradicted / Unsupported / Overstated count toward Fix before PR (dedupe by root cause). Soft style nits stay out of chat. - ---- - -## Catches that matter (linter cannot) - -1. Made-up facts -2. Invented terms / alert names / dashboard names -3. Overstatements (counts, "zero impact," "most/all/every") -4. Competitive or prescriptive framing without a source -5. Pre-GA / preview features taught as GA - ---- - -## Report format - -Write `.cursor/lp-preflight-state/{slug}-claim-check.md`: - -```markdown ---- -disclaimer: Auto-generated by preflight-learning-path claim-check. Do not edit manually. -path_dir: {path_dir} ---- - -# Claim check: {path_dir} - -**Claims checked: N | Supported: N | Contradicted: N | Unsupported: N | Overstated: N** - -## MUST FIX (Fix before PR) - -### Contradicted -1. `{file}` - {claim}. Source: {quote or URL}. Fix: {one line}. - -### Unsupported -… - -### Overstated -… - -## Author decides -… - -## Sources used -… -``` - -MUST FIX first, then author-decides. Do not dump Supported claims into author chat. No em dashes in the report body. - ---- - -## Author chat (results menu) - -After claim-check, merge MUST FIX items into the findings that feed the **one results menu** (dedupe). Use plain language (problem + why + file). Do **not** put verdict labels like "Contradicted" in author bullets. Do not open with a "What this check is" primer. - -Offer **fix all** / **fix N** / combos for package-fixable claim items per [Author-facing findings](reference-checks.md#author-facing-findings). - -If none, say the claim check found no contradicted or unsupported product facts (as part of What we checked / clean results). +When preflight runs the static pass, follow that file. Write the report to `.cursor/lp-preflight-state/{slug}-claim-check.md` and use the **Preflight (results menu)** chat section. diff --git a/.cursor/skills/preflight-learning-path/reference-checks.md b/.cursor/skills/preflight-learning-path/reference-checks.md index 386abc176..bb1a651af 100644 --- a/.cursor/skills/preflight-learning-path/reference-checks.md +++ b/.cursor/skills/preflight-learning-path/reference-checks.md @@ -61,7 +61,7 @@ Apply the same five-phase coach rules (cite shared reference-checks; do not soft - Path root / manifest `id` mismatch; Pathfinder CLI validate failure - Secrets `doIt: true`; confirmed 404s; conversion prose only in legacy markdown - Fragile / wrong selectors when live fails, or stable `data-testid` exists in DOM and the guide uses a weak selector -- **Claim-check MUST FIX:** Contradicted, Unsupported, or Overstated product facts per [claim-check.md](claim-check.md) (made-up counts, invented names, docs contradictions) +- **Claim-check MUST FIX:** Contradicted, Unsupported, or Overstated product facts per shared [claim-check.md](../review-learning-path/claim-check.md) (made-up counts, invented names, docs contradictions) ### Never surface @@ -86,7 +86,7 @@ Apply every section from [../review-learning-path/reference-checks.md](../review - noop and non-interactive steps - CODEOWNERS (discard for author chat) -Then run [claim-check.md](claim-check.md) across path root + milestone prose. Route Contradicted / Unsupported / Overstated as Fix before PR. Hide Supported from chat. Author-decides items may appear in readiness as open questions. +Then run shared [claim-check.md](../review-learning-path/claim-check.md) across path root + milestone prose. Route Contradicted / Unsupported / Overstated as Fix before PR. Hide Supported from chat. Author-decides items may appear in readiness as open questions. Tag each finding; keep only post-inline for author-facing output. @@ -108,13 +108,22 @@ Infer from branch diff, directory age, and legacy website source. Record in `{sl `static-only: ` at the **login / stack pause** skips Playwright and smoke (jump to the results menu). +**Precedence (evaluate in order; first match wins):** + +1. **Bare `static-only` (no reason)** → always **reject**. +2. **`path_type` is `new` or `conversion` and the path has interactive milestones** → always **reject**, even if the author cites "no stack access" or "practice run." Playwright is mandatory here. +3. **`path_type` is `update` and the change touches only markdown / `website.yaml` (no interactive selector work)** → **allow** with a non-empty reason. Cap readiness (never **Ready for PR** if interactive milestones exist and were not live-tested). +4. **Practice run / no stack access on `update` only** → **allow** with a non-empty reason. Cap readiness the same way. +5. Anything else → **reject** and ask for a clearer reason or proceed with live checks. + | Situation | Allowed? | |---|---| -| **new** / **conversion** with interactive milestones | **No** | +| Bare `static-only` | **No** | +| **new** / **conversion** with interactive milestones (any reason, including no stack) | **No** | | **update** touching only markdown / `website.yaml` | Yes, with reason | -| Practice run / no stack access | Yes, with reason (caps readiness) | +| **update** practice / no stack access | Yes, with reason (caps readiness) | -Reject bare `static-only`. Record `waive_live_testing` + `static_only_reason`. +Record `waive_live_testing` + `static_only_reason` only when allowed. When live was skipped or incomplete, readiness must include **Not live-tested** (interactive path `milestones` minus recorded Playwright results). Never recommend **Ready for PR** for new/conversion interactive when Playwright was waived. @@ -174,7 +183,7 @@ Path: `.cursor/lp-preflight-state/{slug}.json` "smoke_mode": null, "smoke_notes": null, "pre_review_assets": {}, - "phase": 3, + "checkpoint": "login", "status": "in_progress", "readiness": null, "playwright": {}, @@ -189,9 +198,12 @@ Path: `.cursor/lp-preflight-state/{slug}.json` | `smoke_notes` | Author notes for already-tested / skip | | `pathfinder` | Only when `walk-me`; keys = milestone slug | | `playwright` | DOM results per milestone | -| `phase` | Integer 0–5 | +| `checkpoint` | Named gate (required). One of: `identify` \| `login` \| `dom` \| `smoke` \| `results` \| `package_fixes` \| `frontend`. Persist at every gate per [SKILL.md](SKILL.md). Do **not** use integer phase 0–5. | +| `status` | `in_progress` \| `blocked` \| `complete` | | `readiness` | `Ready for PR` \| `Fix then re-preflight` \| `Open PR with notes` | +Legacy state files with numeric `phase` are invalid for resume: ask **start fresh**, or map once (`0`→`identify`, `1`→`login`, `2`→`dom`, `3`→`results`, `4`→`package_fixes`, `5`→`frontend`) then rewrite `checkpoint` and drop `phase`. + --- ## Pathfinder CLI validate diff --git a/.cursor/skills/review-learning-path/SKILL.md b/.cursor/skills/review-learning-path/SKILL.md index 684e90417..0154c9571 100644 --- a/.cursor/skills/review-learning-path/SKILL.md +++ b/.cursor/skills/review-learning-path/SKILL.md @@ -21,7 +21,7 @@ Help a **human reviewer** work through a `{slug}-lj/` pull request in **five pha **Skill memory:** State lives in `.cursor/pr-review-state/` (gitignored). Phase 1 dispatches [audit-guide](../audit-guide/SKILL.md), which writes `{milestone}/assets/` on the PR branch. See [Commit safety](#commit-safety). -**Routing:** [reference-checks.md](reference-checks.md) · [comment-style.md](comment-style.md) · [learning-hub-standards.md](learning-hub-standards.md) · [github-review.md](github-review.md) +**Routing:** [reference-checks.md](reference-checks.md) · [claim-check.md](claim-check.md) · [comment-style.md](comment-style.md) · [learning-hub-standards.md](learning-hub-standards.md) · [github-review.md](github-review.md) **Related:** [audit-guide](../audit-guide/SKILL.md) · [review-guide-pr.mdc](../../review-guide-pr.mdc) · [preflight-learning-path](../preflight-learning-path/SKILL.md) (author pre-PR mirror) @@ -148,7 +148,7 @@ If `.cursor/pr-review-state/pr-{n}.json` exists: ## Phase 1: Static pass -**Goal:** Audit every milestone + path consistency + Learning Hub checks. Output: **internal workbook only**. +**Goal:** Audit every milestone + path consistency + Learning Hub checks + shared [claim-check](claim-check.md). Output: **internal workbook only**. Combines the former Phases 1–2 and workbook write. @@ -162,15 +162,16 @@ Combines the former Phases 1–2 and workbook write. 1. Snapshot `pre_review_assets`; dispatch [audit-guide](../audit-guide/SKILL.md) per milestone (parallel OK). 2. Walk all [reference-checks.md](reference-checks.md) checklists + [learning-hub-standards.md](learning-hub-standards.md). -3. **Always scan** for [section intro markdown that may number as a step](reference-checks.md#section-intro-markdown-numbered-as-step) and [false noops](reference-checks.md#noop-and-non-interactive-steps). Put matches under **Verify in Block Editor**. +3. **Always scan** for [section intro markdown that may number as a step](reference-checks.md#section-intro-markdown-numbered-as-a-step) and [false noops](reference-checks.md#noop-and-non-interactive-steps). Put matches under **Verify in Block Editor**. 4. Run Pathfinder CLI validate if available. -5. Tag every finding with [finding routing](reference-checks.md#finding-routing): **post inline**, **internal**, or **discard**. -6. Write `pr-{n}-findings.md` — header: *"Reviewer workbook — internal only. Do not paste to PR."* +5. Run the shared [claim-check](claim-check.md) pass. Write `pr-{n}-claim-check.md`. Route Contradicted / Unsupported / Overstated as **post inline** (same bar as preflight). Do not edit package JSON here. +6. Tag every finding with [finding routing](reference-checks.md#finding-routing): **post inline**, **internal**, or **discard**. +7. Write `pr-{n}-findings.md` — header: *"Reviewer workbook — internal only. Do not paste to PR."* - **Verify in Block Editor** — items that need live test to confirm (include section-intro markdown and false-noop candidates) - - **Post inline if confirmed** — static compliance issues (broken depends, id mismatch, CLI fail) + - **Post inline if confirmed** — static compliance issues (broken depends, id mismatch, CLI fail) and claim-check MUST FIX items - **Internal** — nits, LH editorial, selector polish, `website.yaml` gaps -7. Mandatory audit cleanup; verify `git status`. -8. **Do not** cite rule numbers or blocking counts in chat. +8. Mandatory audit cleanup; verify `git status`. +9. **Do not** cite rule numbers or blocking counts in chat. ### Checkpoint @@ -399,6 +400,7 @@ Not a numbered phase. New review cycle for major author pushes. Use REST inline |---|---|---| | `pr-{n}.json` | 0+ | State ([schema](github-review.md#state-file-schema)) | | `pr-{n}-findings.md` | 1 | **Internal workbook** — never paste to author | +| `pr-{n}-claim-check.md` | 1 | Shared claim-check report ([claim-check.md](claim-check.md)) | | `pr-{n}-review-body.md` | 3 → 4 | Final summary for GitHub submit | Workbook frontmatter: @@ -418,6 +420,7 @@ pr_number: {n} | Topic | Doc | |---|---| | Finding routing + checklists | [reference-checks.md](reference-checks.md) | +| Claim-check (shared with preflight) | [claim-check.md](claim-check.md) | | Comment voice + summary | [comment-style.md](comment-style.md) | | Learning Hub checks (workbook) | [learning-hub-standards.md](learning-hub-standards.md) | | GitHub GraphQL | [github-review.md](github-review.md) | diff --git a/.cursor/skills/review-learning-path/claim-check.md b/.cursor/skills/review-learning-path/claim-check.md new file mode 100644 index 000000000..9b56af5b7 --- /dev/null +++ b/.cursor/skills/review-learning-path/claim-check.md @@ -0,0 +1,133 @@ +# Claim check (shared learning-path policy) + +Adversarial factual check for Pathfinder learning path packages. Adapted from the Learning Hub claim-check skill and the MUST FIX bar in journey audit reports. Goal: catch invented product facts, not Hugo slide structure. + +**Canonical policy for both** [review-learning-path](SKILL.md) and [preflight-learning-path](../preflight-learning-path/SKILL.md). Do not fork a second verdict table. Preflight keeps a thin pointer at `../preflight-learning-path/claim-check.md` that redirects here. + +**When to run:** During the static pass, after audit-guide and path / Learning Hub checks, before the live gate. + +**Independence:** Prefer a fresh agent pass that did not author the package prose. Default stance: unproven. A claim is flagged unless a source plainly supports it. + +--- + +## Scope (path package) + +Read all prose that learners see: + +- Path root `content.json` markdown blocks +- Every milestone `content.json` markdown (including framing dirs not in path `milestones`, if present) +- Interactive step `content` / tooltips that state product facts (skip pure click instructions) +- Path and milestone `website.yaml` `description` / CTA copy when it asserts product behavior + +Skip: pure navigation instructions ("Click **Save**"), structural Pathfinder rules, and restatements of UI chrome with no product claim. + +Website repo (when in workspace) is **read-only** for sources (`content/docs/...`). Do not require a companion website PR. + +--- + +## What counts as a claim + +Falsifiable statements about the product, including: + +- What a feature does or does not do +- Feature / product / alert / dashboard names +- Versions, defaults, limits, prerequisites, platform availability +- Absolutes and quantifiers (only, never, all, every, must, N dashboards, N alerts) +- Comparisons that rank or prescribe one Grafana capability over another + +### Not claims + +- "In this milestone you will…" framing +- UI click paths without a product assertion +- Learning Hub boilerplate that matches standards verbatim + +--- + +## Procedure + +1. Extract claims (batch by milestone; include path root). +2. For each claim, find a source: local `website` docs first, then WebFetch to live grafana.com docs. No source → **Unsupported**. +3. Open the source; quote the supporting or contradicting line. +4. Verdict (see below). Sweep phrase + category across the whole package so the same error is one finding with multiple locations. +5. Write the report (path depends on caller; see below). + +Do not edit package JSON during the claim check. Fixes wait for author request (preflight) or reviewer post approval (review). + +--- + +## Verdicts + +| Verdict | Meaning | Shared routing | +|---|---|---| +| **Supported** | Source plainly states the claim | Hide (optional Supported list in the report only) | +| **Contradicted** | Source says something different | Review-level: **post inline** / Fix before PR | +| **Unsupported** | No source, or source does not address it | Review-level: **post inline** / Fix before PR | +| **Overstated** | Source supports a weaker version; claim adds absolute/superlative/framing | Review-level: **post inline** / Fix before PR | +| **Author decides** | Product-truth call a human must make | Workbook / readiness open question; do not auto-edit | + +Only Contradicted / Unsupported / Overstated count toward review-level findings (dedupe by root cause). Soft style nits stay Internal / out of author chat. + +--- + +## Catches that matter (linter cannot) + +1. Made-up facts +2. Invented terms / alert names / dashboard names +3. Overstatements (counts, "zero impact," "most/all/every") +4. Competitive or prescriptive framing without a source +5. Pre-GA / preview features taught as GA + +--- + +## Report paths + +| Caller | Report file | +|---|---| +| **preflight** | `.cursor/lp-preflight-state/{slug}-claim-check.md` | +| **review** | `.cursor/pr-review-state/pr-{n}-claim-check.md` | + +```markdown +--- +disclaimer: Auto-generated by learning-path claim-check. Do not edit manually. +path_dir: {path_dir} +--- + +# Claim check: {path_dir} + +**Claims checked: N | Supported: N | Contradicted: N | Unsupported: N | Overstated: N** + +## MUST FIX (review-level) + +### Contradicted +1. `{file}` - {claim}. Source: {quote or URL}. Fix: {one line}. + +### Unsupported +… + +### Overstated +… + +## Author decides +… + +## Sources used +… +``` + +MUST FIX first, then author-decides. Do not dump Supported claims into chat. No em dashes in the report body. + +--- + +## Caller-specific chat + +### Preflight (results menu) + +Merge MUST FIX items into the findings that feed the **one results menu** (dedupe). Use plain language (problem + why + file). Do **not** put verdict labels like "Contradicted" in author bullets. Do not open with a "What this check is" primer. + +Offer **fix all** / **fix N** / combos for package-fixable claim items per [preflight Author-facing findings](../preflight-learning-path/reference-checks.md#author-facing-findings). + +If none, say the claim check found no contradicted or unsupported product facts (as part of What we checked / clean results). + +### Review (Phase 1 workbook) + +Merge MUST FIX items into `pr-{n}-findings.md` under **Post inline if confirmed** (or **Verify in Block Editor** when live confirmation is needed). Tag **post inline** per [finding routing](reference-checks.md#finding-routing). Do not dump Supported into chat. Author-decides may stay Internal or become a short open question in the draft summary. diff --git a/.cursor/skills/review-learning-path/reference-checks.md b/.cursor/skills/review-learning-path/reference-checks.md index d76397d0b..9ea314375 100644 --- a/.cursor/skills/review-learning-path/reference-checks.md +++ b/.cursor/skills/review-learning-path/reference-checks.md @@ -69,7 +69,7 @@ Run via [audit-guide](../audit-guide/SKILL.md) plus confirm every row: | `schemaVersion` not `"1.1.0"` when present | post inline | | Markdown `##` / `###` for grouping | internal | | Section bookends missing (rule 14) — no intro/summary **around** the section | **post inline** | -| In-section intro markdown that may number as a step | **post inline** (see [section intro markdown](#section-intro-markdown-numbered-as-step)). Prefer bookends **outside** the section per rule 14. | +| In-section intro markdown that may number as a step | **post inline** (see [section intro markdown](#section-intro-markdown-numbered-as-a-step)). Prefer bookends **outside** the section per rule 14. | | Missing `exists-reftarget`, `navmenu-open` | internal until live fails | | Missing `on-page` | internal until live fails | | `lazyRender` missing on virtualized targets | internal until live fails | @@ -209,13 +209,22 @@ Prose not captured in package on conversion → **post inline**. Front matter ma `static-only: ` at end of Phase 1 skips Phase 2. +**Precedence (evaluate in order; first match wins):** + +1. **Bare `static-only` (no reason)** → always **reject**. +2. **`pr_type` is `new` or `conversion` and the path has interactive milestones** → always **reject**, even if the reviewer cites "practice" or "no stack." Playwright is mandatory here. +3. **`pr_type` is `update` with only markdown / `website.yaml` changes** → **allow** with a non-empty reason. +4. **Practice / archaeology on a merged PR** → **allow** with a non-empty reason (never suggest APPROVE when waived). +5. Anything else → **reject**. + | Situation | Allowed? | |---|---| -| **new** / **conversion** with interactive milestones | **No** | +| Bare `static-only` | **No** | +| **new** / **conversion** with interactive milestones (any reason) | **No** | | **update** with only markdown / `website.yaml` | Yes, with reason | | Practice / archaeology on merged PR | Yes, with reason | -Record `waive_live_testing: true` and `static_only_reason`. Never suggest APPROVE when waived. +Record `waive_live_testing: true` and `static_only_reason` only when allowed. Never suggest APPROVE when waived. ### Not live-tested disclosure (required) diff --git a/AGENTS.md b/AGENTS.md index c1c8ed29b..0ce891391 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -83,5 +83,5 @@ Full reference documentation lives in `docs/`. AI-oriented references live in `. | [/check](.cursor/commands/check.md) | Check guide quality against best practices | | [/attack](.cursor/commands/attack.md) | Find issues by simulating confused users | | [/review-learning-path-pr](.cursor/commands/review-learning-path-pr.md) | Full learning path PR review (audit, consistency, Playwright, Pathfinder, GitHub submit) | -| [/preflight-learning-path](.cursor/commands/preflight-learning-path.md) | Author pre-PR self-review for a learning path (same checks as review, then optional fixes) | +| [/preflight-learning-path](.cursor/commands/preflight-learning-path.md) | Author pre-PR self-review for a learning path (mirrors review checks + shared claim-check, then optional fixes) | | [/build-interactive-lj](.cursor/commands/build-interactive-lj/README.md) | Multi-phase learning journey builder |