feat(retry+decompose): 范围型驳回不重试 + 拆解 prompt 补 scope 铁律
- ingest:复审 reject 时若任务有 scopeFiles 且理由命中越界/范围外/声明范围等标记 → 判为范围型驳回,调 store.failScopeReject 直接转 needs_attention(清退避、不进重试链),因 executor 碰不了范围外文件、重试必然同样被驳回;- store.failScopeReject:补记 failed run 承载原因 + 直转 needs_attention(带单测);- runner 拆解 prompt:加「files 范围铁律」——覆盖全跨层足迹 / 后端能力别塞前端范围 / 宁空勿窄 / 全或空。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -834,6 +834,24 @@ export class Store {
|
||||
return this.getTask(taskId)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* 范围型驳回:复审因「任务需求超出其声明范围(scopeFiles)」而拒——重试 executor 必然无解(它碰不了范围外文件,
|
||||
* 只会同样被驳回,盲目重试到 needs_attention 纯属浪费)。故不进重试链:补记一条 failed executor run 承载原因
|
||||
* (供 UI lastRunError 兜底显示),直接转 needs_attention,待人工放宽 scopeFiles 或回 planner 重新拆解。
|
||||
*/
|
||||
failScopeReject(taskId: string, reason: string): Task {
|
||||
const row = this.getTaskRow(taskId);
|
||||
if (!row) throw new StoreError(`任务不存在: ${taskId}`);
|
||||
const r = this.startRun(taskId, 'executor');
|
||||
this.finishRun(r.id, 'failed', { error: reason });
|
||||
if ((this.getTaskRow(taskId)!.status as TaskStatus) !== 'failed') {
|
||||
this.transition(taskId, 'failed', { by: 'failScopeReject', error: reason });
|
||||
}
|
||||
this.setNextEligibleAt(taskId, null);
|
||||
this.transition(taskId, 'needs_attention', { by: 'failScopeReject', reason });
|
||||
return this.getTask(taskId)!;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用规则13 执行前分歧重评估:sync main 发现 defaultBranch 改动与任务声明范围(scopeFiles)重叠,
|
||||
* 原方案可能过时 → 不重试、不计失败次数,直接把任务转 needs_attention 待人工重评估。
|
||||
|
||||
Reference in New Issue
Block a user