Close the downstream pointer issue too, not just the conformance ticket #36

Open
opened 2026-08-15 21:31:50 +00:00 by geusebio · 0 comments
Owner

tools/conformance converges its own ticket per app and nothing else. Where someone has also filed a pointer issue in the app's own repo — so the work is visible on the tracker of the repo that has to act — that pointer has no lifecycle. It is opened by hand and it stays open, including after the conformance ticket it points at has closed itself.

What happened

  • symfony-brand-kit#12 (Brand kit drift: someones.computer) closed itself once the app conformed. Correct.
  • Grey.ooo/Someones.Computer#453, hand-filed as a pointer to it, stayed open.

That stale pointer then cost a full session in the consuming repo: it reads as live work, it is picked up as live work, and the investigation to establish that it is not runs the whole audit again by hand — composer update (nothing to do), the live roster on the deployed site, the template against the current component API. The pointer even carried the ticket's own already-superseded framing ("this is a version pin"), which #12's body had by then corrected to "this is a deployment that has not gone out, not a version pin" — so the copy was wrong as well as stale, and the wrong half is the half that sends someone to the wrong repo.

The pointer is not the mistake. Routing the fix to the repo that owns it is exactly right, and TARGETS[key].repo exists to say where that is. The mistake is that a hand-filed copy cannot follow the thing it copies.

Proposal

Extend reconcile() in report.mjs to treat the downstream pointer as a second surface of the same ticket, reconciled by the same rules that already govern the local one. TARGETS[key].repo already names the repo, so no new configuration is needed.

Two ways to close the loop, and I'd argue for the second:

  1. Adopt hand-filed pointers. A pointer carrying <!-- brandkit-conformance:<key> --> in its body gets found and closed alongside the local ticket. Cheap, but it only works when whoever files the pointer remembers the marker — the failure mode is silent and looks exactly like today.
  2. File the pointer itself (recommended). If the tool opens the downstream pointer, it owns both ends, and convergence is guaranteed by the same code path that already guarantees it locally. Nobody has to know the marker convention for it to hold.

Either way the pointer body should be a link plus the routing verdict, not a copy of the findings — a copied body is a second thing to keep in step, which is the defect above in a new place.

Things worth getting right

  • Token scope. FORGEJO_TOKEN is scoped to this repo. Cross-repo issue writes need something broader; roster.yml already reads the estate with GREYOOO_PAT, so there is precedent. Absent the wider token, downstream reconciliation should degrade to a logged no-op — the same way attach() already tolerates a token that cannot write labels — rather than failing the run.
  • Two keys can share a repo. video and git both map to Grey.ooo/Infrastructure. Pointers must therefore be keyed per app key, not per repo, or the two collide and reconcile each other.
  • Keep the close-then-comment ordering. Same reasoning as the local path: if the comment went first and the close failed, every subsequent nightly run would repeat the branch forever. That argument does not weaken across a repo boundary.
  • Unreachable stays untouched downstream too. A site that is merely down must not close a downstream pointer any more than it closes the local ticket.
  • Only index open issues, as the local path does, so an app that drifts again gets a fresh pointer instead of a resurrected months-old thread.

Acceptance

An app that comes good has both its conformance ticket and its downstream pointer closed by the same nightly run, with the pointer's closing comment linking to the ticket that verified it.

`tools/conformance` converges its own ticket per app and nothing else. Where someone has also filed a **pointer issue in the app's own repo** — so the work is visible on the tracker of the repo that has to act — that pointer has no lifecycle. It is opened by hand and it stays open, including after the conformance ticket it points at has closed itself. ## What happened - symfony-brand-kit#12 (*Brand kit drift: someones.computer*) closed itself once the app conformed. Correct. - Grey.ooo/Someones.Computer#453, hand-filed as a pointer to it, stayed open. That stale pointer then cost a full session in the consuming repo: it reads as live work, it is picked up as live work, and the investigation to establish that it is not runs the whole audit again by hand — `composer update` (nothing to do), the live roster on the deployed site, the template against the current component API. The pointer even carried the ticket's own already-superseded framing (*"this is a version pin"*), which #12's body had by then corrected to *"this is a deployment that has not gone out, not a version pin"* — so the copy was wrong as well as stale, and the wrong half is the half that sends someone to the wrong repo. The pointer is not the mistake. Routing the fix to the repo that owns it is exactly right, and `TARGETS[key].repo` exists to say where that is. The mistake is that a hand-filed copy cannot follow the thing it copies. ## Proposal Extend `reconcile()` in `report.mjs` to treat the downstream pointer as a second surface of the same ticket, reconciled by the same rules that already govern the local one. `TARGETS[key].repo` already names the repo, so no new configuration is needed. Two ways to close the loop, and I'd argue for the second: 1. **Adopt hand-filed pointers.** A pointer carrying `<!-- brandkit-conformance:<key> -->` in its body gets found and closed alongside the local ticket. Cheap, but it only works when whoever files the pointer remembers the marker — the failure mode is silent and looks exactly like today. 2. **File the pointer itself** (recommended). If the tool opens the downstream pointer, it owns both ends, and convergence is guaranteed by the same code path that already guarantees it locally. Nobody has to know the marker convention for it to hold. Either way the pointer body should be a link plus the routing verdict, not a copy of the findings — a copied body is a second thing to keep in step, which is the defect above in a new place. ## Things worth getting right - **Token scope.** `FORGEJO_TOKEN` is scoped to this repo. Cross-repo issue writes need something broader; `roster.yml` already reads the estate with `GREYOOO_PAT`, so there is precedent. Absent the wider token, downstream reconciliation should degrade to a logged no-op — the same way `attach()` already tolerates a token that cannot write labels — rather than failing the run. - **Two keys can share a repo.** `video` and `git` both map to `Grey.ooo/Infrastructure`. Pointers must therefore be keyed per **app key**, not per repo, or the two collide and reconcile each other. - **Keep the close-then-comment ordering.** Same reasoning as the local path: if the comment went first and the close failed, every subsequent nightly run would repeat the branch forever. That argument does not weaken across a repo boundary. - **Unreachable stays untouched downstream too.** A site that is merely down must not close a downstream pointer any more than it closes the local ticket. - **Only index open issues**, as the local path does, so an app that drifts again gets a fresh pointer instead of a resurrected months-old thread. ## Acceptance An app that comes good has both its conformance ticket **and** its downstream pointer closed by the same nightly run, with the pointer's closing comment linking to the ticket that verified it.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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
Grey.ooo/symfony-brand-kit#36
No description provided.