From 8a47d25003008171177bb03a1c81989de3c5da95 Mon Sep 17 00:00:00 2001 From: WilcoLouwerse Date: Tue, 13 Oct 2026 18:33:39 +0200 Subject: [PATCH 1/3] docs(claude): never name a document-internal label bare in the personal CLAUDE.md template A finding, question, step or revision label (F8, f2, A1, r26) means nothing in a reply read without its source document. The template now asks for a short gloss and a link on first mention, and names the kind of label instead of one example so the rule covers every scheme. Co-Authored-By: Claude Opus 5.5 --- docs/claude/examples/global-CLAUDE.md.example | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/claude/examples/global-CLAUDE.md.example b/docs/claude/examples/global-CLAUDE.md.example index 7f9881df..c6e7ce05 100644 --- a/docs/claude/examples/global-CLAUDE.md.example +++ b/docs/claude/examples/global-CLAUDE.md.example @@ -66,6 +66,12 @@ Deliver exactly the thing requested. When something else looks wrong along the w - Present every command I am expected to run as a **fenced code block** on its own line, never inline-backticked inside prose. A fenced block is a clean copy target. - Exactly **one** final, copy-ready command block per handover. Decide everything — commit type, wording, file list — *before* writing it. Never a block with a correction further down: the first block is what gets copied. +## Short labels in replies: never bare + +A label that only means something inside its source document is opaque in a reply, whatever its letter or numbering: a plan finding (F8), a review finding (f2, F2–F4), an audit item (A1), a question (Q3), a plan step, a revision (r26), a scenario number, a tracking tag. I read the reply without that document open. Every first mention carries, in parentheses, what it is and preferably a link (plan line, issue, PR, review thread): "F8 (the search page returns 500 when a catalogue points at an unknown register, [plan](…))". + + + ## PR review threads: two roles - As the **author** of a PR: after pushing a fix in response to a review thread, ask yes/no before replying; reply in neutral framing and never resolve the thread, the reviewer does that. From a951388fcce9b97e392253cff98c646766c8a744 Mon Sep 17 00:00:00 2001 From: WilcoLouwerse Date: Tue, 13 Oct 2026 20:03:12 +0200 Subject: [PATCH 2/3] test(hydra-gates): read gate output via here-strings in the scope matrix suite The suite runs under `set -o pipefail` and matched gate output with `printf '%s' "$out" | grep -q`. grep -q exits on the first match, so on a large enough output printf takes SIGPIPE, the pipeline returns non-zero and a matching assertion is reported as a failure ("printf: write error: Broken pipe"). Feed grep through a here-string so there is no pipe to break. Co-Authored-By: Claude Opus 5.5 --- .../scripts/lib/test_gate_scope_matrix.sh | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hydra-gates/scripts/lib/test_gate_scope_matrix.sh b/hydra-gates/scripts/lib/test_gate_scope_matrix.sh index 968c24d6..c951be50 100644 --- a/hydra-gates/scripts/lib/test_gate_scope_matrix.sh +++ b/hydra-gates/scripts/lib/test_gate_scope_matrix.sh @@ -96,7 +96,7 @@ printf '\n- unrelated doc tweak\n' >> "${WORK}/inherited/docs/CHANGELOG.md" gf_commit_paths "${WORK}/inherited" "docs: unrelated change" docs/CHANGELOG.md _pc="$(cd "${WORK}/inherited" && python3 "${CHECKER}" . --all 2>&1)" -if printf '%s' "${_pc}" | grep -qF 'lib/Listener/InheritedDebtListener.php'; then +if grep -qF 'lib/Listener/InheritedDebtListener.php' <<< "${_pc}"; then _ok "positive control: checker --all NAMES lib/Listener/InheritedDebtListener.php" else echo "FAIL — the positive control did not fire: check_listener_placement.py --all" @@ -107,7 +107,7 @@ else printf '%s\n' "${_pc}" | sed 's/^/ /' exit 1 fi -if printf '%s' "${_pc}" | grep -qE 'checked 1 post-event registration'; then +if grep -qE 'checked 1 post-event registration' <<< "${_pc}"; then _ok "positive control: exactly 1 registration is present to be judged" else _bad "positive control: expected 'checked 1 post-event registration', got: $(printf '%s' "${_pc}" | tail -2 | tr '\n' ' ')" @@ -182,8 +182,8 @@ gf_commit_all "${WORK}/inherited-nobase" "docs: unrelated change" _out="$(gf_run_wrapper "${WORK}/inherited-nobase" "${WORK}/log-full")" -if printf '%s' "${_out}" | grep -qF 'SCOPE-MODE: full' \ - && printf '%s' "${_out}" | grep -qF 'Delta base: NONE'; then +if grep -qF 'SCOPE-MODE: full' <<< "${_out}" \ + && grep -qF 'Delta base: NONE' <<< "${_out}"; then _ok "the run states BOTH its file scope (full) and that it resolved no delta base" else _bad "the run did not state both 'SCOPE-MODE: full' and 'Delta base: NONE'; the rest of this arm is unsafe to interpret because nothing pins which inputs produced it" @@ -207,19 +207,19 @@ case "${_v}" in ;; *) _bad "gate-61 on --full gave an unrecognised verdict: ${_v:0:160}" ;; esac -if printf '%s' "${_v}" | grep -qF 'out of scope'; then +if grep -qF 'out of scope' <<< "${_v}"; then _bad ".github#347 is LIVE: gate-61 on --full still claims 'the diff ... put every post-event registration out of scope', on a run whose own preamble says it computed no diff, over a tree whose single registration the positive control just failed. 0 of 1 inspected, and the reason cites a diff that does not exist." else _ok "gate-61's --full reason no longer claims a diff excluded anything" fi -if printf '%s' "${_v}" | grep -qF 'computed NO diff'; then +if grep -qF 'computed NO diff' <<< "${_v}"; then _ok "gate-61's --full reason names the ABSENCE of a diff — the falsifiable form" else _bad "gate-61's --full reason does not state that the run computed no diff, so a reader still cannot tell an empty scope from an empty tree: ${_v:0:200}" fi # The size of what went unread must be stated, or the skip is unfalsifiable in # the other direction: '0 of 1' and '0 of 45' print identically without it. -if printf '%s' "${_v}" | grep -qE 'ADVISORY.*[0-9]+ registration\(s\) carrying [0-9]+ finding\(s\)'; then +if grep -qE 'ADVISORY.*[0-9]+ registration\(s\) carrying [0-9]+ finding\(s\)' <<< "${_v}"; then _ok "gate-61's --full skip states the size of the backlog it did not inspect" else _bad "gate-61's --full skip does not state how many registrations went unread — the advisory sweep is missing, so '0 of 1' and '0 of 45' are typographically identical: ${_v:0:200}" @@ -242,7 +242,7 @@ echo "== arm 3b — FULL file scope WITH a delta base (the new common case) ==" # the claim rather than trust it. _outb="$(gf_run_wrapper "${WORK}/inherited" "${WORK}/log-full-base")" -if printf '%s' "${_outb}" | grep -qE '^\[hydra-gates\] Delta base: [^N]'; then +if grep -qE '^\[hydra-gates\] Delta base: [^N]' <<< "${_outb}"; then _ok "the full-scope run resolved a delta base and NAMED it" else _bad "the full-scope run resolved no delta base though the fixture has refs/remotes/origin/development — arm 3b would then be re-measuring arm 3 and proving nothing" @@ -261,8 +261,8 @@ esac # A reason may name a diff ONLY on a run that computed one. Asserted from the # other side here, so the pair pins both directions. -if printf '%s' "${_vb}" | grep -qF 'the diff against'; then - if printf '%s' "${_outb}" | grep -qE '^\[hydra-gates\] Delta base: [^N]'; then +if grep -qF 'the diff against' <<< "${_vb}"; then + if grep -qE '^\[hydra-gates\] Delta base: [^N]' <<< "${_outb}"; then _ok "gate-61 names the diff it was actually given, on a run that printed that base — a checkable claim, not #347's unfalsifiable one" else _bad ".github#347 IS LIVE BY A NEW ROUTE: gate-61 names a diff on a run that announced no delta base" @@ -272,7 +272,7 @@ fi # The backlog SIZE must be stated here too. This is now the common path, and # without it '0 of 1' and '0 of 45' print identically on every PR in the fleet — # the exact ambiguity the advisory sweep was added to remove on the other path. -if printf '%s' "${_vb}" | grep -qE 'ADVISORY.*[0-9]+ registration\(s\) carrying [0-9]+ finding\(s\)'; then +if grep -qE 'ADVISORY.*[0-9]+ registration\(s\) carrying [0-9]+ finding\(s\)' <<< "${_vb}"; then _ok "gate-61 states the size of the backlog it did not inspect at FULL scope too, not only when there is no base" else _bad "gate-61's full-scope skip does not state how many registrations went unread. This is the common case now, so the ambiguity the advisory sweep removed on the no-base path has simply moved to the path everyone runs: ${_vb:0:200}" @@ -321,7 +321,7 @@ _known_defect "wording (unfiled)" \ # And the legitimate wording must STAY legitimate. _v29="$(gf_verdict "${_out}" 29)" -if printf '%s' "${_v29}" | grep -qF 'intrinsically diff-relative'; then +if grep -qF 'intrinsically diff-relative' <<< "${_v29}"; then _ok "gate-29 declines on --full with an honest reason ('intrinsically diff-relative') — the good pattern" else _bad "gate-29's --full reason changed; it used to state honestly that the run is not diff-scoped. Got: ${_v29:0:140}" @@ -336,7 +336,7 @@ echo "== coverage accounting: NOT APPLICABLE must carry a reason ==" _bare=0 while IFS= read -r _line; do # everything after "NOT APPLICABLE" should be an em-dash + prose - if ! printf '%s' "${_line}" | grep -qE 'NOT APPLICABLE (—|-) .{20,}'; then + if ! grep -qE 'NOT APPLICABLE (—|-) .{20,}' <<< "${_line}"; then echo " bare: ${_line:0:120}" _bare=$((_bare + 1)) fi From f4541cecc4d4e7f0c28573f692821541a2f6eb17 Mon Sep 17 00:00:00 2001 From: WilcoLouwerse Date: Tue, 13 Oct 2026 20:06:15 +0200 Subject: [PATCH 3/3] test(hydra-gates): suppress SC2016 on the remaining PHP fixtures in the gate-3 suite Five single-quoted PHP fixtures in test_gate_3_external_contract_and_tabs.sh lacked the per-assignment SC2016 suppression the first one carries, so the repo-wide ShellCheck job failed on every PR that touches a shell script. The `$` in those strings is PHP source and must not expand. Co-Authored-By: Claude Opus 5.5 --- .../scripts/lib/test_gate_3_external_contract_and_tabs.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hydra-gates/scripts/lib/test_gate_3_external_contract_and_tabs.sh b/hydra-gates/scripts/lib/test_gate_3_external_contract_and_tabs.sh index d39cccd7..6075a6a5 100755 --- a/hydra-gates/scripts/lib/test_gate_3_external_contract_and_tabs.sh +++ b/hydra-gates/scripts/lib/test_gate_3_external_contract_and_tabs.sh @@ -97,6 +97,7 @@ interface LifecycleGuardInterface { }//end interface ' +# shellcheck disable=SC2016 # PHP source: single quotes are REQUIRED _STUB_IFACE_NOPARAM='