Skip to content

design(woodpecker): reconcile stranded required check runs (RIG-3462) - #47

Draft
rigel-mintaka wants to merge 5 commits into
mainfrom
runners/rig-3462-status-reconciler
Draft

rigel-mintaka wants to merge 5 commits into
mainfrom
runners/rig-3462-status-reconciler

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This is the design record for the remaining half of RIG-3462. A reconciler in the Woodpecker server finds terminal pipelines whose required agg or meta check run is still queued, in_progress or absent on GitHub. It then finishes the run with the stored verdict, within a bounded quota budget.

  • Record: docs/designs/woodpecker/status-reconciler.md
  • Decisions: DL-565..DL-576 in docs/designs/woodpecker/decisions/status/

Rulings

  • RIG-5680: Q1 = A (index pipelines.updated), Q2 = B (repair open or absent runs only).
  • Matt on this PR (2026-10-19): move to check runs (RIG-5779, cut over in RIG-5844). D1–D5 and DL-565..569 were rewritten for it.

Do not merge yet

The record builds on the RIG-5844 cutover contract (orion-docs#60, draft): App 4045728, external_id wp1/<instance>/<number>/<kind>, lookup with check_name, app_id and filter=all.

  • It takes names and conclusions from the cutover's helpers, so RIG-5875 (names, canceled conclusion) needs no change here.
  • It waits for that contract to freeze. Whether both servers can run one repo's pipelines at once is unverified; until RIG-5844 settles it, the reconciler runs on one server.

Process

  1. The design subagent drafted the record.
  2. A design-critic pass found 13 findings. One became Q2; the other 12 were folded in.
  3. Four review rounds on the status version: clean at 8ecfb8ee.
  4. Check-run revision e4aa9eba: one review round, 1 high and 1 medium, both fixed in the same commit (see the review-loop note).

Checks

  • bun test: 24 pass.
  • rumdl check, bun run gate, bun run ref-gate: clean.
  • Prose: about 2,800 words. The record's § Length gives the reason.

…462)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@linear-code

linear-code Bot commented Oct 18, 2026

Copy link
Copy Markdown

RIG-3462

@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Rigel public design docs preview: https://runners-rig-3462-status-reco.docs-2ui.pages.dev

Deployed from runners/rig-3462-status-reconciler at e4aa9eb.

rigel-mintaka and others added 2 commits October 18, 2026 06:05
…s (RIG-3462)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
…responses (RIG-3462)

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka

Copy link
Copy Markdown
Contributor Author

Review-loop note

Round SHA Lens Findings Fix
critic draft design-critic 13 (1 fork) fork → Q2; 12 folded before 720d77d6
1 720d77d6 review 5 medium 4 fixed in e4969116; DL-566 vs Q2 settles with RIG-5680
2 e4969116 review 2 medium 27eeddee (hard request cap, PR-head fence)
3 27eeddee review 3 medium 2 fixed in 8ecfb8ee; source-quote finding declined (repo records cite by path; 2,500-word limit)
4 8ecfb8ee review clean none

Head 8ecfb8ee is review-clean. The PR stays draft until Matt answers Q1/Q2 in RIG-5680; then D2/DL-566 and the Open Questions are rewritten to the ruling.

…ler (RIG-3462)

Q1 = A (index pipelines.updated), Q2 = B (repair pending and absent; count final mismatches).

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka

Copy link
Copy Markdown
Contributor Author

Review loop at head 3557ff01: delta from 8ecfb8ee records the Q1=A / Q2=B rulings, clears Open Questions, and checks the Matt task. design-ledger-gate OK, ref-gate clean, rumdl clean, 24/0. Prose ~2,400 words (target 2,500).

@rigel-mintaka
rigel-mintaka marked this pull request as ready for review October 18, 2026 21:26
@mattwilkinsonn

Copy link
Copy Markdown
Contributor

Want to migrate to the checks API see RIG-5779. Also want to see if we can re-add individual checks for the different jobs, or at least some more granularity, if we're using a GH App and batching the calls.

@rigel-mintaka
rigel-mintaka marked this pull request as draft October 19, 2026 00:26
@rigel-mintaka

Copy link
Copy Markdown
Contributor Author

Back to draft. The reconciler will repair the check runs from the RIG-5844 cutover, not commit statuses.

Plan

  • RIG-5844 (upstream-woodpecker) owns the check-run names, granularity and how writes are batched. I'm coordinating with them so the two records agree.
  • This record then changes its read and write paths:
    • Read: one GET /repos/{owner}/{repo}/commits/{sha}/check-runs with app_id set, instead of the combined status. It is still up to 100 runs per page.
    • Repair: PATCH the existing check run by ID, instead of posting a new status. The fork's findCheckRun already matches on external_id and the App ID.
    • Budget, memory, fences and the Q1/Q2 rulings carry over unchanged.

Batching facts (GitHub docs, rate limits for the REST API)

  • REST has no bulk check-run endpoint, and each REST POST/PATCH costs 5 secondary-limit points against 900 a minute.
  • A GraphQL request costs 5 points if it carries any mutation, so several createCheckRun/updateCheckRun mutations in one request cost 5 instead of 5 each. That is what makes per-job checks affordable.
  • Not verified yet: whether the content-creation limit (80 a minute, 500 an hour) counts each check run inside one request. Per-job checks on busy pipelines could hit 500 an hour, so the RIG-5844 design needs to measure this first.

…-3462)

Matt moved the required gates to check runs (RIG-5844). The reconciler
now reads check runs by name with filter=all, matches its run by
external_id, PATCHes by run id, and takes names and conclusions from
the cutover so RIG-5875 needs no change here.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka rigel-mintaka changed the title design(woodpecker): reconcile stranded pending commit statuses (RIG-3462) design(woodpecker): reconcile stranded required check runs (RIG-3462) Oct 19, 2026
@rigel-mintaka

Copy link
Copy Markdown
Contributor Author

Review loop at head e4aa9eba (check-run revision, per Matt's comment above). One review pass, with both findings fixed before the push:

Finding Severity Fix
rpi5 and AKS have separate stores and locks, so an absent-run create could land after the other server's newer run high The fence re-lists the name under the key lock before any create and skips the create if any run exists. The remaining window is marked unverified and assigned to RIG-5844. Until then the reconciler runs on one server. Budget minimum 10 → 11
No test for an absent run alongside a newer run from another pipeline medium T3 rows 16 and 17

The reviewer found these consistent with the RIG-5844 contract: names from the cutover's helpers, aggregateCheckState conclusions, the external_id shape, filter=all, PATCH by id, and DL-565..569 matching D1–D5.

design-ledger-gate OK, ref-gate clean, rumdl clean, 24/0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants