### Fixed - `actions/refs-not-closing` gathers over REST through the forge shim instead of one GraphQL query, so it produces a real verdict on Forgejo — which serves no GraphQL surface at all — rather than refusing (#199). - The closing set is parsed by `lib/closes_references.sh` over the PR body **and** every commit message, unioned. Forgejo honours closing keywords in commit messages, so a body-only port would miss a PR that closes an issue from a commit subject (#199). - The `hasNextPage` refusal is carried onto the paginated commit read: an incomplete gather refuses instead of returning a partial verdict, reusing the backend's `x-total-count` completeness proof (#199). - A failed read never reaches the parser. An unread body parses to an empty closing set, which is a passing verdict the action never earned (#199). - `.github/workflows/refs-guard.yml` no longer gates the job on the forge. A portable action behind a github-only gate is a guard that passes by never running (#199, #198). - The `CEREMONY_FORGE_CLIENT=gh` declaration is gone, and the contract test asserts its absence: an opt-out with no `gh` behind it is a standing permission slip (#199). ### Added - `lib/issue_references.sh` — the LOCAL/CROSS classifier, moved out of `actions/issueflow-reconcile`'s executable so a second caller can use it without sourcing a reconciler, which would run one (#199, #61). - `test/refs-not-closing.test.sh` drives the action's boundary on **both** backends with stubs at the transport, proving one fixture yields the same verdict on each — including a closing keyword that appears only in a commit message (#199).