From 5c669f5f70e2b9a033a1d7bf4e2974603a85794d Mon Sep 17 00:00:00 2001 From: rocklambros Date: Thu, 17 Sep 2026 15:57:21 -0600 Subject: [PATCH] Run the board reconcile twice, because adds and Status cannot land in one pass The workflow added in #157 left newly added items at the wrong Status for a full day, and the cause is an ordering problem rather than a flaky API. Adding an item triggers project 9's own "Item added to project" workflow, which stamps a default Status asynchronously. `apply_governance.py` builds its entire plan before executing any of it, so on a run that adds anything it has already decided the Status actions before those items exist on the board. The default lands after the run finishes, and nothing corrects it until the next run. Measured on the 2026-09-17 backfill. The first pass added 40 items and made 1 Status change. A second pass immediately afterwards found 5 more waiting: #135 and #131, both labelled `status:accepted`, and #126, #113 and #112, all open pull requests. None of those five has the default as its correct Status, which is exactly the population a single pass strands. Nightly, that is up to 24 hours of a board that reads Needs triage for work that is accepted or in flight, which is the failure the board exists to prevent. The reconciler is idempotent and converges, verified by a third pass reporting zero actions, so the second pass costs one API listing on any run that added nothing. Once "Auto-add to project" is enabled on the project that is every run. Signed-off-by: Rock Lambros --- .github/workflows/board-reconcile.yml | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/board-reconcile.yml b/.github/workflows/board-reconcile.yml index 5130573..a9bd0f3 100644 --- a/.github/workflows/board-reconcile.yml +++ b/.github/workflows/board-reconcile.yml @@ -107,11 +107,32 @@ jobs: # A scheduled run always applies. A manual run defaults to printing the plan # so a maintainer can read what would change before letting it change. APPLY: ${{ github.event_name == 'schedule' && 'true' || inputs.apply }} + # Two passes, and the second is not belt-and-braces. + # + # Adding an item triggers the project's own "Item added to project" workflow, + # which stamps a default Status asynchronously. The reconciler builds its whole + # plan up front, so on a run that adds anything it has already decided the + # Status actions before those items exist on the board, and the default lands + # after it finishes. A single pass therefore leaves every newly added item whose + # correct Status is not the default sitting wrong until the next run. + # + # Measured on the 2026-09-17 backfill: the first pass added 40 items, and a + # second pass immediately after had 5 Status corrections waiting, two issues + # labelled status:accepted and three open pull requests. Nightly, that is up to + # a day of wrong Status after any add. + # + # The reconciler is idempotent and converges, so the second pass is a no-op on + # a run that added nothing, which is every run once auto-add is enabled. run: | set -euo pipefail - if [ "$APPLY" = "true" ]; then - python3 tools/apply_governance.py --only board --apply - else + if [ "$APPLY" != "true" ]; then echo "Dry run. Pass apply=true to run these commands." python3 tools/apply_governance.py --only board + exit 0 fi + echo "::group::Pass 1, adds and the Status changes known before them" + python3 tools/apply_governance.py --only board --apply + echo "::endgroup::" + echo "::group::Pass 2, Status for anything pass 1 added" + python3 tools/apply_governance.py --only board --apply + echo "::endgroup::"