@@ -187,10 +187,12 @@ jobs:
187187 else if (isTier2) tier = 2;
188188 else tier = 3;
189189
190- // Escalate very large non-critical PRs to Tier 4; this also applies to agent
191- // branches that were bumped to Tier 3 above — a 400+ line agent-generated change
192- // warrants deep review regardless of which files it touches.
193- if (tier === 3 && linesChanged > 400) tier = 4;
190+ // Escalate very large non-critical PRs to Tier 4. Agent branches use a lower
191+ // threshold (400 lines) since they warrant deeper scrutiny. Human-authored PRs
192+ // are only escalated for truly massive diffs (1000+ lines); Tier 3 already
193+ // requires full human review, so smaller large PRs don't need the extra urgency.
194+ const sizeThreshold = isAgentBranch ? 400 : 1000;
195+ if (tier === 3 && linesChanged > sizeThreshold) tier = 4;
194196
195197 // Apply label
196198 for (const existing of currentLabels) {
@@ -204,22 +206,43 @@ jobs:
204206
205207 // Build comment body
206208 const info = TIER_INFO[tier];
207- const signals = [];
208- if (isTier4) signals.push('critical-path files detected');
209- if (isAgentBranch) signals.push(`agent branch (\`${branchName}\`)`);
210- if (linesChanged > 400) signals.push(`large diff (${linesChanged} lines changed)`);
211- if (isTrivialAuthor) signals.push(`bot author (${author})`);
212- if (allFilesTrivial && !isTrivialAuthor) signals.push('all files are docs/images/lock files');
213- if (touchesApiModels) signals.push('API routes or data models changed');
214209
215- const signalList = signals.length > 0 ? `\n**Signals**: ${signals.join(', ')}` : '';
210+ // Primary triggers — what actually determined (or escalated) the tier
211+ const triggers = [];
212+ const criticalFiles = files.filter(f => TIER4_PATTERNS.some(p => p.test(f)));
213+ if (criticalFiles.length > 0) {
214+ triggers.push(`**Critical-path files** (${criticalFiles.length}):\n${criticalFiles.map(f => ` - \`${f}\``).join('\n')}`);
215+ }
216+ if (tier === 4 && linesChanged > sizeThreshold && criticalFiles.length === 0) {
217+ triggers.push(`**Large diff**: ${linesChanged} lines changed (threshold: ${sizeThreshold})`);
218+ }
219+ if (isTrivialAuthor) triggers.push(`**Bot author**: \`${author}\``);
220+ if (allFilesTrivial && !isTrivialAuthor) triggers.push('**All files are docs / images / lock files**');
221+ // Agent branch prevents Tier 2 — it's a cause for Tier 3, not just context
222+ if (isAgentBranch && tier <= 3) triggers.push(`**Agent-generated branch** (\`${branchName}\`) — bumped to Tier 3 for mandatory human review`);
223+ // Catch-all for Tier 3 PRs that don't match any specific trigger above
224+ if (triggers.length === 0 && tier === 3) triggers.push('**Standard feature/fix** — introduces new logic or modifies core functionality');
225+
226+ // Informational signals — didn't drive the tier by themselves
227+ const contextSignals = [];
228+ if (isAgentBranch && tier === 4) contextSignals.push(`agent branch (\`${branchName}\`)`);
229+ if (touchesApiModels && criticalFiles.length === 0) contextSignals.push('touches API routes or data models');
230+ if (linesChanged > sizeThreshold && criticalFiles.length > 0) contextSignals.push(`large diff (${linesChanged} lines)`);
231+
232+ const triggerSection = triggers.length > 0
233+ ? `\n**Why this tier:**\n${triggers.map(t => `- ${t}`).join('\n')}`
234+ : '';
235+ const contextSection = contextSignals.length > 0
236+ ? `\n**Additional context:** ${contextSignals.join(', ')}`
237+ : '';
216238
217239 const body = [
218240 '<!-- pr-triage -->',
219241 `## ${info.emoji} ${info.headline}`,
220242 '',
221243 info.detail,
222- signalList,
244+ triggerSection,
245+ contextSection,
223246 '',
224247 `**Review process**: ${info.process}`,
225248 `**SLA**: ${info.sla}`,
0 commit comments