Skip to content

Board reconciler: trust Triage blocks only from collaborators - #1823

Merged
Azgaar merged 2 commits into
Azgaar:masterfrom
barrulus:fix/board-reconciler-trust-gate
Sep 9, 2026
Merged

Azgaar merged 2 commits into
Azgaar:masterfrom
barrulus:fix/board-reconciler-trust-gate

Conversation

@barrulus

@barrulus barrulus commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #1818, from a review of the code as it runs. One hole that should not have shipped, and three smaller things.

The hole: any reporter could set their own Priority

The reconciler reads a ### Triage block from the issue body to fill Priority and Size. Nothing checked who wrote it. Since anyone can edit the body of an issue they filed, and the workflow runs on issues: edited, a reporter could add three lines to their own bug and have it show as P0 – Urgent on your board within minutes — looking exactly like a moderator had triaged it.

Nothing exploited it, and fill-only meant you could always override, but the field was supposed to mean "someone you trust judged this", and it didn't.

Now a block counts only when the issue author's association is OWNER, MEMBER or COLLABORATOR, or their login is in a repository variable TRUSTED_TRIAGE_LOGINS (comma-separated). The variable is for the Discord intake bot once it exists, since it will write under its own identity — it can stay unset until then, which means "collaborators only". An ignored block is listed in the run summary rather than silently dropped, so a reporter who tries it is visible.

The three smaller things

An empty Triage block read values from the next section. The heading regex swallowed the blank line after ### Triage, so a body with an empty block followed by, say, ### Additional context containing a Priority: line would write that value. Contrived, but it is a value nobody put in the block. Fixed, and the parser now explicitly handles the \r\n line endings the web form submits — the tests had only ever used \n.

The workflow would go red on every fork. It reads the board by repository owner but writes with this repository's hardcoded project id. A fork carrying the file — mine, at the next sync — would fail with PROJECT_TOKEN is not set on every issue event. The job is now gated on github.repository.

The labeler had no fallback. theme-label.yml imports the shared classifier at runtime. If that ever failed, a new issue got no label at all. It now falls back to needs-theme with a warning. Worth noting: that import has not yet run in production — no issue has been filed since #1818 merged — so the first new issue is its first real execution, and this makes the failure mode visible rather than silent.

Nothing to do on your side

Dry run against the board at this commit is identical to the last scheduled run: 0 field writes, 0 label writes, 9 items reported. 39 script tests pass, 8 of them new. No behaviour changes for anything already on the board.

…t an empty one

Anyone can edit the body of an issue they filed, so a `### Triage` block was
a way for any reporter to set their own Priority on the board within minutes
of the `issues: edited` trigger firing. A block now counts only when the
author's association is OWNER, MEMBER or COLLABORATOR, or the login is in
TRUSTED_TRIAGE_LOGINS, which the intake bot needs because it writes under
its own identity. An ignored block is reported as drift rather than dropped.

Separately, the heading regex ended with `\s*\n`, which swallowed the blank
line after an empty `### Triage` and let the next section's lines be read as
triage values. It now stops at the heading's own line end, and tolerates the
CRLF bodies the web form submits — the existing tests only ever used LF.
…egrade

The reconciler reads the board as `user(login: <repo owner>)` but writes
with this repository's hardcoded project id, so a fork carrying the file
would read a different board and, lacking PROJECT_TOKEN, fail red on every
issue event. The job is now gated on the repository name.

theme-label.yml imports the shared classifier at runtime. If that import
ever fails — the script renamed, or a syntax error committed straight to
master — a new issue previously got no label at all. It now falls back to
`needs-theme` with a warning, so the failure is visible and the issue still
surfaces for a human.

TRUSTED_TRIAGE_LOGINS is passed from a repository variable so the intake
bot's login can be allowlisted without a code change.
@netlify

netlify Bot commented Sep 9, 2026

Copy link
Copy Markdown

Deploy Preview for afmg ready!

Name Link
🔨 Latest commit 2bb1b0e
🔍 Latest deploy log https://app.netlify.com/projects/afmg/deploys/6aa1525a291b5600082453b1
😎 Deploy Preview https://deploy-preview-1823--afmg.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Azgaar
Azgaar self-requested a review September 9, 2026 12:47
@Azgaar
Azgaar merged commit b248196 into Azgaar:master Sep 9, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in FMG dev board Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants