Skip to content

chore: standard issue templates + label-automation dispatchers - #2028

Open
chrisferry wants to merge 7 commits into
mainfrom
chore/standard-issue-templates
Open

chore: standard issue templates + label-automation dispatchers#2028
chrisferry wants to merge 7 commits into
mainfrom
chore/standard-issue-templates

Conversation

@chrisferry

@chrisferry chrisferry commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Org-standard YAML issue forms (native type: Bug/Feature/Task, status:untriaged, this repo's component:* default, dropdown where multi-component) replacing the legacy .md templates, plus SHA-pinned dispatchers for the shared reusable label workflows. node-release-checklist.md is preserved.

Also in scope:

  • CODEOWNERS: the enumerated .github rules collapse into a single /.github/ rule, so security and SRE own everything under .github rather than a fixed list that new files fall outside of. The previous rules had real gaps — /.github/workflows/dependabot.yml matched nothing (that file lives at .github/dependabot.yml), and three of the owned paths are .md templates this PR deletes.
  • Fork PRs: ai-assisted-label moves to pull_request_target, because GitHub gives fork-originated PRs a read-only token on pull_request and this repo takes external contributions regularly. Safe here — the reusable never checks out or executes PR code.

Dispatchers call the public midnightntwrk/workflows reusable library, pinned to a SHA. Verified live: the re-pointed ai-assisted-label dispatcher resolves and runs green, which the previous private-.github route could not do from a public repo.

Closes #2027

Org-standard YAML issue forms (native type:, status:untriaged, repo
component label, component dropdown where multi-component) replacing the
legacy .md templates, plus dispatchers for the org reusable label
workflows (default-labels-on-open, default-origin-on-open,
drop-untriaged-on-assign, ai-assisted-label, apply-component-from-form).

Assisted-by: Claude <noreply@anthropic.com>
@chrisferry chrisferry added the bot:ai-assisted Authored or substantially edited by an AI agent label Aug 14, 2026
@chrisferry
chrisferry requested review from a team as code owners August 14, 2026 20:30
@chrisferry chrisferry added the bot:ai-assisted Authored or substantially edited by an AI agent label Aug 14, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1806cdfd7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +6 to +7
pull_request:
types: [opened, edited, synchronize]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a writable trigger for fork-originated PRs

For PRs opened from forks or by Dependabot, GitHub downgrades the pull_request event's GITHUB_TOKEN to read-only despite the requested pull-requests: write permission. The called reusable workflow therefore cannot add or remove bot:ai-assisted for those PRs; use a safely designed writable context such as pull_request_target, or another trusted-token mechanism, so the repository's AI-label requirement is enforced for external contributions too.

AGENTS.md reference: AGENTS.md:L178-L183

Useful? React with 👍 / 👎.

Public repos cannot resolve reusable workflows hosted in a private
repo, so every dispatcher call was failing at workflow resolution. Re-points
them at the public midnightntwrk/workflows mirror (byte-identical reusables).

The component dropdown is renamed to Components with literal component:*
options and multiple: true, which is the form the reusable's parser matches —
the previous singular/bare-name form silently no-oped.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Chris Ferry <chris.ferry@shielded.io>
Collapses the enumerated .github rules into a single /.github/ rule so security
and SRE own everything under .github. The narrow rules left gaps: the
dependabot.yml rule pointed under workflows/ where that file does not exist,
and only scan.yaml was owned among the workflows.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Chris Ferry <chris.ferry@shielded.io>
justinfrevert
justinfrevert previously approved these changes Aug 20, 2026
justinfrevert and others added 2 commits August 20, 2026 13:59
GitHub hands fork-originated PRs a read-only token on pull_request regardless
of the permissions requested, so the label was never applied to external
contributions — and this repo takes them regularly.

pull_request_target is safe for this dispatcher specifically: the reusable it
calls never checks out or executes PR code, it only reads PR metadata through
the API.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Chris Ferry <chris.ferry@shielded.io>
@chrisferry

Copy link
Copy Markdown
Contributor Author

Codex P2 applied, after checking both halves of it — the risk and the need.

The need is real. This repo has taken 8 fork PRs in its last 100, so external contribution is current practice, not hypothetical. On pull_request, GitHub hands fork-originated PRs a read-only GITHUB_TOKEN regardless of the pull-requests: write we request, so bot:ai-assisted was never being applied to any of them. The reusable's own header had already predicted this ("Fork PRs would not be labeled — revisit if external forks become common") — that condition is now met.

The risk is not. pull_request_target is dangerous when a workflow checks out and executes PR code with a privileged token. This one cannot: the reusable runs a single actions/github-script step, performs no checkout, and only reads PR metadata (body + commit messages) through the API. Untrusted text is regex-tested in JS, never passed to a shell. So the trigger switch buys the write token without opening the usual pull_request_target hole.

actionlint clean. Committed normally, not force-pushed, per AGENTS.md.


Separate, larger finding while verifying the above — the backstop cannot detect this repo's own mandated disclosure format.

The reusable matches on:

(co-authored-by:.*(claude|anthropic\.com|codex|openai|copilot|cursor|gemini|gpt-[0-9]))
| (generated (with|by) .*(claude|codex|copilot))
| 🤖 generated (with|by)

But AGENTS.md:179-181 explicitly forbids Co-authored-by for LLM tools and mandates Assisted-by: AGENT_NAME:MODEL_VERSION instead — which matches none of those alternatives. So a PR that follows this repo's convention exactly is invisible to the automatic labeller, and the backstop only fires for authors using the format the repo tells them not to use.

That is a fix in the shared reusable rather than here, so it is out of scope for this PR. Raising it so it is not mistaken for working once this merges.

Comment thread .github/workflows/ai-assisted-label.yml Fixed
Required by the changes check, which wants both a PR link and an issue link.

DCO Remediation Commit for Chris Ferry <chris.ferry@shielded.io>

I, Chris Ferry <chris.ferry@shielded.io>, hereby add my Signed-off-by to this commit: a1806cd

Signed-off-by: Chris Ferry <chris.ferry@shielded.io>

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
zizmor fails the scan gate on pull_request_target unconditionally, so the fork
gap stays open pending a security decision rather than suppressing the rule
here. The limitation is now documented in the file.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Chris Ferry <chris.ferry@shielded.io>
@chrisferry

Copy link
Copy Markdown
Contributor Author

Update on the Codex P2 (fork PRs) — it collides head-on with this repo's own security gate, so I have reverted it and need a decision.

I applied pull_request_target as recommended. zizmor then failed the scan check with an error:

.github/workflows/ai-assisted-label.yml:10
use of fundamentally insecure workflow trigger:
pull_request_target is almost always used insecurely

So the two automated reviewers directly contradict each other: Codex says use pull_request_target to enforce the AI-label requirement on external contributions; zizmor blocks that trigger unconditionally and gates the merge.

My read is that zizmor's rule is a blanket heuristic and this is one of the cases where it is a false positive — pull_request_target is dangerous when a workflow checks out and executes PR code with a privileged token, and this reusable does neither (one actions/github-script step, no checkout, PR metadata read through the API, untrusted text only regex-tested in JS). But suppressing a security gate is not a call to make quietly inside a templates PR, so I have reverted to pull_request and documented the gap in the file. scan is green again.

The three ways forward:

  1. Accept the gap (current state). Fork PRs are never auto-labelled; external contributors rely on reviewer enforcement. Zero risk, requirement not mechanically enforced for forks — which is precisely what Codex objected to.
  2. Suppress the rulepull_request_target plus a scoped # zizmor: ignore[dangerous-triggers] with the justification above. Closes the gap; needs security sign-off, and sets a precedent others may copy into workflows that do check out PR code, where it would be genuinely unsafe.
  3. Use workflow_run — the pattern GitHub actually recommends for needing a write token on fork PRs. zizmor-clean and structurally safer, but it is a redesign of the shared reusable (the PR number is not in the event payload, so it has to be recovered by head SHA) and would land fleet-wide, not just here.

@midnightntwrk/mn-security — this one is yours. Option 1 is in effect until someone says otherwise, so this PR is not blocked on it.

Separately, the disclosure-regex gap I flagged above still stands and is arguably the bigger issue: the reusable cannot match Assisted-by:, the format AGENTS.md actually mandates, so the labeller is blind to correctly-formatted PRs regardless of which trigger is used.

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

Labels

bot:ai-assisted Authored or substantially edited by an AI agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standardize issue templates and label automation

3 participants