Check the deployed apps against the roster daily and ticket the drift #11
No reviewers
Labels
No labels
brandkit-conformance
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Grey.ooo/symfony-brand-kit!11
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/brandkit-conformance-ci"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Nothing enforced that the apps serving the grey.ooo chrome were serving the current one. A consumer pinned to an older
grey-ooo/brand-kitkeeps rendering the roster as it was the day it deployed, and looks entirely healthy doing so — so the estate had quietly drifted apart.This adds a daily job that drives a browser at every app in
GreyOooApps::ALL, screenshots it, checks what it renders against this repo's roster and--gooo-*tokens, and keeps one ticket open here per app that has fallen behind.What it finds today
Run against production from this branch:
code; Projects still points atprojects.grey.ooogrey.videoandcode; Niall.chat stillhref="#"Projects,grey.video,code; Niall.chat stillhref="#"bar.jsinjection was never extended to itEach staleness is datable against this repo's own history: niall.chat predates
4b25aed, someones.computer predates494be0b, stuff.grey.ooo predates731500e.How it works
tools/conformance/targets.mjstools/conformance/audit.mjstools/conformance/report.mjsA browser is not optional: grey.video's bar is injected client-side from
brandkit.grey.ooo/bar.js, so the HTML on the wire carries no chrome and acurl-based check would report every proxied host as unbranded.The checker reads the roster by
require-ingGreyOooApps.phpand the tokens out ofbrand-kit.css, rather than keeping copies. That is the point — a stale hand-written mirror of the roster is the exact bug being hunted (bar.jskeeps one, by necessity, and says so).Tickets are filed here, not on each app's repo, because this is where the roster lives and where the whole estate is visible at once; each one names and links the repo the fix belongs in and says whether that fix is a
composer updateor a change under Infrastructure'sservices/brandkit/.Two properties worth preserving
Red means "did not find out", not "found something". Only an unreachable app, a dead browser, or a
targets.mjs/roster mismatch fails the run. Drift exits 0 and reports itself as tickets, because drift is fixed by someone else redeploying on their own schedule — a scheduled job that stays red until they do stops being read within a week.Findings are confirmed before they are believed. Any app with failures is visited twice and only failures present in both are reported, intersected on a stable check id rather than on the rendered message. PrintShop showed why this matters and why a second visit alone is not enough: it serves its assets through PHP with the profiler on (note its
_wdtroute), so its stylesheet can still be in flight at measurement time. That measures identically to a 404 — auto-height bar, every--gooo-*token empty, nothing logged as an error — and it reproduces across visits. Measurements are therefore gated on the page reachingload, and an app that does not get there is recorded as unreachable rather than broken. Without that, the first run would have filed a false ticket against a healthy app.Verification
actin the pinned Playwright container (/ci-local): PHP install,npm ci, audit against the live sites, reporter, artifact upload — job succeeded.report.mjsexercised in dry run;--previewrenders the exact ticket body it would file.summary.jsonrefuses to file (exit 2); atargets.mjs/roster mismatch aborts before checking anything (exit 2).composer validate --strict --no-check-publishpasses.A subagent review of the harness caught four real bugs before this landed, all fixed here: a close path that could re-comment indefinitely if the close failed, an asset sweep that would permanently break the images in a closed ticket, a pagination short-circuit that could file duplicate tickets nightly on an instance with a lower
MAX_RESPONSE_ITEMS, and a confirmation pass that intersected on prose rather than check ids — that last could have closed a legitimate ticket.Notes for review
pull_requesttrigger, by design — this workflow writes to the issue tracker, so it must not run per-PR. It isschedule(05:43 daily) plusworkflow_dispatch, which also keeps it off the single shared runner during working hours. It follows that CI is not green on this PR because there is nothing here for CI to run;actis the gate instead.php-cliis installed into a Node container. Deliberate, and the alternative is worse: it buys the roster being read from its source instead of duplicated. The house Alpine act-runner image cannot be used because Playwright does not support Alpine.FORGEJO_TOKENfalls back togithub.token; setBRANDKIT_BOT_TOKENif that turns out to lack issue or attachment write scope. Without either, the reporter prints its intent and changes nothing.git.grey.ooo's ticket is expected on the first run and is not a false positive — thebar.jsinjection genuinely has not been applied to it yet.