--- source_keys: - apm-cli-installed-source - apm-docs-llms-full - adr-0029-prompt-house-rule --- # Authoring an apm prompt Reached from `SKILL.md` Step 1 for a prompt. Run the Gate, then write against the description contract and the checklist, then return to `SKILL.md` Step 3. ## Gate This repo holds a prompt to ADR-0029, which is stricter than apm: apm calls a prompt "a callable program", but on Claude it deploys as a command that is a skill in every respect except that it keeps fewer frontmatter keys, apm drops `disable-model-invocation` so it can never be made user-only, and Codex receives no prompts at all. A prompt that carries procedure is therefore a worse skill on every harness. - **Reusable know-how, steps, gotchas, bundled files, or anything the model should find on its own** → a skill. Stop and hand to `skill-author`; if a short steering message is still wanted afterwards, come back and write it against the new skill. - **A single-intent message the user would otherwise type repeatedly, steering existing skills or agents by name** → continue. Confirm each skill or agent it names exists and is not `disable-model-invocation: true`: the prompt's body reaches the model, and the model cannot invoke a skill that sets it, so the steering would dead-end (the same check `factory-audit`'s prompt flow applies). ## Description contract One plain, user-facing sentence stating the action and naming the skills or agents it steers — "Review the current PR with `gitea-prs` and `factory-audit`, then summarise the findings." No "Use when" trigger clause and no `Not X -> Y` boundary: on Claude the description is model-visible, and a trigger clause invites the router to pick the wrapper over the skills it wraps. ## Checklist Copy `assets/templates/name.prompt.md.template` and drop `.template` only on the final path. Must: 1. The path is `.apm/prompts/.prompt.md`, directly in that directory, not a symlink or hardlink. `` is a safe path segment and unique across `.apm/prompts/` and the package root; it becomes the Copilot filename and the Claude `/command` name. 2. `description` is present and non-empty. 3. Every `input:` name matches `^[A-Za-z][\w-]{0,63}$`, written in the object form `- pr_number: "The PR to review"`. Never copy apm's published `- name: pr_number` / `description: …` example: apm reads the map's keys, so it produces the arguments `name` and `description`. 4. Every `${input:x}` in the body is declared in `input:`, and every declared name is used. Without `input:`, no `${input:…}` may appear — it would reach Claude unrewritten. Should: 5. Frontmatter keys stay within `description`, `allowed-tools`, `model`, `argument-hint` and `input`. Claude drops everything else with only a warning. The exception: a Copilot-only key (`agent`, `tools`, …) that is intended, with its Claude drop accepted and said so. 6. The description follows the contract above: one plain sentence, no trigger or boundary clause, naming the skills or agents it steers. 7. Spell keys in kebab-case — `allowed-tools`, `argument-hint` — not the camelCase aliases. 8. Omit `argument-hint` when `input:` is set; apm synthesises ` ` from the input names. 9. Keep one intent per prompt, and write the body as second-person instructions. 10. Keep `description` to 250 characters or fewer. 11. Give `model` a slug the target accepts. Copilot ignores `allowed-tools` and `model`, so neither constrains a Copilot run.