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>
This commit is contained in:
2026-09-16 11:52:14 +00:00
parent 2119da9700
commit 4de5b6b355
20 changed files with 233 additions and 1442 deletions

View File

@@ -45,8 +45,8 @@ IFS='' read -r -d '' KYBERFORGE_RESOLVER_PY <<'KYBERFORGE_ADR0020_RESOLVER_PY' |
# plugins/kyberforge/.apm/skills/factory-audit/scripts/lib-boundary-resolver.sh
# The block between these markers must stay byte-identical in both. It is copied
# rather than imported because a cache-installed plugin's scripts cannot read
# files outside their own plugin directory, and this repo-root hook resolves via
# .pre-commit-hooks.yaml, where entry[0] is the only token pre-commit rewrites --
# files outside their own plugin directory, and this repo-root hook is kept fit for
# a published hook manifest (retired; ADR-0014), where only entry[0] is rewritten --
# so no single file is reachable by both (the same constraint that duplicates the
# ADR-0020 constants). Edit one copy, then paste it over the other.
#

View File

@@ -29,10 +29,11 @@ set -euo pipefail
#
# Divergence 1: with no `--config` at all, this script's own sibling
# `assets/vale/.vale.ini` is used instead of vale's upward search. pre-commit
# prefixes only `entry[0]` with the hook-repo clone path, so a `--config` in
# `.pre-commit-hooks.yaml` would resolve against the *consuming* repo and
# hard-fail (E100) for every external consumer. The manifest therefore passes the
# script alone, and an explicit `--config` from any other caller still wins.
# prefixes only `entry[0]` with the hook-repo clone path, so a `--config` in a
# published `.pre-commit-hooks.yaml` would resolve against the *consuming* repo
# and hard-fail (E100) for every external consumer. That manifest is retired
# (ADR-0014, 2026-09-16 amendment), but the script still needs no `--config` so it
# can return; an explicit `--config` from any other caller still wins.
#
# Divergence 2: a path-shaped argument that does not exist is a hard error
# (exit 2). Bare vale drops it, falls back to reading stdin, and prints

View File

@@ -1989,7 +1989,7 @@ EOF
# NEW with the merge and additive: pre-merge, handing the SKILL.md itself to
# skill-audit's validate-provenance.sh hit the "not a directory" precondition
# and died. It matters because pre-commit `files:` hooks match FILES — the
# exported kyberforge-vale-audit-skill hook's regex is (^|/)SKILL\.md$ — so
# vale-audit-prefilter-skill hook's regex ends in /SKILL\.md$ — so
# every hook-driven invocation hands over a SKILL.md path, never its
# directory. The entry point rewrites the token to the directory in place.
local skill="$TMPDIR/my-skill"

View File

@@ -1016,8 +1016,8 @@ EOF
# NEW with the merge and additive rather than ported: pre-merge, handing the
# SKILL.md itself to skill-audit's validate.sh hit the directory precondition
# and gave a useless exit 1. It matters because pre-commit `files:` hooks
# match FILES — the exported kyberforge-vale-audit-skill hook's regex is
# (^|/)SKILL\.md$ — so every hook-driven invocation hands over a SKILL.md
# match FILES — the vale-audit-prefilter-skill hook's regex ends in
# /SKILL\.md$ — so every hook-driven invocation hands over a SKILL.md
# path, never the directory above it. The entry point resolves the file to
# its directory before dispatching.
local skill="$TMPDIR/my-skill"