name: pharn-skill
skill: "pharn-skill"
version: "0.27.2"
description: "Scaffolds new PHARN-convention skills into the user's project. Five buyer-facing types: command, validator, lens, vendor-bridge, hook. Generates correct frontmatter, body structure (purpose / when-to-use / procedure / what-NOT-to-do / verification), README, and three eval-case skeletons. Every scaffold is kind: community (vendor-bridges additionally carry seal: vendor-bridge); the scaffolder never sets kind: pharn-owned or the PHARN ✓ reviewed seal — only PHARN maintainers promote a skill to first-party. Output goes to the user's .claude/skills/ or .claude/hooks/, never to pharn-oss."
kind: pharn-owned
module: pharn-core
model_tier: sonnet
priority: pharn-owned
depends_on: []
rule_files: []
reads:
- "pharn.config.json"
- ".claude/CONSTITUTION.md"
- ".claude/skills//SKILL.md"
writes:
- ".claude/skills// "
- ".claude/hooks//**"
modes:
- default
flags:
- --type
- --name
- --purpose
- --output
- --force
pharn_version: "0.68.0"
seal: "PHARN ✓ reviewed"
/pharn-skill
/pharn-skill scaffolds new PHARN-convention skills into your project. It generates correct frontmatter, the PHARN body structure (purpose / when-to-use / procedure / what-NOT-to-do / verification), a README, and three eval-case skeletons. Five types are supported: command, validator, lens, vendor-bridge, hook — the types buyers and users most commonly extend with. The output is a structured scaffold with TODO markers; you fill them in, then run /pharn-eval (when installed) to validate.
This is PHARN's extensibility entry point. Marketplace pack buyers, agency teams, and indie developers create custom skills, validators, lenses, vendor-bridges, and hooks without having to learn the conventions by hand.
When to use this skill
Trigger phrases:
- "create a custom skill" / "scaffold a new validator" / "scaffold a new lens" / "scaffold a hook"
- "
/pharn-skill" / "/pharn-skill --type validator --name <name>" - Extending PHARN with project-specific commands, domain-specific validators, custom review lenses, library wiring, or pre-tool-use hooks.
How /pharn-skill differs from a generic skill creator
A generic skill-creation tool (e.g. Anthropic's built-in skill-creator) produces plain Claude Code skills. /pharn-skill produces PHARN-convention skills specifically — PHARN frontmatter fields (kind, module, priority, pharn_version, seal), the kind/seal policy below, the evals/cases/ + evals/expected/ layout (cases as .md with YAML frontmatter, expected as .json), and the PHARN body shape (purpose, when-to-use, procedure, what-NOT-to-do, verification). Use this skill for skills that participate in the PHARN ecosystem — skillPrecedence resolution, the pipeline, the conventions. For generic Claude skills outside the PHARN ecosystem, a generic creator is fine.
The kind / seal policy (enforced — read this)
Every skill /pharn-skill generates carries:
kind: community— the community label (the middle tier ofskillPrecedence: pharn-owned > community > vendor).- No
seal: "PHARN ✓ reviewed". The PHARN seal is reserved for content PHARN maintainers authored and reviewed. - Vendor-bridges additionally carry
seal: vendor-bridge— distinct from plain community, marking library-wiring scope (config + how the vendor connects to PHARN-owned pieces, not API how-to —ai_docs/covers that).
This is the single most important convention the scaffolder enforces. If /pharn-skill set kind: pharn-owned on buyer-authored content, the precedence/trust model would collapse — anyone could mint "official" skills, the "PHARN ✓ reviewed" seal would lose meaning, and skillPrecedence conflicts between user customizations and PHARN-shipped methodology would resolve incorrectly.
The generated README states the skill's community status plainly. If a user later contributes a skill upstream and PHARN maintainers accept it, they change kind: pharn-owned and add the seal — the scaffolder never does.
Procedure — Step 1: determine the type
If --type <type> is passed, use it. Otherwise ask:
What kind of skill would you like to scaffold? [1] command — a slash command the user invokes (e.g.
/sync-airtable). [2] validator — a deterministic pass/fail check the pipeline runs (e.g.no-console-log). [3] lens — a review perspective with confidence-scored findings (forward-compatible with/pharn-review). [4] vendor-bridge — config/wiring for a library without an official Claude skill. [5] hook — a Claude Code hook (PreToolUse/PostToolUse/Stop/UserPromptSubmit).
Validate against the supported set. Reject PHARN-internal types (orchestrator, scout, planner, phase, verifier, griller, MCP server) with a clear message — these are not buyer-facing in v1.
Procedure — Step 2: gather basics
- Name: use
--name <slug>if provided; else ask. Slugify to kebab-case. Validate that it does NOT collide with:- an existing skill in
.claude/skills/(the user's own custom skills), - a PHARN-owned skill name (e.g.
pharn-build,pharn-grill,pharn-ship,pharn-plan,pharn-verify,pharn-pr,pharn-regress,pharn-estimate,pharn-drift,pharn-init,pharn-memory,pharn-docs,create-feature,pharn-skillitself). - The PHARN-owned list is read from
pharn.config.json's manifest if present; else a built-in list shipped with this skill. - On collision, warn the user and ask for a new name (do not silently clobber or rename).
- an existing skill in
- Purpose: ask for a one-sentence description of what the skill does.
- Model tier: ask
haiku | sonnet | opuswith guidance:- haiku — mechanical, regex/pattern checks (a typical validator).
- sonnet — composition, transformation, light reasoning (a typical command).
- opus — security review, high-stakes judgment, agent-safety lenses.
- For hooks:
model_tier: n/a(hooks are deterministic, no model).
Procedure — Step 3: type-specific questions
command:
- Does it read files? Does it write files? (Populates
reads:andwrites:lists, even as TODO placeholders.) - Does it produce an artifact (a report file) or act conversationally?
- Any modes (
default,--check,--defaults) or flags planned? List them.
validator:
- What does it check? (One-line per rule — populates the Checks table.)
- Severity model — for each rule, is a finding 🔴 (blocking) or 🟠 (warning)?
- Pipeline-integrated or standalone? If integrated, which wave does it run after? (Populates
runs_after_waves:.)
lens:
- Anchor (
constitution | plan | memory | stack) — what the lens checks against. Community lenses are typicallystack(project-specific conventions) ormemory(againstpattern-library.md/lessons-learned.md). Seepharn-review/skills/pharn-review/templates/lens.schema.md§"anchor". - Principle —
P1–P6only whenanchor: constitution;nullotherwise. - Precondition — when the lens runs. Standard expressions:
always,has UI,has PLAN.md,has pattern-library,has lessons-learned,has PII entities,has cron/queue,has UI strings,sends email. Default:always. - ID prefix — uppercase 3–4 chars; findings emit as
<PREFIX>-<n>(e.g.MDL-1). Must be unique across the lens roster the user ships alongside. If--nameis provided non-interactively, derive a default from the slug (e.g.my-domain-lens→MDL) and leave a TODO comment to confirm uniqueness. - Performance budget seconds — soft budget for the subagent spawn. Default 30.
vendor-bridge:
- Library name.
- Does this library have an official Claude skill already (Supabase, Firebase, Better Auth, Convex, shadcn, Sentry, Vercel, Expo, …)? If yes, suggest using the official skill instead and ask if the user wants to abort. The PHARN vendor policy (CLAUDE.md §5) is "do not duplicate official skills."
- Scope reminder: config + wiring only. API how-to lives in
ai_docs/(managed by/pharn-docs).
hook:
- Event:
PreToolUse | PostToolUse | Stop | UserPromptSubmit. - Tool matcher (PreToolUse / PostToolUse only — e.g.
"Write|Edit","Bash"). Omit forStop/UserPromptSubmit. - What does it check, redact, log, or block? (Populates the "What it does" TODO.)
- Performance budget (ms) — default 50.
When --type is provided via flag but the type-specific questions are not, ask only those (the flag-driven non-interactive flow still gathers type details — see eval case 06). If --name is also provided, sensible defaults plus TODO markers are used so the scaffold is generated without further prompting; the user fills in the type-specific details after generation.
Procedure — Step 4: resolve the output location
- command / validator / lens / vendor-bridge →
.claude/skills/<name>/(or--output <dir>override). - hook →
.claude/hooks/<name>/(or--output <dir>override).
Refuse to clobber. If the output directory exists and is non-empty, abort with:
<path>already exists and is not empty. Pass--forceto overwrite, or choose a different name with--name <slug>.
This applies even with --force if any file under the path is untracked-and-not-listed-as-a-template-output — --force overwrites the scaffold files but does not blanket-delete the directory.
Refuse without a PHARN install. If no .claude/ directory exists, suggest /pharn-init first:
No
.claude/directory found. Run/pharn-init(ornpx pharn init) before scaffolding skills.
Procedure — Step 5: generate the scaffold
Read the type-specific template under templates/<type>/, substitute {{name}}, {{purpose}}, {{model_tier}}, and type-specific values, and write the files. Set kind: community in every generated frontmatter. For vendor-bridges, additionally set seal: vendor-bridge. Do NOT set kind: pharn-owned. Do NOT set seal: "PHARN ✓ reviewed". Leave TODO markers everywhere the user must fill in detail — the scaffold is a structured skeleton, not a working skill.
For hooks, render settings.snippet.json from settings.snippet.with-matcher.template.json when tool_matcher is set (PreToolUse / PostToolUse); otherwise use settings.snippet.without-matcher.template.json (Stop, UserPromptSubmit).
Files written per type:
| Type | Files |
|---|---|
| command | SKILL.md, README.md, evals/cases/0{1,2,3}-<slug>.md, evals/expected/0{1,2,3}.json |
| validator | VALIDATOR.md, README.md, evals/cases/0{1,2,3}-<slug>.md, evals/expected/0{1,2,3}.json |
| lens | LENS.md, README.md, evals/cases/0{1,2,3}-<slug>.md, evals/expected/0{1,2,3}.json |
| vendor-bridge | SKILL.md, README.md, evals/cases/0{1,2,3}-<slug>.md, evals/expected/0{1,2,3}.json |
| hook | HOOK.md, README.md, <name>.cjs, settings.snippet.json, evals/cases/0{1,2,3}-<slug>.md, evals/expected/0{1,2,3}.json |
Procedure — Step 6: generate eval skeletons
Every scaffold ships with three eval-case skeletons in evals/cases/ (the PHARN minimum, per CLAUDE.md §14 Step 5). The case file is .md with YAML frontmatter (matching repo convention — pharn-pr, pharn-estimate, etc.); the matching expected file is .json. Each skeleton has the correct shape for the type with TODO placeholders.
A skill without evals cannot be tested by /pharn-eval. The scaffolder enforces testability from day one.
Procedure — Step 7: report
Print a summary of what was created:
✓ Scaffolded community skill <name> (type: <type>) at <output_dir>
Files created:
- <output_dir>/SKILL.md (← fill in: procedure, what-NOT-to-do, verification)
- <output_dir>/README.md (← fill in: usage examples)
- <output_dir>/evals/cases/01-<slug>.md (← fill in: case input)
- <output_dir>/evals/cases/02-<slug>.md (← fill in: case input)
- <output_dir>/evals/cases/03-<slug>.md (← fill in: case input)
- <output_dir>/evals/expected/01-<slug>.json (← fill in: expected assertions)
- <output_dir>/evals/expected/02-<slug>.json
- <output_dir>/evals/expected/03-<slug>.json
Kind: community (not pharn-owned — only PHARN maintainers add the PHARN ✓ reviewed seal)
Next steps:
1. Fill in the TODO markers in SKILL.md / VALIDATOR.md / LENS.md / HOOK.md.
2. Write the three eval cases.
3. Run /pharn-eval <name> to validate (when installed).
Do NOT auto-run /pharn-eval. The user fills in the TODOs first; a scaffolded skill with TODO markers will not pass evals and running them immediately would be noise.
What gets generated per type — content shapes
command — a SKILL.md with: PHARN frontmatter (kind: community, no seal), the title, a purpose paragraph from {{purpose}}, a "When to use this skill" TODO, a "Procedure" TODO, a "What NOT to do" TODO, a "Verification" TODO, and a footer marking it as community-authored.
validator — a VALIDATOR.md with: validator frontmatter (kind: community, output_format: "structured YAML: { result: pass | fail, violations: [...] }", a Checks table skeleton with severity column 🔴/🟠, and a severity-criteria TODO).
lens — a LENS.md matching the canonical pharn-review/skills/pharn-review/templates/lens.schema.md contract: kind: community, parent_skill: "pharn-review", plus anchor, principle, precondition, id_prefix, reuses: [], performance_budget_seconds, and output_format: "structured YAML — PHARN finding schema per pharn-review SKILL.md". Body follows the 8-section LENS shape (Purpose, Required context, Composition, Checks table with type slugs, Raw confidence guidance, Severity assignment, Edge cases, Output). When /pharn-review is installed, the orchestrator's Stage 2 glob .claude/skills/**/LENS.md discovers the file automatically — no SKILL.md edit, no manifest entry. Findings carry kind: community and surface in the report as lens:NAME (community).
vendor-bridge — a SKILL.md with: bridge frontmatter (kind: community, seal: vendor-bridge, library, official_skill_available, scope: "config + wiring only (ai_docs covers API usage)"). The body includes the scope note prominently — bridges are not API how-to.
hook — three files: HOOK.md (hook frontmatter with kind: community, hook_event, runtime: "node >=18", dependencies: "stdlib only", tool_matcher where applicable, performance_budget_ms), <name>.cjs (single-file CommonJS stub, stdlib only — reflects PHARN's executable-code carve-out from CLAUDE.md §3), and settings.snippet.json (the settings.json block the user pastes into .claude/settings.json to register the hook).
Failure modes
| Situation | Behavior |
|---|---|
--type unknown / not in the five supported types |
List valid types, abort with non-zero status. |
| Name collides with an existing user skill | Warn (<name> already exists at .claude/skills/<name>/); ask for a new name. Never silently overwrite. |
| Name collides with a PHARN-owned skill name | Refuse outright (<name> is reserved for a PHARN-owned skill — pick a different name). |
| Output directory exists and is non-empty | Refuse without --force. Even with --force, only overwrite template-output files; never blanket-rm. |
No .claude/ directory |
Suggest /pharn-init first; abort. |
| Vendor-bridge requested for a vendor with an official skill | Warn (list vendor); ask whether to proceed anyway or abort. |
| Type-specific questions left blank in non-interactive mode | Use sensible defaults plus TODO markers; surface a "filled with defaults — review before use" note. |
What this skill does NOT do
- Does NOT set
kind: pharn-ownedon generated skills. Buyer-authored content is alwayskind: community(vendor-bridges additionally carryseal: vendor-bridge). Only PHARN maintainers promote a skill topharn-ownedand add the"PHARN ✓ reviewed"seal. - Does NOT add the PHARN seal to any generated content.
- Does NOT scaffold into
pharn-oss. Output always goes to the user's.claude/skills/or.claude/hooks/. - Does NOT generate a complete working skill. The output is a SCAFFOLD with TODO markers — auto-completing the logic would produce untested, possibly-wrong skills masquerading as ready.
- Does NOT skip eval skeletons. Three skeletons per generated skill is the PHARN minimum.
- Does NOT clobber an existing non-empty output directory without
--force. - Does NOT generate hook stubs with external dependencies. PHARN hooks are zero-dep, stdlib-only — the stub reflects this.
- Does NOT support PHARN-internal types in v1: orchestrator, scout, planner, phase, verifier, griller, MCP server. Five buyer-facing types only.
- Does NOT auto-run
/pharn-evalafter scaffolding. The user fills in the TODOs first. - Does NOT create marketplace listings, publish to a registry, or update
pharn.config.json's skill list. Scaffolding produces files on disk; registration is out of scope. - Does NOT modify pharn-owned skills. Only writes new directories under the user's
.claude/.
Verification
After running /pharn-skill, the scaffolded skill must satisfy:
- Frontmatter contains
kind: community(vendor-bridge also hasseal: vendor-bridge); nokind: pharn-owned; no"PHARN ✓ reviewed"seal. - The body has all five PHARN sections present with TODO markers where the user must fill in detail: purpose, when-to-use, procedure, what-NOT-to-do, verification.
-
evals/cases/contains three.mdskeleton files with valid YAML frontmatter. -
evals/expected/contains three matching.jsonskeleton files. - For hooks:
<name>.cjsis a single-file CommonJS stub, norequireof non-stdlib modules, nopackage.jsonadded. - For hooks:
settings.snippet.jsonmatches the chosenhook_event(matcher present only forPreToolUse/PostToolUse) AND uses the required Claude Code nesting — each event maps to an array of{ matcher?, hooks: [{ "type": "command", "command": … }] }groups, never a bare{ "command": … }(a flat command object silently fails to register the hook). - Output path is correct:
.claude/skills/<name>/for command/validator/lens/vendor-bridge,.claude/hooks/<name>/for hook. - README explicitly states the community status of the generated skill.