b2d77b29455daaf3f8a048bf9746441282b962a1
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 0ea3f69dc6 |
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 |
|||
| 9ac5340e15 |
fix(kyberforge): resolve clean-context audit findings on primitive support
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 |
|||
| 70210d6a7e |
feat(factory-audit): audit hooks, instructions and prompts
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
|
|||
| 2c4b6d2615 |
fix(kyberforge): harden Research doc and Basis parsing in the validator
Review of PR 139 found list-rejection and confinement holes that let the exact malformed entries the grammar forbids pass check 7. - Reject comma, space-separated and backticked path lists, so `a/sources.md (x), b/topic.md` no longer exits 0 unchecked. - FAIL absolute paths and any path whose realpath leaves the repo, for both `Research doc:` and `Basis:`. - Anchor `(removed in <sha>)` to the end of the value with a 7-40 hex sha. The sha is format-checked only, not resolved with git cat-file. - Read `* ` bullets and `- **X**` bullets correctly under a `**Basis:**` header, and strip backticks from Basis paths. - Stop the semicolon rule firing on annotation prose, and stop `none` matching `none/foo.md`. - Update the stale field messages to the new grammar and report an empty field as empty, not missing. - Skip a removed Basis silently when there is no repo root. Adds 40 tests. Each guarded line was mutated in place and every mutant is caught. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EGHFJextYtVQseaHPDDhxB |
|||
| 5a52949c57 |
feat(kyberforge): make Research doc name one Research registry
validate-provenance.sh assumed `Research doc:` names a research sources.md whose H2 headings are the source slugs, but 29 corpus entries named topic docs and 6 values were not a single path, so checks 7 and 8 reported INFO for 36 entries and nothing ever failed. `Research doc:` now takes exactly one path. An entry with no registry writes `none` plus one `- **Basis:** <path>` bullet per path; each Basis path is existence-checked unless annotated `(removed in <sha>)`. - Check 7 FAILs when a resolved registry lacks the slug, when the value is a topic doc, or when it is a list. An unresolvable path stays INFO. - Check 8 is retired: one registry serves many skills, so requiring every registry slug in each skill's sources.md is unsatisfiable. - The Research doc and Basis parsers accept the inline, bullet and header-plus-bullets spellings, so a differently spelled field is no longer read as absent. Refs: #121 ADR: 0028 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EGHFJextYtVQseaHPDDhxB |
|||
| e849a823f7 |
fix(gates): report an unparsed routing clause beside a parsing sibling
boundary_clause_status() ran BOUNDARY_ARROW.search() and _arrow_targets()
over the whole description, so one arrow clause that parsed suppressed the
diagnostic for every other clause in it. A backticked hyphenated routing
target wrapped across lines in a folded scalar was therefore silently
unchecked -- no error, no suggestion, exit 0 -- whenever the description
carried one other clause that parsed. Written bare, the same wrap errors
correctly. That is the shape #100 regressed on.
The check is now per clause. Nothing that passed starts failing: all 68
routing targets across the 38 SKILL.md files resolved before and still do.
26 of those descriptions carry more than one arrow clause, so the
suppression was live across two thirds of the corpus, not an edge case.
validate-skill.bats pins the shape. test-adr0020-targets.sh's comment
described the #100 regression as a backticked wrap; the historical text was
unbackticked, which is precisely the shape the gate did not catch.
Also closes three README misroutes the branch left in the enforcement
layer: CompositionNote.yml's message, agent-description-quality.md:58 and
vale-wrap.sh's header still sent overflow to a skill-root README.md and
named the two skills ADR-0025 merged away.
|
|||
| 4de5b6b355 |
chore(gates): retire the external pre-commit hook contract
Why: .pre-commit-hooks.yaml and its release-tag gate served external consumers that do not exist. No repo on the Gitea instance pins these hooks, and the README names apm as the only supported install path. The mechanism was also already failing: skill-size-check.sh changed after v2.0.1 with no tag cut, and the gate cannot fire through Gitea's merge button. (Simplification audit finding 36.) Implementation Notes: - Delete .pre-commit-hooks.yaml, scripts/check-release-needed.sh, tests/test-check-release-needed.sh and tests/test-vale-hooks-consumer.sh, and remove the check-release-needed pre-push hook. The repo: local skill-size-check and vale-audit-prefilter-* hooks are unchanged. - ADR-0014 is amended, not retired: its runtime decision to bundle Vale inside factory-audit stands. The amendment keeps the entry[0]-only constraint (LESSONS.md:101,105) in case the export returns. ADR-0025 gets a pointer. - test-vale-wrap.sh: drop case 33 (the cross-manifest drift check) and case 28's hook-scope half, which read the published manifest. Case 32 now also requires each hook to select every tracked file of its class, which keeps case 33's one-plugin-narrowing guard, with a mutation test. - test-skill-size-check.sh and test-adr0020-contract.sh now assert the hook contract and verbose: true on .pre-commit-config.yaml only. - gates.md: pre-push count goes from 9 to 8 authored hooks (11 to 10 reported), and the Release table, the External consumers section and the two-manifest scope table are removed. README and script/test comments no longer describe the export as live. The resolver comment is edited identically in both copies. - The v1.0.0/v2.0.0/v2.0.1 tags are left in place; they are inert. ADR: 0014 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
|||
| 1d40544075 |
fix(gates): hold skill versions above main's tip as well as the merge-base
Why: two branches that both bump a skill 1.0.0 -> 1.0.1 with different content merge without a conflict, and each passed the gate against its own merge-base, so main could ship two changes under one version. Implementation Notes: - check-skill-version-bump requires the pushed version to exceed both the merge-base and the main tip; failures name the baseline they missed. - Presence is read from the tree, so a blob missing from a partial clone is a read failure instead of a silently exempt "new" skill. - A leading UTF-8 BOM no longer reads as a missing version. - Version parts reject leading zeros in all three validators (check-skill-version-bump, skill-size-check, factory-audit). - New tests cover equal bumps, moved files, major/minor ordering, bad refs, unreadable blobs, mode-only changes, symlinks and tag peeling. Impact: ADR-0022 amended (reverses "not main's current tip"); gates.md updated to match, including pre-commit 4.6.1's exact ref selection. ADR: 0022 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
|||
| 620f20b0fd |
refactor(kyberforge)!: merge skill-audit and agent-audit into factory-audit
Why The two audit skills carried 1,724 lines of byte-identical duplication: the ADR-0020 boundary resolver (1,061), vale-wrap.sh (526), the Vale style rules (44) and the Contributing-files parser (93). Nothing shared them — they were held in sync by a 413-line pre-push gate and its 797-line test suite. Sync-by-gate had already failed once: at |