Forgejo: CI monitoring on the agent's own pull requests #110

Merged
lucas merged 1 commit from agent/issue-109-own-pr-ci into main 2026-10-27 18:51:39 +01:00
Collaborator

Implements plan step 20 as specified in #109.

  • Config: ci_watchdog.own_prs.enabled (default true) → RepoConfig.ciWatchdogOwnPrs.
  • Pre-merge: handleCommitStatus now fans out to own_ci_failed rows too: open agent PRs at that head that have a mapped session. Dedupe works like ci_failed. The gate (resolveOwnCi) re-reads the config and drops the row with head moved since CI finished when the head moved. Only an existing session is continued. Seed: buildOwnCiFailureSeed.
  • Post-merge: migration 019-forgejo-post-merge.sql and db/forgejo-post-merge.ts. When an agent PR merges, its implementer session gets a waiting record instead of being archived. The merge SHA comes from merge_commit_sha, falling back to readPull. Status events for that SHA settle the record atomically:
    • green: archive the session
    • red: mark the record failed and queue a post_merge_ci_failed row (seed: buildPostMergeCiFailureSeed)
  • Sweep: runs at start and every 60 s. If there are still no checks after the grace period, it archives. If checks are still pending after 24 h, it archives and creates an inbox ticket. Both limits can be overridden through deps for tests.
  • Policy: when the session's newest PR has a failed record, one forgejo_create_pr is allowed and the git_branch head lock is lifted. The system context says so.
  • Reviewer sessions and issue handling are unchanged.
  • ForgejoTriggerSummary.action in protocol gains the two new actions.

Verification

  • bun run typecheck is clean.
  • bun test (apps/server): 991 pass, 3 fail. The 3 failures are unrelated to this PR and also show up on the base:
    • 2 in session-policy.test.ts "policySystemContext: forgejo_conversation" (wording "comment or a label change")
    • 1 in routes-forgejo-webhook.test.ts "ignored push is still listed" (expects 200, gets 202)
  • New tests cover:
    • the DB claim semantics
    • config parsing
    • pre-merge resume, dedupe and moved-head drop
    • enabled: false
    • merge → waiting → pending → green archive
    • red → follow-up seed
    • reviewer sessions still archived at merge
    • sweep with no CI and with the timeout ticket
    • the follow-up policy window

Open points

  • Follow-up branch lock: after the follow-up PR is mapped, a session whose scope has headBranch (started from the PR) is still locked to the old head branch for git_branch. Its scope is not updated, so further review-driven fixes on the follow-up PR's branch would be denied. The plan didn't cover this, so I left it as is. A fix would be to treat the head branches of every mapped PR as allowed.
  • Unverified Forgejo behaviour: two things are taken from the issue's assumptions without checking them on the instance. One is whether merge_commit_sha is in the closed payload (there is a readPull fallback). The other is whether Closes: #N with a colon is recognised.

Closes: #109

Implements plan step 20 as specified in #109. - **Config:** `ci_watchdog.own_prs.enabled` (default `true`) → `RepoConfig.ciWatchdogOwnPrs`. - **Pre-merge:** `handleCommitStatus` now fans out to `own_ci_failed` rows too: open agent PRs at that head that have a mapped session. Dedupe works like `ci_failed`. The gate (`resolveOwnCi`) re-reads the config and drops the row with `head moved since CI finished` when the head moved. Only an existing session is continued. Seed: `buildOwnCiFailureSeed`. - **Post-merge:** migration `019-forgejo-post-merge.sql` and `db/forgejo-post-merge.ts`. When an agent PR merges, its implementer session gets a `waiting` record instead of being archived. The merge SHA comes from `merge_commit_sha`, falling back to `readPull`. Status events for that SHA settle the record atomically: - green: archive the session - red: mark the record `failed` and queue a `post_merge_ci_failed` row (seed: `buildPostMergeCiFailureSeed`) - **Sweep:** runs at start and every 60 s. If there are still no checks after the grace period, it archives. If checks are still pending after 24 h, it archives and creates an inbox ticket. Both limits can be overridden through deps for tests. - **Policy:** when the session's newest PR has a `failed` record, one `forgejo_create_pr` is allowed and the `git_branch` head lock is lifted. The system context says so. - Reviewer sessions and issue handling are unchanged. - `ForgejoTriggerSummary.action` in protocol gains the two new actions. ### Verification - `bun run typecheck` is clean. - `bun test` (apps/server): 991 pass, 3 fail. The 3 failures are unrelated to this PR and also show up on the base: - 2 in `session-policy.test.ts` "policySystemContext: forgejo_conversation" (wording "comment or a label change") - 1 in `routes-forgejo-webhook.test.ts` "ignored push is still listed" (expects 200, gets 202) - New tests cover: - the DB claim semantics - config parsing - pre-merge resume, dedupe and moved-head drop - `enabled: false` - merge → waiting → pending → green archive - red → follow-up seed - reviewer sessions still archived at merge - sweep with no CI and with the timeout ticket - the follow-up policy window ### Open points - **Follow-up branch lock:** after the follow-up PR is mapped, a session whose scope has `headBranch` (started from the PR) is still locked to the *old* head branch for `git_branch`. Its scope is not updated, so further review-driven fixes on the follow-up PR's branch would be denied. The plan didn't cover this, so I left it as is. A fix would be to treat the head branches of every mapped PR as allowed. - **Unverified Forgejo behaviour:** two things are taken from the issue's assumptions without checking them on the instance. One is whether `merge_commit_sha` is in the `closed` payload (there is a `readPull` fallback). The other is whether `Closes: #N` with a colon is recognised. Closes: #109
Before merge, a failed CI outcome at the head of an open agent PR with a
mapped session queues an `own_ci_failed` row that resumes the implementer
session; it is deduped per outcome and dropped when the head has moved.

At merge, the agent's implementer session is no longer archived. A durable
`forgejo_post_merge` record waits on the merge commit's CI: green archives,
red resumes the session to open exactly one follow-up PR (allowed by the
session policy), no checks after 60 s archives, and pending after 24 h
archives with an inbox ticket. A periodic sweep resolves what status
events don't.

`ci_watchdog.own_prs.enabled` (default true) turns this off.

Co-Authored-By: Claude Opus 5.5 via omp-deck
lucas approved these changes 2026-10-27 18:51:33 +01:00
lucas merged commit 829579f78b into main 2026-10-27 18:51:39 +01:00
lucas deleted branch agent/issue-109-own-pr-ci 2026-10-27 18:51:39 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 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
lucas/omp-deck!110
No description provided.