import { inspectGate } from "./gates.ts"; import type { ActiveRun } from "./types.ts"; import { buildControlFrame } from "./control-frame.ts"; import { evaluateRequiredFactsContract } from "./data-source-policy.ts"; import { formatNextAction } from "./next-action.ts"; export function formatPlanReadiness(cwd: string, run: ActiveRun): string { const blockers: string[] = []; const openQuestions = (run.questions ?? []).filter((question) => question.status === "open" && question.blocking); if (openQuestions.length > 0) blockers.push(`存在 open blocking question:${openQuestions.map((question) => question.id).join(", ")}`); const gate = inspectGate(cwd, run); if (!gate.passed) blockers.push(`当前门禁阻塞:${gate.reason ?? "未说明原因"}`); const factsContract = evaluateRequiredFactsContract(cwd, run); for (const issue of factsContract.issues.slice(0, 5)) { blockers.push(`${issue.contract} 缺口:${issue.missing.slice(0, 3).join("、")}`); } const canCode = run.phase === "execute" && blockers.length === 0; const frame = buildControlFrame(cwd, run, "readiness"); return [ `status:${canCode ? "ready-to-execute" : "not-ready"}`, `phase:${run.phase}`, `policy:代码修改前必须先完成访谈式澄清、事实契约、PLAN 批准文件、写入边界和验证策略。`, "blockers:", blockers.length > 0 ? blockers.map((item) => `- ${item}`).join("\n") : "- 无。", "structuredNextAction:", formatNextAction(frame.nextAction), "nextAction:", canCode ? "- 按 PLAN.md 批准文件执行,并记录 evidence。" : `- ${frame.nextAction.instruction}`, ].join("\n"); }