Both panel blockers onc63a550. @kimi found the one that mattered: facts.sh got the REPO fix, release.yml's own four call sites did not. A workflow `run:` shell carries no `set -u`, so an unset REPO expands empty and the verb addresses `repos//…` — which 404s, and the 404 is then read as an ANSWER. Reproduced read-only against this instance before fixing: forge_release_exists 0.4.1 -> "no", rc 0 forge_commit_pulls7fc9afe4-> "[]", rc 0 (the !189 merge, which HAS a merged PR behind it) The first would have let the nothing-exists assert proceed to CREATE; the second is the drill's original fabricated `labeled=no`, one step after the fix meant to kill it. Fixed once rather than at four call sites, as kimi suggested: forge_select defaults REPO from GITHUB_REPOSITORY, and forgejo_api_base — which every verb reaches the network through — refuses an empty REPO outright. No fifth call site can forget it. @grok and @kimi both blocked on the same AC gap: the backend suite did not cover the five new verbs, so the two measured asymmetries had no offline coverage. test/forge-backends.test.sh now has 15 cases for them — singular /pull wrapped to an array, 404 as an empty array, 500 refusing, release present/absent/unreadable, POST /tags vs /git/refs, the publish body, and the REPO-empty must-fail. Mutation-checked: reading the plural path fails one case, dropping the REPO guard fails the two must-fails. 1029 assertions, 22 suites, shellcheck-all and actionlint clean. Refs #191 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1.2 KiB
Fixed
-
The release doors run on a Forgejo consumer.
lib/facts.shandrelease.ymlgathered and published throughgh, which the runner image does not ship, so the merge door readlabeled=nofor a correctly labeled ceremony PR and the tag door died at the publish (#191). -
A release fact that could not be read is no longer reported as a definite
no. A completed read finding no label is stillnoand still fail-closed; a read that did not complete refuses and emits no fact (#191).
Added
-
forge_release_exists,forge_commit_pulls,forge_tag_create,forge_release_createandforge_pr_createon both backends, so the release path names no client (#191). -
The forgejo backend serves one PR object at
/commits/{sha}/pullwhere GitHub serves an array at/pulls; both verbs emit the array shape, so the call site carries one expression (#191). -
Forgejo creates tags at
POST /tags— it serves/git/refsGET-only, so GitHub's ref-POST would have 404'd there forever (#191). -
forgejo_api_baserefuses whenREPOis empty. Every verb interpolates it and every call reaches the network through there, sorepos//…— whose 404 reads as "no release" and "no PRs" — is now impossible (#191).