Skip to content

feat(dor): sweep the whole board, and notify only when findings change - #1002

Merged
TaekeK merged 1 commit into
mainfrom
bugfixes/reconcile-board-driven-walk
Aug 11, 2026
Merged

feat(dor): sweep the whole board, and notify only when findings change#1002
TaekeK merged 1 commit into
mainfrom
bugfixes/reconcile-board-driven-walk

Conversation

@TaekeK

@TaekeK TaekeK commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #1001. Two changes to dor_reconcile.sh, both aimed at the same complaint: the health report was simultaneously blind and noisy.

1. Membership, not the gate label, decides what is swept

The per-issue walk started from gh issue list --label "$LABEL", so an issue could sit on the board in any phase and be invisible to every check in it — drift, staleness, liveness, zombie sidekicks, the approval count.

Not a corner case. 42 of the Feature board's 74 items carry no enhancement label: a UI cohort parked in Awaiting design (#749#796), most of the Out of pipeline column, and #758 at Awaiting approval — which is why the value gate reported 2 where the board plainly showed 3.

#758  Awaiting approval  labels=[ui, priority:medium, ready-to-build, state:awaiting-approval]   <- invisible
#665  Awaiting approval  labels=[enhancement, …]
#937  Awaiting approval  labels=[enhancement, …]

The board snapshot now carries each issue's own dates and labels, and the walk runs over board membership. The label query survives for the one thing the board cannot show us: an issue that ought to be on it and is not (the heal path). Board records also move from @tsv to the US separator §2 already used — same reason as #1001: an empty middle field in a tab-joined record shifts everything after it.

2. An item filed on the wrong board is named as such

Driven by membership, a misfiled item would otherwise fall through and be reported as un-routed — "the agent likely never ran" — when the real fault is where it is filed.

#819 sits on the Feature board at Blocked (external) while the Bug board has it at Awaiting functional acceptance. Each sweep only ever reads its own board, so nothing could see the disagreement. It now gets its own line (🧭), and an issue that belongs to the other pipeline entirely is skipped in silence rather than double-reported.

3. The report notifies on change, not on schedule

The sweep commented on every hourly run for as long as anything was open — 87 comments on #886. Comparing bodies cannot fix that: most findings restate a moving age (untouched for 17h), so the text is never identical two sweeps running.

Each exception now also produces a stable identity — marker plus issue (🕳️#941), or marker plus its numbers for the countable lines (🚦3) — and the sorted set rides in the body as an HTML comment:

<!-- dor-fingerprint: 🚦3 🧭#819 -->

The body is refreshed every sweep (editing an issue does not notify); a comment is posted only when that set actually differs, or when a closed health issue has to be reopened. A standing backlog costs one notification instead of one per hour.

Verified against the live boards

Running the real script against the real boards, the Feature report becomes:

- 🧭 #819 sits on this board but its labels route it to the other one …
- 🚦 3 issue(s) waiting in **Awaiting approval** — the Product board's value gate.

Two things worth noting from that run. The 🚦 count corrects itself to 3. And the wave of new findings I expected from the 42 newly-visible items did not materialise — every one of them is correctly routed, label matching Status; they were simply never being checked. The only genuinely new finding is #819.

A second consecutive run produced same exceptions as last sweep — body refreshed silently, which is the notify-on-change behaviour working end to end.

Tests

30 assertions, up from 17. The stub now serves the board as JSON as well and runs the script's own --jq over it, so the board record contract is under test rather than hand-copied into the fixture — the same weakness that hid the #1001 bug. It also strips CR: jq on Windows writes CRLF while gh returns LF, which had been letting a local run disagree with CI about what the script parsed.

Four of the new assertions fail against main:

FAIL  an issue the board carries is swept without the gate label
FAIL  …including in the value-gate backlog
FAIL  a bug on the Feature board is called out as misfiled
FAIL  …but an unchanged exception set posts no comment

jscpd full-repo delta: 123 → 123 clones. The other four ci-scripts suites still pass.

Note

While testing this I ran the script against the live boards with a gh shim that was supposed to block writes. The shim was on PATH as a Windows-style path, which Git Bash ignores for command lookup, so the real gh ran: #886 has one stray comment from me at 08:51:39Z and its body was overwritten with this branch's output. No other issue was touched; #938 is untouched. The next scheduled sweep overwrites that body anyway.

🤖 Generated with Claude Code

Two changes to the reconcile sweep, both aimed at the same complaint: the health
report was simultaneously blind and noisy.

## Membership, not the gate label, decides what is swept

The per-issue walk started from `gh issue list --label "$LABEL"`, so an issue
could sit on the board in any phase and be invisible to every check in it. Not a
corner case: 42 of the Feature board's 74 items carried no `enhancement` label —
a UI cohort parked in "Awaiting design", most of the "Out of pipeline" column,
and an "Awaiting approval" item that made the value-gate count read 2 where the
board plainly showed 3.

The board snapshot now carries each issue's own dates and labels, and the walk
runs over board membership. The label query survives for the one thing the board
cannot show: an issue that ought to be on it and is not (the heal path).

Board records move from `@tsv` to the same US separator §2 already used, for the
same reason: an empty field in the middle of a tab-joined record shifts every
field after it.

## An item on the wrong board is named as such

Membership-driven, a misfiled item would otherwise be reported as un-routed —
"the agent likely never ran" — when the fault is where it is filed. #819 sat on
the Feature board at "Blocked (external)" while the Bug board had it at
"Awaiting functional acceptance"; each sweep only ever reads its own board, so
nothing could see the disagreement. Now 🧭.

## The report notifies on change, not on schedule

It commented on EVERY hourly sweep for as long as anything was open — 87
comments on #886. Comparing bodies cannot fix that: most findings restate a
moving age, so the text is never identical two sweeps running.

Each exception now also yields a stable identity (marker + issue, or marker +
its numbers for the countable lines), and the sorted set is carried in the body
as an HTML comment. The body is refreshed every sweep — editing does not notify
— but a comment is posted only when that set actually differs, or when a closed
health issue has to be reopened. A standing backlog costs one notification
instead of one per hour.

## Tests

30 assertions, up from 17. The stub now serves the board as JSON too and runs
the script's own --jq over it, so the board record contract is under test rather
than hand-copied — and it strips CR, because jq on Windows writes CRLF while
`gh` returns LF, which had been letting a local run disagree with CI about what
the script parsed.

4 of the new assertions fail against main: the two board-driven ones, the
misfiled-board one, and the notify-on-change one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@TaekeK
TaekeK merged commit 3739319 into main Aug 11, 2026
29 checks passed
@TaekeK
TaekeK deleted the bugfixes/reconcile-board-driven-walk branch August 11, 2026 09:08
TaekeK added a commit that referenced this pull request Aug 11, 2026
#1003)

The 💀 notice comments directly on the affected issue and must do so ONCE; the
`dor-stuck` label is how it remembers. That mark was looked up with
`--label dor-stuck --label "$LABEL"`.

Since #1002 the walk follows board membership, so `stalled` can hold an issue
carrying no gate label — and that query can never return such an issue. Its mark
would be invisible, the dedupe would never fire, and the comment would repeat
every hour on something already broken. 38 open Feature-board items have no gate
label, so this was one dead build away from firing. Nothing is in Building on
either board today, which is the only reason it has not.

Scope the lookup by the same ownership rule the walk uses (`belongs_here`)
instead. Equivalent for gate-labelled issues, and the "clear the mark once it
recovers" loop now only touches issues this pipeline owns.

The harness could not see this: its stub served the marked list regardless of
the --label arguments, so both queries looked identical. It now models GitHub's
AND-ing of repeated --label filters, which is what makes the two distinguishable.
Two assertions added; the first fails against main.

Also anchored three 💀 assertions on the comment's target rather than on
"died mid-flight" — that phrase appears in the health digest too, so they could
not tell a direct comment from a line in the report.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant