The existing schema doc covered only Claude and Copilot and called missing description and empty content errors when apm 0.28.0 only warns. Rewrite it with the applyTo grammar and add per-target compile/install mapping and a gotchas doc (unquoted globs, install-vs-compile discovery, dedup and overwrite behaviour), all verified against the apm 0.28.0 binary. Refs: #148 Co-Authored-By: Claude Code <[email protected]> Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
5.8 KiB
topic, source_keys
| topic | source_keys | |||||
|---|---|---|---|---|---|---|
| instructions-gotchas |
|
Surprising behaviours and source contradictions for the instructions primitive. "Verified" means observed with the installed apm 0.28.0 in a throwaway directory outside the repo. Everything else is stated as sourced or inferred.
Verified failure modes
Unquoted glob silently widens scope
applyTo: **/*.py (unquoted) is a YAML alias error. Verified outcome:
apm compileandapm compile --validateprint "Failed to parse" and skip the file, exit 0; the validated-primitive count is one lower.apm installstill deploys the file, to.claude/rules/<name>.mdwith nopaths:frontmatter. A rule meant for Python files becomes an unconditional rule loaded in every session. Nothing errors.- Any frontmatter that is broken YAML (for example
description: [broken) behaves the same way. - Claude Code itself behaves consistently: invalid frontmatter is ignored and the rule loads without
paths.
Rule for the skill: always quote applyTo, and after scaffolding check that the deployed file has the expected paths:; a missing frontmatter block is the symptom.
Validation never fails
Missing description, missing applyTo and an empty body are warnings only. apm compile --validate prints "All primitives validated successfully" and exits 0 even for those, and shows none of the warnings. Only a real apm compile prints them. apm install and apm audit --ci print nothing about instruction content. The official docs call description and applyTo required; the binary does not enforce either. Any enforcement has to live in this repo's own checks.
Nested files: compile sees them, install does not
.apm/instructions/sub/x.instructions.md is folded into compiled root files but never deployed natively. A plain x.md (no .instructions infix) is ignored by both.
Compile writes nothing when native rules exist (Claude, Copilot, Antigravity)
apm compile --target claude after an install exits 0, prints "produced no output files" and creates no CLAUDE.md. Use --force-instructions or compile in a project with no native rules. A test that only checks the exit code passes without testing anything.
Compile duplicates content for the other targets
For cursor, windsurf, kiro, codex (and grok, opencode by source) compile still writes AGENTS.md even though native rules exist, so the same instruction reaches the agent twice.
Install overwrites hand-authored rule files
For claude, cursor, windsurf, kiro and antigravity, an existing file at the deployed path is replaced without warning. Copilot skips it and asks for --force.
Empty-source compile is not an error
Plain apm compile and --target all in a project with no instruction primitives print "no source primitives remain" and exit 0. The apm-workflow compile reference currently says this hard-fails with exit 1 and "No instruction files found in .apm/ directory"; that does not hold in 0.28.0 (see contradictions).
Cursor-specific
- Install emits
globsplusdescriptionand neveralwaysApply. Per the Cursor docs a rule with only adescriptionis "Apply Intelligently", so an unscoped apm instruction does not become always-on in Cursor (inferred from docs plus verified output; Cursor runtime not tested). - Multiple globs are emitted as a YAML list (Kiro likewise). The Cursor docs show only a comma-separated string. Unverified whether Cursor honours the list form.
Claude-specific
descriptionis dropped, so it can never appear in a.claude/rules/file; do not rely on it for Claude Code. Source: the apm source transform and verified deployed output. The apm docs do not state this.- A rule with no
applyTobecomes a file with no frontmatter and loads at every launch, which costs context. Claude Code guidance is to keep each file short (under 200 lines). - The documented Claude
pathsbudget is 1,000 brace-expanded patterns and 4 MiB.
Contradictions between sources
| Point | Official apm docs | Installed 0.28.0 behaviour |
|---|---|---|
description |
Required | Warning only |
applyTo |
Listed as required and also as optional | Optional, warning only |
Instruction with no applyTo |
Folded into compiled root files instead of a per-file rule | Still deployed per-file on every rule-directory target (Claude: no frontmatter; Cursor: description only; Windsurf: always_on; Kiro: always) and also compiled |
| Grok deployed name | .grok/rules/<name>.md |
.grok/rules/<name>.instructions.md |
| Compile with nothing to compile | apm-workflow compile reference: exit 1 with a "No instruction files found" message | Exit 0 |
| Compile scope | Docs say compile "only handles instructions" | Consistent for content, but compile also emits GEMINI.md and honours the agents_md mode |
| Cursor and Windsurf at user scope | Two fetches of the docs disagreed | Source excludes both at user scope; the source was preferred |
An earlier version of this topic's schema file described missing description and empty content as errors and skip_instructions as a config flag; both were wrong for 0.28.0 (warnings; internal variable).
Unverified
- Whether Cursor accepts a YAML list for
globs. - Whether Copilot ignores unknown frontmatter keys such as
description; its docs list onlyapplyToandexcludeAgent. - Runtime behaviour of Windsurf, Kiro and Antigravity on the emitted frontmatter; no downstream docs were fetched.
- Windsurf user-scope global rules.
- The Context7 step was unavailable (invalid API key), so the registry carries no fresh Context7 pull. Doc pages were summarised by a smaller model before reaching this file and can be lossy.
- Apm versions other than 0.28.0 were not tested.