fix(primitive-author): annotate tier moves and route package config

- annotate the research Must demoted to hook Should 12; narrow Must 5 note
- extend Must 6 to scripts run via an interpreter -c string
- add a fallback dispatch row and comma-joined --target guidance
- fall back when agentsmd-author is not installed
- add the apm-workflow boundary; pin upstream apm source URL

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
This commit is contained in:
2026-09-29 08:00:26 +00:00
parent 36723ae3fc
commit fd86ee42f4
5 changed files with 28 additions and 18 deletions

View File

@@ -68,7 +68,7 @@ Must:
else fails the Copilot install outright. The file contributes at least one entry, and every
entry carries at least one handler: an empty list or a handler-less entry deploys nothing, with
only a warning.
4. Every event is one each target the package deploys to fires, after apm's rename for that target
4. Every event is one that each target the package deploys to fires, after apm's rename for that target
(`_HOOK_EVENT_MAP`; no `targets:` means every target). Write Claude's PascalCase names
(`PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `SessionStart`, `Stop`, …), which apm renames
for each target its map covers. A name the map does not cover deploys verbatim with no warning,
@@ -84,10 +84,11 @@ Must:
the path itself, and no space. When quoting, quote the whole token —
`"${PLUGIN_ROOT}/scripts/my-hook.sh"`, never `"${PLUGIN_ROOT}"/scripts/x.sh`: apm rewrites
`${PLUGIN_ROOT}` only when a path separator follows it directly, and only up to the next space
or quote, so a split quote is left unrewritten and a spaced path is cut short. This is stricter
than the research's Should, as with Must 6: either defect fails every time the hook fires. A
missing script is only a warning at install time.
6. A script run directly as the command's first token is executable. This is stricter than the
or quote, so a split quote is left unrewritten and a spaced path is cut short. The quoting and
space rules are stricter than the research's Should, as with Must 6: either defect fails every
time the hook fires. A missing script is only a warning at install time.
6. A script run directly as the command's first token, or as the first token of an interpreter's
`-c` command string (`bash -c "${PLUGIN_ROOT}/x.sh"`), is executable. This is stricter than the
research's Should: without it the hook fails every time it fires. A script passed to an
interpreter (`bash ${PLUGIN_ROOT}/x.sh`) needs no executable bit.
@@ -105,5 +106,5 @@ Should:
12. No filename that routes by target. Case-insensitively, apm routes a stem of exactly
`hooks-<target>` and any stem ending `<target>-hooks` — bare (`claude-hooks`), prefixed
(`x-claude-hooks`) or combined (`claude-codex-hooks`, the union). That routing is deprecated and
reach belongs to `targets:` (see Gate); the research allows it only when deprecated routing is
intended.
reach belongs to `targets:` (see Gate). The research files this as a Must; it is a Should here
because only the author can say deprecated routing is intended.

View File

@@ -15,13 +15,16 @@ An instruction is a scoped rule: it applies when the agent touches files matchin
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`.
always-on source. Stop and hand to `agentsmd-author`; if it is not installed, edit the repo's
AGENTS.md directly.
- **No file pattern fits** → an instruction without `applyTo` is always-on in every session of
every repo that installs this package, and `apm compile` can fold it into the global sections of
`AGENTS.md` and `CLAUDE.md` (CLAUDE.md is skipped when `.claude/rules/` is populated, AGENTS.md
when `.github/instructions/` is, unless `--force-instructions`). 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`.
- **Which harnesses receive it, or other package config** → set by the package `apm.yml`
`targets:`, never by the instruction file. Stop and hand to `apm-workflow`.
- **A rule scoped to a file pattern** → continue.
## Checklist

View File

@@ -26,6 +26,8 @@ worse skill on every harness.
`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).
- **Which harnesses receive it, or other package config** → set by the package `apm.yml`
`targets:`, never by the prompt file. Stop and hand to `apm-workflow`.
## Description contract
@@ -36,7 +38,8 @@ 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.
Copy `assets/templates/name.prompt.md.template` and drop `.template` only on the final path. No
parameters: delete `input:` and the `${input:…}` line.
Must:

View File

@@ -2,7 +2,8 @@
## apm-cli-installed-source
- **URL:** file:///root/.local/pipx/venvs/apm-cli/lib/python3.11/site-packages/apm_cli/
- **URL:** https://github.com/microsoft/apm/tree/v0.28.0/src/apm_cli/
- **Note:** read locally from the pipx install at `~/.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; each Must/Should traces to the research docs' Authoring checklists or audit-only lists, or to ADR-0029, with tier moves annotated inline, and the `**/*.instructions.md` local-discovery glob behind the template-suffix Gotcha is `primitives/discovery.py` `LOCAL_PRIMITIVE_PATTERNS`; the per-target event rename maps are `integration/hook_integrator.py` `_HOOK_EVENT_MAP`; and Step 4.2's render relies on `apm install <local path>` deploying the working tree to every `--target`, verified against 0.28.0
- **Contributing files:** SKILL.md, references/hook.md, references/instruction.md, references/prompt.md