feat(kyberforge): primitive-author and factory-audit support for apm hooks, instructions and prompts #144

Open
Claude wants to merge 12 commits from feat/primitive-author into main
Collaborator

Summary

Closes the gap #94 describes: kyberforge had no author or audit support for three apm primitives (hooks, instructions and prompts), and forge had no route for them.

  • primitive-author (new skill). It authors and improves hooks, instructions and prompts.
    • The shared create/improve procedure lives in SKILL.md.
    • references/{hook,instruction,prompt}.md hold each primitive's boundary gate and Must/Should checklist, and assets/templates/ holds .template files.
    • It closes by running factory-audit inline, then apm install --dry-run, the package version bump, and commit verification.
  • factory-audit: three new Step 0 flows (hook, instruction, prompt). These follow ADR-0020's merge-siblings rule rather than adding a separate audit skill.
    • Deterministic checks are in scripts/lib-checks-primitive.sh. Judgment checks are in the flow references.
    • Author Must ↔ audit FAIL and Should ↔ SUGGESTION. The flow files document the deliberate deviations.
    • Vale covers instruction and prompt bodies.
  • forge gains a route for hooks, instructions and prompts to primitive-author, using the same two-tier clean audit.
  • ADR-0029: prompts are thin, user-triggered steering messages. Procedure belongs in a skill. A prompt's description is one plain sentence that names the skills or agents it steers.
  • CONTEXT.md gains the terms apm primitive, Prompt, Instruction and Hook.
  • The research docs (plugins/kyberforge/docs/research/docs/microsoft-apm/) are completed and corrected against apm 0.28.0:
    • Copilot hooks are not reshaped.
    • A malformed .claude/settings.json is overwritten on install.
    • Instruction validation only produces warnings.
  • kyberforge's own hook now uses the target-neutral ${PLUGIN_ROOT}.
    • The deployed .claude/settings.json entry is unchanged. This was checked by installing two scratch packages that differ only in the token and comparing the output byte for byte.
    • ADR-0019 is amended to accept that Copilot and Codex also receive the hook.
    • The README and docs/hooks.md are corrected.
  • Housekeeping. Literal U+FEFF BOM characters in lib-boundary-resolver.sh and validate-adapter.bats are now Python unicode escape sequences, which silences apm's hidden-character warning. skill-author's ${CLAUDE_PLUGIN_ROOT} guidance now points to primitive-author.

Versions

  • kyberforge 2.0.1 → 2.1.0, and the root executables.allow key moves with it.
  • Catalog 0.5.1 → 0.5.2, with marketplace.json regenerated.
  • factory-audit 1.1.1, forge 1.0.2, skill-author 1.0.6. primitive-author is new at 0.1.0.

Verification

  • Two clean-context factory-audit passes with a consistency check against ADR-0029, CONTEXT.md and the research checklists. All findings are resolved (commits 9ac5340, 0ea3f69).
  • Current audit results: primitive-author and factory-audit pass with no findings. forge passes with 2 suggestions for description and body length that predate this PR, tracked in #143.
  • Tests: factory-audit bats 347/347, and tests/run-tests.sh 21/21 suites.
  • Pre-push hooks all passed, including apm audit --ci, apm pack --check-clean, the provenance corpus check and the executables allow-key sync.

Not in this PR

  • The forge length budgets, tracked in #143.
  • Pre-commit Vale coverage for *.instructions.md and *.prompt.md. The repo has none of these files yet, so check-hooks-apply and test-vale-wrap.sh case 32 reject a hook that matches nothing. Vale's glob coverage for them is already tested in case 28.
  • Unverified at runtime: whether Copilot CLI runs nested hook entries or honours matcher, and how strongly Claude avoids routing to a prompt description with no trigger clause.

Fixes #94

🤖 Generated with Claude Code

https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi

## Summary Closes the gap #94 describes: kyberforge had no author or audit support for three apm primitives (hooks, instructions and prompts), and `forge` had no route for them. - **`primitive-author` (new skill).** It authors and improves hooks, instructions and prompts. - The shared create/improve procedure lives in `SKILL.md`. - `references/{hook,instruction,prompt}.md` hold each primitive's boundary gate and Must/Should checklist, and `assets/templates/` holds `.template` files. - It closes by running `factory-audit` inline, then `apm install --dry-run`, the package version bump, and commit verification. - **`factory-audit`: three new Step 0 flows** (hook, instruction, prompt). These follow ADR-0020's merge-siblings rule rather than adding a separate audit skill. - Deterministic checks are in `scripts/lib-checks-primitive.sh`. Judgment checks are in the flow references. - Author Must ↔ audit FAIL and Should ↔ SUGGESTION. The flow files document the deliberate deviations. - Vale covers instruction and prompt bodies. - **`forge`** gains a route for hooks, instructions and prompts to `primitive-author`, using the same two-tier clean audit. - **ADR-0029: prompts are thin, user-triggered steering messages.** Procedure belongs in a skill. A prompt's description is one plain sentence that names the skills or agents it steers. - **`CONTEXT.md`** gains the terms apm primitive, Prompt, Instruction and Hook. - **The research docs** (`plugins/kyberforge/docs/research/docs/microsoft-apm/`) are completed and corrected against apm 0.28.0: - Copilot hooks are not reshaped. - A malformed `.claude/settings.json` is overwritten on install. - Instruction validation only produces warnings. - **kyberforge's own hook** now uses the target-neutral `${PLUGIN_ROOT}`. - The deployed `.claude/settings.json` entry is unchanged. This was checked by installing two scratch packages that differ only in the token and comparing the output byte for byte. - ADR-0019 is amended to accept that Copilot and Codex also receive the hook. - The README and `docs/hooks.md` are corrected. - **Housekeeping.** Literal U+FEFF BOM characters in `lib-boundary-resolver.sh` and `validate-adapter.bats` are now Python unicode escape sequences, which silences apm's hidden-character warning. skill-author's `${CLAUDE_PLUGIN_ROOT}` guidance now points to `primitive-author`. ## Versions - kyberforge 2.0.1 → 2.1.0, and the root `executables.allow` key moves with it. - Catalog 0.5.1 → 0.5.2, with `marketplace.json` regenerated. - `factory-audit` 1.1.1, `forge` 1.0.2, `skill-author` 1.0.6. `primitive-author` is new at 0.1.0. ## Verification - **Two clean-context `factory-audit` passes** with a consistency check against ADR-0029, `CONTEXT.md` and the research checklists. All findings are resolved (commits `9ac5340`, `0ea3f69`). - **Current audit results:** `primitive-author` and `factory-audit` pass with no findings. `forge` passes with 2 suggestions for description and body length that predate this PR, tracked in #143. - **Tests:** `factory-audit` bats 347/347, and `tests/run-tests.sh` 21/21 suites. - **Pre-push hooks** all passed, including `apm audit --ci`, `apm pack --check-clean`, the provenance corpus check and the executables allow-key sync. ## Not in this PR - The `forge` length budgets, tracked in #143. - Pre-commit Vale coverage for `*.instructions.md` and `*.prompt.md`. The repo has none of these files yet, so `check-hooks-apply` and `test-vale-wrap.sh` case 32 reject a hook that matches nothing. Vale's glob coverage for them is already tested in case 28. - **Unverified at runtime:** whether Copilot CLI runs nested hook entries or honours `matcher`, and how strongly Claude avoids routing to a prompt description with no trigger clause. Fixes #94 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
Claude added the Kind/Enhancement
Priority
Medium
3
labels 2026-09-28 18:48:43 +00:00
Claude added 9 commits 2026-09-28 18:48:43 +00:00
Re-verify the three primitive schema docs against the installed apm-cli
0.28.0 source and live installs, and add an authoring checklist to each.

Corrections to the earlier docs:
- Copilot hooks are not reshaped: events are renamed, paths rewritten and
  version: 1 added, but command/timeout are not renamed to bash/timeoutSec.
- A malformed .claude/settings.json is overwritten on install, losing
  user content.
- Instruction validate() messages are warnings only; apm compile
  --validate never fails on them.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
Record the house rule for the apm prompt primitive: a single-intent,
user-triggered, parameterised message that steers existing skills or
agents by name and carries no procedure of its own. It also sets the
prompt description contract (one plain sentence, no trigger clause).

Add the glossary terms settled in the same grill to CONTEXT.md: apm
primitive, Prompt, Instruction and Hook. Narrow the Skill entry's Avoid
list and log the prompt ambiguity as resolved.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
factory-audit gains three Step 0 rows and flows for the apm primitives
that have no container of their own: a .json file under hooks/, a
*.instructions.md and a *.prompt.md. apm validates almost none of them
(invalid hook JSON is skipped silently, instruction validate() only
warns, input: names are never checked against ${input:x}), so the
deterministic checks live in a new scripts/lib-checks-primitive.sh,
wired into validate.sh's path-shape detection. Each check and tier
traces to the Authoring checklists in the microsoft-apm research docs.

- Hook: JSON/shape/event-list checks mirroring the Copilot payload
  validator, never-firing event casing, missing/escaping/non-executable
  scripts (FAIL); deprecated filename routing and ${CLAUDE_PLUGIN_ROOT}
  (SUGGESTION).
- Instruction: location, frontmatter, description, body, stem clash
  (FAIL); missing or list applyTo and unread keys (SUGGESTION).
- Prompt: location/name, frontmatter, description, input names, the
  upstream `- name: x` docs bug, declared-vs-used ${input:x} (FAIL);
  ADR-0029 description length and trigger clause, dropped keys,
  camelCase aliases, argument-hint with input (SUGGESTION). Whether a
  prompt carries procedure is judgment in prompt-flow.md, not a script
  heuristic.

Vale now lints *.instructions.md and *.prompt.md with the Kyberforge
style; test-vale-wrap.sh gains their probe rows. New
tests/validate-primitive.bats (31 cases). kyberforge 2.0.1 -> 2.1.0 with
the executables.allow key, catalog 0.5.1 -> 0.5.2, marketplace.json
regenerated.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
New skill that creates or improves an apm hook, instruction or prompt.
Its SKILL.md holds the shared procedure (dispatch on primitive, boundary
gate, create-or-improve, factory-audit close); one self-contained
reference per primitive carries its gate, checklist and template, drawn
from the microsoft-apm research docs and ADR-0029.

forge gains a route row sending a hook, instruction or prompt to
primitive-author through author-routes.md, and no longer lists hooks as
unroutable. factory-audit's description adds the primitive-author
boundary now that the target resolves.

Fixes #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
primitive-author:
- description excludes read-only review (-> factory-audit)
- validation Gotcha now matches the research: compile never reads
  prompts, install fails only on a bad Copilot hook payload and warns on
  prompt input names and dropped keys
- instruction fold-in into AGENTS.md/CLAUDE.md stated as conditional on
  dedup and --force-instructions
- hook checklist gains the wrapped-shape Must, drops hardlinks, notes
  why executable is stricter than the research, and states the
  separate Copilot-targeted package route instead of a blanket "don't"
- prompt Must 5 keeps the research's Copilot-only-key exception; adds
  model-slug and 250-char Shoulds; descriptions name skills or agents
- placeholder instruction covers both FILL IN and FILL_IN_ tokens

factory-audit: hardlink FAIL scoped to instructions and prompts
(find_hook_files skips symlinks only), with bats cases; prompt-flow
description rubric names skills or agents.

forge: version-bump, apm-routes and sources references updated for the
primitive route.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
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
Switch the SessionStart hook to apm's target-neutral ${PLUGIN_ROOT} token.
Two scratch packages differing only in the token deploy byte-identical
SessionStart entries with apm 0.28.0, matching the committed
.claude/settings.json, so the deployed output does not change. The test
pin in tests/test-apm-current-hook.sh moves with it.

Correct the claim that Copilot loads no hooks from kyberforge. targets:
is package-wide, so apm also writes .github/hooks/kyberforge-hooks.json
(nested shape passed through, runtime unverified) and merges into
.codex/hooks.json when .codex/ exists. Recorded as accepted in an
ADR-0019 amendment dated 2026-09-28; README and docs/hooks.md updated.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
lib-boundary-resolver.sh and the provider-adapter-author BOM fixtures
carried literal U+FEFF characters, which apm install reports as "files
contain hidden characters". Both sites feed the text to Python, which
interprets the '' escape identically, so behaviour is unchanged:
the resolver's strip_bom and all five validate-adapter BOM cases pass.

No core package bump: the fixture writes the same bytes, so the edit is
not substantive under the apm-workflow version policy.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
deployment-modes.md told authors to use ${CLAUDE_PLUGIN_ROOT} in hook
commands. Hook authoring now belongs to primitive-author, which
specifies the target-neutral ${PLUGIN_ROOT}; point there instead.

Refs #94

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
Claude added this to the Skills & Agents milestone 2026-09-28 18:49:01 +00:00
Defame1297 added 3 commits 2026-09-29 05:45:58 +00:00
- factory-audit: no-op hooks, ./ after interpreters, split-quote and
  spaced ${PLUGIN_ROOT} paths, camelCase events in Claude-targeted flat
  files, case-insensitive routing stems, and non-string YAML keys are
  now caught; input: forms and prompt boundary clauses align with
  primitive-author; bats 347 -> 367
- primitive-author: routing forms, quoting guidance, install exit on
  hidden Unicode, argument-hint exception
- forge: drop duplicated gotcha, fit description and body budgets (#143)
- skill-author: primitive-author boundary, Claude-only env vars
- hook: exit unless CLAUDE_PROJECT_DIR is set, so Copilot/Codex never
  run apm update; ADR-0019 correction, ADR-0025 amendment, docs fixes

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
- factory-audit: ./ and bare/absolute script checks scoped to command
  position (no false FAILs on ./src or printf); hook sources limited to
  .apm/hooks or package-root hooks/; Kiro-aware lowercase events;
  unfilled template placeholders FAIL; repo-only instructions FAIL at
  any scope; Vale description FAIL documented; bats 367 -> 378
- primitive-author: split-quote/spaced paths and handler-less entries
  promoted to Must; Step 4.2 renders into a scratch consumer instead of
  a no-op dry run; dispatch and gate hand-off trimmed
- apm-workflow 1.0.2: mutual boundary with primitive-author
- forge: no double package bump; gotcha wording
- skill-author: create keeps seeded 0.1.0 (ADR-0022); portable,
  retry-safe new-skill.sh; template and flow consistency fixes
- hook docs: cite the ADR-0019 correction; guard caveat

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
- factory-audit: hook events judged per deployed target after apm's
  rename (Claude/Copilot event sets FAIL, others SUGGESTION); Claude
  plugin layouts accepted as hook sources; interpreter options and
  sh -c strings checked; bats 378 -> 386
- primitive-author: Must 4/5 match the audit; reference hand-back
  points at the right steps; Step 4.2 --target all fallback
- skill-author: new-skill.sh repair only on the template marker line,
  so complete skills stay a no-op; provenance and calibration text
- forge: restore "already named" qualifier; drop false HITL claim
- apm-workflow: token example uses an env var
- docs/hooks.md: the apm-hooks.json sidecar is committed, not ignored

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
Author
Collaborator

Review and audit loop: 3 rounds

I ran three rounds of review and fixes on this PR. Each round had:

  • a code review of the branch diff,
  • a clean-context factory-audit of every changed primitive: primitive-author, factory-audit, forge, skill-author, apm-workflow, and kyberforge's hooks.json,
  • fixes through skill-author / primitive-author, followed by the full test suite.

The audits used the branch copy of factory-audit. The deployed copy is older than this PR and cannot audit hooks, instructions or prompts.

Round Findings Commit
1 Review: 4 MEDIUM, 5 LOW. Audits: 2 FAIL, 18 SUGGESTION df28351
2 Review: 2 MEDIUM, 1 LOW. Audits: 5 FAIL, 30 SUGGESTION (deeper passes, some on code older than this PR) 965208b
3 Review: 3 MEDIUM, 2 LOW. Audits: 1 FAIL, 11 SUGGESTION 5d0f988

After round 3, every agent that applied fixes re-audited its own changes and got PASS; two of those results still carry an INFO note. No fourth independent round was run, because the cap was three rounds.

Behaviour changes

  • kyberforge SessionStart hook: now exits unless CLAUDE_PROJECT_DIR is set.
    • apm deploys this hook to Copilot and Codex too. In a project that consumes it, apm has already written the lockfile, so the lockfile check never stopped it. That meant it would run apm update --yes in Copilot and Codex sessions.
    • ADR-0019 now has a correction. The README and docs/hooks.md are corrected, and there are new tests for the variable being unset or empty.
  • factory-audit: hook checks now catch real breakage. Each of these now fails:
    • a hook with no entries, or an entry with no handler;
    • a missing script run through an interpreter, including one behind interpreter options (bash -e, sh -c "…");
    • a ${PLUGIN_ROOT} path with the quotes split or a space in it, which apm does not rewrite;
    • an event name that a target never fires. This is checked per deployed target, after apm renames events for that target (_HOOK_EVENT_MAP).
  • factory-audit: false positives removed. Commands like npx prettier ./src and printf '.\n' no longer FAIL, and Claude-plugin layouts (plugin.json with no apm.yml) are accepted.
  • factory-audit: two more cases now fail.
    • Unfilled template placeholders.
    • Any instruction whose rule only applies to this repo (it belongs in AGENTS.md).
  • Author and audit severities now line up. A primitive-author "must" rule is a factory-audit FAIL, and a "should" rule is a SUGGESTION. Where a script cannot decide, the difference is documented in the flow files.
  • primitive-author Step 4.2: apm install --dry-run replaced. The dry run showed neither what each target receives nor the branch's own files. The step now renders into a throwaway consumer with a local-path install, which was verified with apm 0.28.0.
  • forge: the description and body now fit their length budgets (closes #143), and it no longer bumps the package version twice.
  • skill-author:
    • Creating a skill keeps the seeded 0.1.0 (ADR-0022).
    • new-skill.sh works with both GNU and BSD sed. A failed run no longer leaves a half-built scaffold, and re-running it on a finished skill changes nothing.
  • apm-workflow 1.0.2: its description now sends hook, instruction and prompt work to primitive-author, so the two skills no longer overlap.

Verification

  • The factory-audit bats suite passes 386/386; it had 347 tests at the start.
  • tests/run-tests.sh passes 21/21 suites.
  • All pre-push gates passed, including apm audit --ci, apm pack --check-clean, the provenance corpus check and the version-bump check.
  • Neither .claude/settings.json nor apm.lock.yaml was touched.

Decisions worth a look

  • Event lists for Claude and Copilot come from their live docs (fetched 2026-09-28) and are recorded in factory-audit's sources.md. These lists will need updating when those docs change.
  • Copilot docs name the event userPromptSubmitted, but apm renames it to userPromptSubmit. The audit accepts apm's name because authors cannot change the rename. This may be an apm bug worth reporting upstream.
  • forge description: it uses the form If named, use instead: skill -> …, at exactly 250 characters. That fits the budget and keeps the "already named" qualifier.

Still open

  • The deployed .claude/skills/factory-audit stays stale until this merges to main and is reinstalled.
  • ADR-0019 lines 207–208 still say the sidecar is gitignored. The 2026-09-16 correction directly below them supersedes that.
  • #94 was closed before this PR merged.
  • The PR description's version and test counts are from before these rounds. apm-workflow 1.0.2 is also new since then.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi

## Review and audit loop: 3 rounds I ran three rounds of review and fixes on this PR. Each round had: - a code review of the branch diff, - a clean-context `factory-audit` of every changed primitive: `primitive-author`, `factory-audit`, `forge`, `skill-author`, `apm-workflow`, and kyberforge's `hooks.json`, - fixes through `skill-author` / `primitive-author`, followed by the full test suite. The audits used the branch copy of `factory-audit`. The deployed copy is older than this PR and cannot audit hooks, instructions or prompts. | Round | Findings | Commit | |---|---|---| | 1 | Review: 4 MEDIUM, 5 LOW. Audits: 2 FAIL, 18 SUGGESTION | `df28351` | | 2 | Review: 2 MEDIUM, 1 LOW. Audits: 5 FAIL, 30 SUGGESTION (deeper passes, some on code older than this PR) | `965208b` | | 3 | Review: 3 MEDIUM, 2 LOW. Audits: 1 FAIL, 11 SUGGESTION | `5d0f988` | After round 3, every agent that applied fixes re-audited its own changes and got PASS; two of those results still carry an INFO note. No fourth independent round was run, because the cap was three rounds. ### Behaviour changes - **kyberforge SessionStart hook: now exits unless `CLAUDE_PROJECT_DIR` is set.** - apm deploys this hook to Copilot and Codex too. In a project that consumes it, apm has already written the lockfile, so the lockfile check never stopped it. That meant it would run `apm update --yes` in Copilot and Codex sessions. - ADR-0019 now has a correction. The README and `docs/hooks.md` are corrected, and there are new tests for the variable being unset or empty. - **factory-audit: hook checks now catch real breakage.** Each of these now fails: - a hook with no entries, or an entry with no handler; - a missing script run through an interpreter, including one behind interpreter options (`bash -e`, `sh -c "…"`); - a `${PLUGIN_ROOT}` path with the quotes split or a space in it, which apm does not rewrite; - an event name that a target never fires. This is checked per deployed target, after apm renames events for that target (`_HOOK_EVENT_MAP`). - **factory-audit: false positives removed.** Commands like `npx prettier ./src` and `printf '.\n'` no longer FAIL, and Claude-plugin layouts (`plugin.json` with no `apm.yml`) are accepted. - **factory-audit: two more cases now fail.** - Unfilled template placeholders. - Any instruction whose rule only applies to this repo (it belongs in AGENTS.md). - **Author and audit severities now line up.** A primitive-author "must" rule is a factory-audit FAIL, and a "should" rule is a SUGGESTION. Where a script cannot decide, the difference is documented in the flow files. - **primitive-author Step 4.2: `apm install --dry-run` replaced.** The dry run showed neither what each target receives nor the branch's own files. The step now renders into a throwaway consumer with a local-path install, which was verified with apm 0.28.0. - **forge:** the description and body now fit their length budgets (closes #143), and it no longer bumps the package version twice. - **skill-author:** - Creating a skill keeps the seeded `0.1.0` (ADR-0022). - `new-skill.sh` works with both GNU and BSD `sed`. A failed run no longer leaves a half-built scaffold, and re-running it on a finished skill changes nothing. - **apm-workflow 1.0.2:** its description now sends hook, instruction and prompt work to `primitive-author`, so the two skills no longer overlap. ### Verification - The factory-audit bats suite passes 386/386; it had 347 tests at the start. - `tests/run-tests.sh` passes 21/21 suites. - All pre-push gates passed, including `apm audit --ci`, `apm pack --check-clean`, the provenance corpus check and the version-bump check. - Neither `.claude/settings.json` nor `apm.lock.yaml` was touched. ### Decisions worth a look - **Event lists for Claude and Copilot** come from their live docs (fetched 2026-09-28) and are recorded in factory-audit's `sources.md`. These lists will need updating when those docs change. - **Copilot docs name the event `userPromptSubmitted`, but apm renames it to `userPromptSubmit`.** The audit accepts apm's name because authors cannot change the rename. This may be an apm bug worth reporting upstream. - **forge description:** it uses the form `If named, use instead: skill -> …`, at exactly 250 characters. That fits the budget and keeps the "already named" qualifier. ### Still open - The deployed `.claude/skills/factory-audit` stays stale until this merges to `main` and is reinstalled. - ADR-0019 lines 207–208 still say the sidecar is gitignored. The 2026-09-16 correction directly below them supersedes that. - #94 was closed before this PR merged. - The PR description's version and test counts are from before these rounds. apm-workflow 1.0.2 is also new since then. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
This pull request doesn't have enough required approvals yet. 0 of 1 approvals granted from users or teams on the allowlist.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/primitive-author:feat/primitive-author
git checkout feat/primitive-author
Sign in to join this conversation.