Skip to content

Review board: free-form comments and Request fixes action - #5322

Open
aaronpowell wants to merge 2 commits into
mainfrom
aaronpowell-plugin-board-free-form-comments
Open

aaronpowell wants to merge 2 commits into
mainfrom
aaronpowell-plugin-board-free-form-comments

Conversation

@aaronpowell

Copy link
Copy Markdown
Contributor

Pull Request Checklist

  • I have read and followed the CONTRIBUTING.md guidelines.
  • I have read and followed the Guidance for submissions involving paid services.
  • My contribution adds a new instruction, prompt, agent, skill, workflow, or canvas extension file in the correct directory.
  • The file follows the required naming convention.
  • The content is clearly structured and follows the example format.
  • I have tested my instructions, prompt, agent, skill, workflow, or canvas extension with GitHub Copilot.
  • I have run npm start and verified that README.md is up to date.
  • I am targeting the main branch for this pull request.

Description

Maintainers using the External Plugin Review Board could only act on submissions through structured commands (/approve, /reject, re-review, bucket moves). There was no way to ask the submitter a question, and no action that sends a submission back for fixes.

This PR adds two footer actions next to Approve and Reject. Both use the same comment box.

  • Comment: posts a free-form comment through the same GitHub helper the existing actions use, after a confirm click. The body must be non-empty. Bodies starting with / are rejected on both the client and the server, so a comment can't trigger the command router. After posting, the drawer switches to the Comments tab and reloads it.
  • Request fixes: posts /request-fixes <reason>, which requires a reason. The button is disabled while a decision is pending or once the issue already has requires-submitter-fixes.
  • New router command /request-fixes <reason> in external-plugin-command-router.yml:
    • Maintainers only (write/maintain/admin).
    • Applies to open external-plugin issues that are not yet approved or rejected.
    • Swaps the labels to requires-submitter-fixes and posts a marker comment listing the requested fixes.
    • When the submitter edits the issue or comments /rerun-intake, intake runs again as usual.
  • The parser is parseRequestFixesCommand in eng/external-plugin-intake.mjs. CONTRIBUTING.md and the extension README are updated.

Type of Contribution

  • New instruction file.
  • New prompt file.
  • New agent file.
  • New plugin.
  • New skill file.
  • New agentic workflow.
  • New canvas extension.
  • Update to existing instruction, prompt, agent, plugin, skill, workflow, or canvas extension.
  • Other (please specify): new /request-fixes maintainer command in the external plugin command router.

Additional Notes

  • The router runs from main, so the Request fixes button only takes effect after this merges. Before that, the command comment is posted but nothing moves the issue.
  • Request fixes leaves the issue open. It doesn't go through the pending-decision flow, which only resolves closed issues. Instead, the server polls briefly for the label and then refreshes the board.
  • No real GitHub comments were posted during testing.

Validation:

  • node --test .github/extensions/external-plugin-review-board/lib/github.test.mjs eng/board-preview.test.mjs eng/external-plugin-review-board-ui.test.mjs eng/external-plugin-review-board-state.test.mjs eng/board-bulk-actions.test.mjs eng/board-column-order.test.mjs eng/external-plugin-review-board.test.mjs eng/external-plugin-intake-state.test.mjs: passed (98/98)
  • node --experimental-vm-modules --test eng/board-state-storage.test.mjs: passed (11/11)
  • node --test --test-name-pattern=parseRequestFixesCommand eng/external-plugin-intake.test.mjs: passed (3/3)

By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.

aaronpowell and others added 2 commits October 23, 2026 14:52
Adds a Comment panel to the External Plugin Review Board drawer with a
two-click confirm. Bodies must be non-empty and cannot start with '/' so
they can't trigger the command router. Posts via the existing
gh.postComment helper and per-issue in-flight guard, then reloads the
Comments tab.

Co-authored-by: Copilot App <[email protected]>
Adds a /request-fixes <reason> maintainer command to the external plugin command router, and footer Comment and Request fixes buttons that reuse the shared comment box.

Co-authored-by: Copilot App <[email protected]>
@aaronpowell
aaronpowell requested a review from a team as a code owner October 23, 2026 04:25
Copilot AI max review requested due to automatic review settings October 23, 2026 04:25
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🚦 Submission status: 👀 Ready for review

Risk tier: merge-risk:high — Privileged execution, automation, or review-policy change
Required to merge: passing submission-gate checks plus 1 approval from reviewers with write access, including a maintainer with admin or maintain permission.

Why this tier
  • .github/extensions/external-plugin-review-board/README.md is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/extensions/external-plugin-review-board/extension.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/extensions/external-plugin-review-board/lib/github.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/extensions/external-plugin-review-board/lib/github.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/extensions/external-plugin-review-board/public/app.js is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/extensions/external-plugin-review-board/public/index.html is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/extensions/external-plugin-review-board/public/styles.css is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • .github/workflows/external-plugin-command-router.yml is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • eng/board-preview.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • eng/external-plugin-intake.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • eng/external-plugin-intake.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • eng/external-plugin-review-board-ui.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
  • eng/external-plugin-review-board.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)

Automated checks

Check Status Details
Line endings ✅ Passed Passed · logs
Spelling ✅ Passed Passed · logs
Submission gate tests ✅ Passed Passed · logs
Contributor reputation ✅ Passed Passed · logs
Duplicate resource scan ✅ Passed Passed · logs
PR quality signal ✅ Passed Passed · logs

Review

  • Approvals: 0/1
  • Assigned reviewer: not assigned yet — comment /request-review to ask for one
  • Review target date: not set
  • Still needed: 1 more approval(s); an approval from a maintainer with admin or maintain permission
  • The core-maintainers pool is not staffed yet; an approver with admin or maintain permission is required instead.

Commands

Command Who What it does
/rerun-checks PR author, maintainers Re-runs failed or incomplete checks and re-evaluates this gate
/request-review PR author, maintainers Asks the review rotation to assign a reviewer (adds needs-reviewer)

Updated for effd9fa · gate run · This comment is maintained automatically — see submission gate docs.

@github-actions

Copy link
Copy Markdown
Contributor

🟡 Contributor Reputation Check: MEDIUM risk

Check Risk
Profile MEDIUM
Credential audit NONE

Maintainers: please review this contributor before merging.
See the workflow run for full details.
Automated check powered by AGT.

@github-actions github-actions Bot added needs-review:MEDIUM Contributor reputation check flagged MEDIUM risk ready-for-review Submission passed intake validation and is ready for maintainer review and removed awaiting-automation labels Oct 23, 2026
@aaronpowell

Copy link
Copy Markdown
Contributor Author

Re: submission status (6357357119): no change needed. The merge-risk:high tier is expected because this PR touches the review board extension and the external plugin command router workflow, so it needs maintainer approval.

Re: contributor reputation check (6357361613): no change needed. This is an informational automated check with nothing actionable in the code; leaving the contributor review to the maintainers.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unsent drafts can be lost, and outstanding fixes requests can permit conflicting decisions.

5 open issues
What changed in this PR

Extends the External Plugin Review Board so maintainers can discuss submissions and request corrections without rejecting them.

Changes:

  • Adds confirmed Comment and Request fixes actions using the shared textarea.
  • Introduces maintainer-only /request-fixes routing to update labels and record requested changes.
  • Documents the workflow and adds parser, validation, and UI coverage.
File Description
eng/​external-plugin-review-board.test.mjs Extends pending-decision button checks.
eng/​external-plugin-review-board-ui.test.mjs Tests availability when fixes are already required.
eng/​external-plugin-intake.test.mjs Tests command parsing and reason handling.
eng/​external-plugin-intake.mjs Adds request-fixes constants and parser.
eng/​board-preview.test.mjs Covers confirmation, posting, refresh, and failure flows.
CONTRIBUTING.md Documents the maintainer request-fixes command.
.github/​workflows/​external-plugin-command-router.yml Authorizes commands, updates labels, and posts feedback.
.github/​extensions/​external-plugin-review-board/​README.md Documents new actions and validation commands.
.github/​extensions/​external-plugin-review-board/​public/​styles.css Styles the new action and confirmation states.
.github/​extensions/​external-plugin-review-board/​public/​index.html Adds footer controls and shared-input guidance.
.github/​extensions/​external-plugin-review-board/​public/​app.js Implements previews, confirmation, posting, and comments refresh.
.github/​extensions/​external-plugin-review-board/​lib/​github.test.mjs Tests comment validation and command formatting.
.github/​extensions/​external-plugin-review-board/​lib/​github.mjs Adds comment validation and request-fixes formatting.
.github/​extensions/​external-plugin-review-board/​extension.mjs Adds posting routes and label-confirmation polling.

Review effort: Max

Comment on lines +216 to +224
for (const delay of [1000, 2000, 4000]) {
await sleep(delay);
const latest = await gh.getIssueStatus(store.state.repo, number);
if (latest.labels.includes("requires-submitter-fixes")) {
await refresh();
return { number, commentUrl, pending: false };
}
}
return { number, commentUrl, pending: true };
Comment on lines +224 to +226
return { number, commentUrl, pending: true };
} finally {
decisionsInFlight.delete(number);
function commentBody(kind) {
const text = ui.comment.value.trim().replace(/^\/(approve|reject)\b\s*/i, "");
if (kind === "comment") return ui.comment.value.trim();
const text = reasonText();
Comment on lines +623 to +630
const hasReason = Boolean(reasonText());
ui.reject.disabled = !hasReason;
ui.reject.title = hasReason ? "" : "Reject requires a reason.";
ui.requestFixes.disabled = !hasReason;
ui.requestFixes.title = hasReason ? "" : "Request fixes requires a description of what to change.";
const commentProblem = freeformCommentError(ui.comment.value.trim());
ui.commentPost.disabled = Boolean(commentProblem);
ui.commentPost.title = commentProblem ?? "";
Comment on lines +693 to +711
const result = await api("POST", "/api/comment", { number, body: ui.comment.value.trim() });
toast(`Posted comment on #${number}`, { link: result.commentUrl });
stagedComments.set(number, "");
if (selected === number) {
ui.comment.value = "";
activeTab = "comments";
renderDrawer();
}
await loadDetail(number, { force: true });
} else if (kind === "request-fixes") {
const result = await api("POST", "/api/request-fixes", { number, comment: ui.comment.value });
toast(
result.pending
? `Posted /request-fixes on #${number}; waiting for the workflow to update labels.`
: `Requested fixes on #${number}`,
{ link: result.commentUrl },
);
stagedComments.delete(number);
if (selected === number) closeDrawer();

This branch was successfully deployed

1 active deployment
github-pages — effd9fad Deployed Oct 23, 2026 by aaronpowell via deploy #1062
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk:high needs-review:MEDIUM Contributor reputation check flagged MEDIUM risk ready-for-review Submission passed intake validation and is ready for maintainer review workflow PR touches workflow automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants