refactor!: carry out the simplification audit across gates, tests, plugins and docs #135

Merged
Defame1297 merged 85 commits from docs/simplification-audit into main 2026-09-20 19:14:03 +00:00
9 changed files with 239 additions and 1196 deletions
Showing only changes of commit ef27c9751a - Show all commits

View File

@@ -27,6 +27,14 @@ applies the body tiers on the skill path only. The two copies must still stay by
plugin script cannot source the root one, which is why a second copy exists at all. Read every
"three" below as the count at the time of writing.
**Amended again (2026-09-16): one copy.** `scripts/skill-size-check.sh` no longer embeds the
resolver. It sources `factory-audit/scripts/lib-boundary-resolver.sh` by path and fails closed if the
library is missing or defines no resolver. The embedded copy had been kept only because the hook was
also exported through `.pre-commit-hooks.yaml`, whose consumers could not reach a file inside the
plugin; `4de5b6b` retired that export (ADR-0014), so the hook runs only inside this repo. The
"byte-identical" sentence above is superseded: there is nothing left to keep identical, and
`tests/test-adr0020-contract.sh` assertion 1 now pins the single copy instead of hashing a pair.
## Context
Every `file:line` citation in this ADR is against the base commit the decision was taken on,

View File

@@ -10,6 +10,13 @@ below (both exported hook IDs survive) and the case 33 port no longer describe t
deleted, and its one-plugin narrowing guard is now a property of case 32. See
[ADR-0014's amendment](0014-vale-prefilter-ships-from-the-plugin.md#amendment-2026-09-16-the-external-hook-contract-is-retired).
**Amended (2026-09-16): the root hook sources the resolver.** Point 6 below records sourcing the
resolver into `scripts/skill-size-check.sh` as refuted, because the hook was consumed through
`.pre-commit-hooks.yaml`. That manifest is retired (above), so the reason no longer holds: the hook now
sources `lib-boundary-resolver.sh`, the repo holds one resolver copy, and the contract test's
assertion 1 pins that copy rather than hashing two. Assertion 1a's "exactly those two files" is now
exactly one. Point 6 is left as the record of the decision at the time.
## Context
Every figure below was measured against the worktree on 2026-09-15. Re-derive rather than quote; the

View File

@@ -410,14 +410,17 @@ skills. They are copied rather than imported because a cache-installed plugin's
files outside their own plugin directory. `tests/test-skill-size-check.sh` asserts the copies agree,
so drift fails CI rather than silently letting an audit bless a skill the commit hook then rejects.
**The shared boundary resolver is now two copies, not three** (ADR-0025). `scripts/skill-size-check.sh`
still carries it embedded between `BEGIN`/`END ADR-0020 SHARED BOUNDARY RESOLVER` markers; the two
plugin copies that used to sit inside `skill-audit`'s and `agent-audit`'s `validate.sh` collapsed
into the single `factory-audit/scripts/lib-boundary-resolver.sh`, sourced by that skill's scripts.
The two remaining copies must still stay byte-identical — a plugin script cannot source the root
one, which is the constraint that forces a copy to exist at all.
**The shared boundary resolver is one copy** (ADR-0025, then 2026-09-16). It lives between the
`BEGIN`/`END ADR-0020 SHARED BOUNDARY RESOLVER` markers in `factory-audit/scripts/lib-boundary-resolver.sh`.
ADR-0025 collapsed the two copies inside `skill-audit`'s and `agent-audit`'s `validate.sh` into that
file. `scripts/skill-size-check.sh` kept an embedded, byte-identical third copy while it was also
exported through `.pre-commit-hooks.yaml`, whose consumers could not reach a file inside the plugin.
`4de5b6b` retired that export (ADR-0014), so the hook now sources the library by path and fails closed
if the library is missing or defines no resolver.
`tests/test-adr0020-contract.sh` pins that arrangement, and one of its assertions was green on a
`tests/test-adr0020-contract.sh` pins that arrangement: the library carries the only marker pair,
the hook carries none, the hook fails closed without the library, and a sentinel planted in a copied
library proves the hook executes the library's text. One of its assertions was green on a
defect it named. "`validate.sh` sources the resolver in **both mode branches**" was implemented as a
file-wide `grep -Ec … -ge 2`, which cannot see a branch at all: delete the `agent)` arm's source line
and duplicate the `skill)` arm's, and the file-wide count is still 2 and the assertion still passes,
@@ -425,7 +428,8 @@ with the agent path running no resolver or some other one. It is now a **per-arm
each arm of `validate.sh`'s `case "$MODE" in` block must carry exactly one `source` line inside its
own body, and the file must carry exactly those two — with a mutation self-test that performs that
exact count-preserving edit on a copy and requires the check to fail on it. The suite went 25 → 28
cases.
cases. It stood at 27 before the 2026-09-16 change and 29 after it, which replaced the two-copy
hash and its line-count floor with the six one-copy assertions above.
### `python3` and PyYAML are hard requirements

View File

@@ -1,19 +1,18 @@
#!/usr/bin/env bash
# lib-boundary-resolver.sh — SOURCED, never executed.
#
# The ADR-0020 shared boundary resolver, as ONE copy for this skill. Both of
# validate.sh's modes compose it into the Python program they run, so the
# skill-mode and agent-mode check suites resolve boundary targets through the
# same code rather than through two copies that can drift apart.
# The ADR-0020 shared boundary resolver — the ONE copy in the repo. Both of
# validate.sh's modes compose it into the Python program they run, and so does
# the repo-root hook scripts/skill-size-check.sh, so the audit and the commit
# hook resolve boundary targets through the same code rather than through
# copies that can drift apart.
#
# The resolver is Python, and bash cannot source Python, so the block is held
# in a shell variable filled from a QUOTED here-doc: nothing inside it is
# expanded, substituted or rewritten, and the text between the two markers
# below is therefore byte-identical to the copy in scripts/skill-size-check.sh
# that tests/test-adr0020-contract.sh hashes. The markers stay on lines of
# their own, at column 0, exactly once each, so `sed -n '/^BEGIN$/,/^END$/p'`
# extracts the same span here as it does from the scripts the test already
# reads. Edit one copy, then paste it over the others.
# expanded, substituted or rewritten, and every consumer runs exactly the text
# between the two markers below. The markers stay on lines of their own, at
# column 0, exactly once each: tests/test-adr0020-contract.sh extracts the span
# with `sed -n '/^BEGIN$/,/^END$/p'`, and asserts no other file carries them.
#
# The here-doc is consumed by the `read` BUILTIN rather than by `$(cat <<...)`.
# This file is sourced by validate.sh before the mode-specific python3/PyYAML
@@ -26,7 +25,7 @@
# exactly ONE newline, never a run: blank lines at the end of a chunk are part
# of the program text the entry script reassembles, and stripping every
# trailing newline deleted them. The here-doc itself is unchanged: still
# QUOTED, still byte-identical between its markers.
# QUOTED, still verbatim between its markers.
#
# Self-containment (agentskills.io, skill-author/references/deployment-modes.md)
# binds BETWEEN skills, not within one: a cache-installed plugin copies each
@@ -34,21 +33,22 @@
# travels with the skill and is always readable. That is why this is sourced
# here and duplicated across skill boundaries elsewhere.
#
# Consumed by: validate.sh (both modes), via $KYBERFORGE_RESOLVER_PY.
# Consumed by: validate.sh (both modes) and scripts/skill-size-check.sh, via
# $KYBERFORGE_RESOLVER_PY. The root hook reaches into this plugin by path, which
# is safe only because it runs solely inside this repo — 4de5b6b retired the
# published hook manifest that once made it run elsewhere (ADR-0014).
# shellcheck shell=bash
# shellcheck disable=SC2034
IFS='' read -r -d '' KYBERFORGE_RESOLVER_PY <<'KYBERFORGE_ADR0020_RESOLVER_PY' || true
# ===== BEGIN ADR-0020 SHARED BOUNDARY RESOLVER =====
# ONE resolver, embedded VERBATIM in two scripts (ADR-0025 retired the third):
# scripts/skill-size-check.sh
# 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 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.
# ONE resolver, and this is its only copy. Sourced from this file by:
# plugins/kyberforge/.apm/skills/factory-audit/scripts/validate.sh (both modes)
# scripts/skill-size-check.sh (the repo-root commit hook)
# ADR-0025 retired the copies in the two pre-merge audit skills, and the
# 2026-09-16 change retired the copy embedded in the root hook, which had been
# kept only while that hook was also exported through a published hook manifest
# (retired by 4de5b6b; ADR-0014). Edit it here; there is nothing to paste over.
#
# Requires: glob, os, re, yaml (imported by the host script; PyYAML is a hard
# dependency, preflighted in bash before the interpreter starts).

View File

@@ -69,9 +69,9 @@ import yaml
# resolver block below pins the reads; this pins the writes.
#
# Deliberately OUTSIDE the ADR-0020 shared boundary resolver block: the two
# validate.sh copies print findings, skill-size-check.sh has its own top-level
# equivalent, and tests/test-adr0020-contract.sh hashes that block for
# byte-identity across all three.
# validate.sh modes print findings, skill-size-check.sh has its own top-level
# equivalent, and the block is one sourced copy all three share, so each
# consumer's own startup stays in its own preamble.
for _stream in (sys.stdout, sys.stderr):
try:
_stream.reconfigure(encoding='utf-8')
@@ -145,9 +145,11 @@ COPILOT_BODY_LIMIT = 30000
# every session exactly like a skill's, so agents take the SAME description
# gates. These two constants are DUPLICATED in three places:
# scripts/skill-size-check.sh, lib-checks-skill.sh beside this file, and here.
# The repo-root hook's copy cannot be shared with this skill — a cache-installed
# plugin's scripts cannot read files outside their own plugin directory, and the
# hook cannot reach inside the plugin. The two copies INSIDE this skill could be
# The repo-root hook's copy cannot be sourced FROM this skill — a cache-installed
# plugin's scripts cannot read files outside their own plugin directory. (The
# hook could now read these from the plugin, as it already sources
# lib-boundary-resolver.sh, but they sit in its Python preamble; hoisting them
# is a separate change.) The two copies INSIDE this skill could be
# shared (ADR-0025: two files in one skill may source a third), and are not only
# because each mode library is a verbatim lift of the pre-merge suite whose
# constants sit in its Python preamble; hoisting them is a separate change.

View File

@@ -68,9 +68,9 @@ import yaml
# resolver block below pins the reads; this pins the writes.
#
# Deliberately OUTSIDE the ADR-0020 shared boundary resolver block: the two
# validate.sh copies print findings, skill-size-check.sh has its own top-level
# equivalent, and tests/test-adr0020-contract.sh hashes that block for
# byte-identity across all three.
# validate.sh modes print findings, skill-size-check.sh has its own top-level
# equivalent, and the block is one sourced copy all three share, so each
# consumer's own startup stays in its own preamble.
for _stream in (sys.stdout, sys.stderr):
try:
_stream.reconfigure(encoding='utf-8')

File diff suppressed because it is too large Load Diff

View File

@@ -3,22 +3,20 @@
# itself. None of them was pinned anywhere before this file, and each one fails
# silently — which is the whole reason they need a test rather than a comment:
#
# 1. "ONE resolver, embedded VERBATIM in two scripts." The block between the
# BEGIN/END markers is copied, not imported, because a cache-installed
# plugin's scripts cannot read files outside their own plugin directory.
# ADR-0025 merged skill-audit and agent-audit, which dropped the count from
# three copies to two: factory-audit now holds ONE copy in a sourced
# lib-boundary-resolver.sh, and scripts/skill-size-check.sh keeps its
# embedded copy because it is a repo-root hook kept fit for a published
# hook manifest (retired; ADR-0014), where entry[0] is the only token
# pre-commit rewrites — it could not reach a file inside the plugin at a
# path any consumer has. Nothing but this file asserts the two copies are still identical, and
# a one-line edit to a single copy is invisible: every constant-agreement
# assertion in tests/test-skill-size-check.sh still passes, because the
# CONSTANTS are not what drifted.
# 1a. The resolver's two copies are the ONLY two, and validate.sh sources
# factory-audit's in both mode branches — the same authority checks 1b
# makes for the parser, which byte-identity alone cannot make.
# 1. "ONE resolver, and both of its consumers run it." The ADR-0020 boundary
# resolver has exactly one copy, factory-audit's sourced
# lib-boundary-resolver.sh. scripts/skill-size-check.sh used to embed a
# second, byte-identical copy, because it was also exported through a
# published hook manifest whose consumers could not reach a file inside the
# plugin; 4de5b6b retired that export (ADR-0014), so the hook now sources
# the library too. What must not fail silently: the hook growing its own
# copy back, the library being gutted, or the hook no longer running the
# library's text at all. So this asserts the library is real content, the
# hook carries no marker pair, the hook fails closed without the library,
# and — by a sentinel planted in a copied library — that the text the hook
# executes IS the library's.
# 1a. The library is the ONLY authority, and validate.sh sources it in both
# mode branches — the same authority checks 1b makes for the parser.
# 1b. The same claim, one directory over, for the Contributing-files parser.
# That one was worse: it was embedded in both validate-provenance.sh copies,
# the agent-audit copy's docstring ASSERTED it was kept behaviourally
@@ -49,8 +47,8 @@ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
HOOK="$REPO_ROOT/scripts/skill-size-check.sh"
FACTORY_AUDIT="$REPO_ROOT/plugins/kyberforge/.apm/skills/factory-audit"
# ADR-0025: one auto-detecting entry point, and one sourced copy of the resolver
# behind it. The entry point is what the preflight assertions run; the library is
# what the byte-identity assertion hashes.
# behind it, which the root hook sources as well. The entry point is what the
# preflight assertions run; the library is what assertion 1 inspects.
FACTORY_VALIDATE="$FACTORY_AUDIT/scripts/validate.sh"
FACTORY_RESOLVER="$FACTORY_AUDIT/scripts/lib-boundary-resolver.sh"
PASS=0
@@ -66,70 +64,111 @@ BEGIN_MARKER='# ===== BEGIN ADR-0020 SHARED BOUNDARY RESOLVER ====='
END_MARKER='# ===== END ADR-0020 SHARED BOUNDARY RESOLVER ====='
# ---------------------------------------------------------------------------
# 1. The shared resolver block is byte-identical in both scripts
# 1. The resolver has one copy, and the root hook runs it
# ---------------------------------------------------------------------------
# Two copies, not three, since ADR-0025 merged skill-audit and agent-audit:
# scripts/skill-size-check.sh (embedded — sourcing the plugin's copy was
# considered and refuted, see the header) and factory-audit's single sourced
# lib-boundary-resolver.sh. The claim is unchanged and so is the check: the
# span between the markers must be byte-identical wherever it appears.
# One copy since the 2026-09-16 change: factory-audit's lib-boundary-resolver.sh.
# scripts/skill-size-check.sh sources it rather than embedding a second copy, so
# there is no pair left to hash. What replaces the hash is the set of ways a
# single sourced copy can still fail quietly.
echo ""
echo "--- the ADR-0020 shared resolver block is byte-identical in both scripts ---"
echo "--- the ADR-0020 resolver has one copy, and skill-size-check.sh runs it ---"
# Marker discipline first. An unbalanced or duplicated marker pair makes the
# extraction below silently measure the wrong span — a sed range that never
# closes swallows the rest of the file, and one that opens twice concatenates
# two spans. Both would still compare "equal" if both were mangled the
# same way, so the shape is asserted before the contents.
MARKERS_OK=true
for f in "$HOOK" "$FACTORY_RESOLVER"; do
if [[ ! -f "$f" ]]; then
fail "script not found: $f"
MARKERS_OK=false
continue
fi
b="$(grep -cFx "$BEGIN_MARKER" "$f" || true)"
e="$(grep -cFx "$END_MARKER" "$f" || true)"
if [[ "$b" == "1" && "$e" == "1" ]]; then
pass "${f#"$REPO_ROOT/"} carries exactly one BEGIN and one END marker"
else
fail "${f#"$REPO_ROOT/"} has $b BEGIN and $e END markers, expected 1 and 1"
MARKERS_OK=false
fi
done
if ! $MARKERS_OK; then
fail "skipping the byte-identity comparison — the marker pairs are not well-formed, so any extraction would measure the wrong span"
# (i) The library carries exactly one well-formed marker pair around real
# content. An unbalanced pair makes every extraction measure the wrong span, and
# an emptied-out block would still "load" while enforcing nothing. The resolver
# is ~1,060 lines; 100 is a floor low enough never to need maintenance and high
# enough that a gutted block cannot sneak past.
if [[ ! -f "$FACTORY_RESOLVER" ]]; then
fail "resolver library not found: ${FACTORY_RESOLVER#"$REPO_ROOT/"}"
else
HASHES=()
LINECOUNTS=()
for f in "$HOOK" "$FACTORY_RESOLVER"; do
out="$TMPDIR_T/block-$(echo "$f" | md5sum | cut -c1-8).txt"
sed -n "/^${BEGIN_MARKER}\$/,/^${END_MARKER}\$/p" "$f" > "$out"
HASHES+=("$(md5sum < "$out" | cut -d' ' -f1)")
LINECOUNTS+=("$(wc -l < "$out" | tr -d ' ')")
done
if [[ "${HASHES[0]}" == "${HASHES[1]}" ]]; then
pass "both copies hash to ${HASHES[0]} (${LINECOUNTS[0]} lines) — agreement by construction, not by coincidence"
b="$(grep -cFx "$BEGIN_MARKER" "$FACTORY_RESOLVER" || true)"
e="$(grep -cFx "$END_MARKER" "$FACTORY_RESOLVER" || true)"
if [[ "$b" == "1" && "$e" == "1" ]]; then
pass "${FACTORY_RESOLVER#"$REPO_ROOT/"} carries exactly one BEGIN and one END marker"
span="$(sed -n "/^${BEGIN_MARKER}\$/,/^${END_MARKER}\$/p" "$FACTORY_RESOLVER" | wc -l | tr -d ' ')"
if [[ "$span" -gt 100 ]]; then
pass "the resolver span is $span lines — real content, not an empty block"
else
fail "the resolver span is only $span lines — a gutted block would load and resolve nothing"
fi
else
fail "the shared resolver has DRIFTED: skill-size-check=${HASHES[0]} (${LINECOUNTS[0]} lines), factory-audit/scripts/lib-boundary-resolver.sh=${HASHES[1]} (${LINECOUNTS[1]} lines). Edit one copy, then paste it over the other."
fail "${FACTORY_RESOLVER#"$REPO_ROOT/"} has $b BEGIN and $e END markers, expected 1 and 1"
fi
# A block that has been emptied out would hash equal in both and pass the
# comparison above while enforcing nothing. The resolver is ~1,060 lines; 100
# is a floor low enough never to need maintenance and high enough that a
# gutted block cannot sneak past.
if [[ "${LINECOUNTS[0]}" -gt 100 ]]; then
pass "the extracted block is ${LINECOUNTS[0]} lines — the comparison is over real content, not an empty span"
fi
# (ii) The hook carries no copy of its own. A column-0 marker line in the hook
# is the shape the old embedded copy had, and the shape a paste-back would have.
if [[ ! -f "$HOOK" ]]; then
fail "hook not found: ${HOOK#"$REPO_ROOT/"}"
else
hb="$(grep -cFx "$BEGIN_MARKER" "$HOOK" || true)"
he="$(grep -cFx "$END_MARKER" "$HOOK" || true)"
if [[ "$hb" == "0" && "$he" == "0" ]]; then
pass "${HOOK#"$REPO_ROOT/"} carries no resolver marker lines — it has not grown its own copy back"
else
fail "the extracted shared block is only ${LINECOUNTS[0]} lines — two identical empty spans would compare equal and assert nothing"
fail "${HOOK#"$REPO_ROOT/"} carries $hb BEGIN and $he END marker lines — a second copy of the resolver is back in the hook"
fi
fi
# (iii) and (iv) run the hook from a scratch tree that mirrors the two paths it
# depends on, so the real library is never touched. The scratch hook is a copy
# of the real one; its library is either absent, gutted, or the real library
# with a sentinel planted inside the resolver block.
SSC_TREE="$TMPDIR_T/ssc-tree"
SSC_LIB_DIR="$SSC_TREE/plugins/kyberforge/.apm/skills/factory-audit/scripts"
mkdir -p "$SSC_TREE/scripts" "$SSC_LIB_DIR" "$TMPDIR_T/ssc-skill/probe-skill"
cp "$HOOK" "$SSC_TREE/scripts/skill-size-check.sh"
printf -- '---\nname: probe-skill\ndescription: Use when probing the resolver wiring.\nmetadata:\n version: "0.1.0"\n---\n\n## Step 1\n\nDo the thing.\n' \
> "$TMPDIR_T/ssc-skill/probe-skill/SKILL.md"
PROBE="$TMPDIR_T/ssc-skill/probe-skill/SKILL.md"
run_scratch_hook() {
local rc=0
SSC_OUT="$(bash "$SSC_TREE/scripts/skill-size-check.sh" "$PROBE" 2>&1)" || rc=$?
SSC_RC=$rc
}
# (iii) Fail closed: no library, then a library that defines nothing.
rm -f "$SSC_LIB_DIR/lib-boundary-resolver.sh"
run_scratch_hook
if [[ "$SSC_RC" -ne 0 && "$SSC_OUT" == *"boundary resolver library was not found"* ]]; then
pass "with the library missing, the hook exits $SSC_RC and names the missing library — not a vacuous pass"
else
fail "with the library missing, the hook exited $SSC_RC without naming it: $SSC_OUT"
fi
printf '# gutted\n' > "$SSC_LIB_DIR/lib-boundary-resolver.sh"
run_scratch_hook
if [[ "$SSC_RC" -ne 0 && "$SSC_OUT" == *"did not define the ADR-0020 boundary resolver"* ]]; then
pass "with a library that defines no resolver, the hook exits $SSC_RC and says so"
else
fail "with a gutted library, the hook exited $SSC_RC without saying so: $SSC_OUT"
fi
# (iv) The text the hook executes IS the library's. A sentinel print planted
# just after the BEGIN marker of a copied library must appear in the hook's
# output. Without this, a hook that sourced the library but ran some other
# program would pass (i)-(iii).
SENTINEL="ADR0020-RESOLVER-SENTINEL-$$"
if [[ -f "$FACTORY_RESOLVER" ]]; then
awk -v m="$BEGIN_MARKER" -v s="$SENTINEL" '{ print } $0 == m { print "print(\"" s "\")" }' \
"$FACTORY_RESOLVER" > "$SSC_LIB_DIR/lib-boundary-resolver.sh"
if [[ "$(grep -cF "$SENTINEL" "$SSC_LIB_DIR/lib-boundary-resolver.sh" || true)" -ne 1 ]]; then
fail "fixture check: the sentinel was not planted exactly once in the copied library — the case below would prove nothing"
else
run_scratch_hook
if [[ "$SSC_RC" -eq 0 && "$SSC_OUT" == *"$SENTINEL"* ]]; then
pass "a sentinel planted in the library's resolver block runs inside the hook — the hook executes the library's text"
else
fail "the hook did not run the library's resolver text (rc=$SSC_RC, sentinel absent from output): $SSC_OUT"
fi
fi
fi
# ---------------------------------------------------------------------------
# 1a. The resolver copies are the ONLY two, and validate.sh sources its one
# 1a. The resolver library is the ONLY authority, and validate.sh sources it
# ---------------------------------------------------------------------------
# Byte-identity between two named files says nothing about a THIRD copy, and
# nothing about whether factory-audit's copy is the one that runs. Assertion 1b
# Assertion 1 says nothing about a copy somewhere else in the tree, and nothing
# about whether validate.sh runs the library. Assertion 1b
# pins both of those for the Contributing-files parser; the resolver is the same
# defect class and gets the same two checks:
#
@@ -137,16 +176,14 @@ fi
# branches — asserted inside each arm of `case "$MODE" in`, not by counting
# source lines file-wide, because a count cannot see a branch. A library
# that is identical, unique and never sourced is a copy that has quietly
# been replaced by an inline one — and the byte-identity check above would
# stay green over it.
# been replaced by an inline one — and assertion 1 would stay green over it.
# b. Nothing has re-inlined it. The BEGIN marker and a def unique to the
# resolver (`_authoring_root`) appear in exactly the two authorities —
# scripts/skill-size-check.sh and lib-boundary-resolver.sh — and nowhere
# else under the tree. A mode library that grows a "just this once" copy
# would otherwise escape assertion 1 entirely, because 1 hashes only the
# two files it names.
# resolver (`_authoring_root`) appear in exactly one file,
# lib-boundary-resolver.sh, and nowhere else under the tree. A mode library
# or a root script that grows a "just this once" copy would otherwise
# escape assertion 1 entirely, because 1 inspects only the files it names.
echo ""
echo "--- the ADR-0020 resolver has exactly two authorities, and validate.sh sources factory-audit's ---"
echo "--- the ADR-0020 resolver has exactly one authority, and validate.sh sources it ---"
# Deployed and vendored trees are generated copies, not authorities: .claude/ is
# apm install output, apm_modules/ is resolved dependencies, build/ is release
@@ -303,18 +340,18 @@ PY
fi
fi
# (b) Exactly the two authorities, for both spellings of a copy.
EXPECTED_RESOLVERS="$(printf '%s\n' "$HOOK" "$FACTORY_RESOLVER" | sort)"
# (b) Exactly the one authority, for both spellings of a copy.
EXPECTED_RESOLVERS="$FACTORY_RESOLVER"
check_resolver_authorities() {
local label="$1" needle="$2"
local found
found="$(tree_scan "$needle")"
if [[ "$found" == "$EXPECTED_RESOLVERS" ]]; then
pass "$label appears in exactly the two resolver authorities and nowhere else"
pass "$label appears in exactly the one resolver authority and nowhere else"
elif [[ -z "$found" ]]; then
fail "$label was found in NO file at all — the scan is looking for the wrong text"
else
fail "$label appears in an unexpected set of files, so the resolver has been re-inlined or lost: $(echo "$found" | tr '\n' ' ')— expected exactly ${HOOK#"$REPO_ROOT/"} and ${FACTORY_RESOLVER#"$REPO_ROOT/"}"
fail "$label appears in an unexpected set of files, so the resolver has been re-inlined or lost: $(echo "$found" | tr '\n' ' ')— expected exactly ${FACTORY_RESOLVER#"$REPO_ROOT/"}"
fi
}
check_resolver_authorities "the resolver's BEGIN marker" "$BEGIN_MARKER"
@@ -325,7 +362,7 @@ check_resolver_authorities "a 'def _authoring_root' definition" "def _authoring_
# ---------------------------------------------------------------------------
# Same defect class, one directory over. parse_contributing_files() used to be
# embedded in both validate-provenance.sh copies for the same reason the resolver
# is embedded twice, and until this assertion existed the agent-audit copy's
# was once embedded in several scripts, and until this assertion existed the agent-audit copy's
# docstring merely CLAIMED it was "kept behaviourally identical to skill-audit's
# copy" — an invariant nothing checked, and the two did drift into different
# spellings of the bullet loop at 484357a. That drift happened to be

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# Regression test for the two ways an ADR-0020 gate can be made to check NOTHING
# while still exiting 0. Both were live defects, both were silent, and both sit
# in the shared resolver block that all three scripts embed verbatim — so every
# case below runs against all three.
# in the shared resolver block that all three entry points run — one sourced
# copy since 2026-09-16 — so every case below runs against all three.
#
# 1. THE FRONTMATTER BLOCKER. The frontmatter matcher used to be `^---\n`. A
# UTF-8 BOM, a leading blank line, a trailing space after either marker, or