fix(kyberforge): align primitive-author and factory-audit rule tiers
Second clean-context audit found author Must/Should and audit FAIL/SUGGESTION tiers drifting apart, and author Musts the audit never checked. - factory-audit: FAIL on absolute or bare relative hook script paths, an applyTo present but empty, and unbalanced braces/brackets in applyTo; judgment steps for dependency stem collisions, helper .json in hook dirs, unresolvable instruction links, prompt model slugs and second-person bodies; an unmatched glob drops to SUGGESTION; deliberate tier deviations recorded in hook-flow.md; validate.sh --help lists the three new modes; DescriptionOpener message no longer prescribes "Use when". - primitive-author: deprecated routing, extra prompt keys and the prompt description contract become Shoulds; hook Musts gain "contributes an entry", no bare relative paths, and executable-when-run-directly; prompt Must 1 covers hardlinks; Vale prose FAILs resolved at close. - forge: say "hook, instruction or prompt" rather than "apm primitive". Refs #94 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:
@@ -47,7 +47,8 @@ target:
|
||||
|
||||
- **`${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_PLUGIN_ROOT}` is rewritten identically, so it is valid, but it ties the source to one
|
||||
harness's name (Should 12).
|
||||
- **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. Per-file target routing is deprecated, so a Copilot-native flat hook
|
||||
@@ -59,20 +60,23 @@ target:
|
||||
Must:
|
||||
|
||||
1. The file sits directly in `.apm/hooks/`, is not a symlink, and parses as a JSON object. apm
|
||||
skips invalid JSON silently.
|
||||
skips invalid JSON silently. (apm also discovers a package-root `hooks/`, and `factory-audit`
|
||||
accepts it for third-party packages; author in `.apm/hooks/`.)
|
||||
2. Use the wrapped shape `{"hooks": {Event: [...]}}`. If a naked settings slice is used instead,
|
||||
every top-level value must be a list, with no stray scalar keys anywhere.
|
||||
3. Every event value is a list of objects, and every nested `hooks` is a list of objects. Anything
|
||||
else fails the Copilot install outright.
|
||||
else fails the Copilot install outright. The file contributes at least one entry: an empty one
|
||||
deploys nothing, with only a warning.
|
||||
4. 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.
|
||||
5. 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. Executable is stricter than the
|
||||
research's Should: a script invoked as the command's first token fails at runtime without it.
|
||||
6. No `hooks-<target>` or `*-<target>-hooks` filename. That routing is deprecated; reach belongs to
|
||||
`targets:` (see Gate).
|
||||
5. The script is referenced as `${PLUGIN_ROOT}/…` (or `${CLAUDE_PLUGIN_ROOT}/…`, see Shape) for
|
||||
the package root, or `./…` for the hook directory, and exists inside the package. No absolute
|
||||
path and no bare relative path (`scripts/x.sh`): apm bundles and rewrites neither. No `$` or
|
||||
backtick in the path itself. 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
|
||||
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.
|
||||
|
||||
Should:
|
||||
|
||||
@@ -85,3 +89,6 @@ Should:
|
||||
10. Quote a script path that may contain spaces: `"${PLUGIN_ROOT}/scripts/my hook.sh"`.
|
||||
11. Keep helper files in the hook directory non-JSON. Copilot's loader rejects any bundled `.json`
|
||||
without a `hooks` key.
|
||||
12. Prefer `${PLUGIN_ROOT}` over `${CLAUDE_PLUGIN_ROOT}`.
|
||||
13. No `hooks-<target>` or `*-<target>-hooks` filename. That routing is deprecated and reach belongs
|
||||
to `targets:` (see Gate); the research allows it only when deprecated routing is intended.
|
||||
|
||||
Reference in New Issue
Block a user