Skip to content

Fill the dev board's field values automatically - #1818

Merged
Azgaar merged 10 commits into
Azgaar:masterfrom
barrulus:feat/dev-board-automation
Sep 8, 2026
Merged

Azgaar merged 10 commits into
Azgaar:masterfrom
barrulus:feat/dev-board-automation

Conversation

@barrulus

@barrulus barrulus commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

You asked whether the dev board could be automated because updating it by hand is a chore. This does the part that is genuinely mechanical, and deliberately does not do the part that isn't.

What it does

A single reconciler runs hourly, reads the whole board, and writes only what is missing:

  • Theme field is set from the item's theme: label.
  • theme: labels are applied to items theme-label.yml never sees — it fires on issues and discussion only, which is why pull requests have none.
  • Priority and Size are set from a ### Triage block in the issue body, when one is present. Nothing writes one today; that is the hook for the Discord intake bot, where a human moderator picks both values before approving.

What it will not do

Nothing is ever guessed, and nothing a human set is ever overwritten. Two invariants, both enforced in code and covered by tests:

  1. It only ever fills an empty field. If you have set a value, it is never changed — even when a label disagrees with it. Disagreements are reported, never resolved.
  2. Every value written traces to a label a human applied or a dropdown a human selected. Where the source is ambiguous — an item carrying two theme: labels — it writes nothing and reports it.

So an empty cell on the board keeps meaning "nobody has judged this yet", which is only true because nothing writes a guess into it. There is no model and no inference anywhere in this PR.

It also never writes needs-theme. theme-label.yml still applies that at creation, and you can delete it to mean "I looked, nothing fits" — if the reconciler re-applied it, your deletion would be undone within the hour. Items it cannot classify are listed in the run summary instead.

Dry run against the board as it stands

118 items → 11 Theme fills, 14 label writes, 4 items reported, 0 Priority/Size writes.

The reported items are #1658, #1805 and #1808 (title and body do not classify — a human call), and #1810, which carries both theme: ui-editors and theme: markers-zones, so it refuses to pick one.

The run is idempotent: a second run writes nothing, and a third writes nothing. It converges in two passes because an item that gets a label in run 1 gets its Theme field in run 2.

About the change to theme-label.yml

That workflow already had the classifier inline, and the reconciler needs the same logic for pull requests. Rather than keep two copies of a 13-entry keyword table that would drift — and then theme the same item differently depending on which path saw it first — the classifier moves to scripts/theme-classify.mjs and both import it.

The extraction is behaviour-identical, and I checked rather than assuming: the DROPDOWN and KEYWORDS objects are deepStrictEqual to the originals, and running the old inline algorithm against the new one over 109 inputs — 100 real issues from this repo plus 9 adversarial cases (null title, null body, an unmapped dropdown answer, ###Theme with no space, a body-only tie, a 5000-character title) — gives 0 mismatches. The scoring threshold is unchanged.

The workflow gains an actions/checkout step, which it needs to import the module.

Before merging

The secret is already in place — thank you. It reads the PROJECT_TOKEN you created, and the name in the workflow matches. Recording why it had to be a classic PAT, for whoever reads this later: GITHUB_TOKEN cannot write to Projects v2 at all, and because the board is user-owned rather than org-owned, fine-grained PATs and GitHub App tokens do not work either — those cover organization projects only. It needs project scope and nothing else; both repos are public, so no repo scope.

The cron is live on merge, and the first run makes about 25 writes — most of them labels on merged pull requests, each notifying that PR's subscribers. Worth dispatching it once by hand first: workflow_dispatch defaults to dry_run: true, which prints the full plan and writes nothing. If the plan looks right, dispatch again with dry_run: false, and the hourly schedule takes it from there.

If the token ever lapses, the run stops and opens a single issue saying so, using the workflow's own token rather than the PAT.

If the token ever expires, the run opens a single issue saying so rather than failing quietly. That check is careful to fire only on genuine authentication failures, not on rate limits or transient errors.

Testing

npm run test:scripts — 31 tests under Node's built-in runner, wired into unit-tests.yml. They live outside src/, so vitest does not collect them (its root is ./src); hence the separate script. No new dependencies — global fetch and node: builtins only. The existing 648 unit tests are unaffected.

…rift

- grant pull-requests: write so addLabel can label PRs (14/17 of writes)
- stop routing addLabel (GITHUB_TOKEN) failures through the PROJECT_TOKEN
  auth-failure reporter
- planLabelWrites prefers a human-set Theme field over the keyword guess,
  and now surfaces unclassifiable/unmapped/conflicting theme labels as
  drift instead of writing a sticky needs-theme label
- widen labels(first: 20) to 100, log a failed dedupe search, drop dead
  FIELDS[*].id, fix the "N theme labels" wording, and surface a Triage
  block that resolves a field to nothing as drift
@netlify

netlify Bot commented Sep 8, 2026

Copy link
Copy Markdown

Deploy Preview for afmg ready!

Name Link
🔨 Latest commit 314f493
🔍 Latest deploy log https://app.netlify.com/projects/afmg/deploys/6aa087dfc605fb00088ffd66
😎 Deploy Preview https://deploy-preview-1818--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-assigned this Sep 8, 2026
@Azgaar
Azgaar merged commit 4de6838 into Azgaar:master Sep 8, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in FMG dev board Sep 8, 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