chore(metadata): tighten issue and pr governance#974
Conversation
|
✅ Template check passed after update. Thanks for fixing the PR description. |
|
Warning Review limit reached
More reviews will be available in 46 minutes and 29 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (36)
📝 WalkthroughWalkthroughIntroduces a new ChangesMetadata Governance & Label Taxonomy Overhaul
Sequence DiagramsequenceDiagram
participant GH as GitHub Event (issues / pull_request_target)
participant WF as metadata-governance.yml
participant script as issue-pr-metadata.cjs
participant REST as GitHub REST API
participant GQL as GitHub GraphQL API
participant OUT as GITHUB_OUTPUT / STEP_SUMMARY
GH->>WF: trigger (opened / labeled / edited / …)
WF->>script: node scripts/agents/includes/issue-pr-metadata.cjs
script->>script: getItemFromEvent → parseRelationshipHints
script->>REST: assignIssue (candidate usernames)
script->>REST: listMilestones / createMilestone
script->>REST: updateMilestone on item
script->>GQL: addSubIssueRelationship (issues only)
script->>REST: upsertComment (marker-based governance comment)
script->>OUT: write assignee, milestone, linkedRefs, …
WF->>OUT: append Metadata governance report to STEP_SUMMARY
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
d66acb7 to
5e0e9df
Compare
🔍 Reviewer Summary for PR #974CI Status: ❌ Recommendations
|
There was a problem hiding this comment.
Code Review
This pull request deprecates the legacy project-meta-sync.agent.js script in favor of a new metadata governance model driven by metadata-governance.yml and project-meta-sync.yml workflows, supported by helper scripts issue-pr-metadata.cjs and derive-project-fields.cjs. It also updates extensive documentation, refactors label priorities and types, and adds robust unit tests. Feedback on the new implementation suggests improving robustness by handling missing event payloads in getItemFromEvent, combining sequential GraphQL queries to reduce network roundtrips, relaxing the bot-user check when identifying existing comments, and wrapping milestone operations in a try-catch block to prevent workflow failures.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| function getItemFromEvent(event) { | ||
| if (event.pull_request) { | ||
| return { | ||
| kind: "pull_request", | ||
| number: event.pull_request.number, | ||
| nodeId: event.pull_request.node_id, | ||
| title: event.pull_request.title || "", | ||
| body: event.pull_request.body || "", | ||
| labels: Array.isArray(event.pull_request.labels) | ||
| ? event.pull_request.labels | ||
| : [], | ||
| milestone: event.pull_request.milestone || null, | ||
| author: event.pull_request.user?.login || "", | ||
| }; | ||
| } | ||
|
|
||
| return { | ||
| kind: "issue", | ||
| number: event.issue.number, | ||
| nodeId: event.issue.node_id, | ||
| title: event.issue.title || "", | ||
| body: event.issue.body || "", | ||
| labels: Array.isArray(event.issue.labels) ? event.issue.labels : [], | ||
| milestone: event.issue.milestone || null, | ||
| author: event.issue.user?.login || "", | ||
| }; | ||
| } |
There was a problem hiding this comment.
If the workflow is triggered by an event other than issues or pull_request_target (for example, during manual dispatch or push events), both event.pull_request and event.issue will be undefined. Accessing event.issue.number directly in the fallback block will throw a TypeError. Adding an explicit check for event.issue and throwing a descriptive error makes the code more robust and easier to debug.
function getItemFromEvent(event) {
if (event.pull_request) {
return {
kind: "pull_request",
number: event.pull_request.number,
nodeId: event.pull_request.node_id,
title: event.pull_request.title || "",
body: event.pull_request.body || "",
labels: Array.isArray(event.pull_request.labels)
? event.pull_request.labels
: [],
milestone: event.pull_request.milestone || null,
author: event.pull_request.user?.login || "",
};
}
if (event.issue) {
return {
kind: "issue",
number: event.issue.number,
nodeId: event.issue.node_id,
title: event.issue.title || "",
body: event.issue.body || "",
labels: Array.isArray(event.issue.labels) ? event.issue.labels : [],
milestone: event.issue.milestone || null,
author: event.issue.user?.login || "",
};
}
throw new Error("Event payload does not contain a pull_request or issue");
}
| async function addSubIssueRelationship(github, owner, repo, parentNumber, childNumber) { | ||
| const parent = await github.graphql( | ||
| ` | ||
| query($owner: String!, $repo: String!, $number: Int!) { | ||
| repository(owner: $owner, name: $repo) { | ||
| issue(number: $number) { | ||
| id | ||
| } | ||
| } | ||
| } | ||
| `, | ||
| { owner, repo, number: parentNumber }, | ||
| ); | ||
|
|
||
| const child = await github.graphql( | ||
| ` | ||
| query($owner: String!, $repo: String!, $number: Int!) { | ||
| repository(owner: $owner, name: $repo) { | ||
| issue(number: $number) { | ||
| id | ||
| } | ||
| } | ||
| } | ||
| `, | ||
| { owner, repo, number: childNumber }, | ||
| ); | ||
|
|
||
| const parentId = parent?.repository?.issue?.id; | ||
| const childId = child?.repository?.issue?.id; | ||
| if (!parentId || !childId) return false; |
There was a problem hiding this comment.
The sequential GraphQL queries to fetch the parent and child issue IDs can be combined into a single GraphQL query. This reduces the number of network roundtrips to the GitHub API from two to one, improving the efficiency of the metadata sync process.
async function addSubIssueRelationship(github, owner, repo, parentNumber, childNumber) {
const response = await github.graphql(
`
query($owner: String!, $repo: String!, $parentNumber: Int!, $childNumber: Int!) {
repository(owner: $owner, name: $repo) {
parent: issue(number: $parentNumber) {
id
}
child: issue(number: $childNumber) {
id
}
}
}
`,
{ owner, repo, parentNumber, childNumber },
);
const parentId = response?.repository?.parent?.id;
const childId = response?.repository?.child?.id;
if (!parentId || !childId) return false;
| const existing = comments.find( | ||
| (comment) => comment.user?.type === "Bot" && comment.body?.includes(COMMENT_MARKER), | ||
| ); |
There was a problem hiding this comment.
Relying on comment.user?.type === "Bot" to identify the existing comment can be fragile. If the workflow is executed using a Personal Access Token (PAT) or a custom GitHub App, the comment author's type might be "User" or another value instead of "Bot". Since the COMMENT_MARKER (<!-- metadata-governance -->) is highly unique, it is safer and more robust to find the comment solely by checking if the body includes the marker.
const existing = comments.find(
(comment) => comment.body?.includes(COMMENT_MARKER),
);
| let milestoneSummary = item.milestone?.title || ""; | ||
| if (!milestoneSummary) { | ||
| const linkedMilestone = | ||
| item.kind === "pull_request" | ||
| ? await resolveLinkedIssueMilestone( | ||
| github, | ||
| owner, | ||
| repo, | ||
| [...new Set([...hints.linkedRefs, ...extractIssueRefs(item.body)])], | ||
| ) | ||
| : null; | ||
| const milestoneTitle = linkedMilestone?.title || deriveMilestoneTitle(item.title); | ||
| const milestone = linkedMilestone || (await ensureMilestone(github, owner, repo, milestoneTitle)); | ||
| await updateIssueMilestone(github, owner, repo, item.number, milestone.number); | ||
| milestoneSummary = milestone.title; | ||
| } |
There was a problem hiding this comment.
If any of the milestone API calls (such as ensureMilestone or updateIssueMilestone) fail due to secondary rate limits, validation errors, or permission issues, the entire metadata governance workflow will crash. Wrapping this block in a try-catch block ensures that milestone assignment failures are handled gracefully and logged, matching the robust error-handling strategy used for other optional metadata operations in this file (like assignees and sub-issue relationships).
let milestoneSummary = item.milestone?.title || "";
if (!milestoneSummary) {
try {
const linkedMilestone =
item.kind === "pull_request"
? await resolveLinkedIssueMilestone(
github,
owner,
repo,
[...new Set([...hints.linkedRefs, ...extractIssueRefs(item.body)])],
)
: null;
const milestoneTitle = linkedMilestone?.title || deriveMilestoneTitle(item.title);
const milestone = linkedMilestone || (await ensureMilestone(github, owner, repo, milestoneTitle));
if (milestone?.number) {
await updateIssueMilestone(github, owner, repo, item.number, milestone.number);
milestoneSummary = milestone.title;
}
} catch (error) {
console.info(`Milestone governance failed for #${item.number}: ${error.message}`);
}
}
There was a problem hiding this comment.
💡 Codex Review
This canonical workflow snippet still tells users to run node ../scripts/agents/labeling.agent.js, but this change removed the direct-run guard from labeling.agent.js and moved execution to run-labeling-agent.cjs. In environments with dependencies installed, following this instruction now imports the module and exits without running runLabelingAgent, so manual or dry-run labelling checks silently do nothing; update the command to the wrapper or preserve the direct entrypoint.
ℹ️ 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".
| function extractIssueRefs(text) { | ||
| const refs = new Set(); | ||
| const source = String(text || ""); | ||
| const matches = source.matchAll(/#(\d+)/g); |
There was a problem hiding this comment.
Ignore non-local qualified issue references
When a body contains a qualified GitHub shorthand reference such as other-repo#123, this regex still extracts 123, and downstream milestone inheritance or sub-issue creation treats it as an issue in the current repository. That can copy metadata from, comment about, or create relationships to the wrong local issue whenever contributors link cross-repository work; parse the owner/repo and ignore non-local refs, or only accept unqualified local #123 references.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (5)
scripts/agents/includes/issue-pr-metadata.cjs (1)
273-318: ⚡ Quick winConsider consolidating the two GraphQL queries into one to halve API calls.
The
addSubIssueRelationshipfunction makes two separate GraphQL queries to fetch the parent and child issue IDs, then a third for the mutation. You could fetch both in a single query, which would be kinder to the rate limits and a tad snappier!♻️ Proposed single-query approach
async function addSubIssueRelationship(github, owner, repo, parentNumber, childNumber) { - const parent = await github.graphql( + const result = await github.graphql( ` - query($owner: String!, $repo: String!, $number: Int!) { + query($owner: String!, $repo: String!, $parentNumber: Int!, $childNumber: Int!) { repository(owner: $owner, name: $repo) { - issue(number: $number) { + parent: issue(number: $parentNumber) { id } + child: issue(number: $childNumber) { + id + } } } `, - { owner, repo, number: parentNumber }, + { owner, repo, parentNumber, childNumber }, ); - const child = await github.graphql( - ` - query($owner: String!, $repo: String!, $number: Int!) { - repository(owner: $owner, name: $repo) { - issue(number: $number) { - id - } - } - } - `, - { owner, repo, number: childNumber }, - ); - - const parentId = parent?.repository?.issue?.id; - const childId = child?.repository?.issue?.id; + const parentId = result?.repository?.parent?.id; + const childId = result?.repository?.child?.id; if (!parentId || !childId) return false;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/agents/includes/issue-pr-metadata.cjs` around lines 273 - 318, The addSubIssueRelationship function currently makes two separate GraphQL queries to fetch the parent and child issue IDs sequentially. Consolidate these into a single GraphQL query that fetches both issue IDs at once by modifying the query structure to accept both parentNumber and childNumber as parameters and retrieve both parent.repository.issue.id and child.repository.issue.id in the same query call. This will reduce the total API calls from three to two, improving efficiency and reducing rate limit consumption..github/workflows/metadata-governance.yml (1)
23-23: ⚖️ Poor tradeoffConsider SHA-pinning actions for stronger supply-chain security.
The coding guidelines note that
@v4tags are acceptable, but SHA pins are better. For a workflow with write permissions, pinning to specific commit SHAs reduces the risk of a compromised upstream action.This is optional but recommended for high-privilege workflows.
Also applies to: 26-26
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/metadata-governance.yml at line 23, Replace the version tag reference in the actions/checkout action with a SHA pin for stronger supply-chain security. Instead of using `actions/checkout@v4`, pin the action to a specific commit SHA (e.g., `actions/checkout@<FULL_SHA>`). This should be done at both occurrences mentioned in the comment to ensure consistent security practices throughout the workflow, particularly since this workflow has write permissions.Source: Coding guidelines
scripts/agents/includes/derive-project-fields.cjs (1)
22-33: ⚡ Quick winQuick safety net: default
cfgto avoid a faceplant.Line 31 dereferences
cfgimmediately. If this helper is called withoutcfg(or config load returnsnull), it throws before fallback logic can run.Suggested tweak
function deriveProjectFieldValues({ - cfg, + cfg = {}, labels = [], eventName = "", eventAction = "", prMerged = false,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/agents/includes/derive-project-fields.cjs` around lines 22 - 33, The deriveProjectFieldValues function immediately dereferences cfg on line 31 when accessing cfg.project_field_mappings without any null or undefined check. If cfg is not provided or is null, this will throw an error before any fallback logic can run. Add a default value for cfg in the destructuring assignment of the deriveProjectFieldValues function parameters to ensure cfg has a safe fallback value (such as an empty object) when it is not provided.scripts/agents/includes/__tests__/derive-project-fields.test.js (1)
33-50: ⚡ Quick winAdd one more guardrail test for
status:in-progress.Nice coverage for the “not started” and “ready” states. Adding the second positive kickoff state (
status:in-progress) would lock the full contract and prevent sneaky regressions.Proposed test addition
test("populates kickoff dates when the item is ready to start", () => { @@ }); + + test("populates kickoff dates when the item is already in progress", () => { + const result = deriveProjectFieldValues({ + cfg: issueFieldsConfig, + labels: ["status:in-progress", "priority:important", "type:feature"], + eventName: "issues", + eventAction: "edited", + itemCreatedAt: "2026-06-18T10:15:00Z", + milestoneDueOn: "2026-07-18T00:00:00Z", + }); + + expect(result).toMatchObject({ + status: "In Progress", + priority: "Important", + type: "Feature", + startDate: "2026-06-18", + targetDate: "2026-07-18", + }); + }); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/agents/includes/__tests__/derive-project-fields.test.js` around lines 33 - 50, Add a new test case for the `status:in-progress` state to match the existing test structure. Create a test that calls deriveProjectFieldValues with the same configuration and fields as the current test ("populates kickoff dates when the item is ready to start"), but replace the "status:ready" label with "status:in-progress". Verify that the result properly populates the startDate and targetDate fields to ensure the deriveProjectFieldValues function correctly handles both the ready and in-progress states, preventing regressions in this critical path.scripts/agents/run-labeling-agent.cjs (1)
3-7: ⚡ Quick winAdd JSDoc on
main()to keep JS docs/lint standards tidy.A short JSDoc block here keeps the new entrypoint aligned with the repo’s JS documentation rules.
As per coding guidelines, "JavaScript and TypeScript files must follow linting standards defined in instructions/languages.instructions.md, including JSDoc documentation."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/agents/run-labeling-agent.cjs` around lines 3 - 7, The main() function is missing JSDoc documentation which violates the repository's JavaScript documentation standards. Add a JSDoc block above the main() function definition that describes its purpose as the entrypoint for running the labeling agent. The JSDoc should be brief and clearly explain what the function does, using standard JSDoc syntax with description tags as appropriate.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/metadata-governance.yml:
- Around line 22-23: Add the persist-credentials parameter set to false in the
checkout action to enhance security. Locate the step with uses:
actions/checkout@v4 and add persist-credentials: false as a parameter under the
with section. This ensures that the GitHub token is not persisted for subsequent
steps, following security best practices when the workflow uses
pull_request_target with write permissions.
In @.github/workflows/project-meta-sync.yml:
- Line 136: The `titoportas/update-project-fields` action is pinned to a mutable
version tag (v0.1.0) which creates supply-chain risk. Replace the version tag
with the full commit SHA `421a54430b3cdc9eefd8f14f9ce0142ab7678751` for all
occurrences of the `titoportas/update-project-fields` action in the workflow
file to ensure only the specific, immutable commit is used.
In `@docs/ISSUE_FIELDS.md`:
- Around line 5-7: The frontmatter metadata at the top of the ISSUE_FIELDS.md
file has been updated with version v1.0.5, created_date 2026-05-31, and
last_updated 2026-06-18, but the visible "Version" and "Last Updated" fields
displayed within the document body still contain older values. Locate the
in-document "Version" and "Last Updated" fields (typically in a metadata or
header section within the visible content) and update them to match the
frontmatter values to maintain consistency across the documentation.
In `@docs/LABEL_COLOR_STRATEGY.md`:
- Around line 5-7: The frontmatter metadata in LABEL_COLOR_STRATEGY.md has been
updated to version v1.0.1 with created_date 2026-05-31 and last_updated
2026-06-18, but there is a visible metadata block elsewhere in the document that
still contains older version and date values. Locate the visible metadata block
in the document body and update its version and date fields to match the
frontmatter values (v1.0.1, created_date 2026-05-31, last_updated 2026-06-18) to
ensure consistency across the entire document.
In `@docs/LABELING.md`:
- Around line 5-6: The frontmatter metadata has been updated with version
'v1.0.2' and last_updated '2026-06-18', but the visible "Version" and "Last
Updated" sections elsewhere in the LABELING.md document still contain outdated
values. Find and update any "Version" or "Last Updated" section headers and
their corresponding values in the document body to match the frontmatter values
(v1.0.2 and 2026-06-18) to ensure consistency and prevent reader confusion.
In `@scripts/agents/includes/issue-pr-metadata.cjs`:
- Around line 58-68: The getItemFromEvent function lacks a defensive check to
validate that event.issue exists before attempting to access its properties
(number, node_id, title, body, etc.). If the event object lacks both
pull_request and issue properties, this code will throw a TypeError when trying
to access event.issue.number. Add a guard clause at the beginning of the
function or before the return statement that validates event.issue exists, and
either return a safe default value or throw a descriptive error if the required
event.issue data is missing.
In `@scripts/agents/run-labeling-agent.cjs`:
- Around line 3-7: The `main()` function is calling `runLabelingAgent()` without
passing any options, but the function expects an options object with a `dryRun`
property that should be populated from the `DRY_RUN` environment variable.
Modify the `main()` function to read the `DRY_RUN` environment variable and pass
it to `runLabelingAgent()` as an options object with the shape `{ dryRun:
<boolean-value> }`, ensuring the environment variable is properly converted to a
boolean since `runLabelingAgent()` expects `opts.dryRun` to determine the
workflow behavior.
---
Nitpick comments:
In @.github/workflows/metadata-governance.yml:
- Line 23: Replace the version tag reference in the actions/checkout action with
a SHA pin for stronger supply-chain security. Instead of using
`actions/checkout@v4`, pin the action to a specific commit SHA (e.g.,
`actions/checkout@<FULL_SHA>`). This should be done at both occurrences
mentioned in the comment to ensure consistent security practices throughout the
workflow, particularly since this workflow has write permissions.
In `@scripts/agents/includes/__tests__/derive-project-fields.test.js`:
- Around line 33-50: Add a new test case for the `status:in-progress` state to
match the existing test structure. Create a test that calls
deriveProjectFieldValues with the same configuration and fields as the current
test ("populates kickoff dates when the item is ready to start"), but replace
the "status:ready" label with "status:in-progress". Verify that the result
properly populates the startDate and targetDate fields to ensure the
deriveProjectFieldValues function correctly handles both the ready and
in-progress states, preventing regressions in this critical path.
In `@scripts/agents/includes/derive-project-fields.cjs`:
- Around line 22-33: The deriveProjectFieldValues function immediately
dereferences cfg on line 31 when accessing cfg.project_field_mappings without
any null or undefined check. If cfg is not provided or is null, this will throw
an error before any fallback logic can run. Add a default value for cfg in the
destructuring assignment of the deriveProjectFieldValues function parameters to
ensure cfg has a safe fallback value (such as an empty object) when it is not
provided.
In `@scripts/agents/includes/issue-pr-metadata.cjs`:
- Around line 273-318: The addSubIssueRelationship function currently makes two
separate GraphQL queries to fetch the parent and child issue IDs sequentially.
Consolidate these into a single GraphQL query that fetches both issue IDs at
once by modifying the query structure to accept both parentNumber and
childNumber as parameters and retrieve both parent.repository.issue.id and
child.repository.issue.id in the same query call. This will reduce the total API
calls from three to two, improving efficiency and reducing rate limit
consumption.
In `@scripts/agents/run-labeling-agent.cjs`:
- Around line 3-7: The main() function is missing JSDoc documentation which
violates the repository's JavaScript documentation standards. Add a JSDoc block
above the main() function definition that describes its purpose as the
entrypoint for running the labeling agent. The JSDoc should be brief and clearly
explain what the function does, using standard JSDoc syntax with description
tags as appropriate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 1aeb1833-d4c3-4ad0-9957-4b0a1c4d417a
📒 Files selected for processing (30)
.github/issue-fields.yml.github/workflows/README.md.github/workflows/labeling.yml.github/workflows/metadata-governance.yml.github/workflows/project-meta-sync.yml.github/workflows/template-enforcement.ymlagents/agent.mdagents/project-meta-sync.agent.mddocs/AUTOMATION.mddocs/GITHUB_PROJECT_OPERATIONS_SPEC.mddocs/ISSUE_CREATION_GUIDE.mddocs/ISSUE_FIELDS.mddocs/LABELING.mddocs/LABEL_COLOR_STRATEGY.mddocs/PR_CREATION_PROCESS.mddocs/WORKFLOW_COORDINATION.mddocs/agents/PLANNER_RUNBOOK.mdinstructions/automation.instructions.mdinstructions/project-meta-sync.instructions.mdscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/derive-project-fields.cjsscripts/agents/includes/issue-pr-metadata.cjsscripts/agents/includes/label-heuristics.jsscripts/agents/labeling.agent.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/run-labeling-agent.cjs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: coderabbit-gate
- GitHub Check: Mergify Merge Protections
- GitHub Check: Summary
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{php,js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{php,js,ts,jsx,tsx}: Follow WordPress Coding Standards for PHP files, ESLint/Prettier for JS/TS files, and PHPCS/WPCS for PHP files.
Security: Validate all input, escape all output, use nonces, never commit secrets.
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/label-heuristics.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/labeling.agent.js
**/*.{js,ts,jsx,tsx,html}
📄 CodeRabbit inference engine (CLAUDE.md)
Performance: Avoid unnecessary JS, defer/lazy-load where possible, prefer native blocks.
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/label-heuristics.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/labeling.agent.js
**/*.{php,js,ts}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not enqueue editor-only WordPress assets on the front end (and vice versa).
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/label-heuristics.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/labeling.agent.js
**/*.{php,js,css,html}
📄 CodeRabbit inference engine (AGENTS.md)
Follow WordPress Coding Standards (CSS, HTML, JavaScript, PHP) and inline-documentation standards at all times
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/label-heuristics.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/labeling.agent.js
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
JavaScript and TypeScript files must follow linting standards defined in instructions/languages.instructions.md, including JSDoc documentation
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/label-heuristics.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/labeling.agent.js
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
All test files must follow Jest testing standards and maintain minimum coverage thresholds as defined in instructions/quality-assurance.instructions.md
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.js
**/*.{js,ts}
⚙️ CodeRabbit configuration file
**/*.{js,ts}: Review JavaScript/TypeScript:
- Ensure code is linted and follows project style guides.
- Check for dead code, unused variables, and clear function naming.
- Validate accessibility and performance optimisations.
- Ensure tests are isolated and do not depend on external state.
- Check for descriptive test names and clear test structure.
Files:
scripts/agents/includes/__tests__/derive-project-fields.test.jsscripts/agents/includes/__tests__/label-utils.test.jsscripts/agents/includes/label-heuristics.jsscripts/agents/__tests__/project-meta-sync.agent.test.jsscripts/agents/project-meta-sync.agent.jsscripts/agents/includes/__tests__/issue-pr-metadata.test.jsscripts/agents/__tests__/labeling.agent.test.jsscripts/agents/labeling.agent.js
**/*.{md,markdown,txt,instructions.md}
📄 CodeRabbit inference engine (CLAUDE.md)
Language: Use UK English throughout (optimise, organisation, colour, behaviour).
Files:
docs/agents/PLANNER_RUNBOOK.mdinstructions/project-meta-sync.instructions.mdagents/project-meta-sync.agent.mdagents/agent.mddocs/LABELING.mddocs/LABEL_COLOR_STRATEGY.mddocs/GITHUB_PROJECT_OPERATIONS_SPEC.mddocs/ISSUE_FIELDS.mddocs/AUTOMATION.mddocs/PR_CREATION_PROCESS.mddocs/ISSUE_CREATION_GUIDE.mddocs/WORKFLOW_COORDINATION.mdinstructions/automation.instructions.md
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
All documentation must follow Markdown formatting standards and include YAML frontmatter as specified in instructions/documentation-formats.instructions.md
Files:
docs/agents/PLANNER_RUNBOOK.mdinstructions/project-meta-sync.instructions.mdagents/project-meta-sync.agent.mdagents/agent.mddocs/LABELING.mddocs/LABEL_COLOR_STRATEGY.mddocs/GITHUB_PROJECT_OPERATIONS_SPEC.mddocs/ISSUE_FIELDS.mddocs/AUTOMATION.mddocs/PR_CREATION_PROCESS.mddocs/ISSUE_CREATION_GUIDE.mddocs/WORKFLOW_COORDINATION.mdinstructions/automation.instructions.md
**/docs/**/*.md
⚙️ CodeRabbit configuration file
**/docs/**/*.md: Review documentation files:
- Ensure markdown is linted and formatted per project style guides.
- Flag illogical folder structures, file naming, or misplaced content.
- Confirm documentation is up to date, accurate, and cross-referenced.
- Ensure accessibility (heading hierarchy, alt text for images, UK English).
Files:
docs/agents/PLANNER_RUNBOOK.mddocs/LABELING.mddocs/LABEL_COLOR_STRATEGY.mddocs/GITHUB_PROJECT_OPERATIONS_SPEC.mddocs/ISSUE_FIELDS.mddocs/AUTOMATION.mddocs/PR_CREATION_PROCESS.mddocs/ISSUE_CREATION_GUIDE.mddocs/WORKFLOW_COORDINATION.md
**/*.instructions.md
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.instructions.md: Do not create instruction files with a 'references' frontmatter field; use inline links or footer sections instead.
Instruction files must follow the pattern: frontmatter + role declaration + Overview + General Rules + Detailed Guidance + Examples + Validation + References.
Files:
instructions/project-meta-sync.instructions.mdinstructions/automation.instructions.md
instructions/**
⚙️ CodeRabbit configuration file
instructions/**: Review portable instruction files:
- Verify frontmatter follows the canonical pattern (file_type, version, last_updated, owners, tags, status, domain, stability).
- Flag any
references:frontmatter field — prohibited by CLAUDE.md.- Confirm the file has: Overview, General Rules, Detailed Guidance, Examples, Validation, and Cross-References sections.
- Check that language is UK English throughout.
Files:
instructions/project-meta-sync.instructions.mdinstructions/automation.instructions.md
**/.github/workflows/*.yml
⚙️ CodeRabbit configuration file
**/.github/workflows/*.yml: Review GitHub Actions workflows for this governance repo:
- Security: check for least-privilege permissions (use
permissions:at job level, default to read-only).- Secret handling: ensure secrets are passed via env vars, not interpolated directly into run: steps to prevent injection.
- Action pinning: prefer SHA-pinned actions over mutable tags (e.g.
actions/checkout@v4is acceptable; SHA pins are better).- No
pull_request_targetwith untrusted code execution unless explicitly justified.- Avoid storing sensitive outputs as unmasked step outputs.
- Check for reusable workflow patterns and matrix strategies where appropriate.
- Validate
on:triggers: ensure branch/path filters are present to avoid unnecessary runs.- Confirm workflows are documented, DRY, and maintainable.
- Ensure agent-triggered workflows use
workflow_dispatchwith defined inputs.
Files:
.github/workflows/labeling.yml.github/workflows/metadata-governance.yml.github/workflows/project-meta-sync.yml.github/workflows/template-enforcement.yml
🪛 ESLint
scripts/agents/includes/__tests__/derive-project-fields.test.js
[error] 1-1: 'require' is not defined.
(no-undef)
[error] 2-2: 'require' is not defined.
(no-undef)
[error] 3-3: 'require' is not defined.
(no-undef)
[error] 4-4: 'require' is not defined.
(no-undef)
scripts/agents/__tests__/project-meta-sync.agent.test.js
[error] 5-5: 'require' is not defined.
(no-undef)
scripts/agents/run-labeling-agent.cjs
[error] 11-11: 'console' is not defined.
(no-undef)
[error] 12-12: 'console' is not defined.
(no-undef)
[error] 13-13: 'process' is not defined.
(no-undef)
scripts/agents/project-meta-sync.agent.js
[error] 32-32: 'require' is not defined.
(no-undef)
[error] 32-32: 'module' is not defined.
(no-undef)
[error] 39-39: 'module' is not defined.
(no-undef)
[error] 40-40: 'module' is not defined.
(no-undef)
[error] 41-41: 'module' is not defined.
(no-undef)
scripts/agents/includes/__tests__/issue-pr-metadata.test.js
[error] 8-8: 'require' is not defined.
(no-undef)
scripts/agents/includes/derive-project-fields.cjs
[error] 80-80: 'process' is not defined.
(no-undef)
[error] 81-81: 'process' is not defined.
(no-undef)
[error] 85-85: 'process' is not defined.
(no-undef)
[error] 93-93: 'process' is not defined.
(no-undef)
[error] 94-94: 'process' is not defined.
(no-undef)
[error] 95-95: 'process' is not defined.
(no-undef)
[error] 96-96: 'process' is not defined.
(no-undef)
[error] 97-97: 'process' is not defined.
(no-undef)
[error] 100-100: 'process' is not defined.
(no-undef)
scripts/agents/includes/issue-pr-metadata.cjs
[error] 235-235: 'console' is not defined.
(no-undef)
[error] 266-266: 'console' is not defined.
(no-undef)
[error] 394-394: 'console' is not defined.
(no-undef)
[error] 402-402: 'console' is not defined.
(no-undef)
[error] 421-421: 'process' is not defined.
(no-undef)
[error] 422-422: 'process' is not defined.
(no-undef)
[error] 423-423: 'process' is not defined.
(no-undef)
[error] 431-431: 'process' is not defined.
(no-undef)
[error] 432-432: 'process' is not defined.
(no-undef)
[error] 445-445: 'process' is not defined.
(no-undef)
[error] 447-447: 'process' is not defined.
(no-undef)
[error] 466-466: 'console' is not defined.
(no-undef)
[error] 467-467: 'process' is not defined.
(no-undef)
🪛 LanguageTool
docs/LABELING.md
[style] ~65-~65: Would you like to use the Oxford spelling “prioritized”? The spelling ‘prioritised’ is also correct.
Context: ...tant— High-impact work that should be prioritised soon -priority:normal` — Standard fea...
(OXFORD_SPELLING_Z_NOT_S)
docs/GITHUB_PROJECT_OPERATIONS_SPEC.md
[uncategorized] ~88-~88: Loose punctuation mark.
Context: ...nt Derivation source notes: - Status, Priority, and Type are mapped from ...
(UNLIKELY_OPENING_PUNCTUATION)
[uncategorized] ~88-~88: The official name of this software platform is spelled with a capital “H”.
Context: ..., and Type are mapped from labels via .github/issue-fields.yml mappings. - Effort ...
(GITHUB)
[uncategorized] ~91-~91: The official name of this software platform is spelled with a capital “H”.
Context: ... relationships is handled separately by .github/workflows/metadata-governance.yml. Cu...
(GITHUB)
[grammar] ~101-~101: There seems to be a noun/verb agreement error. Did you mean “writes” or “wrote”?
Context: ...Y` Safe automation boundary: - Active write path is limited to the five core derive...
(SINGULAR_NOUN_VERB_AGREEMENT)
docs/ISSUE_FIELDS.md
[style] ~457-~457: Consider using a more formal alternative.
Context: ...ocked - On hold: status:on-hold - Needs more info: status:needs-more-info - Closed: statu...
(MORE_INFO)
docs/ISSUE_CREATION_GUIDE.md
[uncategorized] ~130-~130: Do not mix variants of the same word (‘labelled’ and ‘labeled’) within a single text.
Context: ... - Incomplete templates are flagged and labelled for correction rather than closed. - Me...
(EN_EXACT_COHERENCY_RULE)
docs/WORKFLOW_COORDINATION.md
[uncategorized] ~447-~447: The official name of this software platform is spelled with a capital “H”.
Context: ...eferences - [Next Issues Execution Plan](../.github/projects/active/next-issues-execution-p...
(GITHUB)
🪛 zizmor (1.25.2)
.github/workflows/metadata-governance.yml
[warning] 22-23: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 3-7: use of fundamentally insecure workflow trigger (dangerous-triggers): pull_request_target is almost always used insecurely
(dangerous-triggers)
[error] 23-23: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 26-26: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
.github/workflows/project-meta-sync.yml
[error] 136-136: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🔇 Additional comments (46)
.github/issue-fields.yml (1)
29-29: LGTM!scripts/agents/includes/label-heuristics.js (1)
34-37: LGTM!docs/agents/PLANNER_RUNBOOK.md (1)
218-218: LGTM!scripts/agents/includes/__tests__/label-utils.test.js (1)
56-57: LGTM!Also applies to: 61-61, 333-334
.github/workflows/template-enforcement.yml (1)
59-71: LGTM!Also applies to: 73-95, 113-151
scripts/agents/includes/issue-pr-metadata.cjs (12)
1-8: LGTM!Also applies to: 471-484
13-19: LGTM!
21-40: LGTM!
70-88: LGTM!
90-150: LGTM!
152-193: LGTM!
195-271: LGTM!
351-418: LGTM!
420-443: LGTM!
464-469: LGTM!
320-349: Bot comment detection is correctly implemented using the standard GitHub API approach.The filter
comment.user?.type === "Bot"is the recommended way to identify bot comments in the GitHub API, andgithub-actions[bot]correctly returnsuser.type === "Bot". This approach is more robust than checking the login name for a[bot]suffix, as documented in GitHub's REST API guidance.
445-458: GitHub Actions output format cannot handle multi-line values in the current implementation.The code joins output lines with
\nand adds trailing newlines, which works perfectly for single-line values. However, GitHub Actions' standardkey=value\nformat is inherently newline-delimited and cannot safely handle values containing embedded newlines (e.g., milestone titles, assignee names, or linked reference descriptions with line breaks).If any of these values might contain newlines, switch to the heredoc syntax with a unique delimiter to ensure reliable parsing:
if (process.env.GITHUB_OUTPUT) { const delimiter = `EOF_${Date.now()}`; fs.appendFileSync( process.env.GITHUB_OUTPUT, `metadata_assignee<<${delimiter}\n${result.assignee || ""}\n${delimiter}\n` + `metadata_milestone<<${delimiter}\n${result.milestone || ""}\n${delimiter}\n` + // ... repeat for other fields ); }This approach guarantees correct parsing regardless of special characters or line breaks in the output values.
.github/workflows/metadata-governance.yml (4)
1-17: LGTM!
25-38: LGTM!
40-61: LGTM!
6-7:pull_request_targettrigger requires developer verification of script safety.The
pull_request_targettrigger runs with write permissions in the base branch context, which can be risky if untrusted code from the PR gets executed. This workflow appears to check out the base branch (default behaviour) and runs a script from the trusted codebase—not from the PR itself. However, I couldn't directly inspect the script to confirm it never dynamically requires or evaluates anything from the PR's source tree.Please verify that
scripts/agents/includes/issue-pr-metadata.cjsdoesn't userequire(),eval(), or similar patterns with paths or inputs controlled by the PR. If it only reads the event payload for metadata and makes API calls, the usage should be safe.Bonus notes:
- Consider setting
persist-credentials: falsein any checkout steps as a best practice with write permissions.- Action pinning to SHA is optional but would be a nice hardening step for future improvements.
.github/workflows/README.md (3)
5-5: LGTM!
48-48: LGTM!
84-88: LGTM!docs/AUTOMATION.md (1)
75-78: Excellent alignment with the new metadata governance split!The table correctly reflects the separation of concerns:
metadata-governance.ymlhandles assignees/milestones/relationships, whilstproject-meta-sync.ymlsyncs project fields. The new "Metadata Governance" section (lines 156–161) clearly articulates the automation contract, including the kickoff-aware date gating. Spot on!docs/GITHUB_PROJECT_OPERATIONS_SPEC.md (1)
86-91: 💤 Low valueTight kickoff-aware date-gating logic — perfectly aligned with the refactored derive-project-fields.cjs.
Lines 84–91 clearly articulate that
Start dateandTarget dateremain empty until an item reachesstatus:readyorstatus:in-progress. This mirrors the PR's refactored project-field derivation and prevents premature date population. Excellent contract clarity!A minor note: the linting tool flagged a loose punctuation mark around line ~88 (likely a whitespace artifact before the bullet dash). If you spot errant spacing, a quick trim will keep the markup tidy.
docs/PR_CREATION_PROCESS.md (1)
130-140: Brilliant addition of the linked development requirement!Line 139's requirement for linked development references (
Closes #,Fixes #,Related to #) is spot on — it's essential for the newissue-pr-metadata.cjsscript to capture and parse relationship hints correctly. Similarly, line 138 correctly notes that the PR author is auto-assigned unless a local rule overrides, which aligns perfectly with the new metadata-governance workflow. The label example update totype:documentation(line 131) is also consistent with the label taxonomy overhaul. Nice cohesion!docs/WORKFLOW_COORDINATION.md (1)
51-52: Perfect placement of the new metadata workflows in the Always-Run registry!Lines 51–52 correctly document
metadata-governance.yml(issues/pull_request_target triggers) andproject-meta-sync.yml(push/issues/pull_request triggers) as always-run, metadata-only workflows. This aligns beautifully with the PR's separation of concerns: metadata governance runs on issue/PR events, whilst project-meta-sync runs on code/issue/PR events to keep the project board in sync. The registry now clearly reflects the split that was implemented. Excellent clarity!agents/agent.md (1)
3-4: Spot-on deprecation marking for the legacy project-meta-sync agent!The version bump (v2.1 → v2.1.1) and updated description at line 62 clearly signal that
project-meta-sync.agent.mdis now a deprecated compatibility spec, not the active contract. This is exactly the right tone for guiding maintainers away from the old path and towards the new metadata-governance and derive-project-fields workflows. Crystal clear!Also applies to: 62-62
agents/project-meta-sync.agent.md (1)
1-5: Exemplary deprecation guidance — crystal clear and unambiguous!The updated description (lines 3–5) and guardrails (lines 70–71) leave zero room for misinterpretation: this spec is deprecated, compatibility-only, and the active automation lives in
project-meta-sync.yml,metadata-governance.yml, and their helper scripts. This kind of explicit guardrailing prevents future confusion and guides maintainers straight to the current truth. Top-tier deprecation practice!Also applies to: 70-71
instructions/automation.instructions.md (1)
284-284: Excellent alignment of priority taxonomy and script invocation!Lines 284 and 548–551 correctly update the priority label examples and field mappings to reflect the new four-level taxonomy:
critical,important,normal,minor. This is consistent with the label taxonomy overhaul across the PR.More critically, line 570 updates the project sync script invocation from the deprecated
project-meta-sync.agent.jsto the refactoredincludes/derive-project-fields.cjs. This is the heart of the metadata governance split: derive-project-fields now handles the project-field syncing logic with kickoff-aware date gating, whilst metadata-governance handles the assignee/milestone/relationship metadata.Top-notch alignment of documentation with the implementation refactor!
Also applies to: 548-551, 570-570
docs/ISSUE_CREATION_GUIDE.md (1)
102-132: No action needed—UK English is correctly applied in prose.The file correctly uses British spelling ("labelled") in the documentation text. The American spellings present (
labeling.yml,labeled/unlabeledevents) are references to actual GitHub Actions workflow file names and API event types, which are fixed artefacts that cannot be changed for style consistency. Conflating code references with prose style is a category error. The documentation already complies with the UK English requirement for markdown files.> Likely an incorrect or invalid review comment.instructions/project-meta-sync.instructions.md (2)
4-6: ⚡ Quick winVerify apply_to targets align with the deprecation narrative.
The description states this is "deprecated compatibility guidance," yet
.github/workflows/project-meta-sync.yml(line 22) remains in the apply_to list without being marked as removed. The AI summary claims it should be removed, but it's still present.If project-meta-sync.yml is truly deprecated, should it be:
- Removed from apply_to entirely, or
- Kept as a target because the instruction still governs its legacy contract?
Please clarify the intent — either way, the apply_to list should be consistent with the deprecation narrative once the file body is added.
Also applies to: 23-25
1-26: Confirm whether instruction file body sections are present beyond the frontmatter.The frontmatter is properly structured with all required metadata fields, and no prohibited
referencesfield is present. However, the code snippet shows only the frontmatter ending at line 26. Per coding guidelines, instruction files must follow this structure:frontmatter + role declaration + Overview + General Rules + Detailed Guidance + Examples + Validation + References
If the body sections (Overview, General Rules, Detailed Guidance, Examples, Validation, and References) are truly missing or incomplete, this constitutes a structural violation of the required instruction file format. Given that the file is marked as deprecated guidance, the Overview section should at minimum redirect readers to the active project-meta-sync and metadata-governance workflows.
scripts/agents/includes/derive-project-fields.cjs (1)
79-100: ESLint configuration forprocessglobal in CommonJS scripts needs verification.This file uses
processglobally (lines 80–100), which may trigger ESLint'sno-undefrule if Node globals aren't declared. Please verify your project's ESLint setup:
- Check whether
.cjsfiles orscripts/**have an environment override that declares Node globals- If not already configured, add
/* eslint-env node */as a file header or configure an ESLint override for CommonJS scriptsscripts/agents/includes/__tests__/issue-pr-metadata.test.js (2)
8-8: Same lint/env snag here at Line 8 (require).
10-277: LGTM!scripts/agents/__tests__/project-meta-sync.agent.test.js (2)
5-5: Duplicate of therequirelint/env issue (Line 5).
7-27: LGTM!scripts/agents/__tests__/labeling.agent.test.js (1)
1-78: LGTM!scripts/agents/includes/__tests__/derive-project-fields.test.js (1)
1-4: ESLint gets twitchy with CommonJSrequirestatements in this Jest test file.When using CommonJS
require()in Jest tests without explicit ESLint configuration, theno-undeflinter will rightfully complain aboutrequire,module, and Jest globals not being defined. The fix is straightforward—add an ESLint environment directive at the top of the file to inform the linter that Node and Jest globals are available:Quick fix for this file
+/* eslint-env node, jest */ const fs = require("fs"); const path = require("path"); const yaml = require("js-yaml"); const { deriveProjectFieldValues } = require("../derive-project-fields.cjs");Alternatively, ensure your project's ESLint configuration properly defines the Node and Jest environments via
.eslintrcoreslint.config.jsto avoid duplicating this comment across all test files.Per the coding guidelines, JavaScript files must follow linting standards—this blocks the pipeline unless addressed.
scripts/agents/project-meta-sync.agent.js (2)
3-30: LGTM!
32-41: A sneaky module-format gremlin: CJS globals in this.jsshim can break execution.Lines 32 and 39–41 use
require/module.exports, while static analysis already flagsno-undefhere. If this file is treated as ESM (as in sibling agent.jsfiles), the shim can fail before returning the deprecation descriptor.scripts/agents/labeling.agent.js (1)
23-24: LGTM!.github/workflows/labeling.yml (1)
93-93: LGTM!scripts/agents/run-labeling-agent.cjs (1)
11-13: Ensure ESLint configuration applies Node globals to.cjsfiles.Static analysis is flagging
consoleandprocessas undefined on these lines. Verify that your ESLint config properly handles.cjsfiles with Node environment settings—otherwise, this shiny new entrypoint might hit lint gate troubles.
| return { | ||
| kind: "issue", | ||
| number: event.issue.number, | ||
| nodeId: event.issue.node_id, | ||
| title: event.issue.title || "", | ||
| body: event.issue.body || "", | ||
| labels: Array.isArray(event.issue.labels) ? event.issue.labels : [], | ||
| milestone: event.issue.milestone || null, | ||
| author: event.issue.user?.login || "", | ||
| }; | ||
| } |
There was a problem hiding this comment.
Potential crash when neither pull_request nor issue exists in event.
If getItemFromEvent is called with an event that lacks both pull_request and issue (e.g., a malformed or unexpected event type), this will throw a TypeError when accessing event.issue.number.
A defensive check would make this more resilient:
🛡️ Proposed defensive guard
}
+ if (!event.issue) {
+ throw new Error("Event payload contains neither pull_request nor issue");
+ }
+
return {
kind: "issue",
number: event.issue.number,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return { | |
| kind: "issue", | |
| number: event.issue.number, | |
| nodeId: event.issue.node_id, | |
| title: event.issue.title || "", | |
| body: event.issue.body || "", | |
| labels: Array.isArray(event.issue.labels) ? event.issue.labels : [], | |
| milestone: event.issue.milestone || null, | |
| author: event.issue.user?.login || "", | |
| }; | |
| } | |
| if (!event.issue) { | |
| throw new Error("Event payload contains neither pull_request nor issue"); | |
| } | |
| return { | |
| kind: "issue", | |
| number: event.issue.number, | |
| nodeId: event.issue.node_id, | |
| title: event.issue.title || "", | |
| body: event.issue.body || "", | |
| labels: Array.isArray(event.issue.labels) ? event.issue.labels : [], | |
| milestone: event.issue.milestone || null, | |
| author: event.issue.user?.login || "", | |
| }; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/agents/includes/issue-pr-metadata.cjs` around lines 58 - 68, The
getItemFromEvent function lacks a defensive check to validate that event.issue
exists before attempting to access its properties (number, node_id, title, body,
etc.). If the event object lacks both pull_request and issue properties, this
code will throw a TypeError when trying to access event.issue.number. Add a
guard clause at the beginning of the function or before the return statement
that validates event.issue exists, and either return a safe default value or
throw a descriptive error if the required event.issue data is missing.
|
@Mergifyio queue |
Merge Queue Status
Waiting for
All conditions
|
|
@Mergifyio queue |
☑️ Command
|
2d20ab6 to
c5a37c7
Compare
🎨 Mermaid Diagram Validation✅ All Mermaid diagram checks passed.
|
Superseded by follow-up commits and passing validation on the current head.
Linked issues
Relates to #968
Summary
Changelog
Added
Changed
status:readyorstatus:in-progress.Fixed
Removed
Risk Assessment
Risk Level: Medium
Potential Impact:
This change touches metadata automation and the supporting docs, but keeps the scope to governance and project-field sync.
Mitigation Steps:
How to Test
Prerequisites
Test Steps
Expected Results
Start dateandTarget dateremain empty until kickoff.Edge Cases to Verify
Checklist (Global DoD / PR)