From c26e530cdb08db9863815765105e3d53d4ab2711 Mon Sep 17 00:00:00 2001 From: bong-water-water-bong Date: Tue, 10 Nov 2026 18:12:18 -0400 Subject: [PATCH 1/3] bump-hrx: the failure report carries the failing step and the conflicting files #1945's own closing line is the reason this exists: bump-hrx failed on every scheduled run from 2026-10-01 to 2026-10-05 without anyone noticing. The workflow now files an issue so it cannot be silent, and it dedupes while one is open -- both verified, both left alone. What it did NOT do is say what broke: the body was a static template with the run URL and instructions, so the reader was told where to look and never what to find. The failing step's name, the conflicting paths and the SHAs were all in the log the run already had. So the body construction moves into scripts/bump-hrx-report.sh, stdout = the issue body, which makes it testable without running the workflow (this lane cannot edit .github/workflows -- no `workflow` scope; the one-line call site is left as a stated change for whoever has it). Three cases the report must keep apart, because conflating any two of them is how a report stops being read: * files in conflict -- git spells this two ways (CONFLICT (content): Merge conflict in , and CONFLICT (modify/delete): deleted in ...); a report that knows only the first silently lists half the conflict, which the second arm caught during development; * a failure that is NOT a conflict -- must say so rather than print an empty file block, since an empty list reads as "no problem found"; * a log that could not be read -- must say THAT, not "no conflicts", because "nothing conflicted" and "nobody looked" are different facts and only one of them is actionable. Eleven arms in tests/bump_hrx_report_test.sh, verified in both directions: an empty --log, a repeated path (listed once), the modify/delete spelling, a non-conflict log, no log at all, and the usage contract (--run required, unknown flag exits 2). Refs #1945. --- scripts/bump-hrx-report.sh | 67 +++++++++++++++++++++++++++++++++++ tests/bump_hrx_report_test.sh | 54 ++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100755 scripts/bump-hrx-report.sh create mode 100755 tests/bump_hrx_report_test.sh diff --git a/scripts/bump-hrx-report.sh b/scripts/bump-hrx-report.sh new file mode 100755 index 000000000..677db2d10 --- /dev/null +++ b/scripts/bump-hrx-report.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Copyright 2026 bong-water-water-bong +# SPDX-License-Identifier: Apache-2.0 +# +# bump-hrx-report.sh -- build the body of the issue a failed scheduled sync files. +# +# Why this exists (engine#1945): the report step already files an issue so a broken sync cannot sit unnoticed +# for five days, but its body was a static template -- the run URL and instructions, never the failing step or +# the files in conflict. So the reader was told where to look and not what broke. This turns the log the run +# already has into the body, and lives in scripts/ so it is testable without running the workflow. +# +# usage: bump-hrx-report.sh --run [--step ] [--log |-] [--attempt ] +# stdout = the issue body; rc 0 unless an argument is missing. +# --log - reads stdin. No --log means "the log was not available": the body says so rather than claiming +# there were no conflicts, which is the difference between "nothing conflicted" and "nobody looked". +set -uo pipefail + +run="" step="" log="" attempt="" +while [ $# -gt 0 ]; do + case "$1" in + --run) run=${2:?--run needs a URL}; shift 2 ;; + --step) step=${2:?--step needs a name}; shift 2 ;; + --log) log=${2:?--log needs a path or -}; shift 2 ;; + --attempt) attempt=${2:?--attempt needs a number}; shift 2 ;; + -h|--help) sed -n '3,17p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) echo "bump-hrx-report: unknown argument: $1" >&2; exit 2 ;; + esac +done +[ -n "$run" ] || { echo "bump-hrx-report: --run is required" >&2; exit 2; } + +text="" +if [ "$log" = "-" ]; then + text=$(cat) +elif [ -n "$log" ]; then + if [ -r "$log" ]; then text=$(cat "$log"); else + echo "bump-hrx-report: cannot read log: $log" >&2; exit 2 + fi +fi + +# git names every conflicting path in a line of the form "CONFLICT (content): Merge conflict in "; +# "CONFLICT (modify/delete)" and friends use the same prefix. Paths can repeat across retries, so dedupe. +# git spells the same event two ways, and a report that knows only one of them silently lists half the conflict: +# CONFLICT (content): Merge conflict in +# CONFLICT (modify/delete): deleted in and modified in +# CONFLICT (rename/delete): renamed ... (path is the source side) +conflicts=$(printf '%s\n' "$text" \ + | sed -n -e 's/.*CONFLICT ([^)]*): Merge conflict in \(.*\)$/\1/p' \ + -e 's/.*CONFLICT ([^)]*): \(.*\) \(deleted\|renamed\) in .*/\1/p' \ + | sort -u) + +printf 'The bump-hrx run failed: %s\n' "$run" +if [ -n "$step" ]; then + printf '\n**Failing step:** `%s`' "$step" + [ -n "$attempt" ] && printf ' (attempt %s)' "$attempt" + printf '\n' +fi + +if [ -n "$conflicts" ]; then + printf '\n**Conflicting files** (from the log):\n\n```\n%s\n```\n' "$conflicts" + printf '\nResolve these by hand on `1bit/hrx-vulkan-patched` or on `1bit-MONSTER/hrx-system` `1bit/main`, then re-run the workflow.\n' +elif [ -z "$log" ]; then + printf '\n**The log was not available to this report**, so the conflicting files are not listed here. Open the run above and read the failing step.\n' +else + printf '\n**No conflicting files were named in the log** -- this failure is not a merge conflict. Open the run above and read the failing step.\n' +fi + +printf '\nWhy this report exists: bump-hrx failed on every scheduled run from 2026-10-01 to 2026-10-05 without anyone\nnoticing, and the HRX pin silently froze. A failed run files this issue; it is deduped while open.\n' diff --git a/tests/bump_hrx_report_test.sh b/tests/bump_hrx_report_test.sh new file mode 100755 index 000000000..98d360726 --- /dev/null +++ b/tests/bump_hrx_report_test.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Copyright 2026 bong-water-water-bong +# SPDX-License-Identifier: Apache-2.0 +# +# bump_hrx_report_test.sh -- arms for scripts/bump-hrx-report.sh (engine#1945). +# +# The three cases a failure report must distinguish, because conflating any two of them is how a report stops +# being read: files in conflict, a failure that is not a conflict, and a report that could not read the log. +# +# usage: bump_hrx_report_test.sh +set -uo pipefail + +S=${1:?usage: bump_hrx_report_test.sh } +[ -x "$S" ] || { echo "not executable: $S"; exit 1; } +fail=0 +ok() { echo "ok $1"; } +bad() { echo "FAIL $1"; fail=1; } + +# 1. A merge conflict: git's two shapes (content and modify/delete), one path repeated as a retry would. +got=$("$S" --run https://example/runs/1 --log - --step "Sync the fork and merge AMD's pin into our line" <<'LOG' +Auto-merging ggml/src/ggml-hrx/ggml-hrx.cpp +CONFLICT (content): Merge conflict in ggml/src/ggml-hrx/ggml-hrx.cpp +CONFLICT (modify/delete): drivers/fake.c deleted in HEAD and modified in abc123 +CONFLICT (content): Merge conflict in ggml/src/ggml-hrx/ggml-hrx.cpp +LOG +) +[[ $got == *"ggml/src/ggml-hrx/ggml-hrx.cpp"* ]] && ok "a conflict names the file" || bad "a conflict names the file" +[[ $got == *"drivers/fake.c"* ]] && ok "the modify/delete form is caught too" || bad "the modify/delete form is caught too" +[[ $(printf '%s' "$got" | grep -c 'ggml-hrx/ggml-hrx.cpp') -ge 1 ]] || bad "path present" +n=$(printf '%s\n' "$got" | sed -n '/^```$/,/^```$/p' | grep -c 'ggml/src/ggml-hrx/ggml-hrx.cpp') +[ "$n" = 1 ] && ok "a repeated path is listed once" || bad "a repeated path is listed once (got $n)" +[[ $got == *"Failing step"*"Sync the fork"* ]] && ok "the failing step is in the body" || bad "the failing step is in the body" + +# 2. A failure that is NOT a conflict must say so -- an empty list would read as "no problem found". +got=$("$S" --run https://example/runs/2 --log - --step "Merge AMD's hrx-system pin into our line" <<'LOG' +error: could not apply 1a2b3c4... some commit +fatal: Exiting because of an unresolved dispute +LOG +) +[[ $got == *"not a merge conflict"* ]] && ok "a non-conflict failure says so" || bad "a non-conflict failure says so" +[[ $got != *'```'* ]] && ok "and prints no empty file block" || bad "and prints no empty file block" + +# 3. No log at all: the body must still render and must not claim there were no conflicts. +got=$("$S" --run https://example/runs/3 --step "Sync") +[[ $got == *"log was not available"* ]] && ok "a missing log is stated, not implied" || bad "a missing log is stated, not implied" +[[ $got != *"not a merge conflict"* ]] && ok "a missing log is not reported as a non-conflict" || bad "a missing log is not reported as a non-conflict" +[[ $got == *"https://example/runs/3"* ]] && ok "the run URL is always present" || bad "the run URL is always present" + +# 4. Contract: --run is required, an unknown flag is a usage error, not a silent empty body. +"$S" > /dev/null 2>&1; [ $? = 2 ] && ok "a missing --run exits 2" || bad "a missing --run exits 2" +"$S" --run x --nope > /dev/null 2>&1; [ $? = 2 ] && ok "an unknown argument exits 2" || bad "an unknown argument exits 2" + +[ $fail = 0 ] && echo "all bump-hrx-report arms passed" +exit $fail From 7ba389cc1f7521343ebf2edc05f400ab5afbf854 Mon Sep 17 00:00:00 2001 From: bong-water-water-bong Date: Tue, 10 Nov 2026 18:40:53 -0400 Subject: [PATCH 2/3] bump-hrx-report: the full Apache notice in the header (copyright.py --check) --- scripts/bump-hrx-report.sh | 11 +++++++++++ tests/bump_hrx_report_test.sh | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/scripts/bump-hrx-report.sh b/scripts/bump-hrx-report.sh index 677db2d10..a75443953 100755 --- a/scripts/bump-hrx-report.sh +++ b/scripts/bump-hrx-report.sh @@ -2,6 +2,17 @@ # Copyright 2026 bong-water-water-bong # SPDX-License-Identifier: Apache-2.0 # +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # bump-hrx-report.sh -- build the body of the issue a failed scheduled sync files. # # Why this exists (engine#1945): the report step already files an issue so a broken sync cannot sit unnoticed diff --git a/tests/bump_hrx_report_test.sh b/tests/bump_hrx_report_test.sh index 98d360726..52d8cca8e 100755 --- a/tests/bump_hrx_report_test.sh +++ b/tests/bump_hrx_report_test.sh @@ -2,6 +2,17 @@ # Copyright 2026 bong-water-water-bong # SPDX-License-Identifier: Apache-2.0 # +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # bump_hrx_report_test.sh -- arms for scripts/bump-hrx-report.sh (engine#1945). # # The three cases a failure report must distinguish, because conflating any two of them is how a report stops From c379c59f7025710de2a816926994d62400821717 Mon Sep 17 00:00:00 2001 From: bong-water-water-bong Date: Tue, 10 Nov 2026 19:00:50 -0400 Subject: [PATCH 3/3] tests: register bump_hrx_report, so the ratchet that caught it can also run it (engine#1945) --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86cb25cf9..8db5e62a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,6 +200,7 @@ add_test(NAME serve_hangup COMMAND ${CMAKE_SOURCE_DIR}/tests/serve_hangup_test.s # engine#1945: scripts/bump-hrx-sync.sh tells AMD's own commit from a line AMD rebased apart from a commit that # is not AMD's. Local git repositories only: no network, no GPU. add_test(NAME bump_hrx_sync COMMAND bash ${CMAKE_SOURCE_DIR}/tests/bump_hrx_sync_test.sh ${CMAKE_SOURCE_DIR}/scripts/bump-hrx-sync.sh) +add_test(NAME bump_hrx_report COMMAND bash ${CMAKE_SOURCE_DIR}/tests/bump_hrx_report_test.sh ${CMAKE_SOURCE_DIR}/scripts/bump-hrx-report.sh) add_test(NAME metrics_serve COMMAND ${CMAKE_SOURCE_DIR}/tests/metrics_serve.sh $) # serve --print-backend: the llama-server Lemonade starts itself, one hop (docs/serve.md): no GPU. add_test(NAME print_backend COMMAND ${CMAKE_SOURCE_DIR}/tests/print_backend.sh $)