Skip to content

Commit a073125

Browse files
committed
feat(wave6): canonical-names guard, DYADT residual fix, licence-flag record
Capstone wave: close the last pull-forward holes and record the flag-only licence discipline. (Campaign umbrella #460.) - scripts/verify-claims.sh: close the residual DYADT bypass from the adversarial review (#461) — an always-matching `contains:` regex (`.*`, `^`, `$`, `.`, `.+`) no longer confirms vacuously; it now requires a literal character and returns `unverifiable trivial-pattern` otherwise. CLAIM-FORMAT.adoc pins the `contains:` dialect to POSIX ERE and states the trivial-pattern rule; a conformance vector (always-match) + a wave4 assertion lock it (10 vectors, 15 dyadt assertions). - scripts/check-canonical-names.sh: reintroduction guard for the deprecated names (6a2 -> descriptiles, agent_instructions -> bot_directives) from the CANONICAL-NAMES.adoc mandate. Inspects only ADDED diff lines so the chartered bulk migration of existing occurrences is untouched; skips meta-references (lines that describe the deprecation). Wired into `just validate` and the pre-commit hook. scripts/tests/wave6-canonical-names-test.sh (4/4). - audits/licence-flags-2026-07.adoc: flag-only record — the whole program made no SPDX edits and no auto licence PRs; DYADT treats licence claims as manual-only end to end. Two owner-review flags surfaced, none acted on. CHANGELOG is git-cliff-generated (not hand-edited); the first tagged release + the rand<0.9.3 advisory expiry are owner actions tracked under #460. Orphan A2ML-ATOMICITY-PROTOCOL registration + REORGANIZATION-PLAN archival deferred to #460 as minor cleanup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0114ps6mY5jAH4Sz
1 parent 47cde2c commit a073125

11 files changed

Lines changed: 212 additions & 1 deletion

File tree

.machine_readable/REGISTRY.a2ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ name = "DYADT — Did-You-Actually-Do-That"
234234
stream = "governance"
235235
home = "did-you-actually-do-that/"
236236
canonical_doc = "did-you-actually-do-that/README.adoc"
237-
source_hash = "sha256:2ae635b9ede51e76781cb7c171108f2a4505b0aae9ac97fb05c910915141eb2a"
237+
source_hash = "sha256:453bf00d0dfac71576b5e7b4068fb8987abc3337d4bc3bf75c081e0332ae1dff"
238238
route = "post-action agent-claim verification (Tier 4 accountability)"
239239

240240
[[spec]]

Justfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ dyadt-test:
8989
language-guides-check:
9090
@bash scripts/check-language-guide.sh
9191

92+
# Block reintroduction of deprecated names (6a2, agent_instructions) in new diff
93+
canonical-names-check base="origin/main":
94+
@bash scripts/check-canonical-names.sh "{{base}}"
95+
9296
# Aggregate compliance gate: registry drift is the HARD gate (registry-check,
9397
# a hard dep). The RSR self-audit is INFORMATIONAL — a monorepo is not expected
9498
# to score Gold — but a *broken* audit (exit 4 / unexpected) must fail loudly
@@ -97,6 +101,8 @@ validate: registry-check
97101
@echo "=== validate: registry drift (HARD GATE) — passed as a dependency above ==="
98102
@echo "=== validate: per-language testing guides (structural, HARD GATE) ==="
99103
@bash scripts/check-language-guide.sh
104+
@echo "=== validate: canonical-names reintroduction guard (vs origin/main) ==="
105+
@bash scripts/check-canonical-names.sh origin/main || bash scripts/check-canonical-names.sh HEAD
100106
@echo "=== validate: RSR self-audit (INFORMATIONAL grade; errors fail loudly) ==="
101107
@bash scripts/rsr-selfaudit.sh .
102108
@echo "=== validate: done ==="

audits/licence-flags-2026-07.adoc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: CC-BY-SA-4.0
2+
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
3+
= Licence Flags — Estate Audit & Optimization (2026-07)
4+
:icons: font
5+
6+
[.lead]
7+
Flag-only record for the estate audit-and-optimization program (umbrella
8+
`hyperpolymath/standards#460`). Per the Manual-Only licence policy
9+
(`.claude/CLAUDE.md`), this program made **no** licence/SPDX edits and generated
10+
**no** automated licence-change PRs. This document records that discipline and
11+
flags — for owner review only — anything licence-adjacent that surfaced.
12+
13+
== Discipline upheld
14+
15+
* No SPDX headers were added, changed, or swept in any wave (0, 1, 3, 4, 5, 6).
16+
* New files created by the program carry the SPDX identifier matching the
17+
repo's classification at birth (authoring, not relicensing): scripts →
18+
`MPL-2.0`, prose/specs → `CC-BY-SA-4.0`. This is consistent with the estate
19+
policy that new files may carry the correct SPDX from birth.
20+
* The DYADT verifier (`did-you-actually-do-that/`) treats any licence/SPDX claim
21+
as `manual-only` end to end — it returns `unverifiable`, never auto-`confirmed`,
22+
and the consequence ledger's confirmation rate is explicitly unaffected by
23+
licence verdicts. The Manual-Only policy is preserved *by construction* in the
24+
new tooling.
25+
26+
== Flags for owner review (no action taken)
27+
28+
None of the following were edited; they are surfaced for the owner to rule on.
29+
30+
[cols="1,3", options="header"]
31+
|===
32+
| Location | Observation (flag-only)
33+
34+
| `rhodium-standard-repositories/rsr-audit.sh`
35+
| Header carries a dual `SPDX-License-Identifier: MPL-2.0 AND Palimpsest-0.8`.
36+
Palimpsest is a carve-out family; whether this file should carry a
37+
Palimpsest component is an owner ruling, not an audit action. Left untouched.
38+
39+
| `SECURITY-ADVISORIES.adoc`
40+
| A standing deferred `rand < 0.9.3` advisory is recorded. Not a licence matter,
41+
but flagged alongside release hygiene: renew with an expiry date or bump.
42+
(Tracked under the umbrella's release-hygiene item.)
43+
|===
44+
45+
== No sweep, no auto-PR
46+
47+
This program did not run, and must not be read as licensing, any bulk SPDX
48+
normalisation. Licence drift findings remain FLAG-ONLY and owner-gated, per the
49+
neurophone#99 precedent and the estate licence-policy umbrella.

did-you-actually-do-that/spec/CLAIM-FORMAT.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ A verifier MUST reject (`unverifiable`) a claim whose `verifier` is not listed
106106
as compatible with its `claim_class` in VERIFICATION-PROTOCOL — an
107107
agent MUST NOT be able to choose a weaker verifier than the claim class warrants.
108108

109+
=== `contains:` regex dialect (normative)
110+
111+
The `contains:<regex>` predicate uses **POSIX Extended Regular Expressions
112+
(ERE)**, matched case-sensitively against the whole file (`grep -E`). A pattern
113+
that contains no literal character — i.e. is trivially always-matching (`.*`,
114+
`.`, `^`, `$`, `.+`, and the like) — is NOT evidence and MUST be rejected as
115+
`unverifiable` (reason `trivial-pattern`); it would otherwise confirm any
116+
non-empty file. `stdout-contains:<s>` is a fixed-string (non-regex) substring
117+
match.
118+
109119
== Honesty constraints (normative)
110120

111121
. A claim's verdict MUST be derived from primary evidence re-collected by the
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[claims]
2+
schema = "dyadt/claim@1"
3+
actor = "conformance"
4+
[[claim]]
5+
id = "C1"
6+
claim_class = "file-changed"
7+
statement = "a vacuous always-matching contains pattern"
8+
target = "README.adoc"
9+
expect = "contains:.*"
10+
verifier = "git-diff"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
C1 unverifiable

hooks/pre-commit

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ if [ -f scripts/build-registry.sh ]; then
9191
fi
9292
fi
9393

94+
# Canonical-names guard: block reintroduction of the deprecated names listed in
95+
# CANONICAL-NAMES.adoc within the staged diff. Only added lines are checked, so
96+
# not-yet-migrated existing occurrences do not trip it.
97+
if [ -f scripts/check-canonical-names.sh ]; then
98+
if ! bash scripts/check-canonical-names.sh HEAD >/dev/null 2>&1; then
99+
echo -e "${RED}✗ Deprecated name reintroduced (see CANONICAL-NAMES.adoc):${NC}"
100+
bash scripts/check-canonical-names.sh HEAD 2>&1 | grep '' || true
101+
ERRORS=$((ERRORS + 1))
102+
fi
103+
fi
104+
94105
# Final result
95106
echo ""
96107
if [ $ERRORS -gt 0 ]; then

scripts/check-canonical-names.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: MPL-2.0
3+
#
4+
# check-canonical-names.sh — block REINTRODUCTION of deprecated names.
5+
#
6+
# CANONICAL-NAMES.adoc (owner mandate 2026-06-30) deprecates:
7+
# * 6a2 -> descriptiles
8+
# * agent_instructions -> bot_directives
9+
# The bulk migration of existing occurrences is chartered separately; this guard
10+
# stops NEW occurrences from landing in the meantime. It inspects only the
11+
# ADDED lines of a diff (grandfathered existing text is untouched), so it can be
12+
# wired into pre-commit and CI without tripping on the not-yet-migrated files.
13+
#
14+
# Usage: check-canonical-names.sh [base-ref]
15+
# base-ref default: origin/main (CI) then HEAD (pre-commit staged diff).
16+
# Exit: 0 no new deprecated tokens · 1 a deprecated token was added · 2 usage
17+
18+
set -uo pipefail
19+
cd "$(git rev-parse --show-toplevel)"
20+
21+
BASE="${1:-}"
22+
if [ -z "$BASE" ]; then
23+
if git rev-parse --verify -q origin/main >/dev/null 2>&1; then BASE="origin/main"; else BASE="HEAD"; fi
24+
fi
25+
26+
# Deprecated token -> canonical replacement (for the error message).
27+
declare -A REPL=( ["6a2"]="descriptiles" ["agent_instructions"]="bot_directives" )
28+
29+
# Files that legitimately NAME the deprecated tokens (the mandate itself, this
30+
# guard, migration/charter docs). Excluded from the check.
31+
is_excluded() {
32+
case "$1" in
33+
CANONICAL-NAMES.adoc|scripts/check-canonical-names.sh|scripts/tests/*|\
34+
*MIGRATION*|*migration*|*CHANGELOG*|*/6a2/*|.machine_readable/6a2/*) return 0 ;;
35+
esac
36+
return 1
37+
}
38+
39+
# Added lines in the working diff vs BASE, per file.
40+
added_diff() { git diff "$BASE" -- . 2>/dev/null; }
41+
42+
rc=0
43+
current_file=""
44+
while IFS= read -r line; do
45+
case "$line" in
46+
"+++ b/"*) current_file="${line#+++ b/}" ;;
47+
"+"*)
48+
is_excluded "$current_file" && continue
49+
body="${line#+}"
50+
# Skip a line that is DESCRIBING the deprecation rather than using the old
51+
# name — it also mentions the canonical replacement or the mandate itself
52+
# (e.g. tooling comments, this guard's own wiring, docs about the rename).
53+
if printf '%s' "$body" | grep -Eqi 'deprecat|canonical|reintroduc|descriptiles|bot_directives'; then
54+
continue
55+
fi
56+
for tok in "${!REPL[@]}"; do
57+
# word-ish boundary so e.g. 'v6a2ml' style false hits are limited
58+
if printf '%s' "$body" | grep -Eq "(^|[^A-Za-z0-9])$tok([^A-Za-z0-9]|$)"; then
59+
echo "$current_file: reintroduces deprecated '$tok' — use '${REPL[$tok]}' (CANONICAL-NAMES.adoc)"
60+
echo " + $body"
61+
rc=1
62+
fi
63+
done ;;
64+
esac
65+
done < <(added_diff)
66+
67+
if [ "$rc" -eq 0 ]; then
68+
echo "✅ no deprecated names reintroduced (vs $BASE)"
69+
fi
70+
exit $rc

scripts/tests/wave4-dyadt-test.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ target = "echo marker >&2; true"
166166
expect = "stdout-contains:marker"
167167
verifier = "command-transcript"'
168168
[[ "$(reason_of "$TMP/se.a2ml" C1)" == REFUTED* ]] && ok "stderr does not satisfy stdout-contains" || bad "stderr false-confirmed stdout claim"
169+
# an always-matching contains: regex is not evidence (#461)
170+
mk am.a2ml '[claims]
171+
[[claim]]
172+
id = "C1"
173+
claim_class = "file-changed"
174+
target = "README.adoc"
175+
expect = "contains:.*"
176+
verifier = "git-diff"'
177+
[[ "$(reason_of "$TMP/am.a2ml" C1)" == unverifiable*trivial-pattern ]] && ok "always-matching contains: -> unverifiable" || bad "always-match pattern confirmed vacuously"
178+
169179
# licence claim phrased only in the statement is still manual-only
170180
mk lic.a2ml '[claims]
171181
[[claim]]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: MPL-2.0
3+
set -uo pipefail
4+
#
5+
# Wave-6 regression: the canonical-names reintroduction guard must block a NEW
6+
# deprecated token while leaving grandfathered existing occurrences alone.
7+
8+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
9+
CHK="$ROOT/scripts/check-canonical-names.sh"
10+
11+
pass=0 fail=0
12+
ok() { echo "$1"; pass=$((pass + 1)); }
13+
bad() { echo "$1"; fail=$((fail + 1)); }
14+
15+
cd "$ROOT"
16+
17+
echo "== guard blocks a newly-added deprecated token =="
18+
f="wave6_guard_probe.txt"
19+
printf 'this file uses the 6a2 layout\n' > "$f"
20+
git add "$f" 2>/dev/null
21+
if bash "$CHK" HEAD >/dev/null 2>&1; then bad "new '6a2' token not blocked"; else ok "new '6a2' token blocked"; fi
22+
# agent_instructions too
23+
printf 'agent_instructions live here\n' > "$f"
24+
git add "$f" 2>/dev/null
25+
if bash "$CHK" HEAD >/dev/null 2>&1; then bad "new 'agent_instructions' not blocked"; else ok "new 'agent_instructions' blocked"; fi
26+
git reset -q "$f" 2>/dev/null; rm -f "$f"
27+
28+
echo "== guard passes with no offending additions =="
29+
printf 'a perfectly canonical descriptiles + bot_directives line\n' > "$f"
30+
git add "$f" 2>/dev/null
31+
bash "$CHK" HEAD >/dev/null 2>&1 && ok "canonical names pass" || bad "canonical names wrongly blocked"
32+
git reset -q "$f" 2>/dev/null; rm -f "$f"
33+
34+
echo "== the guard excludes CANONICAL-NAMES.adoc itself =="
35+
grep -q 'CANONICAL-NAMES.adoc' "$CHK" && ok "mandate doc is excluded from the guard" || bad "mandate doc not excluded"
36+
37+
echo
38+
echo "Wave-6 canonical-names regression: $pass passed, $fail failed"
39+
[ "$fail" -eq 0 ]

0 commit comments

Comments
 (0)