Skip to content

Restore the ProjectsV2 steps in issue-triage and openspec-sync once a project-scoped credential exists #432

Description

@rubenvdlinde

The project-board steps in issue-triage.yml and openspec-sync.yml are disabled behind a PROJECTS_ENABLED = false constant. This issue tracks restoring them.

Why they were disabled

PROJECT_TOKEN was a personal access token and it died on or about 2026-08-04 — HTTP 401 on GET /user. That endpoint is an authentication probe, so the failure is revocation or expiry; re-scoping cannot address it. It was also stored per-repository in only 8 of the 18 apps; the other 10 received an empty value and failed on a different branch of the same root cause.

Every workflow run already gets GITHUB_TOKEN, which cannot expire or be revoked out from under the fleet, and which can do all of the issue work in both files — create, update, label, assign, comment. What it cannot do is ProjectsV2: it is scoped to a single repository and carries no project scope, and the board here is an organisation project (organization(login:…){ projectV2(number:…) }). orgs.checkMembershipForUser is likewise unavailable to it, though that call was already wrapped in a try/catch that degrades to source = 'community'.

So the split is: keep the issue automation working today on a credential that cannot rot, and switch the board steps back on when a project-scoped credential exists.

What is disabled

file site what still happens what does not
issue-triage.yml addToProject() label, assign, welcome comment board placement, App/Source fields
issue-triage.yml triage:accept-* acceptance comment, label removal Status → Proposal
issue-triage.yml backlog-triage label + assign every untriaged issue board placement
openspec-sync.yml per-change loop issue created / updated / closed board placement, Status/App/Change Name/Source

Every disabled site emits a core.notice naming what did not happen. They do not pass silently — a step that stops doing its work while still reporting success is the failure mode this repository exists to prevent.

One user-visible copy change came with it: the triage welcome comment no longer tells the contributor their issue "has been added to our triage board", because while the board step is off that would be false. A bot claiming work it did not do is worse than a bot saying less.

To restore

A project-scoped token cannot simply replace github-token:. These scripts do repo issue work and project work, and actions/github-script gives one authenticated client. Restoring needs:

  1. A project-scoped credential — preferably a GitHub App installed org-wide with Organization → Projects: Read and write, minting an installation token per run via actions/create-github-app-token. An App has no expiry to rotate, covers all 18 repos from one install (removing the present-in-8-absent-in-10 split structurally), and states its permissions explicitly rather than a classic PAT's blanket repo. A PAT with repo + read:org + project published as an org secret is the lighter alternative.
  2. A second authenticated client in each script for the GraphQL calls, leaving github as the GITHUB_TOKEN client for issues.
  3. Flip PROJECTS_ENABLED to true at all 4 sites (12 references in issue-triage.yml, 6 in openspec-sync.yml).

Verify the restore, do not assume it

The old preflight probed GET /user, which any live token answers 200 — so it proved authentication and said nothing about the project scope. A restore is verified by a board mutation succeeding, not by a preflight passing.

Also worth knowing before judging the result: OpenSpec Sync has never succeeded on any repo, so there is no known-good state to return to. Issue Triage has (openregister has 131 successes), so that one has a baseline.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions