docs: fix the review findings on the hook-contract retirement
Why: a review of4de5b6band3c5f6a6found seven places that still described the retired external hook contract as current, or that could pass without checking anything. Implementation Notes: - gates.md: drop the "one caveat below" pointer; the caveat is gone. - SIMPLIFICATION-AUDIT.md: the §7 note now says all but one entry is closed and lists 36 (4de5b6b) as struck. Finding 2's count chain gets a closing note: pre-push is 8 repo-authored hooks (10 reported). - .pre-commit-config.yaml: the check-vale-style-sync comment points at case 32 (one-plugin narrowing guard), not the deleted case 33. - ADR-0014: the retirement pointer now covers the ADR-0025 amendment above it too, naming case 33 and the exported hook IDs. ADR-0022 gets a reciprocal amended-by note on its check-release-needed comparison. Historical body text is unchanged. - test-vale-wrap.sh case 32: property 3 fails when a class's corpus regex matches no tracked file, instead of passing vacuously after a layout move. The corpus regexes are now globals so a new Part D can point them at a missing layout and require that failure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2002,6 +2002,11 @@ PC_CONFIG32="$REPO_ROOT/.pre-commit-config.yaml"
|
||||
# repository paths, so a regex matching no tracked path matches nothing the gate
|
||||
# will ever hand the hook.
|
||||
REPO_FILES32="$(cd "$REPO_ROOT" && git ls-files)"
|
||||
# Each class's full authoring-source corpus, per the layout AGENTS.md fixes
|
||||
# (`plugins/<name>/.apm/` is the only authoring source). Globals, not locals,
|
||||
# so Part D can point them at a layout that no longer exists.
|
||||
CORPUS_RE_SKILL32='^plugins/[^/]+/\.apm/skills/[^/]+/SKILL\.md$'
|
||||
CORPUS_RE_AGENT32='^plugins/[^/]+/\.apm/agents/[^/]+\.agent\.md$'
|
||||
|
||||
# Prints one failure token per defect; empty output means every prefilter hook in
|
||||
# $1 is scoped to a live corpus of its own artifact class. The config path is an
|
||||
@@ -2010,7 +2015,7 @@ REPO_FILES32="$(cd "$REPO_ROOT" && git ls-files)"
|
||||
# the live check.
|
||||
prefilter_scope_failures32() {
|
||||
local config="$1" files="$2"
|
||||
local records id re class matched count offenders offending m corpus missing nmissing
|
||||
local records id re class matched count offenders offending m corpus missing nmissing corpus_re
|
||||
local seen_skill=false seen_agent=false bad=""
|
||||
records="$(hook_records28 "$config")"
|
||||
if [[ -z "$records" ]]; then
|
||||
@@ -2061,13 +2066,21 @@ EOF_MATCHED32
|
||||
if [[ "$offending" -gt 0 ]]; then
|
||||
bad+="[$id: 'files: $re' selects $count file(s), $offending of them outside the $class artifact class, so the two prefilter scopes are no longer independently addressable and vale is handed files no glob in its config covers — first: $offenders] "
|
||||
fi
|
||||
# The class's full authoring-source corpus, per the layout AGENTS.md fixes
|
||||
# (`plugins/<name>/.apm/` is the only authoring source). Every path in it
|
||||
# must be selected, or part of the corpus is silently unprefiltered.
|
||||
# Every path in the class's corpus (CORPUS_RE_*32 above) must be
|
||||
# selected, or part of the corpus is silently unprefiltered.
|
||||
if [[ "$class" == skill ]]; then
|
||||
corpus="$(printf '%s\n' "$files" | { grep -E '^plugins/[^/]+/\.apm/skills/[^/]+/SKILL\.md$' || true; })"
|
||||
corpus_re="$CORPUS_RE_SKILL32"
|
||||
else
|
||||
corpus="$(printf '%s\n' "$files" | { grep -E '^plugins/[^/]+/\.apm/agents/[^/]+\.agent\.md$' || true; })"
|
||||
corpus_re="$CORPUS_RE_AGENT32"
|
||||
fi
|
||||
corpus="$(printf '%s\n' "$files" | { grep -E "$corpus_re" || true; })"
|
||||
# An empty corpus makes the comparison below vacuous: nothing can be
|
||||
# missing from nothing. The corpus regex is hard-coded to today's layout,
|
||||
# so a layout move would silently turn this property into a pass. Fail
|
||||
# instead, the same way property 1 fails on zero matches.
|
||||
if [[ -z "$(printf '%s\n' "$corpus" | grep . || true)" ]]; then
|
||||
bad+="[$id: the $class corpus regex '$corpus_re' matches no tracked file, so this case cannot check that 'files: $re' selects the whole $class corpus; update the regex to the current layout] "
|
||||
continue
|
||||
fi
|
||||
missing="$(comm -23 <(printf '%s\n' "$corpus" | grep . | sort) <(printf '%s\n' "$matched" | grep . | sort) || true)"
|
||||
nmissing="$(printf '%s\n' "$missing" | grep -c . || true)"
|
||||
@@ -2152,6 +2165,25 @@ else
|
||||
pass "narrowing either hook's 'files:' regex to one plugin is caught by Part A as an incomplete corpus"
|
||||
fi
|
||||
|
||||
# Part D: proof that property 3 cannot pass vacuously. Each corpus regex is
|
||||
# pointed at a layout no tracked file has -- what a future move of
|
||||
# plugins/*/.apm/ would do to the hard-coded regexes -- and the live config must
|
||||
# then fail as an empty corpus rather than pass with nothing to compare.
|
||||
SAVED_SKILL_RE32="$CORPUS_RE_SKILL32"
|
||||
SAVED_AGENT_RE32="$CORPUS_RE_AGENT32"
|
||||
CORPUS_RE_SKILL32='^zzz-no-such-path/SKILL\.md$'
|
||||
CORPUS_RE_AGENT32='^zzz-no-such-path/[^/]+\.agent\.md$'
|
||||
EMPTY_FAILS32="$(prefilter_scope_failures32 "$PC_CONFIG32" "$REPO_FILES32")"
|
||||
CORPUS_RE_SKILL32="$SAVED_SKILL_RE32"
|
||||
CORPUS_RE_AGENT32="$SAVED_AGENT_RE32"
|
||||
if ! grep -qF "vale-audit-prefilter-skill: the skill corpus regex" <<< "$EMPTY_FAILS32"; then
|
||||
fail "a skill corpus regex matching no tracked file did not fail Part A, so property 3 would pass vacuously after a layout move: ${EMPTY_FAILS32:-<no failure>}"
|
||||
elif ! grep -qF "vale-audit-prefilter-agent: the agent corpus regex" <<< "$EMPTY_FAILS32"; then
|
||||
fail "an agent corpus regex matching no tracked file did not fail Part A, so property 3 would pass vacuously after a layout move: ${EMPTY_FAILS32:-<no failure>}"
|
||||
else
|
||||
pass "a corpus regex matching no tracked file fails Part A instead of passing vacuously"
|
||||
fi
|
||||
|
||||
# --- 34. Every glob section loads a real style, asserted without vale --------
|
||||
#
|
||||
# Case 28 asks this behaviourally -- it lints a probe through the real config
|
||||
|
||||
Reference in New Issue
Block a user