sync_blocked_label.py is a no-op: labels moved to the org #3

Closed
opened 2026-09-07 16:04:20 +00:00 by claude · 0 comments
Member

The reconciler is currently a no-op in all five repos. My regression, from
today's move to org-level labels (weblib-archive#63).

Measured, not inferred:

$ sync_blocked_label.py --repo weblib/weblib-archive --dry-run
weblib/weblib-archive:
  skipped: no 'Status/Blocked' label in this repo
--> 0 change(s)

label_id() resolves the label from repos/{repo}/labels, and that now
returns [] everywhere — the labels moved to orgs/weblib/labels. So every
run skips, and Status/Blocked has not been maintained since the migration.

It fails safe — skipping rather than mislabelling, which is what the
docstring on label_id was written for — so nothing is corrupted. But nothing
is reconciled either, and that is silent: the job goes green every 15 minutes.

Fix 1 — resolve the label from the org, falling back to the repo

Try repos/{repo}/labels first and then orgs/{owner}/labels. Keeping the
repo lookup means the script still works for a repo that has local labels, and
does not care which way a given instance is set up.

Fix 2 — never overwrite another Status/*

This one is not yet broken; it arms the moment Status/* becomes exclusive
again, which bit has said it will:

status will become mutually exclusive again. if something is on hold, it
cannot need more info. — bit, 2026-09-07

The reasoning is sound for On Hold vs Need More Info. The case it does not
cover is that Status/Blocked is set by this script, automatically, every 15
minutes
— so under an exclusive Status/*, the moment a parked issue gains a
dependency the reconciler would silently delete a human-set label:

issue has:  Status/On Hold          (set by bit, deliberately)
reconciler: POST .../labels [Status/Blocked]
issue has:  Status/Blocked          <- On Hold is gone, nobody was told

And because Status/On Hold is exactly what makes the backlog sweep skip an
issue, the parked issue would then be offered back as available work — the
failure that label was created to prevent.

Measured on the org labels while they were briefly exclusive: adding
Status/Blocked did evict Status/Need More Info.

Rule: a human-set status wins. If an issue already carries a Status/*
other than Status/Blocked, the reconciler leaves it alone rather than adding
Blocked. Nothing is lost — On Hold, Need More Info and Abandoned all
already mean "not workable", which is what Blocked would have said.

Removal is unaffected and stays as it is: if Blocked is present and every
blocker is closed, take it off.

Verification

  • run against a repo and see it not skip
  • an issue with an open dependency gains Status/Blocked
  • an issue with Status/On Hold and an open dependency does not, and keeps
    On Hold
  • --dry-run still changes nothing

Type/Bug, Priority/High — it is a live regression in a job that runs every
15 minutes and reports success while doing nothing.

**The reconciler is currently a no-op in all five repos.** My regression, from today's move to org-level labels (weblib-archive#63). Measured, not inferred: ``` $ sync_blocked_label.py --repo weblib/weblib-archive --dry-run weblib/weblib-archive: skipped: no 'Status/Blocked' label in this repo --> 0 change(s) ``` `label_id()` resolves the label from **`repos/{repo}/labels`**, and that now returns `[]` everywhere — the labels moved to `orgs/weblib/labels`. So every run skips, and `Status/Blocked` has not been maintained since the migration. It fails *safe* — skipping rather than mislabelling, which is what the docstring on `label_id` was written for — so nothing is corrupted. But nothing is reconciled either, and that is silent: the job goes green every 15 minutes. ## Fix 1 — resolve the label from the org, falling back to the repo Try `repos/{repo}/labels` first and then `orgs/{owner}/labels`. Keeping the repo lookup means the script still works for a repo that has local labels, and does not care which way a given instance is set up. ## Fix 2 — never overwrite another `Status/*` This one is not yet broken; it arms the moment `Status/*` becomes exclusive again, which bit has said it will: > status will become mutually exclusive again. if something is on hold, it > cannot need more info. — bit, 2026-09-07 The reasoning is sound for `On Hold` vs `Need More Info`. The case it does not cover is that **`Status/Blocked` is set by this script, automatically, every 15 minutes** — so under an exclusive `Status/*`, the moment a parked issue gains a dependency the reconciler would *silently delete a human-set label*: ``` issue has: Status/On Hold (set by bit, deliberately) reconciler: POST .../labels [Status/Blocked] issue has: Status/Blocked <- On Hold is gone, nobody was told ``` And because `Status/On Hold` is exactly what makes the backlog sweep skip an issue, the parked issue would then be offered back as available work — the failure that label was created to prevent. Measured on the org labels while they were briefly exclusive: adding `Status/Blocked` did evict `Status/Need More Info`. **Rule:** a human-set status wins. If an issue already carries a `Status/*` other than `Status/Blocked`, the reconciler leaves it alone rather than adding `Blocked`. Nothing is lost — `On Hold`, `Need More Info` and `Abandoned` all already mean "not workable", which is what `Blocked` would have said. Removal is unaffected and stays as it is: if `Blocked` is present and every blocker is closed, take it off. ## Verification - run against a repo and see it *not* skip - an issue with an open dependency gains `Status/Blocked` - **an issue with `Status/On Hold` and an open dependency does not**, and keeps `On Hold` - `--dry-run` still changes nothing `Type/Bug`, `Priority/High` — it is a live regression in a job that runs every 15 minutes and reports success while doing nothing.
claude added the
Type
Bug
Priority
High
2
labels 2026-09-07 16:04:20 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: weblib/weblib-ci#3