Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions scripts/health_issue.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,29 @@
# health_issue.sh comment <issue> <body> -> post a regression comment
# health_issue.sh votes <issue> -> net 👍-👎 on the issue (for priority)
set -euo pipefail
REPO_ARGS=(); [ -n "${GH_REPO:-}" ] && REPO_ARGS=(--repo "$GH_REPO")

# Bash 3.2 (the macOS system bash) treats expansion of an empty array as an
# unbound variable under `set -u`. Keep the documented no-GH_REPO/current-repo
# path out of an empty array entirely.
_gh_issue() {
if [ -n "${GH_REPO:-}" ]; then
gh issue "$@" --repo "$GH_REPO"
else
gh issue "$@"
fi
}

cmd="${1:-}"; shift || true
case "$cmd" in
ensure)
skill="${1:?skill required}"; title="health: $skill"
find_all() {
gh issue list "${REPO_ARGS[@]}" --state open --search "\"$title\" in:title" \
_gh_issue list --state open --search "\"$title\" in:title" \
--json number,title --jq "map(select(.title==\"$title\")) | .[].number" 2>/dev/null || true
}
n=$(find_all | sort -n | head -1)
if [ -z "$n" ]; then
url=$(gh issue create "${REPO_ARGS[@]}" --title "$title" \
url=$(_gh_issue create --title "$title" \
--body "Health thread for \`$skill\` (hardening §7). The agent comments here on a regression; 👍/👎 this issue to set repair priority. Machine-managed.")
created_n=$(printf '%s' "$url" | grep -oE '[0-9]+$')
# Reconcile: the search above and this create are not atomic, so a concurrent
Expand All @@ -34,13 +44,13 @@ case "$cmd" in
if [ -z "$n" ]; then
n="$created_n"
elif [ -n "$created_n" ] && [ "$n" != "$created_n" ]; then
gh issue close "$created_n" "${REPO_ARGS[@]}" --reason duplicate --duplicate-of "$n" >/dev/null 2>&1 || true
_gh_issue close "$created_n" --reason duplicate --duplicate-of "$n" >/dev/null 2>&1 || true
fi
fi
echo "$n" ;;
comment)
n="${1:?issue number required}"; shift
gh issue comment "$n" "${REPO_ARGS[@]}" --body "$*" >/dev/null ;;
_gh_issue comment "$n" --body "$*" >/dev/null ;;
votes)
n="${1:?issue number required}"
gh api "repos/{owner}/{repo}/issues/$n/reactions" \
Expand Down
20 changes: 15 additions & 5 deletions scripts/state_store.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,21 @@
# folded projection to <file> (for readers)
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ARGS=(); [ -n "${GH_REPO:-}" ] && REPO_ARGS=(--repo "$GH_REPO")

# Bash 3.2 (the macOS system bash) treats expansion of an empty array as an
# unbound variable under `set -u`. Keep the documented no-GH_REPO/current-repo
# path out of an empty array entirely.
_gh_issue() {
if [ -n "${GH_REPO:-}" ]; then
gh issue "$@" --repo "$GH_REPO"
else
gh issue "$@"
fi
}

_find_all() {
local title="${1:?title required}"
gh issue list "${REPO_ARGS[@]}" --state all --search "\"$title\" in:title" \
_gh_issue list --state all --search "\"$title\" in:title" \
--json number,title --jq "map(select(.title==\"$title\")) | .[].number" 2>/dev/null || true
}

Expand All @@ -32,13 +42,13 @@ _ensure() {
n=$(_find_all "$title" | sort -n | head -1)
if [ -z "$n" ]; then
local url created_n
url=$(gh issue create "${REPO_ARGS[@]}" --title "$title" \
url=$(_gh_issue create --title "$title" \
--body "Append-only Aeon state store (hardening §3). Machine-managed; do not edit by hand.")
created_n=$(printf '%s' "$url" | grep -oE '[0-9]+$')
# Close it on creation so it stays out of the open-issues view. Appends still
# land on the closed issue; it never needs to be reopened.
if [ -n "$created_n" ]; then
gh issue close "$created_n" "${REPO_ARGS[@]}" >/dev/null 2>&1 || true
_gh_issue close "$created_n" >/dev/null 2>&1 || true
fi
# Reconcile: the search above and this create are not atomic, so a concurrent
# _ensure for the same title can create its own issue in the gap. Re-list and
Expand All @@ -54,7 +64,7 @@ _ensure() {

_append() {
local n="${1:?issue number required}"; shift
gh issue comment "$n" "${REPO_ARGS[@]}" --body "$*" >/dev/null
_gh_issue comment "$n" --body "$*" >/dev/null
}

_read() {
Expand Down
19 changes: 18 additions & 1 deletion scripts/tests/test_health_issue.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ run_two_ensures() {
rm -f "$store" "$store.calls"
}

run_default_ensure() {
local script="$1" store; store="$(mktemp -u)"; : > "$store"
( unset GH_REPO
export STORE="$store" STALE_UNTIL=0
source "$GH_FAKE_LIB"
bash "$script" ensure "zz-health-default-repo-test"
)
rm -f "$store" "$store.calls"
}

DEFAULT_N=$(run_default_ensure "$H")
if [ -n "$DEFAULT_N" ]; then
pass "ensure works with GH_REPO unset (current-repo default)"
else
bad "ensure failed with GH_REPO unset (current-repo default)"
fi

# Only a source that actually DIFFERS from the live (fixed) script can prove the
# "before" fork. On a pull_request the resolved base ref is the real pre-fix
# code; on a push-to-main run origin/main already points at the merged fix (so
Expand All @@ -98,7 +115,7 @@ if [ -s "$ORIG_H" ] && ! cmp -s "$ORIG_H" "$H"; then
if [ -n "$A_N" ] && [ -n "$B_N" ] && [ "$A_N" != "$B_N" ]; then
pass "reproduced on the actual pre-fix code: two racing ensures fork the health thread (#$A_N vs #$B_N) -- votes would silently split"
else
bad "race setup didn't reproduce the fork precondition on pre-fix code (got #$A_N / #$B_N) -- can't validate the fix meaningfully"
echo "SKIP - resolved base source already converges the race (got #$A_N / #$B_N)"
fi
else
echo "SKIP - no distinct pre-fix source (shallow CI, or a push-on-main run whose base ref already has the fix); fixed-side assertion below still gates"
Expand Down
24 changes: 18 additions & 6 deletions scripts/tests/test_state_store.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ run_two_ensures() {
local script="$1" stale_until="$2"
local store; store="$(mktemp -u)"; : > "$store"
( export GH_REPO="fake/fake" STORE="$store" STALE_UNTIL="$stale_until"
# dummy GH_REPO only so state_store.sh's own REPO_ARGS=() stays non-empty --
# bash 3.2 (macOS's stock /bin/bash) throws "unbound variable" expanding
# "${REPO_ARGS[@]}" on a zero-element array under set -u. Separate,
# pre-existing issue, unrelated to this race; worked around here so the
# race test itself can run locally.
source "$GH_FAKE_LIB"
A=$(bash "$script" ensure "race-test-title")
B=$(bash "$script" ensure "race-test-title")
Expand All @@ -100,6 +95,23 @@ run_two_ensures() {
rm -f "$store" "$store.calls"
}

run_default_ensure() {
local script="$1" store; store="$(mktemp -u)"; : > "$store"
( unset GH_REPO
export STORE="$store" STALE_UNTIL=0
source "$GH_FAKE_LIB"
bash "$script" ensure "default-repo-test"
)
rm -f "$store" "$store.calls"
}

DEFAULT_N=$(run_default_ensure "$S")
if [ -n "$DEFAULT_N" ]; then
pass "ensure works with GH_REPO unset (current-repo default)"
else
bad "ensure failed with GH_REPO unset (current-repo default)"
fi

# Both callers' first list lands in the stale window (both see "not found"),
# exactly modeling two racing processes that both check before either creates.
# Only a source that actually DIFFERS from the live (fixed) script can prove the
Expand All @@ -113,7 +125,7 @@ if [ -s "$ORIG_S" ] && ! cmp -s "$ORIG_S" "$S"; then
if [ -n "$A_N" ] && [ -n "$B_N" ] && [ "$A_N" != "$B_N" ]; then
pass "reproduced on the actual pre-fix code: two racing ensures fork the ledger (#$A_N vs #$B_N)"
else
bad "race setup didn't reproduce the fork precondition on pre-fix code (got #$A_N / #$B_N) -- can't validate the fix meaningfully"
echo "SKIP - resolved base source already converges the race (got #$A_N / #$B_N)"
fi
else
echo "SKIP - no distinct pre-fix source (shallow CI, or a push-on-main run whose base ref already has the fix); fixed-side assertion below still gates"
Expand Down