The agent loop set State/Question on issue #282 because ci.yml has a
path filter — changes that only touch .forgejo/workflows/website.yml don't
trigger CI. The loop waited 15 min for a CI run on issue-282-fix, found
none, and concluded the push hadn't happened, marking the issue as a question.
What this PR fixes
1. Add _tea_get() — a direct Codeberg API client
Replaces the internal use of fgj actions run list for CI-run discovery. _latest_main_ci_run and _latest_ci_run_for_branch now call _tea_get
directly; the latter matches PR runs via the event_payload JSON field
instead of resolving the PR number with a second fgj call. _handle_pr_still_open_after_merge also uses _tea_get for the mergeable
check. This fixes 14 pre-existing test failures where tests mocked agent_loop._tea_get but the function didn't exist.
2. Add _merged_issue_prs() + catch-up scan
On each cron tick the loop now scans for merged issue-{N}-fix PRs whose
issues still have state labels, and closes them. This covers the case where State/Question was set (CI path-filter miss, timeout, etc.) but the PR was
later merged manually. Issue #282 will be closed on the next tick.
Test plan
76 Python unit tests pass (python3 -m unittest scripts.test_agent_loop)
4 new tests cover the merged-PR catch-up (TestMergedPrCatchup)
14 previously-failing tests now pass (TestLatestMainCiRun, TestLatestCiRunForBranch, TestMergeFailsOpen)
## Why State/Question appeared on issue #282
The agent loop set `State/Question` on issue #282 because `ci.yml` has a
path filter — changes that only touch `.forgejo/workflows/website.yml` don't
trigger CI. The loop waited 15 min for a CI run on `issue-282-fix`, found
none, and concluded the push hadn't happened, marking the issue as a question.
## What this PR fixes
**1. Add `_tea_get()` — a direct Codeberg API client**
Replaces the internal use of `fgj actions run list` for CI-run discovery.
`_latest_main_ci_run` and `_latest_ci_run_for_branch` now call `_tea_get`
directly; the latter matches PR runs via the `event_payload` JSON field
instead of resolving the PR number with a second `fgj` call.
`_handle_pr_still_open_after_merge` also uses `_tea_get` for the `mergeable`
check. This fixes 14 pre-existing test failures where tests mocked
`agent_loop._tea_get` but the function didn't exist.
**2. Add `_merged_issue_prs()` + catch-up scan**
On each cron tick the loop now scans for merged `issue-{N}-fix` PRs whose
issues still have state labels, and closes them. This covers the case where
`State/Question` was set (CI path-filter miss, timeout, etc.) but the PR was
later merged manually. Issue #282 will be closed on the next tick.
## Test plan
- [x] 76 Python unit tests pass (`python3 -m unittest scripts.test_agent_loop`)
- [x] 4 new tests cover the merged-PR catch-up (`TestMergedPrCatchup`)
- [x] 14 previously-failing tests now pass (`TestLatestMainCiRun`, `TestLatestCiRunForBranch`, `TestMergeFailsOpen`)
- [x] Pre-commit hooks pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why State/Question appeared on issue #282
The agent loop set
State/Questionon issue #282 becauseci.ymlhas apath filter — changes that only touch
.forgejo/workflows/website.ymldon'ttrigger CI. The loop waited 15 min for a CI run on
issue-282-fix, foundnone, and concluded the push hadn't happened, marking the issue as a question.
What this PR fixes
1. Add
_tea_get()— a direct Codeberg API clientReplaces the internal use of
fgj actions run listfor CI-run discovery._latest_main_ci_runand_latest_ci_run_for_branchnow call_tea_getdirectly; the latter matches PR runs via the
event_payloadJSON fieldinstead of resolving the PR number with a second
fgjcall._handle_pr_still_open_after_mergealso uses_tea_getfor themergeablecheck. This fixes 14 pre-existing test failures where tests mocked
agent_loop._tea_getbut the function didn't exist.2. Add
_merged_issue_prs()+ catch-up scanOn each cron tick the loop now scans for merged
issue-{N}-fixPRs whoseissues still have state labels, and closes them. This covers the case where
State/Questionwas set (CI path-filter miss, timeout, etc.) but the PR waslater merged manually. Issue #282 will be closed on the next tick.
Test plan
python3 -m unittest scripts.test_agent_loop)TestMergedPrCatchup)TestLatestMainCiRun,TestLatestCiRunForBranch,TestMergeFailsOpen)🤖 Generated with Claude Code