feat(kyberforge): primitive-author and factory-audit support for apm hooks, instructions and prompts #144
@@ -2,12 +2,12 @@
|
|||||||
name: factory-audit
|
name: factory-audit
|
||||||
description: >
|
description: >
|
||||||
Use when a skill, agent, or apm hook, instruction or prompt needs auditing,
|
Use when a skill, agent, or apm hook, instruction or prompt needs auditing,
|
||||||
including "is this ready to ship", or after hand-editing one outside its
|
or "is this ready to ship". Not fixing a skill -> skill-author.
|
||||||
author skill. Not applying skill fixes -> skill-author.
|
Not fixing an agent -> agent-author.
|
||||||
Not applying agent fixes -> agent-author.
|
Not fixing a hook, instruction or prompt -> primitive-author.
|
||||||
allowed-tools: Bash Read
|
allowed-tools: Bash Read
|
||||||
metadata:
|
metadata:
|
||||||
version: "1.1.0"
|
version: "1.1.1"
|
||||||
category: factory
|
category: factory
|
||||||
source_keys:
|
source_keys:
|
||||||
- agentskills-home
|
- agentskills-home
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
name: forge
|
name: forge
|
||||||
description: >
|
description: >
|
||||||
Use when the user wants to build or improve something but has not yet named
|
Use when the user wants to build or improve something but has not yet named
|
||||||
the artifact type — skill, agent, plugin, or marketplace entry; "not sure if
|
the artifact type; "not sure if this should be a skill or a plugin", "I have
|
||||||
this should be a skill or a plugin", "I have an idea but don't know where it
|
an idea but don't know where it belongs". Routes to the matching author
|
||||||
belongs". Routes to the matching author skill. Do not use when the type is
|
skill. Do not use when the type is already named — invoke `skill-author`,
|
||||||
already named — invoke `skill-author`, `agent-author` or `apm-workflow`
|
`agent-author`, `primitive-author` or `apm-workflow` directly.
|
||||||
directly.
|
|
||||||
metadata:
|
metadata:
|
||||||
version: "1.0.1"
|
version: "1.0.2"
|
||||||
category: factory
|
category: factory
|
||||||
source_keys:
|
source_keys:
|
||||||
- claude-code-subagents-docs
|
- claude-code-subagents-docs
|
||||||
@@ -18,7 +17,7 @@ metadata:
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
- forge is an optional guided entry point, not a gate — `skill-author`, `agent-author`, `factory-audit` and `apm-workflow` all stay directly invokable, and forge never intercepts a direct call to one.
|
- forge is an optional guided entry point, not a gate — `skill-author`, `agent-author`, `primitive-author`, `factory-audit` and `apm-workflow` all stay directly invokable, and forge never intercepts a direct call to one.
|
||||||
- Claude Code's skill-level `context: fork` frontmatter field and the `/fork` subagent command are opposites despite the shared word: `context: fork` isolates (fresh context, no parent access), while `/fork` inherits the full conversation. The route reference each classification loads spends that distinction: `references/author-routes.md` chooses between the two, `references/apm-routes.md` rules the fork out.
|
- Claude Code's skill-level `context: fork` frontmatter field and the `/fork` subagent command are opposites despite the shared word: `context: fork` isolates (fresh context, no parent access), while `/fork` inherits the full conversation. The route reference each classification loads spends that distinction: `references/author-routes.md` chooses between the two, `references/apm-routes.md` rules the fork out.
|
||||||
|
|
||||||
## Step 1 — Grill the intent
|
## Step 1 — Grill the intent
|
||||||
@@ -37,12 +36,13 @@ Match the grilled intent against exactly one row — or more than one, if the in
|
|||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| A reusable capability the agent loads inline in the main conversation, triggered by description-matching, free to bundle its own `references/`, `scripts/` or `assets/` | Skill | `skill-author` | `references/author-routes.md` |
|
| A reusable capability the agent loads inline in the main conversation, triggered by description-matching, free to bundle its own `references/`, `scripts/` or `assets/` | Skill | `skill-author` | `references/author-routes.md` |
|
||||||
| A recurring task needs its own reusable definition — dedicated system prompt, tools and description, invokable by name across sessions | Agent / subagent | `agent-author` | `references/author-routes.md` |
|
| A recurring task needs its own reusable definition — dedicated system prompt, tools and description, invokable by name across sessions | Agent / subagent | `agent-author` | `references/author-routes.md` |
|
||||||
|
| A runtime callback at a harness event, a rule scoped to a file pattern, or a reusable user-typed message steering existing skills | Hook / instruction / prompt (apm primitive) | `primitive-author` | `references/author-routes.md` |
|
||||||
| A new distributable unit — no existing plugin is the right home for the skill, agent, hook or MCP server being built, or the bundle needs its own manifest, versioning and install lifecycle | Plugin | `apm-workflow` (`apm plugin init`) | `references/apm-routes.md` |
|
| A new distributable unit — no existing plugin is the right home for the skill, agent, hook or MCP server being built, or the bundle needs its own manifest, versioning and install lifecycle | Plugin | `apm-workflow` (`apm plugin init`) | `references/apm-routes.md` |
|
||||||
| The plugin already exists and only its marketplace-facing metadata changes — a first listing, or a version/description update, never the plugin's contents | Marketplace entry | `apm-workflow` (`apm marketplace package add`) | `references/apm-routes.md` |
|
| The plugin already exists and only its marketplace-facing metadata changes — a first listing, or a version/description update, never the plugin's contents | Marketplace entry | `apm-workflow` (`apm marketplace package add`) | `references/apm-routes.md` |
|
||||||
|
|
||||||
The table classifies what to build, not how to run it: a one-off task that merely needs an isolated or context-inheriting run is not an artifact and has no row here. If the intent stays genuinely ambiguous between rows after grilling, ask the user rather than guessing.
|
The table classifies what to build, not how to run it: a one-off task that merely needs an isolated or context-inheriting run is not an artifact and has no row here. If the intent stays genuinely ambiguous between rows after grilling, ask the user rather than guessing.
|
||||||
|
|
||||||
A real artifact that matches no row — a hook, an MCP server, an AGENTS.md, a research doc — has no route here. Say so, hand the user the skill that does own it, and never bend it into a row to make the table fit.
|
A real artifact that matches no row — an MCP server, an AGENTS.md, a research doc — has no route here. Say so, hand the user the skill that does own it, and never bend it into a row to make the table fit.
|
||||||
|
|
||||||
When the intent spans several rows, chain the routes in dependency order — an artifact that must exist on disk before another skill can target it goes first, so `apm-workflow` scaffolds the plugin directory before `skill-author` scaffolds a skill inside it.
|
When the intent spans several rows, chain the routes in dependency order — an artifact that must exist on disk before another skill can target it goes first, so `apm-workflow` scaffolds the plugin directory before `skill-author` scaffolds a skill inside it.
|
||||||
|
|
||||||
@@ -51,4 +51,4 @@ When the intent spans several rows, chain the routes in dependency order — an
|
|||||||
## Step 3 — Closing gates, common to every route
|
## Step 3 — Closing gates, common to every route
|
||||||
|
|
||||||
- **Resolve before closing.** A route is finished only when its verification reports nothing unresolved. An actionable finding reopens the route; it is never reported onward as a caveat.
|
- **Resolve before closing.** A route is finished only when its verification reports nothing unresolved. An actionable finding reopens the route; it is never reported onward as a caveat.
|
||||||
- **Bump the package version.** A skill route always lands here: `skill-author` moves only a skill's own `metadata.version`, which is not the package `apm.yml`'s number — so read `references/version-bump.md` after one. `agent-author` and the apm routes bump the package themselves at plugin scope; after those, read it only when their output does not say they did.
|
- **Bump the package version.** A skill route always lands here: `skill-author` moves only a skill's own `metadata.version`, which is not the package `apm.yml`'s number — so read `references/version-bump.md` after one. `agent-author`, `primitive-author` and the apm routes bump the package themselves at plugin scope; after those, read it only when their output does not say they did.
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ source_keys:
|
|||||||
- claude-code-subagents-docs
|
- claude-code-subagents-docs
|
||||||
---
|
---
|
||||||
|
|
||||||
# Routing a skill or agent to its author skill
|
# Routing a skill, agent or apm primitive to its author skill
|
||||||
|
|
||||||
Reached from `SKILL.md` Step 2 when the classified artifact is a skill or an agent/subagent
|
Reached from `SKILL.md` Step 2 when the classified artifact is a skill, an agent/subagent
|
||||||
definition. Route a skill to `skill-author` and an agent to `agent-author`. The two branches
|
definition, or a hook, instruction or prompt. Route a skill to `skill-author`, an agent to
|
||||||
differ on the author skill only — both verify the result with `factory-audit`, which detects the
|
`agent-author`, and a hook, instruction or prompt to `primitive-author`. The branches differ on
|
||||||
artifact type itself — and everything below applies to both.
|
the author skill only — all verify the result with `factory-audit`, which detects the artifact type
|
||||||
|
itself — and everything below applies to all of them.
|
||||||
|
|
||||||
## Choose fork or inline
|
## Choose fork or inline
|
||||||
|
|
||||||
@@ -25,8 +26,8 @@ Fall back to an **inline invocation** — same conversation, no subagent — whe
|
|||||||
|
|
||||||
## Two-tier verification
|
## Two-tier verification
|
||||||
|
|
||||||
Both author skills already close out with their own inline audit, in the same context as the
|
Every author skill already closes out with its own inline audit, in the same context as the
|
||||||
authoring work: `skill-author` and `agent-author` each invoke `factory-audit` on what they wrote.
|
authoring work: `skill-author`, `agent-author` and `primitive-author` each invoke `factory-audit` on what they wrote.
|
||||||
That is tier one, and forge does not change it.
|
That is tier one, and forge does not change it.
|
||||||
|
|
||||||
Tier two belongs to forge. Once the author skill's run has finished, spin up a separate
|
Tier two belongs to forge. Once the author skill's run has finished, spin up a separate
|
||||||
|
|||||||
52
plugins/kyberforge/.apm/skills/primitive-author/SKILL.md
Normal file
52
plugins/kyberforge/.apm/skills/primitive-author/SKILL.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
name: primitive-author
|
||||||
|
description: >
|
||||||
|
Use when the user wants an apm hook, instruction or prompt file created, or
|
||||||
|
audit findings or feedback applied to an existing one.
|
||||||
|
Not skills -> skill-author. Not agents -> agent-author.
|
||||||
|
allowed-tools: Bash Read Write Edit
|
||||||
|
metadata:
|
||||||
|
version: "0.1.0"
|
||||||
|
category: factory
|
||||||
|
source_keys:
|
||||||
|
- apm-cli-installed-source
|
||||||
|
- apm-docs-llms-full
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gotchas
|
||||||
|
|
||||||
|
- `apm compile --validate` is not a gate. apm turns every instruction and prompt problem into a warning and exits 0, and `apm install` never validates at all — `/factory-audit` is the only check that fails.
|
||||||
|
- Never draft with the real suffix outside `.apm/<type>/`. apm's local discovery globs `**/*.instructions.md` across the whole tree, so a draft or template named that way anywhere in the repo compiles into `AGENTS.md`. The templates carry a trailing `.template` for this reason; drop it only on the final path.
|
||||||
|
- Never hand-write `.claude/settings.json`, even to test a hook. apm owns that file (ADR-0019), overwrites it outright when it is malformed, and `apm audit --ci` fails on anything it would not have written.
|
||||||
|
|
||||||
|
## Step 1 — Dispatch
|
||||||
|
|
||||||
|
| Target or intent | Primitive | Reference |
|
||||||
|
|---|---|---|
|
||||||
|
| A hook — `.apm/hooks/<name>.json`, or "run X whenever Y happens" | hook | `references/hook.md` |
|
||||||
|
| An instruction — `.apm/instructions/<name>.instructions.md`, or a rule for files matching a pattern | instruction | `references/instruction.md` |
|
||||||
|
| A prompt — `.apm/prompts/<name>.prompt.md`, or a reusable message the user types to kick off work | prompt | `references/prompt.md` |
|
||||||
|
| A skill or an agent | — | stop: route to `skill-author` or `agent-author` |
|
||||||
|
|
||||||
|
Read only the reference matching the resolved primitive — each is self-contained. If the target sits inside a git worktree, capture `rtk git log --oneline -1` before touching the filesystem; Step 4 needs it.
|
||||||
|
|
||||||
|
## Step 2 — Boundary gate
|
||||||
|
|
||||||
|
Run the reference's **Gate** section before writing anything. A failed gate stops this skill: name the owner it points to — `skill-author` for procedure, `agentsmd-author` for a repo-only rule, `apm-workflow` for reach or `targets:` — and hand over. Never bend the artifact to pass the gate.
|
||||||
|
|
||||||
|
## Step 3 — Create or improve
|
||||||
|
|
||||||
|
| Condition | Action |
|
||||||
|
|---|---|
|
||||||
|
| No file at the target path | Create: copy the reference's template from `assets/templates/`, drop `.template`, fill every `FILL IN`, and apply the reference's checklist |
|
||||||
|
| File exists, at least one signal | Improve: read the whole file, then apply each signal against the reference's checklist |
|
||||||
|
| File exists, no signal | Stop and ask whether the user meant a new file or has feedback to apply |
|
||||||
|
|
||||||
|
Signals: grill output, `/factory-audit` findings, inline feedback, session context describing what went wrong. Group findings by root cause and fix the cause once.
|
||||||
|
|
||||||
|
## Step 4 — Validate and close
|
||||||
|
|
||||||
|
1. Run `/factory-audit` on the file, inline in this context; resolve every FAIL before reporting done.
|
||||||
|
2. Run `rtk apm install --dry-run` from the repo root and read what each target will receive. On a feature branch, discard `apm.lock.yaml` churn afterwards (`rtk git checkout -- apm.lock.yaml`).
|
||||||
|
3. Bump the owning package's `apm.yml` `version:` — minor for a new primitive, patch for a fix — unless this branch already bumped it for unreleased work. A primitive has no version of its own.
|
||||||
|
4. **Commit verification.** Inside a git worktree, once the audit is clean, run `rtk git add` and `rtk git commit`, then re-run `rtk git log --oneline -1` and confirm the hash changed from Step 1's. Staged-but-uncommitted work is silently lost if the tree is cleaned up. Outside a worktree, report done on a clean audit and name that as the reason.
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"FILL_IN_PascalCaseEvent": [
|
||||||
|
{
|
||||||
|
"matcher": "FILL_IN_matcher",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "${PLUGIN_ROOT}/.apm/hooks/FILL_IN_script.sh",
|
||||||
|
"timeout": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
description: "FILL IN: one sentence on what this rule governs"
|
||||||
|
applyTo: "FILL IN: glob, e.g. **/*.{ts,tsx}"
|
||||||
|
---
|
||||||
|
|
||||||
|
FILL IN: the rule, as direct second-person guidance. Put any rationale Claude needs here — the
|
||||||
|
description above never reaches Claude.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
description: "FILL IN: one user-facing action naming the skills it steers"
|
||||||
|
input:
|
||||||
|
- FILL_IN_name: "FILL IN: what the user supplies"
|
||||||
|
---
|
||||||
|
|
||||||
|
FILL IN: the message the user would otherwise type, steering existing skills or agents by name.
|
||||||
|
Use ${input:FILL_IN_name} where the value belongs.
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
---
|
||||||
|
source_keys:
|
||||||
|
- apm-cli-installed-source
|
||||||
|
- apm-docs-llms-full
|
||||||
|
---
|
||||||
|
|
||||||
|
# Authoring an apm hook
|
||||||
|
|
||||||
|
Reached from `SKILL.md` Step 1 for a hook. Run the Gate, then write against the shape and the
|
||||||
|
checklist, then return to `SKILL.md` Step 3.
|
||||||
|
|
||||||
|
## Gate
|
||||||
|
|
||||||
|
A hook is a runtime callback the harness fires inside its own tool loop — "this must always
|
||||||
|
happen at this event", enforced deterministically rather than left to the model. apm's own
|
||||||
|
guidance is to reach for a skill, instruction or prompt first, and to treat hooks as opt-in
|
||||||
|
surface: they ship to a strict subset of harnesses and are silently skipped everywhere else.
|
||||||
|
|
||||||
|
- **Procedure, know-how, or anything the model should decide to do** → a skill. Stop and hand to
|
||||||
|
`skill-author`.
|
||||||
|
- **The hook must reach only some harnesses** → reach is set by the package `apm.yml` `targets:`,
|
||||||
|
never by the hook file. Stop and hand to `apm-workflow`. `targets:` is package-wide, so a
|
||||||
|
harness-specific hook in a multi-target package means either a separate package or accepting that
|
||||||
|
the other targets receive it too.
|
||||||
|
- **A runtime callback** → continue.
|
||||||
|
|
||||||
|
## Shape
|
||||||
|
|
||||||
|
One JSON file per concern at `.apm/hooks/<name>.json`, with a plain name. Copy
|
||||||
|
`assets/templates/hook.json.template`. Write the canonical shape apm documents and renders per
|
||||||
|
target:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"PreToolUse": [
|
||||||
|
{
|
||||||
|
"matcher": "Bash",
|
||||||
|
"hooks": [
|
||||||
|
{"type": "command", "command": "${PLUGIN_ROOT}/.apm/hooks/check.sh", "timeout": 10}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`${PLUGIN_ROOT}`** is the target-neutral token; apm rewrites it per target
|
||||||
|
(`"${CLAUDE_PROJECT_DIR}/.claude/hooks/<pkg>/…"` on Claude, repo-relative elsewhere).
|
||||||
|
`${CLAUDE_PLUGIN_ROOT}` also works but ties the source to one harness's name.
|
||||||
|
- **Claude is the verified target.** apm 0.28.0 passes this nested shape to Copilot without
|
||||||
|
reshaping it, and whether Copilot CLI runs nested entries or honours `matcher` is unverified. That
|
||||||
|
gap is apm's to close — do not work around it with a second, Copilot-flat file.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
Must:
|
||||||
|
|
||||||
|
1. The file sits directly in `.apm/hooks/`, is not a symlink or hardlink, and parses as a JSON
|
||||||
|
object. apm skips invalid JSON silently.
|
||||||
|
2. Every event value is a list of objects, and every nested `hooks` is a list of objects. Anything
|
||||||
|
else fails the Copilot install outright.
|
||||||
|
3. Event names are PascalCase (`PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `SessionStart`,
|
||||||
|
`Stop`, …). An all-lowercase name (`stop`) never warns and never fires; a camelCase name outside
|
||||||
|
apm's rename map (`userPromptSubmit`) deploys verbatim to Claude and never fires.
|
||||||
|
4. The script is referenced as `${PLUGIN_ROOT}/…` (package root) or `./…` (hook directory),
|
||||||
|
exists inside the package, and is executable. No absolute path, and no `$` or backtick in the
|
||||||
|
path itself. A missing script is only a warning at install time.
|
||||||
|
5. No `hooks-<target>` or `*-<target>-hooks` filename. That routing is deprecated; reach belongs to
|
||||||
|
`targets:` (see Gate).
|
||||||
|
|
||||||
|
Should:
|
||||||
|
|
||||||
|
6. Every handler sets `"type": "command"` and an explicit `timeout` in seconds — apm passes `type`
|
||||||
|
through but never supplies it.
|
||||||
|
7. Set `matcher` explicitly on tool events and on `SessionStart` (`startup`, `resume`, …). Omitted,
|
||||||
|
Claude receives `"*"`.
|
||||||
|
8. Do not author Copilot's flat `bash` / `powershell` / `timeoutSec` keys in a Claude-shaped file;
|
||||||
|
they render onto Claude as stray keys.
|
||||||
|
9. Quote a script path that may contain spaces: `"${PLUGIN_ROOT}/scripts/my hook.sh"`.
|
||||||
|
10. Keep helper files in the hook directory non-JSON. Copilot's loader rejects any bundled `.json`
|
||||||
|
without a `hooks` key.
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
source_keys:
|
||||||
|
- apm-cli-installed-source
|
||||||
|
- apm-docs-llms-full
|
||||||
|
---
|
||||||
|
|
||||||
|
# Authoring an apm instruction
|
||||||
|
|
||||||
|
Reached from `SKILL.md` Step 1 for an instruction. Run the Gate, then write against the checklist,
|
||||||
|
then return to `SKILL.md` Step 3.
|
||||||
|
|
||||||
|
## Gate
|
||||||
|
|
||||||
|
An instruction is a scoped rule: it applies when the agent touches files matching its `applyTo`
|
||||||
|
glob. On Claude it deploys to `.claude/rules/<stem>.md` with `applyTo` renamed to `paths:`.
|
||||||
|
|
||||||
|
- **A rule for this repo alone** → it belongs in the repo's AGENTS.md, which is the single
|
||||||
|
always-on source. Stop and hand to `agentsmd-author`.
|
||||||
|
- **No file pattern fits** → an instruction without `applyTo` is always-on in every session of
|
||||||
|
every repo that installs this package, and `apm compile` folds it into the global sections of
|
||||||
|
`AGENTS.md` and `CLAUDE.md`. Say exactly that to the user and continue only on an explicit yes.
|
||||||
|
Legitimate when a package deliberately ships guidance to its consumers; never a default.
|
||||||
|
- **Procedure the agent follows step by step** → a skill. Stop and hand to `skill-author`.
|
||||||
|
- **A rule scoped to a file pattern** → continue.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
Copy `assets/templates/name.instructions.md.template` and drop `.template` only on the final path.
|
||||||
|
|
||||||
|
Must:
|
||||||
|
|
||||||
|
1. The path is `.apm/instructions/<stem>.instructions.md`, directly in that directory, not a
|
||||||
|
symlink or hardlink.
|
||||||
|
2. `description` is a non-empty string. apm only warns when it is missing.
|
||||||
|
3. The body is non-empty. apm deploys an empty rule silently.
|
||||||
|
4. `applyTo` is a non-empty glob or comma-separated list — top-level commas only as separators,
|
||||||
|
alternation inside `{}` (`"**/*.{ts,tsx}"`) — or absent after the Gate's explicit yes.
|
||||||
|
5. The stem is unique across the package and its dependencies: a `.claude/rules/<stem>.md`
|
||||||
|
collision is silently overwritten.
|
||||||
|
|
||||||
|
Should:
|
||||||
|
|
||||||
|
6. Write `applyTo` as a scalar string, not a YAML list. Copilot receives the source verbatim, and
|
||||||
|
its handling of a list is unverified.
|
||||||
|
7. Keep frontmatter to `description` and `applyTo`, plus optional `author` and `version`. No target
|
||||||
|
consumes other keys, and Claude drops them.
|
||||||
|
8. Put any rationale Claude needs in the body. `description` never reaches Claude — it survives only
|
||||||
|
for Copilot and as Cursor's index text.
|
||||||
|
9. Keep relative markdown links resolvable from the source file.
|
||||||
|
10. Check the glob against the tree: one that matches nothing never fires, and one broader than the
|
||||||
|
rule's real scope spends context on every file it touches.
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
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`, which the model cannot invoke.
|
||||||
|
|
||||||
|
## Description contract
|
||||||
|
|
||||||
|
One plain, user-facing sentence stating the action and naming the skills 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. 250 characters at
|
||||||
|
most.
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
Copy `assets/templates/name.prompt.md.template` and drop `.template` only on the final path.
|
||||||
|
|
||||||
|
Must:
|
||||||
|
|
||||||
|
1. The path is `.apm/prompts/<name>.prompt.md`, directly in that directory, not a symlink. `<name>`
|
||||||
|
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, per the contract above.
|
||||||
|
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.
|
||||||
|
5. Frontmatter keys stay within `description`, `allowed-tools`, `model`, `argument-hint` and
|
||||||
|
`input`. Claude drops everything else with only a warning.
|
||||||
|
|
||||||
|
Should:
|
||||||
|
|
||||||
|
6. Spell keys in kebab-case — `allowed-tools`, `argument-hint` — not the camelCase aliases.
|
||||||
|
7. Omit `argument-hint` when `input:` is set; apm synthesises `<a> <b>` from the input names.
|
||||||
|
8. Keep one intent per prompt, and write the body as second-person instructions.
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
# Sources
|
||||||
|
|
||||||
|
## apm-cli-installed-source
|
||||||
|
|
||||||
|
- **URL:** file:///root/.local/pipx/venvs/apm-cli/lib/python3.11/site-packages/apm_cli/
|
||||||
|
- **Research doc:** plugins/kyberforge/docs/research/docs/microsoft-apm/sources.md
|
||||||
|
- **Description:** Installed apm-cli 0.28.0 source — ground truth for what apm deploys from a hook, instruction or prompt file and what it silently skips or only warns on; every Must/Should checklist item traces to the research docs' Authoring checklists, and the `**/*.instructions.md` local-discovery glob behind the template-suffix Gotcha is `primitives/discovery.py` `LOCAL_PRIMITIVE_PATTERNS`
|
||||||
|
- **Contributing files:** SKILL.md, references/hook.md, references/instruction.md, references/prompt.md
|
||||||
|
- **Status:** `extracted`
|
||||||
|
|
||||||
|
## apm-docs-llms-full
|
||||||
|
|
||||||
|
- **URL:** https://microsoft.github.io/apm/llms-full.txt
|
||||||
|
- **Research doc:** plugins/kyberforge/docs/research/docs/microsoft-apm/sources.md
|
||||||
|
- **Description:** Published apm docs bundle — the "Hooks and commands" guide's canonical hook shape, `${PLUGIN_ROOT}`, reach via `targets:` rather than deprecated filename routing, and "reach for a skill, instruction, or prompt first"; the "Author a prompt" guide's one-intent rule
|
||||||
|
- **Contributing files:** SKILL.md, references/hook.md, references/instruction.md, references/prompt.md
|
||||||
|
- **Status:** `extracted`
|
||||||
|
|
||||||
|
## adr-0029-prompt-house-rule
|
||||||
|
|
||||||
|
- **URL:** docs/adr/0029-prompts-are-thin-user-triggered-steering-messages.md
|
||||||
|
- **Research doc:** none
|
||||||
|
- **Basis:** docs/adr/0029-prompts-are-thin-user-triggered-steering-messages.md
|
||||||
|
- **Description:** The repo's prompt house rule — a prompt is a single-intent, user-triggered steering message with no procedure — and its description contract: one user-facing sentence naming the steered skills, no trigger or boundary clause
|
||||||
|
- **Contributing files:** references/prompt.md
|
||||||
|
- **Status:** `extracted`
|
||||||
@@ -39,10 +39,11 @@ Authoring source lives in `.apm/`; it is the only content source and the only th
|
|||||||
|
|
||||||
| Skill | Description |
|
| Skill | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `forge` | Grill an unclassified "I want to add something" request, decide whether it's a skill, agent, plugin, or marketplace entry, then route to the matching author skill |
|
| `forge` | Grill an unclassified "I want to add something" request, decide whether it's a skill, agent, hook, instruction, prompt, plugin, or marketplace entry, then route to the matching author skill |
|
||||||
| `skill-author` | Create or improve a skill from scratch, audit findings, or inline feedback |
|
| `skill-author` | Create or improve a skill from scratch, audit findings, or inline feedback |
|
||||||
| `agent-author` | Author an agent definition file |
|
| `agent-author` | Author an agent definition file |
|
||||||
| `factory-audit` | Audit a skill directory or an agent definition — structure, provider safety, description and body quality, and provenance; produces a findings report. Auto-detects which of the two it was handed (ADR-0025) |
|
| `primitive-author` | Create or improve an apm hook, instruction or prompt, gated on whether it should be one at all (ADR-0029 for prompts) |
|
||||||
|
| `factory-audit` | Audit a skill directory, an agent definition, or an apm hook, instruction or prompt — structure, provider safety, description and body quality, and provenance; produces a findings report. Auto-detects which it was handed (ADR-0025) |
|
||||||
| `apm-install` | Install or upgrade the apm CLI and set up the agent runtimes it drives (Copilot CLI, Codex, Gemini, generic llm) |
|
| `apm-install` | Install or upgrade the apm CLI and set up the agent runtimes it drives (Copilot CLI, Codex, Gemini, generic llm) |
|
||||||
| `apm-workflow` | Author apm.yml, scaffold an apm package/marketplace, install dependencies, and compile/pack/publish/audit apm content |
|
| `apm-workflow` | Author apm.yml, scaffold an apm package/marketplace, install dependencies, and compile/pack/publish/audit apm content |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user