fix(gates): restore byte-identity of the shared ADR-0020 boundary resolver

915eb09 rewrote the bare-arrow carve-out comment in scripts/skill-size-check.sh
without pasting the block over the two other copies, so the resolver stood at
764 lines in the hook and 755 in both audit validators.
tests/test-adr0020-contract.sh exists to catch exactly this and did -- it was
the regression behind that suite's failure, and I reported the suite green
after 915eb09 without re-running it.

No behaviour changes: the drift was comment-only. Restoring identity keeps the
invariant the test enforces, which matters because the three copies are the
only thing making the hook and the two validators agree on what a boundary
target is.

Refs #99

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWb5RQgCL1ye7cGp2RPb2u
This commit is contained in:
2026-08-30 16:42:51 +00:00
parent 264a5dbd67
commit 79c60715dc
4 changed files with 44 additions and 8 deletions

View File

@@ -446,8 +446,17 @@ def known_targets(start_dir):
# condition, pc-run's "run pre-commit hooks" reads as a route to a # condition, pc-run's "run pre-commit hooks" reads as a route to a
# non-existent `pre-commit` skill. # non-existent `pre-commit` skill.
# * A BARE arrow target counts only in ADR-0020's compressed boundary form, # * A BARE arrow target counts only in ADR-0020's compressed boundary form,
# `Not <thing> -> <skill-name>`. Without that, diagnose's process chain # `Not <thing> -> <skill-name>`. The example that motivated it is gone:
# "fix -> regression-test" reads as a route to `regression-test`. # diagnose's process chain "fix -> regression-test", which without the
# gate read as a route to a non-existent `regression-test` skill, was cut
# when issue #99 retrofitted that description. So the gate is currently
# UNEXERCISED — gating and not gating produce the same verdict corpus-wide.
# Keep it anyway. It is a false-positive guard against prose no one has
# written yet, and any new process chain re-arms it. Unexercised is not the
# same as unnecessary, and the branch it guards is still load-bearing: the
# bare-arrow rule is the sole extractor for three real targets in
# kyberforge's audit skills (agent-audit -> agent-author, agent-audit ->
# skill-audit, skill-audit -> skill-author), all written unbackticked.
# * A backticked hyphenated token counts only inside a boundary sentence. # * A backticked hyphenated token counts only inside a boundary sentence.
# Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard # Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard
# FAIL with no escape hatch. Gating it costs nothing (measured over this # FAIL with no escape hatch. Gating it costs nothing (measured over this

View File

@@ -372,8 +372,17 @@ def known_targets(start_dir):
# condition, pc-run's "run pre-commit hooks" reads as a route to a # condition, pc-run's "run pre-commit hooks" reads as a route to a
# non-existent `pre-commit` skill. # non-existent `pre-commit` skill.
# * A BARE arrow target counts only in ADR-0020's compressed boundary form, # * A BARE arrow target counts only in ADR-0020's compressed boundary form,
# `Not <thing> -> <skill-name>`. Without that, diagnose's process chain # `Not <thing> -> <skill-name>`. The example that motivated it is gone:
# "fix -> regression-test" reads as a route to `regression-test`. # diagnose's process chain "fix -> regression-test", which without the
# gate read as a route to a non-existent `regression-test` skill, was cut
# when issue #99 retrofitted that description. So the gate is currently
# UNEXERCISED — gating and not gating produce the same verdict corpus-wide.
# Keep it anyway. It is a false-positive guard against prose no one has
# written yet, and any new process chain re-arms it. Unexercised is not the
# same as unnecessary, and the branch it guards is still load-bearing: the
# bare-arrow rule is the sole extractor for three real targets in
# kyberforge's audit skills (agent-audit -> agent-author, agent-audit ->
# skill-audit, skill-audit -> skill-author), all written unbackticked.
# * A backticked hyphenated token counts only inside a boundary sentence. # * A backticked hyphenated token counts only inside a boundary sentence.
# Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard # Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard
# FAIL with no escape hatch. Gating it costs nothing (measured over this # FAIL with no escape hatch. Gating it costs nothing (measured over this

View File

@@ -446,8 +446,17 @@ def known_targets(start_dir):
# condition, pc-run's "run pre-commit hooks" reads as a route to a # condition, pc-run's "run pre-commit hooks" reads as a route to a
# non-existent `pre-commit` skill. # non-existent `pre-commit` skill.
# * A BARE arrow target counts only in ADR-0020's compressed boundary form, # * A BARE arrow target counts only in ADR-0020's compressed boundary form,
# `Not <thing> -> <skill-name>`. Without that, diagnose's process chain # `Not <thing> -> <skill-name>`. The example that motivated it is gone:
# "fix -> regression-test" reads as a route to `regression-test`. # diagnose's process chain "fix -> regression-test", which without the
# gate read as a route to a non-existent `regression-test` skill, was cut
# when issue #99 retrofitted that description. So the gate is currently
# UNEXERCISED — gating and not gating produce the same verdict corpus-wide.
# Keep it anyway. It is a false-positive guard against prose no one has
# written yet, and any new process chain re-arms it. Unexercised is not the
# same as unnecessary, and the branch it guards is still load-bearing: the
# bare-arrow rule is the sole extractor for three real targets in
# kyberforge's audit skills (agent-audit -> agent-author, agent-audit ->
# skill-audit, skill-audit -> skill-author), all written unbackticked.
# * A backticked hyphenated token counts only inside a boundary sentence. # * A backticked hyphenated token counts only inside a boundary sentence.
# Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard # Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard
# FAIL with no escape hatch. Gating it costs nothing (measured over this # FAIL with no escape hatch. Gating it costs nothing (measured over this

View File

@@ -372,8 +372,17 @@ def known_targets(start_dir):
# condition, pc-run's "run pre-commit hooks" reads as a route to a # condition, pc-run's "run pre-commit hooks" reads as a route to a
# non-existent `pre-commit` skill. # non-existent `pre-commit` skill.
# * A BARE arrow target counts only in ADR-0020's compressed boundary form, # * A BARE arrow target counts only in ADR-0020's compressed boundary form,
# `Not <thing> -> <skill-name>`. Without that, diagnose's process chain # `Not <thing> -> <skill-name>`. The example that motivated it is gone:
# "fix -> regression-test" reads as a route to `regression-test`. # diagnose's process chain "fix -> regression-test", which without the
# gate read as a route to a non-existent `regression-test` skill, was cut
# when issue #99 retrofitted that description. So the gate is currently
# UNEXERCISED — gating and not gating produce the same verdict corpus-wide.
# Keep it anyway. It is a false-positive guard against prose no one has
# written yet, and any new process chain re-arms it. Unexercised is not the
# same as unnecessary, and the branch it guards is still load-bearing: the
# bare-arrow rule is the sole extractor for three real targets in
# kyberforge's audit skills (agent-audit -> agent-author, agent-audit ->
# skill-audit, skill-audit -> skill-author), all written unbackticked.
# * A backticked hyphenated token counts only inside a boundary sentence. # * A backticked hyphenated token counts only inside a boundary sentence.
# Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard # Unconditionally, `pre-push` or `commit-msg` in a TRIGGER clause is a hard
# FAIL with no escape hatch. Gating it costs nothing (measured over this # FAIL with no escape hatch. Gating it costs nothing (measured over this