Skip to main content

verify

Review implementation ownership and verify kitcn packages, the CLI and its `kitcn init -t` scaffolds, prepared scenario apps, auth lanes, and the www docs and example app through their actual proof owners. Use before writing a plan's proof gates, before writing or changing any test, before claiming a fix works, before calling a failure pre-existing or unrelated, before closing any change with a browser-visible result, when choosing a scenario's proof path, and when a test is flaky, contaminated by another file or times out.

Source facts

Repository
udecode/kitcn
Last source activity
November 4, 2026 at 18:00
Detected SKILL.md language
English
Stars
452
Forks
35

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
description
Review implementation ownership and verify kitcn packages, the CLI and its `kitcn init -t` scaffolds, prepared scenario apps, auth lanes, and the www docs and example app through their actual proof owners. Use before writing a plan's proof gates, before writing or changing any test, before claiming a fix works, before calling a failure pre-existing or unrelated, before closing any change with a browser-visible result, when choosing a scenario's proof path, and when a test is flaky, contaminated by another file or times out.
argument-hint
[package | cli | scaffold | scenario <name> | www | example | auth | testing] <target>
name
verify
metadata
{"skiller":{"source":".agents/rules/verify.mdc"}}
# Verify This is the driver skill for pstack's Bug fix playbook. It owns implementation acceptance, proof selection, launch, doctor, driving and evidence for kitcn. Its testing reference, `.agents/rules/verify/references/testing.md`, owns Bun and React test design, suite contamination and flaky failures. Read that reference in full before you write, change or debug a test. ## Completion boundary Before you choose proof, state the reported setup, input, expected result and any necessary follow-up. Keep them in the existing task plan or case. Select the smallest proof owner that can observe each required result. A unit test can diagnose a scaffold, runtime or browser defect without proving it. A committed fixture snapshot proves generated output, not that the generated app runs. A scenario that reaches ready proves runtime startup, not a browser auth flow. A follow-up from the reporter adds to the original acceptance. It never replaces it. A narrower green test cannot discard an original requirement. Report local verification separately from publication. A green local proof says nothing about a published package until the packed artifact is checked. ## Review the implementation For a changed implementation, review the final diff, its owning path and the consumers that use it differently before you accept verification. Do this before an expensive final replay. An existing review of the same candidate counts. - Keep the review proportional. A direct local correction needs a direct source check, not an architecture exercise. - Each added effect, subscription, timer, cache, retry or fallback must earn its place through a current requirement and a correct lifetime. Remove the cause when you can, instead of compensating for it. - Check that the proof observes the user invariant. A mock of the owner or an assertion on the new mechanism can hide the original design error. - Scaffold output has one owner, the package scaffold source. A fix applied to `example/` output, an example plugin file or `fixtures/**` first is in the wrong owner. Change the package template, then regenerate with the CLI (`kitcn add ... --overwrite` for plugins, `bun run fixtures:sync` for fixtures). Record the conclusion and its decisive source evidence in the task plan or handoff. A verified ownership defect keeps the work open even when tests pass. A clean design does not replace runtime proof, and passing runtime proof does not accept a deficient design. ## Canonical inventory Discover the inventory from these owners. Do not keep a second feature map or a hand-maintained coverage count. `pstack:maintain-verification-skill` works on this file and these owners. | Surface | Inventory owner | Proof and driving recipe | | --- | --- | --- | | Package behavior | `packages/*` sources and their `*.test.ts`, `*.vitest.ts` and `*.test-d.ts` files; `convex/**/*.test.ts` | `bun run test` runs `bun test` (root `./packages`, preload `tooling/test-setup.ts`) and then `vitest run` (`vitest.config.mts`, the `integration` and `solid` projects). Run one file first with `bun test <file>` or `bunx vitest run <file>`. | | Types | `turbo typecheck` across workspaces | `bun typecheck`. Typecheck is source-first, so do not build a package just to run types. | | Package artifact and exports | `packages/kitcn/package.json` exports and build output | `bun --cwd packages/kitcn build` after any package change and for any artifact or export claim. `bun run intent:pack` lists what would publish. | | CLI commands | `packages/kitcn/src/cli/` | `bun run test:cli` runs `cli.commands.ts` with `CI=1`. A behavior claim about a command also runs that command in a prepared scenario project. | | `kitcn init -t` scaffolds | `tooling/template.config.ts`; committed output in `fixtures/*` | `bun run fixtures:sync`, then `bun run fixtures:check`. `fixtures:check:full` builds the package and checks the full scope. | | Runtime scenarios | `SCENARIO_KEYS` and `SCENARIO_DEFINITIONS` in `tooling/scenario.config.ts`; `resolveScenarioProofPath` in `tooling/scenarios.ts` | The proof path for each key, as [Scenario proof](#scenario-proof) says. | | Concave backend | `test/concave/` | `bun run test:concave`. | | `kitcn verify` in a fresh app | `test:verify` in root `package.json` | `bun run test:verify` prepares `create-convex-bare` and runs `bunx kitcn verify` inside it. | | www docs | `www/content/docs/**`, `www/app/` | `bun dev` serves the docs app. Drive the route in the browser. | | Example app | `example/` (Next on port 3005 with a kitcn Convex backend) | The [example launch](#launch) and a browser drive. | | Auth browser flows | `tooling/auth-smoke.ts`, `tooling/auth-e2e.ts` | `bun run test:auth -- <name|url>` and `bun run test:e2e -- <name|url>` against a running app. | For each selected item, record its user entry, setup and action, expected effect and gotchas from the source and its existing proof. A file count is discovery only. ## Scenario proof Committed `fixtures/*` are sources only. Never run them in place. Each runnable app is prepared into `tmp/scenarios/<name>/project`. `fixtures:*` commands own the committed snapshot sync and check. `scenario:*` commands own the runnable temporary apps. ```bash bun run scenario:prepare -- <name> bun run scenario:dev -- <name> bun run scenario:check -- <name> bun run scenario:test -- <name> bun run test:runtime ``` `scenario:test -- <name>` runs the key's whole proof path and stops what it started. `test:runtime` runs `scenario:test -- runtime`, which is every key whose proof path is not `check`, and is the default non-browser runtime gate. `test:auth` and `test:e2e` assume the scenario already runs. Read `resolveScenarioProofPath` in `tooling/scenarios.ts` for the key's proof path. It returns one of four paths: - **`runtime`.** Prepare, run `scenario:dev` until the ready URL answers, then stop. `scenario:test -- <name>` does all three. - **`auth-demo`** (`next-auth`, `start-auth`). The runtime proof plus `test:auth`, which `scenario:test` runs once the app is ready. This proves runtime and auth smoke only. Browser auth proof is the separate `test:e2e` lane. Prepare, start `scenario:dev`, then run `bun run test:e2e -- <name>`. - **`auth-runtime`** (`expo-auth`, `vite-auth`). The runtime proof only. These apps have no `/auth` page or other browser auth page. Do not fake `test:e2e` or add `test:auth` here unless the registry grows an auth proof lane for them. - **`check`** (the bootstrap-heavy Convex keys in `BOOTSTRAP_CHECK_SCENARIOS`). `bun run scenario:check -- <name>` is the proof. Do not replace it with an ad-hoc `scenario:dev`. Fresh kitcn lanes bootstrap during `scenario:prepare` through `kitcn init -t <next|vite> --yes`, then finish with an in-place `kitcn init --yes` after plugin setup. The raw Convex auth adoption lanes own `convex init` plus `kitcn add auth --preset convex --yes`. They are not a `next-auth` browser demo, so do not invent `/auth` for them. Run `test:e2e` only when an auth page or flow changed. Default `bun check` never depends on it. If a scenario has no real browser auth page, do not invent one. Stop once the assigned proof path succeeds. Do not keep poking the app after that. Re-run `bun run scenario:prepare -- <name>` once when any of these holds: - package or scaffold source changed after the app was prepared; - the app is missing expected local env or generated files. Otherwise reuse the prepared app. If it still fails after one re-prepare, debug the cause. Do not loop on re-prepare. ## Launch Run from the current checkout. Read the relevant script first, and never reuse a port or path from another checkout. Start each long-running process in the background and keep its handle for cleanup. 1. A fresh worktree needs its env files and dependencies first. Copy every nested `.env` and `.env.local` from the source checkout, including `example/.env.local` and `example/convex/.env`, then run `bun install`. `bun install` also regenerates the skills from `.agents/rules`. Before the first scenario or fixture run, run `bun run build:pkg`. Scenario prepare builds `kitcn` itself but packs `packages/resend/dist` as it is, so without that build it fails with `ENOENT` on that folder. 2. Pick the launch that matches the surface: - **Scenario.** `bun run scenario:dev -- <name>` after `scenario:prepare`. It starts the app and its backend from `tmp/scenarios/<name>/project`. It is ready when the URL in the project's `NEXT_PUBLIC_SITE_URL` or `VITE_SITE_URL` answers, or `http://127.0.0.1:3210/_dashboard` when the project has no site URL. The app's dev port starts at 3005 and moves up when that port is taken. - **www docs.** `bun dev` runs `next dev` in `www`. It is ready when Next prints its ready line and the route renders. - **Example app.** `bun --cwd example dev` runs `mprocs`, a terminal UI an agent cannot drive. Start its two processes instead, `bun --cwd example convex:dev` and `bun --cwd example dev:app`. The app is ready when `NEXT_PUBLIC_SITE_URL` (port 3005) renders the route and the backend at `NEXT_PUBLIC_CONVEX_URL` answers. - **Library only.** Use the package test and type scripts. No app launch is needed unless the claim depends on rendering or a running backend. 3. Run one scenario dev process at a time per checkout. Scenarios share the local Convex backend port, so two at once can drive the wrong backend. Ready means the route renders current source. A process that listens is not proof. If a launch fails, capture its output and clean what you started before another attempt. ## Doctor Run these read-only checks before driving and after anything surprising: 1. Bind the process to this checkout. On macOS, `lsof -nP -iTCP:<port> -sTCP:LISTEN` names the listener and `lsof -a -p <pid> -d cwd -Fn` its cwd. A listener from another checkout is not yours to use or stop. 2. Request the route with `curl --fail --silent --show-error <url>`, then open it in the browser. HTTP success proves reachability only. The browser must show the route without a build error or overlay. 3. For a scenario, read `tmp/scenarios/<name>/.kitcn-scenario/scenario.json`. Its `kitcnPackageSpec` and `steps` name what the app was prepared from. If package or scaffold source changed since, re-prepare once. 4. When the process is healthy but the app state is wedged, reset to a known state or relaunch. A failed drive always runs doctor and cleanup before another attempt. Two failure shapes have a known local recovery. Run each recovery once, then rerun the exact failing command: - **Local env rot.** Typecheck, build, dev or a test fails with missing-module or package-resolution errors the diff does not explain, or with local React runtime errors (`Invalid hook call`, a null dispatcher in `resolveDispatcher()`, a package-local `node_modules/react` under `packages/*`, mixed `.bun` and `.pnpm` React paths in one stack). Run `bun install` once. If the failure changes or disappears, it was env rot. If not, debug the code. Reinstalling is never a substitute for fixing a real code error. If you see `failed to load config from .../vitest.config.mts`, remove every `**/node_modules` and install again. - **`fixtures:sync` EPIPE.** `bun run fixtures:sync` dies with a Convex or esbuild `EPIPE`, `The service was stopped` or `Timed out waiting for local Convex bootstrap`. Kill the stale esbuild and Convex workers this checkout's earlier runs left, found by cwd with `lsof`, once, then rerun the sync. If the workers stay in the `U` state after `kill -9`, the host needs a reboot. Ask the owner for it. ## Drive Drive the real user path. Prefer stable handles such as route paths, ARIA labels, visible text and CLI flags over coordinates. **Browser.** Use the runtime's browsers in this order: 1. The in-app browser first, for route navigation, DOM checks, forms, screenshots, responsive checks and rendered UI proof. In Claude Code that is the Browser pane. In Codex it is the Browser plugin. 2. Chrome directly when the claim involves native browser, profile or OS behavior, such as downloads, print preview, file pickers, uploads, clipboard, permissions, dialogs, extension or profile state, or exact Chrome rendering. In Claude Code that is Claude in Chrome. In Codex it is the Chrome plugin. Browser proof alone does not close such a claim. 3. Computer use only when native Chrome or OS UI must be inspected or operated and Chrome automation cannot read it, such as print preview, save and open dialogs or permission sheets. When the in-app browser hits a known limit and native proof matters, switch to Chrome or computer use. Do not lower the claim or ask the owner to confirm. Do not substitute Puppeteer, standalone Playwright or raw Chrome DevTools for these browsers. For a UI change, cover the route at each breakpoint it changes and every state the `design` skill's Honest States list names that the change touches. **Docs.** Wait for the page heading and rendered body after navigation. HTTP success and title metadata can arrive before the content. **CLI.** Run the command inside a prepared scenario project, never in `fixtures/*` or the example app. Use `--yes` for non-interactive runs and `--json` when the claim is about output. Check the files the command wrote, its stdout and its exit code. A dry run is a separate claim from a write run, so observe the files for each. **Scaffolds.** After any `init -t` template or scaffold change, run `bun run fixtures:sync` and then `bun run fixtures:check`, with no exceptions. The sync regenerates every file under `fixtures/**`, including each committed fixture `package.json`. Never patch a fixture file by hand. Review the fixture diff the sync produced as part of the proof. **Auth.** Prepare and start the scenario, then run `bun run test:auth -- <name>` for auth smoke or `bun run test:e2e -- <name>` for the browser auth lane. Pass a URL instead of a name to drive another running app, such as the example app at `http://localhost:3005`. ## Evidence Keep command logs, the route and host, the input or action, the observed result, runtime errors and screenshots under the main checkout's `docs/plans/artifacts/<task-slug>/`, written by absolute path. Git ignores that folder, and removing a worktree would delete a copy kept inside it. Never commit proof logs. Keep the concise conclusion and the proof references in the task plan. Each base, candidate and control run writes its own named log. Capture the action and the resulting state, plus follow-up input and side effects such as files written, rows inserted or emails sent when the claim needs them. Mock only a boundary production code already isolates, and say what the mock cannot prove. A test run that prints an uncaught error stack is not green even when the runner reports a pass. A requested gate that fails keeps the work open until the same gate passes on the final bytes. Calling a failure unrelated does not close it. Only the same command failing the same way at the base commit, run in a clean detached worktree, makes it pre-existing. The final repo gate is `bun check`. `bun check --list` names its steps: the package build, intent validation, lint, typecheck, the Bun, Vitest, tooling, CLI and Concave tests, `fixtures:check`, `test:verify` and `test:runtime`. Run it before a PR, after `bun lint:fix`. `bun check <step>` reruns one step. ## Cleanup Stop only the processes you started, by their handle or a PID you verified. Never kill by process name, and never stop another checkout's listener. Stop spawned scenario dev processes once their proof succeeds or fails. `scenario:test` and `scenario:check` stop what they start. Remove only this run's temporary state. A prepared `tmp/scenarios/<name>` may stay for reuse. Then confirm every cited evidence file still exists. Cleanup that deletes evidence invalidates the run.
View on GitHub