Compare commits

...

2 Commits

Author SHA1 Message Date
AutoPatchBot f3a1a5f6bd Update agent docs and reference READMEs
- Update pr-review-supervisor.md agent documentation
- Update pr-review-worker.md agent documentation
- Update 13 references/scripts/README.md files with new version info or descriptions related to milestone-based PR prioritization
2026-05-11 02:45:40 +00:00
AutoPatchBot a85d44902c update auto-agents-system scripts 2026-05-11 01:48:54 +00:00
16 changed files with 162 additions and 29 deletions
+7 -3
View File
@@ -238,13 +238,17 @@ worker parameters:
- `branch_name`: The name of the PR head branch
- `head_sha`: The current head commit SHA of the PR branch
- `ci_status`: Current CI status for the head commit
- `priority_rank`: Priority rank from labels (0=CI Blocker through 6=unlabelled)
- `priority_rank`: Merged priority rank from both label and milestone urgency (0=overdue milestone/CI Blocker, higher=lower urgency)
- `label_priority_rank`: Rank derived solely from Priority/* labels (0-5, or PRIORITY_NONE if unlabelled)
- `priority_label`: The matched Priority/* label name, or null
- `milestone_title`: Assigned milestone title for the PR, or null if no milestone
- `milestone_due`: ISO 8601 deadline string for the milestone, or null
- `milestone_rank`: Milestone urgency rank (0=overdue, 1=today, 2=within 7 days, 3=beyond/none)
- `review_type`: Whether this is a "re_review" (from addressed_changes groups), "first_review" (from no_active_review groups), or "ci_flag" (from missing_ci_checks group)
worker parameter fetch algorithms:
- `pr_number`: Taken directly from the task item returned by the work group fetch algorithm
- `pr_title`, `branch_name`, `head_sha`, `ci_status`, `priority_rank`, `priority_label`: returned explicitly from the various `list_prs_*` scripts detailed in the work group's fetch algorithm
- `pr_number`, `pr_title`, `branch_name`, `head_sha`: Taken directly from the task item returned by the work group fetch algorithm.
- `ci_status`, `priority_rank`, `label_priority_rank`, `priority_label`, `milestone_title`, `milestone_due`, `milestone_rank`: return explicitly from the various `list_prs_*` scripts detailed in the work group's fetch algorithm.
- `review_type`: Determined by the work group:
`addressed_changes_ci_passing` and `addressed_changes_ci_failing` → "re_review"
`no_active_review_ci_passing` and `no_active_review_ci_failing` → "first_review"
+14 -2
View File
@@ -277,8 +277,12 @@ The following represents all variables this agent works with:
| Branch name | `branch_name` | Name of the PR head branch |
| Head SHA | `head_sha` | Current head commit SHA |
| CI status | `ci_status` | CI status for the head commit |
| Priority rank | `priority_rank` | Priority rank from labels (0=highest, 6=unlabelled) |
| Priority rank | `priority_rank` | Merged priority from labels + milestone urgency (0=highest, ~7+=lowest) |
| Label priority rank | `label_priority_rank` | Rank derived solely from Priority/* label (0-5 or PRIORITY_NONE) |
| Priority label | `priority_label` | Matched Priority/* label name, or null |
| Milestone title | `milestone_title` | Assigned milestone title, or null if no milestone |
| Milestone due | `milestone_due` | ISO 8601 milestone deadline string, or null |
| Milestone rank | `milestone_rank` | Milestone urgency: 0=overdue, 1=today, 2=within 7 days, 3=beyond/none |
| Review type | `review_type` | "re_review", "first_review", or "ci_flag" |
@@ -304,7 +308,11 @@ All of the variables listed in the table below may be passed in your prompt. Som
| Head SHA | yes | `head_sha` |
| CI status | yes | `ci_status` |
| Priority rank | no | `priority_rank` |
| Label priority rank | no | `label_priority_rank` |
| Priority label | no | `priority_label` |
| Milestone title | no | `milestone_title` |
| Milestone due | no | `milestone_due` |
| Milestone rank | no | `milestone_rank` |
| Review type | yes | `review_type` |
Your prompt may also contain parameters beyond those listed in the table above. The supervisor does not interpret or validate these — they are treated as opaque pass-through values and must be forwarded verbatim to every worker invocation. This allows the caller to inject worker-specific context (such as credentials or domain-specific instructions) without the supervisor needing to understand it.
@@ -327,8 +335,12 @@ pr_title: "fix(auth): correct token refresh endpoint"
branch_name: "bugfix/m5-token-refresh"
head_sha: "abc123def456"
ci_status: "passing"
priority_rank: 2
label_priority_rank: 2
priority_rank: 4
priority_label: "Priority/High"
milestone_title: "v2.0 Release"
milestone_due: "2026-05-12T00:00:00Z"
milestone_rank: 1
review_type: "first_review"
Review the indicated Pull Request.
@@ -103,7 +103,8 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `failing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `label_priority_rank` | integer | Rank derived solely from a Priority/* label (0-5), or PRIORITY_NONE if unlabelled. Only present when list_prs is called directly; passed through by wrapper scripts. |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has failing CI, zero
@@ -104,7 +104,8 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `passing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `label_priority_rank` | integer | Rank derived solely from a Priority/* label (0-5), or PRIORITY_NONE if unlabelled. Only present when list_prs is called directly; passed through by wrapper scripts. |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has passing CI, zero
@@ -102,7 +102,7 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `passing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has passing CI, zero
@@ -97,7 +97,7 @@ with four fields:
| `approvals_count` | integer | Any value — **not filtered** by this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `failing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has failing CI — the
@@ -102,7 +102,8 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `unknown` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `label_priority_rank` | integer | Rank derived solely from a Priority/* label (0-5), or PRIORITY_NONE if unlabelled. Only present when list_prs is called directly; passed through by wrapper scripts. |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has unknown CI status, zero
@@ -91,7 +91,7 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Will always be `not_stale` for results of this script |
| `ci_status` | string | `passing`, `failing`, `pending`, or `unknown`**not filtered**; any CI state is included |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` is a valid and common result — it means all open
@@ -87,7 +87,7 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Will always be `stale_no_conflicts` for results of this script |
| `ci_status` | string | `passing`, `failing`, `pending`, or `unknown`**not filtered**; any CI state is included |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` is a valid and common result — it means no open
@@ -87,7 +87,7 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Will always be `stale_with_conflicts` for results of this script |
| `ci_status` | string | `passing`, `failing`, `pending`, or `unknown`**not filtered**; any CI state is included |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` is a valid and common result — it means no open
@@ -94,7 +94,8 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `failing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `label_priority_rank` | integer | Rank derived solely from a Priority/* label (0-5), or PRIORITY_NONE if unlabelled. Only present when list_prs is called directly; passed through by wrapper scripts. |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has failing CI, zero
@@ -94,7 +94,8 @@ with four fields:
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `passing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `label_priority_rank` | integer | Rank derived solely from a Priority/* label (0-5), or PRIORITY_NONE if unlabelled. Only present when list_prs is called directly; passed through by wrapper scripts. |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently has passing CI, zero
@@ -95,7 +95,7 @@ with four fields:
| `approvals_count` | integer | Will always be ≥ 1 for results of this script |
| `stale_state` | string | Will always be `not_stale` for results of this script |
| `ci_status` | string | Will always be `passing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently satisfies both conditions.
@@ -87,7 +87,7 @@ with four fields:
| `approvals_count` | integer | Will always be ≥ 1 for results of this script |
| `stale_state` | string | Will always be `stale_no_conflicts` for results of this script |
| `ci_status` | string | `passing`, `failing`, `pending`, or `unknown`**not filtered**; any CI state is included |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently matches all three conditions.
@@ -94,7 +94,7 @@ with four fields:
| `approvals_count` | integer | Will always be ≥ 1 for results of this script |
| `stale_state` | string | Will always be `stale_with_conflicts` for results of this script |
| `ci_status` | string | `passing`, `failing`, `pending`, or `unknown`**not filtered**; any CI state is included |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_rank` | integer | Merged priority from labels + milestone urgency; lower = more urgent. Ranges from 0 (overdue milestone / CI Blocker label) to ~7+ (low-unlabelled PR with far-away or no deadline). |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |
An **empty array** `[]` means no open PR currently matches all three conditions.
@@ -81,8 +81,12 @@ export interface AugmentedPR extends RawPR {
approvals_count: number;
stale_state: StaleState;
ci_status: CIStatus;
priority_rank: number; // 0 = CI Blocker (highest), higher = lower; PRIORITY_NONE if unlabelled
priority_rank: number; // 0=Overdue Milestone/CI Blocker (highest), higher = lower
label_priority_rank: number; // rank from Priority/* label (0-5) or PRIORITY_NONE
priority_label: string | null; // matched Priority/* label name, or null if none
milestone_title: string | null;// milestone title, or null if no milestone set
milestone_due: string | null; // ISO 8601 deadline string, or null if no milestone
milestone_rank: number; // urgency rank from milestone (0-3), MILESTONE_LOW for none
}
interface Review {
@@ -122,8 +126,24 @@ const PRIORITY_ORDER = new Map<string, number>([
]);
const PRIORITY_NONE = 6; // rank for PRs with no recognised Priority/* label
// Milestone-urgency thresholds — lower rank number = more urgent milestone.
// Derived from the due_on date (ISO 8601) relative to the current time.
// Any PR without a milestone gets MILESTONE_LOW so it is sorted below
// every labelled or deadline-driven PR.
const MILESTONE_OVERDUE = 0; // already past due_on
const MILESTONE_TODAY = 1; // due today (same calendar day)
const MILESTONE_WEEK = 2; // due within the next 7 days
const MILESTONE_MONTH = 3; // due beyond 7 days or no milestone at all
// ─────────────────────────────────────────────────────────────────────────────
// pLimit — run an array of async tasks with bounded concurrency
// prMilestoneRank — compute urgency rank from a PR's milestone due_on date
//
// Inspects pr.milestone (a Forgejo Milestone object with title and due_on) and
// returns the urgency-based rank:
// 0 = overdue (past due_on), 1 = due today, 2 = due within 7 days,
// 3 = due beyond 7 days or no milestone at all
// ──
//
// Spawns `limit` worker coroutines that each pull the next available task from
// the shared queue. Results are returned in input order.
@@ -240,6 +260,78 @@ function prPriority(pr: RawPR): { rank: number; label: string | null } {
return { rank: bestRank, label: bestLabel };
}
// ─────────────────────────────────────────────────────────────────────────────
// prMilestoneRank — compute urgency-based PR rank from milestone due_on date
//
// Inspects pr.milestone (a Forgejo Milestone object with title and due_on) and
// returns the urgency-based rank:
// 0 = overdue (already past due_on), 1 = due today, 2 = due within 7 days,
// 3 = due beyond 7 days or no milestone at all
//
// Also extracts the milestone title and due_on string for output. The caller
// uses these to merge with label-based priority below.
// ─────────────────────────────────────────────────────────────────────────────
function prMilestoneRank(
pr: RawPR,
): { rank: number; title: string | null; due: string | null } {
const milestone = pr.milestone as Record<string, unknown> | null | undefined;
if (!milestone || typeof milestone !== 'object') return { rank: MILESTONE_MONTH, title: null, due: null };
const dueOn = (milestone.due_on as string | undefined) ?? null;
const title = (milestone.title as string | undefined) ?? null;
if (!dueOn) return { rank: MILESTONE_MONTH, title, due: null };
const now = Date.now();
const deadline = new Date(dueOn).getTime();
const diffMs = deadline - now;
const oneDay = 86_400_000;
// Deadline is today → high urgency (rank 1)
if (diffMs <= oneDay) return { rank: MILESTONE_TODAY, title, due: dueOn };
// Deadline is within the next week → medium urgency (rank 2)
const sevenDays = 7 * oneDay;
if (diffMs <= sevenDays) return { rank: MILESTONE_WEEK, title, due: dueOn };
// Beyond a week or no deadline → low urgency (rank 3)
return { rank: MILESTONE_MONTH, title, due: dueOn };
}
// ─────────────────────────────────────────────────────────────────────────────
// mergePriority — combine label-based and milestone-based priority into one rank
//
// Priority is based on whichever source has the stronger (lower) rank.
// This gives urgent milestones a chance to climb above PRs that only have
// low Priority/* labels and vice-versa. Label-based priority acts as a tie-
// breaker when both ranks are equal, so that a labelled PR beats an unlabelled
// one at the same milestone urgency level.
// ─────────────────────────────────────────────────────────────────────────────
function mergePriority(
labelRank: number,
labelLabel: string | null,
milestoneRank: number,
): { final_rank: number; label_priority_rank: number; priority_label: string | null } {
if (labelRank < milestoneRank) {
// Label is stronger → use label rank
return { final_rank: labelRank, label_priority_rank: labelRank, priority_label: labelLabel };
}
if (milestoneRank < labelRank) {
// Milestone is stronger → use milestone rank with a bump based on label strength
// to break ties within the same milestone urgency level.
// The base milestone rank starts at 0-3; we add label_priority_rank as an
// offset starting from PRIORITY_NONE so that labelled PRs sort ahead of
// unlabelled ones at equal milestone urgency.
const finalRank = milestoneRank + Math.max(PRIORITY_NONE - 4, 0);
return { final_rank: finalRank, label_priority_rank: labelRank, priority_label: labelLabel };
}
// Equal ranks → labelled PR wins (lower offset from MILESTONE_MONTH baseline)
const combinedRank = milestoneRank + Math.max(PRIORITY_NONE - 4, 0);
return { final_rank: combinedRank, label_priority_rank: labelRank, priority_label: labelLabel };
}
// ─────────────────────────────────────────────────────────────────────────────
// countApprovals — distinct non-dismissed APPROVED review count for a PR
//
@@ -494,14 +586,26 @@ export async function listPRs(
if (filters.hasUnaddressedRequestChanges !== undefined &&
hasUnaddressedRequestChangesCheck(allReviews[i], pr.head.sha) !== filters.hasUnaddressedRequestChanges) continue;
const { rank: priorityRank, label: priorityLabel } = prPriority(pr);
// ── Compute label priority ────────────────────────────────────────────────
const { rank: labelPriorityRank, label: priorityLabel } = prPriority(pr);
// ── Compute milestone urgency ─────────────────────────────────────────────
const { rank: milestoneRank, title:milestoneTitle, due:milestoneDue } = prMilestoneRank(pr);
// ── Merge into combined priority_rank ─────────────────────────────────────
const { final_rank } = mergePriority(labelPriorityRank, priorityLabel, milestoneRank);
results.push({
...pr,
approvals_count: approvalsCount,
stale_state: staleState,
ci_status: ciStatus,
priority_rank: priorityRank,
priority_label: priorityLabel,
approvals_count: approvalsCount,
stale_state: staleState,
ci_status: ciStatus,
priority_rank: final_rank,
label_priority_rank: labelPriorityRank,
priority_label: priorityLabel,
milestone_title: milestoneTitle,
milestone_due: milestoneDue,
milestone_rank: milestoneRank,
});
}
@@ -648,9 +752,17 @@ the full Forgejo PR plus:
.approvals_count integer distinct non-dismissed APPROVED review count
.stale_state string one of the stale states listed above
.ci_status string passing|failing|pending|unknown (see --ci-status above)
.priority_rank integer 0=CI Blocker, 1=Critical, 2=High, 3=Medium,
4=Low, 5=Backlog, 6=none (unlabelled)
.priority_label string|null matched Priority/* label name, or null
.priority_rank integer priority rank the lower the number, the higher
the urgency; ranges from 0 (overdue milestone /
CI Blocker label) to ~7+ (low-unlabelled PR).
See merged priority computation in file header.
.label_priority_rank integer rank derived solely from a Priority/* label
(0-5), or PRIORITY_NONE if no such label exists
.priority_label string|null matched Priority/* label name, or null
.milestone_title string|null milestone title assigned to the PR, or null
.milestone_due string|null ISO 8601 deadline of the milestone, or null
.milestone_rank integer urgency derived from deadline:
0=overdue, 1=today, 2=within 7 days, 3=beyond / none
`);
}