Skip to content

Nightly triage: sweep unboarded issues onto the board and run the board audit #2463

Description

@cliffhall

Problem

New issues reach the board only when a maintainer runs /issue-triage by hand, currently every day or two. Until then, a user-submitted issue has no card. It is invisible to the board, to its priority ordering and to every Status-filtered view, whether or not it is urgent. The same gap delays the dependabot and SDK-watch issues, which leave boarding to triage.

Goal

A nightly workflow that runs /issue-triage's pass 1 and its board audit, so that every open issue has a card by morning. Pass 2 (assigning a milestone, which is the approval) stays human, as the skill requires: "Pass 2 is a human judgment call and is never done unprompted."

Blocked on

#2462's credential. Board writes need org Projects write access, which GITHUB_TOKEN cannot hold. The GitHub App described there (Projects read & write, Issues read & write) covers this workflow too.

Design

The work splits into a deterministic half and a judgment half. That split, together with AGENTS.md's rule that no model runs in a write-capable job, gives the workflow the same three-job shape as sdk-watch.yml.

1. sweep — deterministic, holds the credential, no model.

2. analyze — the model, contents: read only.

  • Score each new v2 issue with the priority rubric (two axes plus the listed bonuses), and suggest a type label where the form did not determine one.
  • Return structured output only (--json-schema). Restrict the available tools (--tools, not only --allowedTools), give it no Bash and no WebFetch, and let it post nothing. These are the rules AGENTS.md lays down for sdk-watch's analysis job.
  • ⚠️ Issue bodies are untrusted, third-party input. Unlike sdk-watch, whose upstreams are first-party, anyone with a GitHub account can write the text this model reads. That is the case AGENTS.md says would change the trade-off: "Point the analysis at an upstream outside this org, or feed it third-party content, and the trade changes." So this job must not have ANTHROPIC_API_KEY readable through a tool it needs. Use workload identity federation, or a dedicated CI-scoped key with a spend cap, as AGENTS.md names for exactly this case. Decide which before building it.

3. apply — holds the credential, no model.

  • Validate every value analyze returned before writing it:
    • the Priority must be one of the four options
    • the type must be one of the five labels
    • each axis must be an integer from 1 to 5
    • the total must match its parts, recomputed here rather than trusted
  • Then set Priority and post the score comment in the format /issue-triage specifies.
  • A value that fails validation is left unset and reported, never coerced.

4. The board audit — report only.

  • Run the audit query from /issue-triage and fail the job when any check is non-zero, so drift becomes a red run instead of something the next manual pass has to notice.
  • ⚠️ Actions logs on this public repo are public, and the boards are private. The audit output (issue numbers per defect class, Status, Priority) and anything else read from the board must go only to a place with the board's own audience. Print counts only to the log, or write the detail somewhere private. The same applies to the sweep's own logging.

Out of scope

Acceptance

  • Scheduled workflow with sweep → analyze → apply (+ audit), permissions scoped per job as above, with tests pinning:
    • analyze's permissions and tool whitelist
    • that analyze contains no write step
    • that apply validates before it writes
  • Deterministic label/board classification in a scripts/*.mjs helper, with a sibling *.test.mjs, covering:
    • both forms
    • both boards
    • the already-milestoned → Todo exception
    • the incomplete-listing guard
  • Credential decision for the model key recorded (federation, or a dedicated capped key).
  • Nothing read from the private boards reaches a public log beyond counts.
  • /issue-triage and AGENTS.md updated to say the sweep runs nightly, and what is still manual (pass 2).

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

    blockedchoreMaintenance: deps, build tooling, CI, cleanup — no user-facing behavior changev2Issues and PRs for v2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions