fix: exclude completion-transition errors from health escalation at task level (#1157)
When the last task in a slice completes, the doctor detects expected completion-transition issues (missing slice summary, unchecked roadmap) that will be resolved by the upcoming complete-slice dispatch. These were being counted as real errors in the proactive health tracker, inflating consecutiveErrorUnits and potentially triggering misleading heal escalation or verification-failure warnings. Changes: - Export COMPLETION_TRANSITION_CODES from doctor-types.ts (was local to doctor.ts) - doctor.ts uses the shared constant instead of its local copy - auto-post-unit.ts filters out completion-transition codes from the error count and health snapshot when fixLevel is 'task' Existing doctor-fixlevel tests confirm the doctor still detects and reports (but does not fix) these issues at task level. Fixes #1155
This commit is contained in:
parent
8b70fc03f6
commit
22f2f452b9
3 changed files with 23 additions and 9 deletions
|
|
@ -35,6 +35,7 @@ import {
|
|||
import { writeUnitRuntimeRecord, clearUnitRuntimeRecord } from "./unit-runtime.js";
|
||||
import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences } from "./preferences.js";
|
||||
import { runGSDDoctor, rebuildState, summarizeDoctorIssues } from "./doctor.js";
|
||||
import { COMPLETION_TRANSITION_CODES } from "./doctor-types.js";
|
||||
import { recordHealthSnapshot, checkHealEscalation } from "./doctor-proactive.js";
|
||||
import { syncStateToProjectRoot } from "./auto-worktree-sync.js";
|
||||
import { resetRewriteCircuitBreaker } from "./auto-dispatch.js";
|
||||
|
|
@ -154,13 +155,17 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|||
ctx.ui.notify(`Post-hook: applied ${report.fixesApplied.length} fix(es).`, "info");
|
||||
}
|
||||
|
||||
// Proactive health tracking
|
||||
const summary = summarizeDoctorIssues(report.issues);
|
||||
// Proactive health tracking — exclude completion-transition codes at task level
|
||||
// since they are expected after the last task and resolved by complete-slice
|
||||
const issuesForHealth = effectiveFixLevel === "task"
|
||||
? report.issues.filter(i => !COMPLETION_TRANSITION_CODES.has(i.code))
|
||||
: report.issues;
|
||||
const summary = summarizeDoctorIssues(issuesForHealth);
|
||||
recordHealthSnapshot(summary.errors, summary.warnings, report.fixesApplied.length);
|
||||
|
||||
// Check if we should escalate to LLM-assisted heal
|
||||
if (summary.errors > 0) {
|
||||
const unresolvedErrors = report.issues
|
||||
const unresolvedErrors = issuesForHealth
|
||||
.filter(i => i.severity === "error" && !i.fixable)
|
||||
.map(i => ({ code: i.code, message: i.message, unitId: i.unitId }));
|
||||
const escalation = checkHealEscalation(summary.errors, unresolvedErrors);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,19 @@ export type DoctorIssueCode =
|
|||
| "gitignore_missing_patterns"
|
||||
| "unresolvable_dependency";
|
||||
|
||||
/**
|
||||
* Issue codes that represent expected completion-transition states.
|
||||
* These are detected by the doctor but should NOT be auto-fixed at task level —
|
||||
* they are resolved by the complete-slice/complete-milestone dispatch units.
|
||||
* Consumers (e.g. auto-post-unit health tracking) should exclude these from
|
||||
* error counts when running at task fixLevel to avoid false escalation.
|
||||
*/
|
||||
export const COMPLETION_TRANSITION_CODES = new Set<DoctorIssueCode>([
|
||||
"all_tasks_done_missing_slice_summary",
|
||||
"all_tasks_done_missing_slice_uat",
|
||||
"all_tasks_done_roadmap_not_checked",
|
||||
]);
|
||||
|
||||
export interface DoctorIssue {
|
||||
severity: DoctorSeverity;
|
||||
code: DoctorIssueCode;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { invalidateAllCaches } from "./cache.js";
|
|||
import { loadEffectiveGSDPreferences, type GSDPreferences } from "./preferences.js";
|
||||
|
||||
import type { DoctorIssue, DoctorIssueCode } from "./doctor-types.js";
|
||||
import { COMPLETION_TRANSITION_CODES } from "./doctor-types.js";
|
||||
import { checkGitHealth, checkRuntimeHealth } from "./doctor-checks.js";
|
||||
|
||||
// ── Re-exports ─────────────────────────────────────────────────────────────
|
||||
|
|
@ -356,16 +357,11 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
|
|||
// dispatch lifecycle (complete-slice, complete-milestone units), not to
|
||||
// mechanical post-hook bookkeeping. When fixLevel is "task", these are
|
||||
// detected and reported but never auto-fixed.
|
||||
const completionTransitionCodes = new Set<DoctorIssueCode>([
|
||||
"all_tasks_done_missing_slice_summary",
|
||||
"all_tasks_done_missing_slice_uat",
|
||||
"all_tasks_done_roadmap_not_checked",
|
||||
]);
|
||||
|
||||
/** Whether a given issue code should be auto-fixed at the current fixLevel. */
|
||||
const shouldFix = (code: DoctorIssueCode): boolean => {
|
||||
if (!fix) return false;
|
||||
if (fixLevel === "task" && completionTransitionCodes.has(code)) return false;
|
||||
if (fixLevel === "task" && COMPLETION_TRANSITION_CODES.has(code)) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue