agentleFS
paureispaureis/pau-skills/skills/verification/verify-app/SKILL.md

verify-app

Skill2 starsChanged 22 days agoMITView on GitHub

Write or maintain the project's own verification skill and feature map, so any agent can launch the real app, drive it like a user and keep evidence. Use when the user says 'make a verification skill', 'maintain the verify skill', 'match the skeleton', or asks how an agent can test the app, or when a change must be proven in the running app and nothing scripted drives it.

6 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use bughunt.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • avSkill

    bughunt

    Fully autonomous bug hunting pipeline — discover bugs in a scoped area using parallel subagents, independently triage each finding, fix confirmed issues with subagents, then audit all fixes against repo constraints and target platforms. Runs end-to-end without user interaction.

    Also in 3 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

16 rules. 0 are common, 13 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 6 edited versions we read keep these.

  • 13

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If you started this skill on your own, without the user typing its name or asking for what it does, first say in one or two lines what it …

    line 20
  2. Distinctive:

    When an asset the surface never uses blocks start-up (a static folder an API never serves, a sample file), the generated skill may create …

    line 86
  3. Very specific:

    Cleanup: Stop only what $RUN/started.txt lists, checking that each process still has its recorded start time (a process ID can be reused), …

    line 141
  4. Very specific:

    Create .claude/skills/verify-<app>/features/README.md and one file per user-facing feature, from ${CLAUDE_SKILL_DIR}/templates/feature.md, …

    line 156
  5. Distinctive:

    Start with the 3 to 5 features a user meets first, found from routes, commands, menus and docs.

    line 158
  6. Very specific:

    Never weaken a journey to make it pass.

    line 168
  7. Distinctive:

    If you can start a subagent (the Agent tool), give it the brief.

    line 193
  8. Distinctive:

    Only when neither is possible, follow the file yourself, using only what it says.

    line 197
  9. Distinctive:

    After cleanup, confirm that the evidence still exists at the named folder, that nothing the run started is still running (the recorded …

    line 202
  10. Distinctive:

    If the run used a stand-in for the real target (see "Not yet proven on the real target" in step 3: a container instead of a fresh machine, …

    line 208
  11. Distinctive:

    Never drive an instance this run did not start, unless the generated skill says the instance is shared and the user agreed.

    line 237
  12. Distinctive:

    Never weaken a journey, a check or the map to make a run pass.

    line 239
  13. Distinctive:

    Never keep evidence where Cleanup deletes it.

    line 240
  14. Distinctive:

    Never stop a process by name, and never stop what another session started.

    line 241
  15. Distinctive:

    Never put a secret in the generated skill or in evidence.

    line 242
  16. Distinctive:

    Never change product code without the user's yes.

    line 244

“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Verify app

A project needs one scripted way to start the real application, use it the way a user does, and keep proof of what happened. This skill writes that down as a project skill, .claude/skills/verify-<app>/, and later keeps it honest as the app changes. Its reader is the next agent: it arrives cold, in the middle of another task, and has never seen the app. Write every line for that reader: exact commands, real selectors, results it can observe.

Arguments: $ARGUMENTS

If you started this skill on your own, without the user typing its name or asking for what it does, first say in one or two lines what it will do and what it will cost, and wait for a yes. A remark or a question that only matches its description is not asking for it. If the user asked for it, or the brief you are working from does, go ahead.

Pick the mode

  • The arguments start with maintain: maintain mode. Read ${CLAUDE_SKILL_DIR}/MAINTAIN.md and follow it.
  • The project already has a .claude/skills/verify-*/ folder and the user wants a change checked: this skill is not needed. Read that folder's SKILL.md and follow it. If the user asked for a new one anyway, say one exists and offer maintain mode instead of writing a second.
  • The request is only about a skeleton or the loading, empty and error states of a screen: when the project has a .claude/skills/verify-*/ folder with a "States and skeletons" section, read its SKILL.md and run that recipe for the screen named, under that skill's rules (a skeleton is resized only on a yes). When it has no verify skill, say that create mode comes first (an interview of the repository, a generated skill and one end-to-end run, far more than one measurement), and wait for a yes. When its verify skill has no such section, offer maintain mode, which adds it, and wait.
  • Otherwise: create mode, below.

Bundled files, all read only:

  • ${CLAUDE_SKILL_DIR}/DRIVING.md: how to find the project's own end-to-end harness, and what to use without one, per surface (web, CLI, TUI, HTTP, mobile, desktop, library). Read it before step 1.
  • ${CLAUDE_SKILL_DIR}/templates/verify-skill.md and ${CLAUDE_SKILL_DIR}/templates/feature.md: the files you generate. Every spot to fill is marked TODO(verify-app).
  • ${CLAUDE_SKILL_DIR}/templates/measure-boxes.js: browser JavaScript that measures a loading skeleton against the loaded screen and reads the layout-shift score. Copied into the generated skill for an app with a screen.
  • ${CLAUDE_SKILL_DIR}/references/feature-map-example/: a worked feature map, an index and three feature files.
  • ${CLAUDE_SKILL_DIR}/check-map.mjs (with check-map-rules.mjs next to it; Node 20+, no dependencies): checks a generated skill. Exit 0 clean, 1 problems, 2 usage.

Create mode

1. Interview the repository, not the user

Answer each question from the code, and write down the file each answer came from. Ask the user only what the files cannot show, one question at a time (with AskUserQuestion when it is available).

  • Surface. What does a user actually touch: a web UI, a CLI or TUI, an HTTP or gRPC API, a mobile app, a desktop app, a library? A repository can have several. Pick the main one (or the one the arguments name) and list the rest in the generated skill as not covered yet.
  • Run. How does it start locally? Prefer the project's own documented command: the README quick start, the manifest's scripts, Makefile, justfile, compose files, the CI job that runs end-to-end tests. Note ports, environment variables (names only, never values), seed data, migrations and sign-in.
  • Drive. How can an agent use it from a script? The project's own harness first (DRIVING.md, section 1). Only without one, the fallback for the surface (section 2).
  • States. For a screen: the requests its data comes from (the ones to hold, empty or fail), any delay or mock switch the app has, how its skeletons are marked (a project convention, or none yet), and the viewports in the end-to-end config.
  • Observe. What proof can be captured: screenshots, accessibility snapshots, terminal transcripts, response bodies, logs, exit codes, files written, rows stored, messages sent.
  • Isolate. Where does the app write: the current folder, HOME, the XDG folders, the temp folder, a configured path, a database? Each one must point into the run's own folder, or a drive changes the user's data (commands run from the repository root, so a file written "here" lands in the user's repository). Can two instances run side by side (ports, data folders, browser profiles)? If not, the generated skill says so and refuses to drive an instance it did not start. Refusing beats corrupting the user's own session.

2. Make it start

Build and launch the app the way you found, from an empty data state. A skill written against a broken checkout teaches wrong steps.

  • A setup problem with a small fix (dependencies not installed, a sample config to copy): fix it and put the step in Launch.
  • A fix that needs product code: show it to the user and ask before you change anything.
  • Anything else: stop and report the command, the output and what is missing.

When an asset the surface never uses blocks start-up (a static folder an API never serves, a sample file), the generated skill may create it. Mark it as verification scaffolding and remove it in Cleanup.

3. Write the skill

Copy ${CLAUDE_SKILL_DIR}/templates/verify-skill.md to .claude/skills/verify-<app>/SKILL.md and fill in every spot marked TODO(verify-app) and every template token (<app>, <surface>, <harness>) from what steps 1 and 2 found; check-map reports any left. <app> is a short lowercase name for the app. The frontmatter needs name: verify-<app>, equal to the folder name, and a description that names the app, the surface and when to reach for it: without them the skill never registers. The template's fixed text (the run-folder commands, the start-up record, the proof rules) is written for a POSIX shell: keep it, and adapt it only when the project's commands run in another shell, such as PowerShell. Every other command comes from this repository; no example command stays in the file.

Required sections, checked by check-map: Launch, Doctor, Drive, Evidence and Cleanup, none empty, and Launch, Doctor and Cleanup each with a command in a code block. The template also has Run folders, States and skeletons, Helpers, Feature map and Not yet proven on the real target; keep them (Helpers says "None." when there are none). What each section holds:

  • Run folders. Fixed text: the run ID, the scratch folder $RUN, the evidence folder $EV, and the variables saved to $RUN/env, which every later command loads with set -a so the app sees them too. Each Bash tool call starts a fresh shell, so nothing else carries over. You fill in "Where the app writes": every location from step 1, and how each is pointed into $RUN (a variable, a flag, env HOME=..., or running the app from $RUN/work). $RUN stays outside the repository: inside it, an app that searches upward for a repository or a config file would find the project's own, and the drive would test another setup. When a write there is refused, the skill names the folder and asks the user to allow it, and must never move the run into the project.
  • Launch. For a server or a UI: the exact commands that build once and start the app, and how to tell it is ready. Ready means usable, not only that a process answers: a port can be open while migrations or a data load still run, so wait for the condition that proves a user could act now (a ready line in the log, a health check that covers the data store, the first page rendering its main control), from an empty data folder, including migrations and seed data. Record what started in $RUN/started.txt, and make sure the recorded process is the app's own (DRIVING.md, section 3). For a CLI, a TUI or a library nothing stays running: Launch builds or installs once, and each drive gets its own isolated session.
  • Doctor. One read-only check that answers "is this instance worth driving?". For a server or a UI: the process is up, it is the one this run started (process ID or port owner against the record), it runs the build under test (version or commit), its data is in $RUN, sign-in is valid. For a CLI, a TUI or a library: the program the drive will run is the one built from this working tree, not another copy on PATH, and the write locations point into $RUN. Run it before the first drive, after any failed drive, and after anything surprising. When the doctor cannot see the failure (a stuck screen on a healthy process), reset to a known state or relaunch; do not hope.
  • Drive. The harness and the real handles from this repository, with the file each came from: accessible roles and names, labels, test IDs, prompt strings, routes, command names. Prefer them over coordinates, tab order and CSS paths. Wait on a condition, never on a fixed sleep.
  • Evidence. Where proof goes and what counts as proof. The folder is inside the repository, ignored by git, and outside everything Cleanup deletes, so the proof survives the teardown. It is written on a line of its own as Evidence folder: `<path>` (check-map.mjs reads that line). Add the folder to .gitignore, creating the file when the project has none, and show the line. Each run has its own subfolder, each feature a subfolder in that, and each step numbered files: 01-<step>.cmd (exactly what ran), .out, .err, .exit, and screenshots, snapshots or response bodies as the surface needs. The proof rules in the template stay as they are.
  • States and skeletons. For an app with a screen: how this harness holds, empties and fails a data request (or the app's own switch where it cannot intercept), the viewports, the skeleton markers, and the shared recipe that measures a skeleton against the loaded screen. Copy ${CLAUDE_SKILL_DIR}/templates/measure-boxes.js to .claude/skills/verify-<app>/measure-boxes.js: the generated skill must work without this skill installed, so the recipe and its helper live in its own folder. Keep only the harness calls for this project's harness, and write the measuring steps in its language, as a scratch test or script like any other drive. For an app with no screen, the section says so in one line and the helper is not copied.
  • Cleanup. Stop only what $RUN/started.txt lists, checking that each process still has its recorded start time (a process ID can be reused), and delete only the paths it lists. Never by process name (pkill, killall, taskkill /IM), never by a glob, never with a command that wipes ignored files (git clean -x), never by removing shared volumes. Then confirm: every recorded process is gone, the port is free (for a server), the output of git status --porcelain is what it was when the run started (nothing escaped into the repository), and the evidence is still there. Remove $RUN last, because it holds the record. DRIVING.md, section 3, has the commands.
  • Helpers. Optional. Any script the skill ships sits in its folder, can be run as written, and its exact invocation is shown in the section that uses it. A helper the reader has to work out is not a helper.
  • Not yet proven on the real target. The real target is where users run the app; a local run may stand in for parts of it. For example, the runs use a local PostgreSQL in a container while users hit a managed database with its own extensions and permissions, or a mock mail server instead of the real provider, or Linux while users are on Windows. List each stand-in and what it does that the real target will not, or write that there are none.

4. Seed the feature map

Create .claude/skills/verify-<app>/features/README.md and one file per user-facing feature, from ${CLAUDE_SKILL_DIR}/templates/feature.md, following the shape in ${CLAUDE_SKILL_DIR}/references/feature-map-example/. Start with the 3 to 5 features a user meets first, found from routes, commands, menus and docs.

  • The index sets the baseline state, the driving conventions and the proof rules, and links every feature file.
  • Each feature file has a title, one paragraph on what the user sees, and exactly five sections: Sub-features, How to get to it (user's point of view), Driving it with <harness>, Gotchas and States.
  • States says how to force the screen's loading state (hold the data request), its empty state (no data) and its error state (the request fails), what each should look like, and the screenshot kept for each. Where the screen has a skeleton, it names the markers the recipe in "States and skeletons" pairs. A feature with no screen (a CLI command, an HTTP endpoint) says so in one line.
  • Each step in Driving it pairs a user action with the exact command and the result that proves it.
  • Never weaken a journey to make it pass. If the seed data lacks what a journey needs, the journey fails, and the reason goes in that feature's Gotchas.
  • The map is the project's source for verification. A proof that drives one convenient entry point is incomplete when the map lists others.

5. Check it

node "${CLAUDE_SKILL_DIR}/check-map.mjs" .claude/skills/verify-<app>

It checks the frontmatter, the five required sections (none empty; Launch, Doctor and Cleanup with a command in a code block), the evidence line, leftover TODO(verify-app) markers and template tokens, that the index matches the feature files on disk (subfolders of features/ count), the five headings in every feature file, and that the evidence folder is ignored by git with nothing in it tracked. Fix every problem it prints. A clean result means the shape is right, not that the commands work: step 6 proves those.

6. Prove it once, end to end

A generated skill that was never executed is a draft. Run its instructions as written, once: launch, doctor, drive one mapped feature (one is enough; the map is there so later runs can cover the rest), keep the evidence, clean up.

  • The honest test is a reader who has not seen this conversation, with only this brief: "Follow .claude/skills/verify-<app>/SKILL.md to verify the feature in features/<file>.md. Report each command you ran, what you saw, where the evidence is, and every place the instructions were unclear or wrong."
    • If you can start a subagent (the Agent tool), give it the brief.
    • Otherwise, a fresh session: ask the user to open a new Claude Code session in the repository and paste the brief, or run claude -p "<the brief>" from the repository root if the user agrees (it needs permission to run the commands, like any session).
    • Only when neither is possible, follow the file yourself, using only what it says. This is the weaker test, because you know what the file meant to say; say so in the report.
  • For an app with a screen, the drive includes that feature's States: each state forced, its screenshot kept, and the skeleton measured at the viewports the skill names. Report each mismatch with its numbers; resize a skeleton only on the user's yes (it is product code), then measure again.
  • After cleanup, confirm that the evidence still exists at the named folder, that nothing the run started is still running (the recorded processes are gone, the port is free for a server), and that git status shows nothing new outside the evidence folder. A cleanup that eats the proof fails this step.
  • Fix what failed, and run the generated Cleanup after every failed attempt too, so broken attempts leave no process or port behind. A step that failed may already have changed the app's data, so relaunch from empty before trying again rather than carrying on with the same instance.
  • If the run used a stand-in for the real target (see "Not yet proven on the real target" in step 3: a container instead of a fresh machine, a local database instead of the managed one), list every setup step the stand-in did that the target will not, in that section of the generated skill. Those steps stay unproven until a run on the real target covers them.

7. Hand it over

Report, then offer to commit the skill folder and the .gitignore line: the skill is project infrastructure, so every person and agent drives the app the same way. Commit only on a yes. Say that this skill with the argument maintain keeps the map honest when the app changes (/verification:verify-app maintain from the plugin, /verify-app maintain when the skill is installed on its own); suggest a schedule only if the user asks.

The run ends with the block below, filled in, as the first lines of its final message: every field has a value (none where nothing applies). Prose or a table in its place is not the report. Anything else, the commit offer included, comes after the block.

Verify skill: .claude/skills/verify-<app>/ (<surface>, harness <harness>)
Features mapped: <n>: <names>; not covered yet: <surfaces or features, or none>
check-map: clean
End-to-end run: <feature> by <subagent | fresh session | me, the weaker test>: launch <ok>, doctor <ok>, drive <ok>, evidence at <path> (kept after cleanup), cleanup <ok>
States: <loading, empty and error screenshots at <path>, or no screen>; skeleton <matches | each mismatch with its numbers | no skeleton>
Fixed to make it start: <list, or none>
Not yet proven on the real target: <list, or none>
Questions for the user: <list, or none>

Rules

  • Never drive an instance this run did not start, unless the generated skill says the instance is shared and the user agreed.
  • Never weaken a journey, a check or the map to make a run pass. A failure is a finding.
  • Never keep evidence where Cleanup deletes it.
  • Never stop a process by name, and never stop what another session started.
  • Never put a secret in the generated skill or in evidence. Record variable names, and redact tokens from captured requests and logs.
  • Never change product code without the user's yes. In maintain mode, never change it at all. A skeleton is product code: in create mode it is resized only on a yes, and in maintain mode a mismatch is a product gap to report.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.