import { REVIEW_CONSTANTS, isBuildRelatedDim } from './review-constants'; export interface HardRuleContext { buildFailed: boolean; testStepFailed: boolean; duplicateRatio: number; hasAnyReadme: boolean; hasRootReadme: boolean; } export interface HardRuleDim { name: string; score: number; maxScore: number; } export interface HardRuleResult { dimensions: HardRuleDim[]; log: string[]; } /** * 评审 Phase 3c:确定性硬规则封顶(校准后执行)。 * 纯函数、不修改入参;封顶只降不升。 */ export function applyHardRules( dims: HardRuleDim[], ctx: HardRuleContext ): HardRuleResult { const log: string[] = []; const dimensions = dims.map(d => { const name = d.name; let cap = d.maxScore; const isBuildCapDim = isBuildRelatedDim(name); if (ctx.buildFailed && isBuildCapDim) cap = Math.min(cap, Math.floor(d.maxScore * REVIEW_CONSTANTS.BUILD_FAIL_CAP_RATIO)); if (ctx.buildFailed && name.includes('效果与数据')) cap = Math.min(cap, Math.floor(d.maxScore * REVIEW_CONSTANTS.EFFECT_DATA_BUILD_FAIL_RATIO)); if (ctx.testStepFailed && (name.includes('效果与数据') || isBuildCapDim)) cap = Math.min(cap, Math.floor(d.maxScore * REVIEW_CONSTANTS.TEST_FAIL_CAP_RATIO)); if (ctx.duplicateRatio > REVIEW_CONSTANTS.DUP_RATIO_CAP_TRIGGER && name.includes('代码规范')) cap = Math.min(cap, REVIEW_CONSTANTS.DUP_CAP_SCORE); if (!ctx.hasAnyReadme && name.includes('演示与文档')) cap = Math.min(cap, REVIEW_CONSTANTS.NO_README_CAP); else if (!ctx.hasRootReadme && name.includes('演示与文档')) cap = Math.min(cap, REVIEW_CONSTANTS.NO_ROOT_README_CAP); let score = d.score; if (score > cap) { log.push(`${name} ${score}→${cap}(超上限${cap})`); score = cap; } return { name, score, maxScore: d.maxScore }; }); return { dimensions, log }; }