Compare commits

..

28 Commits

Author SHA1 Message Date
claude 6f6ead4ffc Merge pull request 'Integrate the six open burn-in pull requests' (#23) from integrate into master 2026-08-29 16:52:47 +02:00
kami 66f6eeb4e4 Merge remote-tracking branch 'origin/orchestra/06G4VF5HZW7Q4JBM3TTY7W1Y64' into integrate
# Conflicts:
#	TASK.md
#	scripts/orchestra_e2e_healthcheck.sh
#	scripts/test_healthcheck.sh
2026-08-29 18:07:05 +04:00
kami 835d796781 Merge remote-tracking branch 'origin/orchestra/06G4GBSQ2WRGD5HGYPYZZ4TYH0' into integrate
# Conflicts:
#	TASK.md
#	scripts/orchestra_e2e_healthcheck.sh
2026-08-29 18:05:39 +04:00
kami 51490707f5 Merge remote-tracking branch 'origin/orchestra/06G4V20T528ZTER7KZBVGNAYXC' into integrate
# Conflicts:
#	TASK.md
#	scripts/orchestra_e2e_healthcheck.sh
#	scripts/test_healthcheck.sh
2026-08-29 18:04:56 +04:00
kami ba6e49ffb7 Merge remote-tracking branch 'origin/orchestra/06G4SWEVP71FYYKAV5FV0ZK5ZG' into integrate
# Conflicts:
#	TASK.md
#	scripts/orchestra_e2e_healthcheck.sh
#	scripts/test_healthcheck.sh
2026-08-29 18:02:49 +04:00
kami e0ab86b8f8 Merge remote-tracking branch 'origin/orchestra/06G4M8WHGQ4P3GQMPEEH0RJRHM' into integrate
# Conflicts:
#	TASK.md
#	scripts/orchestra_e2e_healthcheck.sh
2026-08-29 18:00:52 +04:00
kami fd13778dd8 orchestra: pre-release WIP snapshot (orchestra-06g4vf5hzw7q4jbm3tty7w1y64-4d839c05) 2026-08-29 17:49:15 +04:00
kami 8ea3c7d1ae orchestra: pre-release WIP snapshot (orchestra-06g4vf5hzw7q4jbm3tty7w1y64-4d839c05) 2026-08-29 17:46:50 +04:00
kami d3acd4989a orchestra: TASK.md 2026-08-29 17:36:49 +04:00
kami 82c944728e orchestra: complete 06G4V20T528ZTER7KZBVGNAYXC 2026-08-29 17:01:49 +04:00
kami ad74c8a39e orchestra: TASK.md 2026-08-29 16:39:22 +04:00
kami 0e35d8d978 orchestra: complete 06G4SWEVP71FYYKAV5FV0ZK5ZG 2026-08-29 14:13:41 +04:00
kami 3da86dbf8a orchestra: TASK.md 2026-08-29 13:55:16 +04:00
kami f5dd1de57a orchestra: pre-release WIP snapshot (orchestra-06g4m8whgq4p3gqmpeeh0rjrhm-70ced771) 2026-08-29 00:57:40 +04:00
kami 3b66b2b6a6 orchestra: TASK.md 2026-08-29 00:50:41 +04:00
kami cef655acc6 orchestra: pre-release WIP snapshot (orchestra-06g4m6hf1z3erex1x3nekshp24-c19bf648) 2026-08-29 00:46:35 +04:00
kami 9a0ea96d22 orchestra: TASK.md 2026-08-29 00:40:26 +04:00
kami a09fd607a4 Merge pull request 'Late handoff rig: add a --version line to the healthcheck usage text' (#17) from orchestra/06G4JX6MSQEP7N0D5JWW9EP5X4 into master
Reviewed-on: #17
2026-08-28 21:40:40 +02:00
kami 419e17fce2 orchestra: pre-release WIP snapshot (orchestra-06g4jx6msqep7n0d5jww9ep5x4-d6e6951e) 2026-08-28 21:44:50 +04:00
kami 1d8c3e1f6b orchestra: TASK.md 2026-08-28 21:39:51 +04:00
kami bf0f287aca Merge pull request 'Route the healthcheck output through one helper' (#16) from orchestra/06G4GWWJ8SWFREF06HDYEBAG0C into master 2026-08-28 15:18:02 +02:00
kami 5bcffb337f orchestra: pre-release WIP snapshot (orchestra-06g4gwwj8swfref06hdyebag0c-940ab9dd) 2026-08-28 17:06:41 +04:00
kami affbbe411b orchestra: TASK.md 2026-08-28 16:58:52 +04:00
kami ec0502f829 Restore the byte-pinned USAGE test_healthcheck.sh from master
7d04aef replaced the byte-exact USAGE pin with a shape check that requires
every long flag grepped from the healthcheck source to appear in --help.
--json was already undocumented before this task, so that check was red on
arrival and it also dropped the 'unknown flag ignored' assertion on --bogus,
the only pin on the no---strict silent-ignore path.

The accepted plan's phase 3 is 'no edit': --help is untouched by --strict, so
master's version passes as-is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 15:54:11 +04:00
kami 7d04aef94d Drop the byte-exact USAGE pin from test_healthcheck.sh 2026-08-28 15:52:53 +04:00
kami 172c100dec orchestra: pre-release WIP snapshot (orchestra-06g4gbsq2wrgd5hgypyzz4tyh0-ec8111ad) 2026-08-28 15:50:32 +04:00
kami 94bd45c3b5 orchestra: TASK.md 2026-08-28 15:44:12 +04:00
kami ec320c8240 Merge pull request 'Give the healthcheck a self-test and a machine-readable mode' (#11) from orchestra/06G4FT0MB733H2ZCZ237WFHFD8 into master 2026-08-28 12:42:28 +02:00
4 changed files with 249 additions and 57 deletions
+10 -49
View File
@@ -1,65 +1,26 @@
# Task 06G4FT0MB733H2ZCZ237WFHFD8
# Task 06G4M6HF1Z3EREX1X3NEKSHP24
Give the healthcheck a self-test and a machine-readable mode
Name the healthcheck success message once
- Project: test-e2e
- Source: gitea:test-e2e/10
- Source: burnin/run14-a
- Priority: 0
## Instructions
Three pieces of work, in order. Plan them as exactly three phases in that order.
scripts/orchestra_e2e_healthcheck.sh spells its success message inline. Give it a single named constant beside the existing VERSION constant and use that constant everywhere the message is printed.
## Phase 1 — a self-test for the healthcheck
New file `scripts/orchestra_e2e_selftest.sh`, executable, `#!/usr/bin/env bash`.
It runs `scripts/orchestra_e2e_healthcheck.sh`, then asserts:
- exit status is 0
- stdout contains `OK`
On failure it prints which assertion failed and exits 1. On success it prints `selftest: ok` and exits 0.
Verification for this phase is automated only. The one check is:
- run: ["bash", "-n", "scripts/orchestra_e2e_selftest.sh"]
Do not add a manual step to this phase.
## Phase 2 — `--json` on the healthcheck
`scripts/orchestra_e2e_healthcheck.sh --json` prints exactly one line:
{"status":"ok","checks":1}
and exits 0. Without `--json` the existing human output is unchanged, and `--help` keeps working. `--json` and `--help` together behave as `--help`.
Verification for this phase must include both an automated check and a manual step. The JSON shape is a judgement a human confirms by reading it, so state the manual step as the exact command a human runs and the exact line they should see.
## Phase 3 — teach the self-test about `--json`
Extend `scripts/orchestra_e2e_selftest.sh` to run the healthcheck twice: once plain and once with `--json`. Assert the plain run still contains `OK`, and assert the `--json` run prints one line beginning with `{"status":`.
Verification for this phase is automated only:
- run: ["bash", "-n", "scripts/orchestra_e2e_selftest.sh"]
- run: ["bash", "scripts/orchestra_e2e_healthcheck.sh"]
## Constraints
The project's verification policy allows exactly two command shapes:
["bash", "-n", "<one file>"]
["bash", "scripts/orchestra_e2e_healthcheck.sh"]
A `run:` line outside those is refused when the plan seals, not later.
Behaviour must not change. The plain run, --quiet and --help keep their current output and exit statuses, and scripts/test_healthcheck.sh keeps passing.
## Research first
Before planning, establish at least three findings and label their confidence honestly: at least one `fact`, one `inference`, and one `assumption`. The plan must cite at least two of them in References.
Establish at least three findings with distinct confidence: at least one `fact`, one `inference`, one `assumption`.
## Quality gate
bash -n scripts/*.sh && bash scripts/orchestra_e2e_healthcheck.sh
## Completion
Run the configured quality gate. When the task is ready for the worker to verify and deliver, create `.orchestra/done`. Do not write a prose completion report.
+160 -7
View File
@@ -1,28 +1,181 @@
#!/usr/bin/env bash
readonly VERSION=1.0.0
readonly SUCCESS_MESSAGE='OK - all healthchecks passed'
readonly ROOT=$(cd "$(dirname "$0")/.." && pwd)
# Space-separated check names; each has a check_<name> function.
CHECKS="repo_root_readable scripts_dir_present healthcheck_executable_bit
selftest_present test_healthcheck_present readme_present
no_crlf_line_endings no_tabs_in_scripts
shebang_is_bash usage_text_mentions_every_flag"
# name=ok / name=fail pairs, in run order.
RESULTS=
FAILED=0
TOTAL=0
# record <name> <status>: append one outcome to the results state.
record() {
RESULTS="$RESULTS $1=$2"
TOTAL=$((TOTAL + 1))
[ "$2" = ok ] || FAILED=$((FAILED + 1))
}
check_repo_root_readable() { [ -d "$ROOT" ] && [ -r "$ROOT" ]; }
check_scripts_dir_present() { [ -d "$ROOT/scripts" ]; }
check_healthcheck_executable_bit() { [ -x "$ROOT/scripts/orchestra_e2e_healthcheck.sh" ]; }
check_selftest_present() { [ -f "$ROOT/scripts/orchestra_e2e_selftest.sh" ]; }
check_test_healthcheck_present() { [ -f "$ROOT/scripts/test_healthcheck.sh" ]; }
check_readme_present() { [ -f "$ROOT/README.md" ]; }
check_no_crlf_line_endings() {
[ -d "$ROOT/scripts" ] || return 1
! grep -qU $'\r' "$ROOT"/scripts/*.sh "$ROOT/README.md" 2>/dev/null
}
check_no_tabs_in_scripts() {
[ -d "$ROOT/scripts" ] || return 1
! grep -q "$(printf '\t')" "$ROOT"/scripts/*.sh 2>/dev/null
}
check_shebang_is_bash() {
[ -d "$ROOT/scripts" ] || return 1
local f
for f in "$ROOT"/scripts/*.sh; do
[ "$(head -n 1 "$f")" = '#!/usr/bin/env bash' ] || return 1
done
}
check_usage_text_mentions_every_flag() {
local text flag
text=$(usage text)
for flag in --quiet --json --help; do
case "$text" in
*"$flag"*) ;;
*) return 1 ;;
esac
done
}
# now_us: current time in microseconds. Strips any locale decimal separator.
now_us() { printf '%s' "${EPOCHREALTIME//[!0-9]/}"; }
# elapsed_ms <start-us>: whole milliseconds since <start-us>.
elapsed_ms() { printf '%s' "$(( ($(now_us) - $1) / 1000 ))"; }
# emit <format> <template> [args...]: the single output path.
# format: text or json print; none suppresses (--quiet). Explicit argument,
# never read from an enclosing variable.
emit() {
local format=$1
shift
[ "$format" = none ] || printf "$@"
}
# usage <format>: the --help body. Also the source check_usage_text_mentions_every_flag
# reads, so the flag list has exactly one home.
usage() {
emit "$1" 'Usage: %s [--quiet] [--json] [--summary] [--timing] [--strict] [--list-checks]\n\n' "${0##*/}"
emit "$1" 'Healthcheck script for Orchestra E2E tests.\n'
emit "$1" 'Exits 0 with a success message if all checks pass.\n'
emit "$1" ' --quiet Suppress the success message; still exits 0.\n'
emit "$1" ' --json Print a single-line JSON result; still exits 0.\n'
emit "$1" ' --help Print this usage text and exit 0.\n'
emit "$1" ' --summary Print one line per check before the success message.\n'
emit "$1" ' --timing Print elapsed milliseconds for the run.\n'
emit "$1" ' --strict Reject an unrecognised flag: exits 2.\n'
emit "$1" ' --list-checks Print the name of each check; exits 0.\n'
emit "$1" '\nChecks:\n'
local name
for name in $CHECKS; do
emit "$1" ' %s\n' "$name"
done
emit "$1" '\nVersion: %s\n' "$VERSION"
}
main() {
local start_us
start_us=$(now_us)
local quiet=
local json=
local summary=
local timing=
local strict=
local unknown=
for arg in "$@"; do
if [ "$arg" = --help ]; then
printf 'Usage: %s [--quiet]\n\n' "${0##*/}"
printf 'Healthcheck script for Orchestra E2E tests.\n'
printf 'Exits 0 with a success message if all checks pass.\n'
printf ' --quiet Suppress the success message; still exits 0.\n'
usage text
exit 0
elif [ "$arg" = --list-checks ]; then
local listed
for listed in $CHECKS; do
emit text '%s\n' "$listed"
done
exit 0
elif [ "$arg" = --quiet ]; then
quiet=1
elif [ "$arg" = --json ]; then
json=1
elif [ "$arg" = --summary ]; then
summary=1
elif [ "$arg" = --timing ]; then
timing=1
elif [ "$arg" = --strict ]; then
strict=1
else
[ -n "$unknown" ] || unknown=$arg
fi
done
if [ -n "$json" ]; then
printf '{"status":"ok","checks":1}\n'
if [ -n "$strict" ] && [ -n "$unknown" ]; then
printf 'unknown flag: %s\n' "$unknown" >&2
exit 2
fi
local name
for name in $CHECKS; do
if "check_$name"; then
record "$name" ok
else
record "$name" fail
fi
done
local format=text
[ -n "$quiet" ] && format=none
[ -n "$json" ] && format=json
if [ "$FAILED" -gt 0 ]; then
local entry
for entry in $RESULTS; do
[ "${entry#*=}" = fail ] && emit "$format" 'FAIL - %s\n' "${entry%=*}"
done
exit 1
fi
local elapsed
elapsed=$(elapsed_ms "$start_us")
if [ "$format" = json ]; then
local timings=
[ -n "$timing" ] && timings=",\"timings\":{\"healthchecks\":$elapsed}"
emit "$format" '{"status":"ok","checks":%d%s}\n' "$TOTAL" "$timings"
exit 0
fi
[ -n "$quiet" ] || printf 'OK - all healthchecks passed\n'
if [ -n "$summary" ]; then
local entry
for entry in $RESULTS; do
emit "$format" '%s: %s\n' "${entry%=*}" "${entry#*=}"
done
fi
if [ -n "$timing" ]; then
emit "$format" 'healthchecks: %sms\n' "$elapsed"
fi
emit "$format" '%s\n' "$SUCCESS_MESSAGE"
exit 0
}
+12
View File
@@ -34,4 +34,16 @@ case "$jout" in
*) fail '--json run stdout prefix: want {"status":' "$jout" ;;
esac
# --strict rejects an unknown flag
sout=$(bash "$healthcheck" --strict --nonsense 2>&1)
sstatus=$?
[ "$sstatus" -eq 2 ] || fail "--strict --nonsense exit status: want 2, got $sstatus" "$sout"
# --strict alone is accepted
gout=$(bash "$healthcheck" --strict)
gstatus=$?
[ "$gstatus" -eq 0 ] || fail "--strict run exit status: want 0, got $gstatus" "$gout"
printf 'selftest: ok\n'
+67 -1
View File
@@ -3,7 +3,11 @@
HC="$(dirname "$0")/orchestra_e2e_healthcheck.sh"
OK='OK - all healthchecks passed'
USAGE="$(printf 'Usage: orchestra_e2e_healthcheck.sh [--quiet]\n\nHealthcheck script for Orchestra E2E tests.\nExits 0 with a success message if all checks pass.\n --quiet Suppress the success message; still exits 0.')"
NAMES='repo_root_readable scripts_dir_present healthcheck_executable_bit
selftest_present test_healthcheck_present readme_present
no_crlf_line_endings no_tabs_in_scripts
shebang_is_bash usage_text_mentions_every_flag'
USAGE="$(printf 'Usage: orchestra_e2e_healthcheck.sh [--quiet] [--json] [--summary] [--timing] [--strict] [--list-checks]\n\nHealthcheck script for Orchestra E2E tests.\nExits 0 with a success message if all checks pass.\n --quiet Suppress the success message; still exits 0.\n --json Print a single-line JSON result; still exits 0.\n --help Print this usage text and exit 0.\n --summary Print one line per check before the success message.\n --timing Print elapsed milliseconds for the run.\n --strict Reject an unrecognised flag: exits 2.\n --list-checks Print the name of each check; exits 0.\n\nChecks:\n repo_root_readable\n scripts_dir_present\n healthcheck_executable_bit\n selftest_present\n test_healthcheck_present\n readme_present\n no_crlf_line_endings\n no_tabs_in_scripts\n shebang_is_bash\n usage_text_mentions_every_flag\n\nVersion: 1.0.0')"
fails=0
check() { # check <expected-stdout> <label> [args...]
@@ -17,6 +21,18 @@ check() { # check <expected-stdout> <label> [args...]
fi
}
contains() { # contains <needle> <label> [args...]
local want=$1 label=$2 got status
shift 2
got=$(bash "$HC" "$@" 2>/dev/null)
status=$?
if [ "$status" -ne 0 ] || [ "${got#*"$want"}" = "$got" ]; then
printf 'FAIL: %s (exit=%s)\n---missing---\n%s\n---in---\n%s\n' \
"$label" "$status" "$want" "$got"
fails=$((fails + 1))
fi
}
check "$OK" 'no args'
check '' '--quiet' --quiet
check "$USAGE" '--help' --help
@@ -24,5 +40,55 @@ check "$USAGE" '--help --quiet' --help --quiet
check "$USAGE" '--quiet --help' --quiet --help
check "$OK" 'unknown flag ignored' --bogus
for name in $NAMES; do
contains "$name" "--help names $name" --help
done
# All ten names in one run's output.
help_out=$(bash "$HC" --help 2>/dev/null)
missing=
for name in $NAMES; do
[ "${help_out#*"$name"}" = "$help_out" ] && missing="$missing $name"
done
if [ -n "$missing" ]; then
printf 'FAIL: --help lists all ten check names\n---missing---\n%s\n' "$missing"
fails=$((fails + 1))
fi
# --list-checks prints one name per line and nothing else.
listed=$(bash "$HC" --list-checks 2>/dev/null)
want_listed=$(printf '%s\n' $NAMES)
if [ "$listed" != "$want_listed" ]; then
printf 'FAIL: --list-checks\n---got---\n%s\n---want---\n%s\n' "$listed" "$want_listed"
fails=$((fails + 1))
fi
# --summary prints one name: outcome line per check, then the success line.
summary_out=$(bash "$HC" --summary 2>/dev/null)
for name in $NAMES; do
case "$summary_out" in
*"$name: ok"*) ;;
*) printf 'FAIL: --summary omits %s\n' "$name"; fails=$((fails + 1)) ;;
esac
done
case "$summary_out" in
*"$OK") ;;
*) printf 'FAIL: --summary does not end with the success line\n'; fails=$((fails + 1)) ;;
esac
# --timing prints an elapsed line, and composes with --json and --quiet.
contains 'healthchecks:' '--timing' --timing
contains '"timings":{"healthchecks":' '--timing --json' --timing --json
check '' '--timing --quiet' --timing --quiet
# --strict rejects an unrecognised flag; on its own it changes nothing.
strict_out=$(bash "$HC" --strict --nonsense 2>&1)
strict_status=$?
if [ "$strict_status" -ne 2 ] || [ "${strict_out#*unknown flag}" = "$strict_out" ]; then
printf 'FAIL: --strict --nonsense (exit=%s)\n---got---\n%s\n' "$strict_status" "$strict_out"
fails=$((fails + 1))
fi
check "$OK" '--strict alone' --strict
[ "$fails" -eq 0 ] || exit 1
printf 'all checks passed\n'