- 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
tests/
Test files for scripts bundled with this skill.
When to add tests
Add tests here when the skill has scripts in scripts/ that are complex enough
to break silently — validators, parsers, generators, anything with branching
logic or edge cases. Test infrastructure (.bats, *_test.*, test_*.sh)
belongs here, not in scripts/.
Dependencies
Tests require bats-support and
bats-assert. The test files load
helpers from the repo root's tests/test_helper/.
From the repo root:
git clone https://github.com/bats-core/bats-support tests/test_helper/bats-support
git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
Run all tests for this skill (from the repo root):
bats plugins/kyberforge/.apm/skills/factory-audit/tests/
Files
| File | Purpose |
|---|---|
validate-skill.bats |
scripts/validate.sh against skill directories |
validate-agent.bats |
scripts/validate.sh against agent files |
validate-provenance-skill.bats |
scripts/validate-provenance.sh against skill directories |
validate-provenance-agent.bats |
scripts/validate-provenance.sh against agent files |
validate-primitive.bats |
scripts/validate.sh against apm hook, instruction and prompt files |
Two scripts, five suites
factory-audit merges what were two skills — skill-audit and agent-audit —
each of which shipped its own validate.sh and validate-provenance.sh. The
merged skill has one of each. Every suite here invokes one of those two
scripts; the four skill and agent files are two scripts × two artifact types, not four scripts.
validate-primitive.bats is a fifth suite over the same scripts/validate.sh, for hooks,
instructions and prompts, which have no provenance mode and so no provenance suite.
validate-skill.bats and validate-agent.bats run the same
scripts/validate.sh and differ only in the fixtures they point it at. The two
provenance suites stand in the same relation to scripts/validate-provenance.sh.
Do not add a third script path here on the assumption that a differently named
suite must mean a differently named script.
Auto-detection is pinned across the suites
Each entry point decides for itself what it was handed. ADR-0025 states the
skill and agent rule: a directory containing SKILL.md takes the skill flow; an
.agent.md file, or a file under a directory named agents/, takes the agent
flow. scripts/validate.sh adds three primitive shapes: a *.instructions.md
or *.prompt.md file takes the instruction or prompt flow wherever it sits, and
a .json file directly under a hooks/ directory takes the hook flow. Any
shape outside the five is rejected rather than guessed at. Classification could
not be wrong before the merge — each script was hard-wired to one artifact type
— so it is asserted from every side rather than in one place:
- the skill-side suites pin the skill-directory classification and the neither-shape rejection,
- the agent-side suites pin the two agent rules separately —
.agent.mdin a directory that is notagents/, and a plain.mdunder.apm/agents/— so that a detector implementing only one of them cannot pass both. Plus a control asserting an agent file never picks up a skill-only gate. validate-primitive.batspins the hook, instruction and prompt shapes, including the precedence that makes a*.instructions.mdor*.prompt.mdunderagents/take the primitive flow rather than the agent flow, a hook file under a package-roothooks/, and a.jsonoutsidehooks/matching no shape. It also pins the primitive exit tiers: every negative case asserts exit 1 (assert_failure 1), and a missing python3 or PyYAML asserts exit 2.
Both skill-side suites additionally pin the SKILL.md file path, not just
the directory: a pre-commit files: hook matches files, so every hook-driven
invocation hands over a SKILL.md path. Each entry point resolves it to the
directory, and the suites assert the two spellings produce the identical
verdict rather than merely that the file spelling survives.
A misclassification is silent and total — the wrong rubric runs end to end and reports the artifact clean against gates that never applied to it — and no other fixture in these suites would notice, because every other fixture is already the shape its own suite expects.
The two provenance exit contracts are different on purpose
scripts/validate-provenance.sh does not behave identically in its two
modes, and the difference is deliberate:
| Mode | Successful run |
|---|---|
| skill | may exit 0 with output — INFO findings print, status stays 0 |
| agent | exits 0 and prints nothing |
Each half is asserted from its own side, by the exit contract: test in each
provenance suite. Both are asserted on purpose: a merge that collapsed one
contract into the other would still satisfy whichever side was left unasserted,
so a single-sided pin would go green on exactly the defect it exists to catch.