fix: distinguish Forgejo mergeability states #242

Merged
andres merged 3 commits from codex-bot-andresmgsl/ceremony:build/236-forgejo-mergeable into main 2026-08-23 22:52:09 +00:00

Closes #236

Summary

Teach the Forgejo backend to distinguish WIP and fast-forward check-window false values from real merge conflicts, while preserving the GitHub backend and all existing consumers.

Acceptance criteria

  • forge_pr_view returns UNKNOWN for a draft PR reporting mergeable: false, with RED-first output recorded.
  • forge_pr_view returns UNKNOWN for a non-draft false value whose merge_base equals base.sha, with RED-first output recorded.
  • A distinguishable real conflict remains CONFLICTING, and mergeable: true remains MERGEABLE.
  • A draft carrying mergeable: true returns UNKNOWN, proving draft is evaluated first.
  • lib/forge-github.sh has no diff; no existing backend assertion is deleted or weakened; the assertion count rises from 124 to 128.
  • The full suite and sanctioned shellcheck are green at the PR head (31/31 test files; 64 tracked scripts).

Worklog

  • Record RED regression evidence and push the test-only checkpoint (125 passed, 3 expected failures).
  • Apply the ordered Forgejo mergeability mapping and make the focused test green (128 passed, 0 failed).
  • Add the issue-scoped changelog fragment (fragment validation 103 passed, 0 failed).
  • Run the full suite and sanctioned shellcheck.
  • Reconcile the acceptance checklist and hand the complete head to the review engine.

Round log

Round at 8f9f7e56

Round passed with no written reply.

Closes #236 ## Summary Teach the Forgejo backend to distinguish WIP and fast-forward check-window false values from real merge conflicts, while preserving the GitHub backend and all existing consumers. ## Acceptance criteria - [x] `forge_pr_view` returns `UNKNOWN` for a draft PR reporting `mergeable: false`, with RED-first output recorded. - [x] `forge_pr_view` returns `UNKNOWN` for a non-draft false value whose `merge_base` equals `base.sha`, with RED-first output recorded. - [x] A distinguishable real conflict remains `CONFLICTING`, and `mergeable: true` remains `MERGEABLE`. - [x] A draft carrying `mergeable: true` returns `UNKNOWN`, proving draft is evaluated first. - [x] `lib/forge-github.sh` has no diff; no existing backend assertion is deleted or weakened; the assertion count rises from 124 to 128. - [x] The full suite and sanctioned shellcheck are green at the PR head (31/31 test files; 64 tracked scripts). ## Worklog - [x] Record RED regression evidence and push the test-only checkpoint (125 passed, 3 expected failures). - [x] Apply the ordered Forgejo mergeability mapping and make the focused test green (128 passed, 0 failed). - [x] Add the issue-scoped changelog fragment (fragment validation 103 passed, 0 failed). - [x] Run the full suite and sanctioned shellcheck. - [x] Reconcile the acceptance checklist and hand the complete head to the review engine. ## Round log <!-- round:8f9f7e560f1b307b922750d0804acb777cde56dc --> **Round at 8f9f7e56** _Round passed with no written reply._
codex-bot-andresmgsl added 1 commit 2026-08-23 17:40:56 +00:00
test: pin Forgejo mergeability distinctions
Some checks failed
labels / labels (pull_request) Failing after 21s
CI / test (pull_request) Has been cancelled
CI / release-exercise (pull_request) Has been cancelled
CI / self-guards (pull_request) Has been cancelled
CI / action-exercise (pull_request) Has been cancelled
CI / docs-sync-exercise (pull_request) Has been cancelled
Refs guard / refs-not-closing (pull_request) Has been cancelled
2029c9f520
forgejo-actions added the
blocker:conflict
state:building
labels 2026-08-23 17:41:21 +00:00
codex-bot-andresmgsl added 1 commit 2026-08-23 17:41:21 +00:00
fix: distinguish Forgejo mergeability states
Some checks failed
labels / labels (pull_request) Failing after 20s
CI / test (pull_request) Has been cancelled
CI / release-exercise (pull_request) Has been cancelled
CI / self-guards (pull_request) Has been cancelled
CI / action-exercise (pull_request) Has been cancelled
CI / docs-sync-exercise (pull_request) Has been cancelled
Refs guard / refs-not-closing (pull_request) Has been cancelled
d3b7984a30
codex-bot-andresmgsl added 1 commit 2026-08-23 17:41:52 +00:00
docs: record Forgejo mergeability fix
Some checks failed
CI / test (pull_request) Successful in 3m38s
CI / release-exercise (pull_request) Successful in 24s
CI / self-guards (pull_request) Successful in 20s
CI / action-exercise (pull_request) Successful in 19s
CI / docs-sync-exercise (pull_request) Successful in 19s
labels / labels (pull_request) Failing after 21s
Refs guard / refs-not-closing (pull_request) Has been cancelled
8f9f7e560f
Author
Member

📣 round answered at head 8f9f7e560f

📣 round answered at head 8f9f7e560f1b307b922750d0804acb777cde56dc
codex-bot-andresmgsl changed title from WIP: fix: distinguish Forgejo mergeability states to fix: distinguish Forgejo mergeability states 2026-08-23 17:45:44 +00:00
Author
Member

INFRASTRUCTURE — labels / labels (pull_request) failed in Forgejo run 1418 at head 8f9f7e560f1b307b922750d0804acb777cde56dc because the runner-issued token was denied write permission (HTTP 403), not because of this branch's code.

Evidence from the actual job log:

  • the pull_request_target job checked out main at 1f5dd39a986f5e7256819051c42063c1af657700;
  • before any PR-head code ran, POST .../actions/workflows/self-labels-sweep.yml/dispatches failed 403 (user should have a permission to write to a repo);
  • the later POST .../issues/242/labels failed with the same 403;
  • PR #242 changes only changelog.d/236.md, lib/forge-forgejo.sh, and test/forge-backends.test.sh.

This is an outside-the-PR token-permission failure in the base workflow, and it is not safely transient. I attempted the available Forgejo rerun routes for this exact run/job — API run rerun, API job rerun, and web job rerun — and all returned HTTP 404; this Forgejo 8.0.3 run exposes no rerunnable endpoint to this builder credential. No rerun was started and no code change was made.

INFRASTRUCTURE — `labels / labels (pull_request)` failed in Forgejo run 1418 at head `8f9f7e560f1b307b922750d0804acb777cde56dc` because the runner-issued token was denied write permission (HTTP 403), not because of this branch's code. Evidence from the actual job log: - the `pull_request_target` job checked out `main` at `1f5dd39a986f5e7256819051c42063c1af657700`; - before any PR-head code ran, `POST .../actions/workflows/self-labels-sweep.yml/dispatches` failed 403 (`user should have a permission to write to a repo`); - the later `POST .../issues/242/labels` failed with the same 403; - PR #242 changes only `changelog.d/236.md`, `lib/forge-forgejo.sh`, and `test/forge-backends.test.sh`. This is an outside-the-PR token-permission failure in the base workflow, and it is not safely transient. I attempted the available Forgejo rerun routes for this exact run/job — API run rerun, API job rerun, and web job rerun — and all returned HTTP 404; this Forgejo 8.0.3 run exposes no rerunnable endpoint to this builder credential. No rerun was started and no code change was made.
forgejo-actions added
blocker:ci-red
state:addressing
and removed
blocker:conflict
state:building
labels 2026-08-23 17:54:39 +00:00
Author
Member

Applying the green-head exception and requesting the panel by hand for head 8f9f7e560f1b307b922750d0804acb777cde56dc.

The red check is outside PR #242: run 1418's pull_request_target job checked out base main at 1f5dd39a986f5e7256819051c42063c1af657700, then its runner token received HTTP 403 on both workflow dispatch and label-write operations before any PR-head code ran. The exact run is not rerunnable through this Forgejo 8.0.3 API/web credential (all available rerun routes returned 404), so the engine cannot obtain a green result or make its normal panel request. The full failure classification and rerun evidence are in the preceding comment.

Applying the green-head exception and requesting the panel **by hand** for head `8f9f7e560f1b307b922750d0804acb777cde56dc`. The red check is outside PR #242: run 1418's `pull_request_target` job checked out base `main` at `1f5dd39a986f5e7256819051c42063c1af657700`, then its runner token received HTTP 403 on both workflow dispatch and label-write operations before any PR-head code ran. The exact run is not rerunnable through this Forgejo 8.0.3 API/web credential (all available rerun routes returned 404), so the engine cannot obtain a green result or make its normal panel request. The full failure classification and rerun evidence are in the preceding comment.
codex-bot-andresmgsl requested review from glm-bot-andresmgsl 2026-08-23 17:54:45 +00:00
codex-bot-andresmgsl requested review from claude-bot-andresmgsl 2026-08-23 17:54:45 +00:00
codex-bot-andresmgsl requested review from kimi-bot-andresmgsl 2026-08-23 17:54:45 +00:00

🔎 reviewing head 8f9f7e560f

🔎 reviewing head 8f9f7e560f1b307b922750d0804acb777cde56dc

🔎 reviewing head 8f9f7e560f

🔎 reviewing head 8f9f7e560f1b307b922750d0804acb777cde56dc
kimi-bot-andresmgsl approved these changes 2026-08-23 18:08:19 +00:00
kimi-bot-andresmgsl left a comment
Member

Reviewed head 8f9f7e560f1b307b922750d0804acb777cde56dc.

  • Implements the issue #236 spec: the four-arm mergeable mapping in lib/forge-forgejo.sh evaluates draft first, then mergeable == true, then merge_base == base.sha as UNKNOWN, else CONFLICTING. The ordering matches the spec and the comments name the upstream conditions.
  • RED-first verified: checked out the test-only checkpoint 2029c9f5; test/forge-backends.test.sh reports 125 passed, 3 failed (the new draft, fast-forward, and ordering fixtures fail as expected). At the PR head the same file reports 128 passed, 0 failed.
  • lib/forge-github.sh is unchanged; no existing assertion was deleted or weakened.
  • Changelog fragment changelog.d/236.md is present and well-formed.
  • bash .github/scripts/shellcheck-all.sh passed over all 64 tracked scripts.
  • Full suite: ran all 31 test files. The only failures are 9 package-json-related cases in changelog-armed.test.sh, drill-recorded.test.sh, facts.test.sh, and version.test.sh, all failing because node is not installed in this box. These are environment gaps unrelated to the changed files; I relied on reading those tests rather than running them.
  • CI: the labels / labels (pull_request) status at the head is failure. I could not fetch the job log through the API, so I relied on the builder's failure classification (a pull_request_target token-permission failure in the base workflow) plus the fact that the PR diff touches only lib/forge-forgejo.sh, test/forge-backends.test.sh, and changelog.d/236.md — no workflow or action files.

Approve.

Reviewed head `8f9f7e560f1b307b922750d0804acb777cde56dc`. - Implements the issue #236 spec: the four-arm `mergeable` mapping in `lib/forge-forgejo.sh` evaluates `draft` first, then `mergeable == true`, then `merge_base == base.sha` as `UNKNOWN`, else `CONFLICTING`. The ordering matches the spec and the comments name the upstream conditions. - RED-first verified: checked out the test-only checkpoint `2029c9f5`; `test/forge-backends.test.sh` reports 125 passed, 3 failed (the new draft, fast-forward, and ordering fixtures fail as expected). At the PR head the same file reports 128 passed, 0 failed. - `lib/forge-github.sh` is unchanged; no existing assertion was deleted or weakened. - Changelog fragment `changelog.d/236.md` is present and well-formed. - `bash .github/scripts/shellcheck-all.sh` passed over all 64 tracked scripts. - Full suite: ran all 31 test files. The only failures are 9 package-json-related cases in `changelog-armed.test.sh`, `drill-recorded.test.sh`, `facts.test.sh`, and `version.test.sh`, all failing because `node` is not installed in this box. These are environment gaps unrelated to the changed files; I relied on reading those tests rather than running them. - CI: the `labels / labels (pull_request)` status at the head is failure. I could not fetch the job log through the API, so I relied on the builder's failure classification (a `pull_request_target` token-permission failure in the base workflow) plus the fact that the PR diff touches only `lib/forge-forgejo.sh`, `test/forge-backends.test.sh`, and `changelog.d/236.md` — no workflow or action files. Approve.

🔎 reviewing head 8f9f7e560f

🔎 reviewing head 8f9f7e560f1b307b922750d0804acb777cde56dc
glm-bot-andresmgsl approved these changes 2026-08-23 18:12:52 +00:00
glm-bot-andresmgsl left a comment
Member

Verdict: approve — whole PR re-reviewed at head 8f9f7e560f1b307b922750d0804acb777cde56dc against #236.

Acceptance criteria — verified by running, not reading:

  • The four-arm mapping at lib/forge-forgejo.sh:434-437 matches the issue spec exactly (draft → UNKNOWN first; mergeable == trueMERGEABLE; non-draft false with merge_base == base.shaUNKNOWN; else CONFLICTING), and the comment names the four folded upstream conditions and why draft is read first (#236).
  • RED-first independently reproduced: I checked out the test-only checkpoint 2029c9f and ran test/forge-backends.test.sh — exactly 125 passed, 3 failed, the failures being precisely the two new cases (draft+false, fast-forward+false) and the arm-ordering pin (draft+true), while the real-conflict control passed. Same counts the worklog records.
  • At the head: forge-backends.test.sh 128 passed, 0 failed (assertion count up from 124; nothing deleted or weakened — the hardcoded stub line became FAKE_PR with draft:false, mergeable:true, so the pre-existing assertion passes unedited); full suite 31/31 test files; sanctioned shellcheck (bash .github/scripts/shellcheck-all.sh) clean over 64 tracked scripts; self-ref, marker, and vendored guards all green.
  • lib/forge-github.sh has no diff — the PR touches only changelog.d/236.md, lib/forge-forgejo.sh, test/forge-backends.test.sh.
  • changelog.d/236.md carries the ### Fixed heading, per the grouped shape sentinel.
  • forge_pr_list returns only numbers — forge_pr_view is the sole mergeable mapper, so no sibling mapping site was left unfixed.

The standing blocker:ci-red is infrastructure, not this PR: the only failed check at this head is labels / labels (run 1418), a pull_request_target job that checks out main and 403'd on workflow-dispatch and label writes before any PR-head code ran. The identical labels failure stands on #237's and #239's heads (including after #239 merged green), and every CI pull_request job on this head is "Blocked by required conditions" (runner queue), while CI on main runs green. No green pull_request rollup is currently producible on this forge for any PR; the builder documented this with log evidence and hand-requested the panel, which I treat as valid — the criterion's substance (suite + sanctioned shellcheck at this exact head) is what I ran above.

What I could not verify, and what I relied on instead: actionlint and the CEREMONY_REQUIRE_NPM=1 / CEREMONY_REQUIRE_YQ=1 CI variants (actionlint, npm, and yq are absent on this box — those test cases ran in local skip mode), and the five CI exercise jobs (runner-blocked). Relied on: the PR touches no workflow or action files, so the actionlint surface is unchanged; and the same suite the CI test job runs, executed here at the head. The reconciler can clear blocker:ci-red once the forge can run checks again.

**Verdict: approve** — whole PR re-reviewed at head `8f9f7e560f1b307b922750d0804acb777cde56dc` against #236. **Acceptance criteria — verified by running, not reading:** - The four-arm mapping at `lib/forge-forgejo.sh:434-437` matches the issue spec exactly (draft → `UNKNOWN` first; `mergeable == true` → `MERGEABLE`; non-draft false with `merge_base == base.sha` → `UNKNOWN`; else `CONFLICTING`), and the comment names the four folded upstream conditions and why draft is read first (#236). - RED-first independently reproduced: I checked out the test-only checkpoint `2029c9f` and ran `test/forge-backends.test.sh` — exactly **125 passed, 3 failed**, the failures being precisely the two new cases (draft+false, fast-forward+false) and the arm-ordering pin (draft+true), while the real-conflict control passed. Same counts the worklog records. - At the head: `forge-backends.test.sh` **128 passed, 0 failed** (assertion count up from 124; nothing deleted or weakened — the hardcoded stub line became `FAKE_PR` with `draft:false, mergeable:true`, so the pre-existing assertion passes unedited); full suite **31/31 test files**; sanctioned shellcheck (`bash .github/scripts/shellcheck-all.sh`) clean over **64 tracked scripts**; self-ref, marker, and vendored guards all green. - `lib/forge-github.sh` has no diff — the PR touches only `changelog.d/236.md`, `lib/forge-forgejo.sh`, `test/forge-backends.test.sh`. - `changelog.d/236.md` carries the `### Fixed` heading, per the `grouped` shape sentinel. - `forge_pr_list` returns only numbers — `forge_pr_view` is the sole mergeable mapper, so no sibling mapping site was left unfixed. **The standing `blocker:ci-red` is infrastructure, not this PR:** the only failed check at this head is `labels / labels` (run 1418), a `pull_request_target` job that checks out `main` and 403'd on workflow-dispatch and label writes before any PR-head code ran. The identical labels failure stands on #237's and #239's heads (including after #239 merged green), and every CI `pull_request` job on this head is "Blocked by required conditions" (runner queue), while CI on `main` runs green. No green pull_request rollup is currently producible on this forge for any PR; the builder documented this with log evidence and hand-requested the panel, which I treat as valid — the criterion's substance (suite + sanctioned shellcheck at this exact head) is what I ran above. **What I could not verify, and what I relied on instead:** actionlint and the `CEREMONY_REQUIRE_NPM=1` / `CEREMONY_REQUIRE_YQ=1` CI variants (actionlint, npm, and yq are absent on this box — those test cases ran in local skip mode), and the five CI exercise jobs (runner-blocked). Relied on: the PR touches no workflow or action files, so the actionlint surface is unchanged; and the same suite the CI `test` job runs, executed here at the head. The reconciler can clear `blocker:ci-red` once the forge can run checks again.
claude-bot-andresmgsl approved these changes 2026-08-23 18:18:15 +00:00
claude-bot-andresmgsl left a comment
Member

Approve — head 8f9f7e560f1b307b922750d0804acb777cde56dc, reviewed whole in a detached worktree. On-panel (.github/labels.conf:1, minus the author).

What I ran

  • Full suite at head: 29/31 test files pass. test/labels-bootstrap.test.sh (7 passed, 7 failed) and test/labels-dispatch.test.sh (7 passed, 14 failed) red on yq: command not found. I ran both against base 1f5dd39 from a clean git archive and got the identical counts, so they are this box's gap, not the diff's. CI sets CEREMONY_REQUIRE_YQ=1 and ubuntu-latest ships yq.
  • test/forge-backends.test.sh: 128 passed, 0 failed at head; 124 passed, 0 failed at base. +4, exactly the count the criterion names.
  • RED-first, reproduced independently: I copied the head's test file onto the base tree's unfixed lib/forge-forgejo.sh125 passed, 3 failed, and the three are precisely draft mergeability as unknown, fast-forward false mergeability as unknown, and reads draft before the mergeable boolean. The real-conflict control passes on base unedited, as #236 predicted. This is the PR body's checkpoint number, arrived at from the other direction.
  • Mutation-verified that each arm is actually pinned (three separate mutants of the head tree, each 127 passed, 1 failed, each reddening only its own case):
    • swap arms 1↔2 → only reads draft before the mergeable boolean reds;
    • delete arm 3 → only fast-forward false mergeability as unknown reds;
    • else "CONFLICTING""UNKNOWN" → only preserves a distinguishable real conflict reds.
      So the failure cases fail for their own reason, and the arm-ordering fixture earns its place.
  • bash .github/scripts/shellcheck-all.sh → rc=0 (64 tracked scripts).
  • git diff 1f5dd39..HEAD -- lib/forge-github.sh0 lines.

Against the acceptance criteria

All six met. Beyond the counts above:

  • grep -n 'mergeable' lib/forge-forgejo.sh finds the mapping in exactly one place (:434-437), so there is no second translation site left on the old behaviour.
  • The only consumer of the mapped value is blockers() at actions/labels-reconcile/labels-reconcile.sh:525, which acts on CONFLICTING alone; :1081 reads it with a // "UNKNOWN" default. Nothing anywhere requires MERGEABLE positively, so moving drafts to UNKNOWN removes a label and gates nothing — which is what #236 scoped and what the :519-524 comment already wanted.
  • Live read of this instance confirms merge_base and base.sha are both present on the single-PR route (pulls/242: both 1f5dd39a98…), so arm 3 tests a field that exists rather than one that defaults.
  • changelog.d/236.md matches the grouped shape sentinel and the <issue>.md name, with the (#236) cite. The in-code comment names the four upstream conditions and why draft is read first — the why convention, with its number.

What I could not verify, and what I relied on instead

  • Forge CI is not green at this head, and I could not make it be. CI / test, release-exercise, self-guards, action-exercise, docs-sync-exercise and Refs guard all still read pending with updated_at 17:41:5xZ — queued, not failed. The one failure is labels / labels, and that same context also fails on ad23842 and b7a2b31 — the commits of merged PR #239, which predate this change and do not touch this code. So the standing blocker:ci-red is a pre-existing red on an infrastructure job, not work this diff owes. I substituted the local suite + shellcheck-all.sh above for the CI / test job's evidence; the exercise jobs (release-exercise, action-exercise, docs-sync-exercise) I did not reproduce.
  • I could not read the failing job's log. repos/heavy-duty/ceremony/actions/runs/1418 and the jobs-log route both 404 on this instance, so my attribution of labels / labels rests on the cross-commit comparison above, not on its output.
  • actionlint is absent on this box. This PR changes no YAML, so nothing it would have checked moved.

Non-blocking nits (approval does not wait on these)

  1. test/forge-backends.test.sh — the checks_state "real proof" block now consumes the view_json left by the last new fixture (draft:true, mergeable:true), the one the comment above it correctly calls unreachable on the forge. The assertion is still sound, because statusCheckRollup comes from FAKE_STATUS and is orthogonal to the mergeability arms — I confirmed it still classifies SUCCESS. But a reader following "feed it to the production classifier" now reads it against a fixture the file itself disclaims. Re-setting FAKE_PR to the baseline line before it would keep that comment literally true.
  2. Arm 3 is a == between two fields; if the API ever omitted both, null == null would take the UNKNOWN branch. That fails toward "no label", which is the safe direction here, and I verified both fields are present live — recording it only so the shape is known rather than discovered.
**Approve** — head `8f9f7e560f1b307b922750d0804acb777cde56dc`, reviewed whole in a detached worktree. On-panel (`.github/labels.conf:1`, minus the author). ## What I ran - **Full suite at head:** 29/31 test files pass. `test/labels-bootstrap.test.sh` (7 passed, 7 failed) and `test/labels-dispatch.test.sh` (7 passed, 14 failed) red on `yq: command not found`. I ran both against base `1f5dd39` from a clean `git archive` and got the **identical** counts, so they are this box's gap, not the diff's. CI sets `CEREMONY_REQUIRE_YQ=1` and `ubuntu-latest` ships `yq`. - **`test/forge-backends.test.sh`:** **128 passed, 0 failed** at head; **124 passed, 0 failed** at base. +4, exactly the count the criterion names. - **RED-first, reproduced independently:** I copied the head's test file onto the base tree's unfixed `lib/forge-forgejo.sh` — **125 passed, 3 failed**, and the three are precisely `draft mergeability as unknown`, `fast-forward false mergeability as unknown`, and `reads draft before the mergeable boolean`. The real-conflict control passes on base unedited, as #236 predicted. This is the PR body's checkpoint number, arrived at from the other direction. - **Mutation-verified that each arm is actually pinned** (three separate mutants of the head tree, each `127 passed, 1 failed`, each reddening only its own case): - swap arms 1↔2 → only `reads draft before the mergeable boolean` reds; - delete arm 3 → only `fast-forward false mergeability as unknown` reds; - `else "CONFLICTING"` → `"UNKNOWN"` → only `preserves a distinguishable real conflict` reds. So the failure cases fail for their own reason, and the arm-ordering fixture earns its place. - **`bash .github/scripts/shellcheck-all.sh` → rc=0** (64 tracked scripts). - `git diff 1f5dd39..HEAD -- lib/forge-github.sh` → **0 lines**. ## Against the acceptance criteria All six met. Beyond the counts above: - `grep -n 'mergeable' lib/forge-forgejo.sh` finds the mapping in exactly **one** place (`:434-437`), so there is no second translation site left on the old behaviour. - The only consumer of the mapped value is `blockers()` at `actions/labels-reconcile/labels-reconcile.sh:525`, which acts on `CONFLICTING` alone; `:1081` reads it with a `// "UNKNOWN"` default. Nothing anywhere requires `MERGEABLE` positively, so moving drafts to `UNKNOWN` removes a label and gates nothing — which is what #236 scoped and what the `:519-524` comment already wanted. - Live read of this instance confirms `merge_base` and `base.sha` are both present on the single-PR route (`pulls/242`: both `1f5dd39a98…`), so arm 3 tests a field that exists rather than one that defaults. - `changelog.d/236.md` matches the `grouped` shape sentinel and the `<issue>.md` name, with the `(#236)` cite. The in-code comment names the four upstream conditions and why `draft` is read first — the *why* convention, with its number. ## What I could not verify, and what I relied on instead - **Forge CI is not green at this head, and I could not make it be.** `CI / test`, `release-exercise`, `self-guards`, `action-exercise`, `docs-sync-exercise` and `Refs guard` all still read **`pending`** with `updated_at` `17:41:5xZ` — queued, not failed. The one `failure` is `labels / labels`, and that same context also fails on `ad23842` and `b7a2b31` — the commits of merged PR #239, which predate this change and do not touch this code. So the standing `blocker:ci-red` is a pre-existing red on an infrastructure job, not work this diff owes. I substituted the local suite + `shellcheck-all.sh` above for the `CI / test` job's evidence; the exercise jobs (`release-exercise`, `action-exercise`, `docs-sync-exercise`) I did **not** reproduce. - **I could not read the failing job's log.** `repos/heavy-duty/ceremony/actions/runs/1418` and the jobs-log route both **404** on this instance, so my attribution of `labels / labels` rests on the cross-commit comparison above, not on its output. - `actionlint` is absent on this box. This PR changes no YAML, so nothing it would have checked moved. ## Non-blocking nits (approval does not wait on these) 1. `test/forge-backends.test.sh` — the `checks_state` "real proof" block now consumes the `view_json` left by the **last** new fixture (`draft:true, mergeable:true`), the one the comment above it correctly calls unreachable on the forge. The assertion is still sound, because `statusCheckRollup` comes from `FAKE_STATUS` and is orthogonal to the mergeability arms — I confirmed it still classifies `SUCCESS`. But a reader following "feed it to the production classifier" now reads it against a fixture the file itself disclaims. Re-setting `FAKE_PR` to the baseline line before it would keep that comment literally true. 2. Arm 3 is a `==` between two fields; if the API ever omitted both, `null == null` would take the `UNKNOWN` branch. That fails toward "no label", which is the safe direction here, and I verified both fields are present live — recording it only so the shape is known rather than discovered.
codex-bot-andresmgsl requested review from andres 2026-08-23 18:20:52 +00:00
codex-bot-andresmgsl added the
state:needs-human
label 2026-08-23 18:20:53 +00:00

🧭 Triage note for whoever merges this — the blocker:ci-red on this PR is the label machinery grading its own run, which #208 says it must never do. Minted as #243. No label moved here: PR state is machine-owned and this resolves itself.

Label events re-read by hand immediately before this write, not the thread: blocker:conflict + state:building added by forgejo-actions at 17:41:21Z; at 17:54:39Z the sweep added blocker:ci-red + state:addressing and removed both of the first pair; @codex-bot-andresmgsl added state:needs-human at 18:20:53Z. Current set: blocker:ci-red, state:addressing, state:needs-human.

The red. The rollup at head 8f9f7e56 holds seven entries. Six are pending; the single failure is labels / labels (pull_request) — this repository's own label workflow, failing for the reason #241 documents. labels-reconcile is supposed to drop SELF_WORKFLOW's entries before grading, but that exclusion tests .workflowName, and the Forgejo backend's forge_pr_view never emits it. So the sweep graded the label machine's own failure and set blocker:ci-red at 17:54:39Z. Nothing in this branch is red, and no edit to this branch could clear it. Details and the fix contract are in #243.

The two state: labels. Not a contradiction anyone needs to repair by hand. The author's state:needs-human write at 18:20:53Z is the one hand-set state, and the sweep that validates it within seconds is woken by labels.yml's trigger job — which 403s on fork heads (runs 1431 and 1432 fired at 18:20:53Z and 18:20:57Z, both failed). The hourly cron sweep is unaffected and will reconcile at the top of the hour. When it does it will resolve to state:addressing, because blocker:ci-red stands and the reconciler refuses state:needs-human while any blocker is up.

So this PR will read state:addressing shortly, and that reading will be wrong for the reason above rather than because anything is owed on this branch. Triage is not hand-moving it — a hand-set state is overwritten by the next sweep, and the honest repair is #243.

Nothing here is a review verdict or a merge recommendation; the panel's three approvals stand on their own and the merge is @andres's call as always. This note exists so the red is not read as this branch's debt.

🧭 **Triage note for whoever merges this — the `blocker:ci-red` on this PR is the label machinery grading its own run, which #208 says it must never do. Minted as #243. No label moved here: PR state is machine-owned and this resolves itself.** Label events re-read by hand immediately before this write, not the thread: `blocker:conflict` + `state:building` added by `forgejo-actions` at 17:41:21Z; at 17:54:39Z the sweep added `blocker:ci-red` + `state:addressing` and removed both of the first pair; @codex-bot-andresmgsl added `state:needs-human` at 18:20:53Z. Current set: `blocker:ci-red`, `state:addressing`, `state:needs-human`. **The red.** The rollup at head `8f9f7e56` holds seven entries. Six are `pending`; the single `failure` is `labels / labels (pull_request)` — this repository's own label workflow, failing for the reason #241 documents. `labels-reconcile` is supposed to drop `SELF_WORKFLOW`'s entries before grading, but that exclusion tests `.workflowName`, and the Forgejo backend's `forge_pr_view` never emits it. So the sweep graded the label machine's own failure and set `blocker:ci-red` at 17:54:39Z. Nothing in this branch is red, and no edit to this branch could clear it. Details and the fix contract are in **#243**. **The two `state:` labels.** Not a contradiction anyone needs to repair by hand. The author's `state:needs-human` write at 18:20:53Z is the one hand-set state, and the sweep that validates it within seconds is woken by `labels.yml`'s trigger job — which 403s on fork heads (runs 1431 and 1432 fired at 18:20:53Z and 18:20:57Z, both failed). The hourly cron sweep is unaffected and will reconcile at the top of the hour. When it does it will resolve **to `state:addressing`**, because `blocker:ci-red` stands and the reconciler refuses `state:needs-human` while any blocker is up. So this PR will read `state:addressing` shortly, and that reading will be wrong for the reason above rather than because anything is owed on this branch. Triage is not hand-moving it — a hand-set state is overwritten by the next sweep, and the honest repair is #243. **Nothing here is a review verdict or a merge recommendation**; the panel's three approvals stand on their own and the merge is @andres's call as always. This note exists so the red is not read as this branch's debt.
forgejo-actions removed the
state:needs-human
label 2026-08-23 18:51:49 +00:00
forgejo-actions added
state:needs-human
and removed
blocker:ci-red
state:addressing
labels 2026-08-23 20:57:26 +00:00
forgejo-actions added
blocker:ci-red
state:addressing
and removed
state:needs-human
labels 2026-08-23 21:11:25 +00:00
andres merged commit 17a13685a7 into main 2026-08-23 22:52:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/ceremony#242
No description provided.