ceremony/lib
cndgrr 13e8f54d60 fix(issueflow): a failed read never reaches a decision function
`gh api` prints a 5xx response body to stdout AND exits non-zero, and
GitHub's 5xx body is a JSON object. Inside the per-issue subshell that
payload passed `has("pull_request") | not`, emptied `.labels[]`, and
`queue_decision` — correct on the input it was handed — wrote
`needs-triage` onto a healthy epic. The run then logged `reconciled.`
and exited 0 (crew#329, #247).

errexit could not have caught it: a command whose status is tested by
`||` runs with errexit suppressed, and the suppression extends through
the whole subshell body, so the `|| log` handler is what disables the
errexit that would have aborted at the failed read. Removing the handler
revives errexit and loses #91's resilience, and an inline `set -e` does
not re-arm it. Explicit per-read checks are the mechanism.

Every read inside that subshell is now checked — the issue read on its
status AND on its payload shape (an HTTP 200 whose body is `null` exits
0 and empties the label set just the same), both reads in
`last_issue_activity`, and the comments read in
`issue_comment_has_marker`. On failure the issue is left exactly as it
is, the reason rides its own `#$n:` line, and the subshell exits with a
distinguished status the sweep counts, so a deliberate skip is not
reported as a crash and a genuine crash is still named byte-identically.

`read_failure_reason` moves to lib/read.sh beside a new `guarded_read`,
sourced by both reconcilers: labels-reconcile's copy was the only one,
and the issue surface needs the identical rule.

Refs #247
2026-08-03 18:01:58 +00:00
..
changelog.sh fix: the sentinel's one-line contract is checked on the file, not the $(cat) word 2026-07-25 13:29:02 +00:00
decide.sh feat: lib/decide.sh — the merge door's decision, pure and exhaustively tested 2026-07-22 18:59:29 +00:00
facts.sh fix: facts.sh reads a parentless head as base_ver=(none) (#134) 2026-07-24 12:14:07 +00:00
read.sh fix(issueflow): a failed read never reaches a decision function 2026-08-03 18:01:58 +00:00
ruling.sh fix: select the best-shaped escalation, not the earliest 2026-08-03 10:55:45 +00:00
version.sh feat: lib/version.sh — one version abstraction, two backends 2026-07-22 18:19:50 +00:00