@zhuan-ai/zhuanspec 2.19.1 → 2.19.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* user-input hook 的结构化调试日志(JSONL)。
|
|
3
|
+
*
|
|
4
|
+
* 历史实现直接 append 到 `<cwd>/.user-input-debug.log`,带来三个问题:
|
|
5
|
+
* 1. 污染业务仓库:detectActiveChange 只看 `<cwd>/zhuanspec/changes`,不向上查找。
|
|
6
|
+
* cwd 落在工作区下的业务子仓库时,每条 prompt 都只会写一行 no-active-change,
|
|
7
|
+
* 于是日志被创建在业务仓库根目录,且因为没有 .gitignore 兜底被提交进版本库。
|
|
8
|
+
* 2. 无上限:只 append 不轮转,单个文件可以无限增长。
|
|
9
|
+
* 3. 无开关:无法关闭。
|
|
10
|
+
*
|
|
11
|
+
* 现在的约定(与 `zhuanspec/.hook-debug.log`、`metrics/.accuracy-debug.log` 一致):
|
|
12
|
+
* - 只有 cwd 确实是 zhuanspec 项目(存在 `<cwd>/zhuanspec` 目录)时才落盘,
|
|
13
|
+
* 否则整体 no-op —— 业务仓库不会再出现这个文件。
|
|
14
|
+
* - 落盘到 `<cwd>/zhuanspec/.user-input-debug.log`,与其它过程产物同域。
|
|
15
|
+
* - 超过 DEBUG_LOG_MAX_BYTES 轮转一代(.1),旧代被覆盖,总占用有上限。
|
|
16
|
+
* - `ZHUANSPEC_DEBUG_LOG=0|false|off|no` 可完全关闭。
|
|
17
|
+
*/
|
|
18
|
+
/** 日志文件名(放在 zhuanspec 项目目录下,与 .hook-debug.log 同级) */
|
|
19
|
+
export declare const DEBUG_LOG_FILE_NAME = ".user-input-debug.log";
|
|
20
|
+
/** 单个日志文件上限:512KB。超过则轮转一代,最坏占用 ~1MB */
|
|
21
|
+
export declare const DEBUG_LOG_MAX_BYTES: number;
|
|
22
|
+
/**
|
|
23
|
+
* 调试日志是否启用。默认启用(保持“每次调用写一行”的排障契约),
|
|
24
|
+
* 显式把 ZHUANSPEC_DEBUG_LOG 设为 0/false/off/no 时关闭。
|
|
25
|
+
*/
|
|
26
|
+
export declare function isDebugLogEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* 解析日志落盘路径。
|
|
29
|
+
* cwd 不是 zhuanspec 项目(没有 `<cwd>/zhuanspec` 目录)时返回 null,调用方据此跳过写入,
|
|
30
|
+
* 避免在业务仓库里凭空创建文件。
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveDebugLogPath(cwd: string): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* 超过上限时轮转一代:当前文件重命名为 `<name>.1`(覆盖上一代),随后由调用方重新 append。
|
|
35
|
+
* 任何失败都静默返回,日志不能影响 hook 主流程。
|
|
36
|
+
*/
|
|
37
|
+
export declare function rotateDebugLogIfNeeded(logPath: string, maxBytes?: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* 追加一行 JSONL 调试日志。禁用、非 zhuanspec 项目或任何 IO 异常都静默跳过。
|
|
40
|
+
* 返回实际写入的路径,便于测试与排障;未写入时返回 null。
|
|
41
|
+
*/
|
|
42
|
+
export declare function appendDebugLog(cwd: string, payload: Record<string, unknown>, env?: NodeJS.ProcessEnv): string | null;
|
|
43
|
+
//# sourceMappingURL=user-input-debug-log.d.ts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* user-input hook 的结构化调试日志(JSONL)。
|
|
3
|
+
*
|
|
4
|
+
* 历史实现直接 append 到 `<cwd>/.user-input-debug.log`,带来三个问题:
|
|
5
|
+
* 1. 污染业务仓库:detectActiveChange 只看 `<cwd>/zhuanspec/changes`,不向上查找。
|
|
6
|
+
* cwd 落在工作区下的业务子仓库时,每条 prompt 都只会写一行 no-active-change,
|
|
7
|
+
* 于是日志被创建在业务仓库根目录,且因为没有 .gitignore 兜底被提交进版本库。
|
|
8
|
+
* 2. 无上限:只 append 不轮转,单个文件可以无限增长。
|
|
9
|
+
* 3. 无开关:无法关闭。
|
|
10
|
+
*
|
|
11
|
+
* 现在的约定(与 `zhuanspec/.hook-debug.log`、`metrics/.accuracy-debug.log` 一致):
|
|
12
|
+
* - 只有 cwd 确实是 zhuanspec 项目(存在 `<cwd>/zhuanspec` 目录)时才落盘,
|
|
13
|
+
* 否则整体 no-op —— 业务仓库不会再出现这个文件。
|
|
14
|
+
* - 落盘到 `<cwd>/zhuanspec/.user-input-debug.log`,与其它过程产物同域。
|
|
15
|
+
* - 超过 DEBUG_LOG_MAX_BYTES 轮转一代(.1),旧代被覆盖,总占用有上限。
|
|
16
|
+
* - `ZHUANSPEC_DEBUG_LOG=0|false|off|no` 可完全关闭。
|
|
17
|
+
*/
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import fs from 'fs';
|
|
20
|
+
/** 日志文件名(放在 zhuanspec 项目目录下,与 .hook-debug.log 同级) */
|
|
21
|
+
export const DEBUG_LOG_FILE_NAME = '.user-input-debug.log';
|
|
22
|
+
/** 单个日志文件上限:512KB。超过则轮转一代,最坏占用 ~1MB */
|
|
23
|
+
export const DEBUG_LOG_MAX_BYTES = 512 * 1024;
|
|
24
|
+
/** 关闭调试日志的环境变量取值(大小写不敏感) */
|
|
25
|
+
const DISABLED_VALUES = new Set(['0', 'false', 'off', 'no']);
|
|
26
|
+
/**
|
|
27
|
+
* 调试日志是否启用。默认启用(保持“每次调用写一行”的排障契约),
|
|
28
|
+
* 显式把 ZHUANSPEC_DEBUG_LOG 设为 0/false/off/no 时关闭。
|
|
29
|
+
*/
|
|
30
|
+
export function isDebugLogEnabled(env = process.env) {
|
|
31
|
+
const raw = env.ZHUANSPEC_DEBUG_LOG;
|
|
32
|
+
if (raw === undefined || raw === '')
|
|
33
|
+
return true;
|
|
34
|
+
return !DISABLED_VALUES.has(raw.trim().toLowerCase());
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 解析日志落盘路径。
|
|
38
|
+
* cwd 不是 zhuanspec 项目(没有 `<cwd>/zhuanspec` 目录)时返回 null,调用方据此跳过写入,
|
|
39
|
+
* 避免在业务仓库里凭空创建文件。
|
|
40
|
+
*/
|
|
41
|
+
export function resolveDebugLogPath(cwd) {
|
|
42
|
+
const zhuanspecDir = path.join(cwd, 'zhuanspec');
|
|
43
|
+
try {
|
|
44
|
+
if (!fs.statSync(zhuanspecDir).isDirectory())
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return path.join(zhuanspecDir, DEBUG_LOG_FILE_NAME);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 超过上限时轮转一代:当前文件重命名为 `<name>.1`(覆盖上一代),随后由调用方重新 append。
|
|
54
|
+
* 任何失败都静默返回,日志不能影响 hook 主流程。
|
|
55
|
+
*/
|
|
56
|
+
export function rotateDebugLogIfNeeded(logPath, maxBytes = DEBUG_LOG_MAX_BYTES) {
|
|
57
|
+
try {
|
|
58
|
+
if (fs.statSync(logPath).size < maxBytes)
|
|
59
|
+
return;
|
|
60
|
+
fs.renameSync(logPath, `${logPath}.1`);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// 文件不存在或轮转失败都不阻塞写入
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 追加一行 JSONL 调试日志。禁用、非 zhuanspec 项目或任何 IO 异常都静默跳过。
|
|
68
|
+
* 返回实际写入的路径,便于测试与排障;未写入时返回 null。
|
|
69
|
+
*/
|
|
70
|
+
export function appendDebugLog(cwd, payload, env = process.env) {
|
|
71
|
+
if (!isDebugLogEnabled(env))
|
|
72
|
+
return null;
|
|
73
|
+
const logPath = resolveDebugLogPath(cwd);
|
|
74
|
+
if (!logPath)
|
|
75
|
+
return null;
|
|
76
|
+
try {
|
|
77
|
+
rotateDebugLogIfNeeded(logPath);
|
|
78
|
+
fs.appendFileSync(logPath, `${JSON.stringify(payload)}\n`, 'utf-8');
|
|
79
|
+
return logPath;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Logging must never block the hook
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=user-input-debug-log.js.map
|
|
@@ -22,22 +22,18 @@ import crypto from 'crypto';
|
|
|
22
22
|
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
23
23
|
import { getBeijingTime, atomicWriteJson, detectActiveChange } from './record-progress.js';
|
|
24
24
|
import { detectHookHost, sanitizeCodexEnvelope } from '../../utils/hook-host.js';
|
|
25
|
+
import { appendDebugLog } from './user-input-debug-log.js';
|
|
25
26
|
import { USER_CORRECTION_KEYWORDS, REQUIREMENT_CHANGE_KEYWORDS, extractProposalSummary, buildCorrectionOptionsContext, buildRequirementChangeContext, isCodexInternalPrompt, } from './deviation-check.js';
|
|
26
27
|
/**
|
|
27
28
|
* Structured JSONL debug log for user-input hook.
|
|
28
|
-
* Writes to <cwd
|
|
29
|
-
* Every hook invocation MUST write exactly one line here, covering every
|
|
30
|
-
* (skip-*, record, baseline-miss, baseline-write) with positive reason codes.
|
|
29
|
+
* Writes to <cwd>/zhuanspec/.user-input-debug.log; failures are swallowed to keep
|
|
30
|
+
* main flow intact. Every hook invocation MUST write exactly one line here, covering every
|
|
31
|
+
* branch (skip-*, record, baseline-miss, baseline-write) with positive reason codes.
|
|
32
|
+
* cwd 不是 zhuanspec 项目时整体跳过,避免在业务仓库里凭空创建日志文件;
|
|
33
|
+
* 落盘策略(位置 / 上限轮转 / 开关)见 user-input-debug-log.ts。
|
|
31
34
|
*/
|
|
32
35
|
function logDebug(cwd, payload) {
|
|
33
|
-
|
|
34
|
-
const logPath = path.join(cwd, '.user-input-debug.log');
|
|
35
|
-
const line = JSON.stringify({ ts: getBeijingTime(), ...payload }) + '\n';
|
|
36
|
-
fs.appendFileSync(logPath, line, 'utf-8');
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// Logging must never block the hook
|
|
40
|
-
}
|
|
36
|
+
appendDebugLog(cwd, { ts: getBeijingTime(), ...payload });
|
|
41
37
|
}
|
|
42
38
|
/** fullPrompt 截断长度:够写知识文件的"背景/问题/解决方案",又不会把 user_inputs.json 撑爆 */
|
|
43
39
|
const FULL_PROMPT_MAX_LEN = 2000;
|
|
@@ -725,7 +725,8 @@ ${baseGuardrails}
|
|
|
725
725
|
- **Rules 和 Knowledge 注入**:编排 Agent MUST 在每个 subagent prompt 中注入 Rules(根据 @skill)和 Knowledge(踩坑警告、最佳实践)。
|
|
726
726
|
- **偏差处理**:PreToolUse Hook 检测到提案范围外修改时弹出选项式交互(更新提案/Bug修复豁免/取消)。3次偏差后强制更新提案。
|
|
727
727
|
- **⚠️ 纠偏处理(红线,禁止委派 subagent)**:当 \`progress.json\` 中 \`correctionContext.active === true\` 时,主 agent **必须亲自处理所有代码修改**,**严禁**将纠偏任务分发给 subagent(applyAgent/tddApplyAgent)。原因:(1) 纠偏代码修改必须走主 agent 的 PostToolUse hook 才能正确计入 \`userCorrectionLines\`;(2) subagent 无法感知纠偏上下文,可能扩大修改范围。违反此约束将导致准确率数据丢失。
|
|
728
|
-
- **correctionContext 写入时序**:\`resolve-correction\` CLI 写入 \`correctionContext\` 后,主 agent 必须在**修改任何代码之前**确认标记已写入(检查 progress.json 中 \`correctionContext.active === true\`),确保后续的 PostToolUse hook 能将修改行数路由到 \`userCorrectionLines
|
|
728
|
+
- **correctionContext 写入时序**:\`resolve-correction\` CLI 写入 \`correctionContext\` 后,主 agent 必须在**修改任何代码之前**确认标记已写入(检查 progress.json 中 \`correctionContext.active === true\`),确保后续的 PostToolUse hook 能将修改行数路由到 \`userCorrectionLines\`。
|
|
729
|
+
- **Wave 间连续执行(红线)**:每个 Wave 完成并生成集成测试报告后,必须立即自动推进到下一个 Wave,禁止在 Wave 之间停下来询问用户"是否继续 / 要开始下一个 Wave 吗 / Wave N 已完成,是否继续"这类无需决策的确认。只有 Wave 集成报告整体状态为 FAIL 且无法自行修复,或出现真正的范围/依赖决策时才暂停。此约束与 lightweightApply 的连续执行红线同等优先级,优先于基础模型"做完一段就停下来确认"的默认倾向。`;
|
|
729
730
|
const applyReferences = `**参考**
|
|
730
731
|
- 如果在实施过程中需要提案的额外上下文,请使用 \`zhuanspec show <id> --json --deltas-only\`。`;
|
|
731
732
|
// Keep apply lightweight, but fix local build/type/import breakage before moving on.
|
|
@@ -745,7 +746,8 @@ const lightweightApplySteps = `**步骤**
|
|
|
745
746
|
|
|
746
747
|
3. **直接实施未完成任务(连续执行,不中途请示)**
|
|
747
748
|
- 默认由当前 Agent 直接改代码,不强制 Wave 并行,不强制启动 subagent。
|
|
748
|
-
- **连续执行**:一次性把所有未完成任务做完,任务之间不要停下来问"是否继续 / 要不要接着做下一个"。只有遇到以下情况才暂停:范围或依赖真正不明确、需要用户做产品/技术决策、或出现无法自行修复的阻塞。除此之外持续推进到全部任务完成。
|
|
749
|
+
- **连续执行**:一次性把所有未完成任务做完,任务之间不要停下来问"是否继续 / 要不要接着做下一个 / 已完成当前任务,继续下一个吗"。只有遇到以下情况才暂停:范围或依赖真正不明确、需要用户做产品/技术决策、或出现无法自行修复的阻塞。除此之外持续推进到全部任务完成。
|
|
750
|
+
- **修复类任务必须自验证**:凡是修复 bug 或纠正错误行为的任务,代码修改完成后必须主动运行相关检查(单测/类型检查/编译/lint)验证修复生效,不得以"代码已修改"为由结束任务;检查不通过则继续修复直至通过,或明确说明阻塞原因。
|
|
749
751
|
- \`@depends\` 只作为建议顺序参考:先做依赖少、改动底层的任务,再做上层调用和界面任务。
|
|
750
752
|
- \`@skill:<name>\` 只作为能力提示:当任务确实匹配且 skill 可用时再调用。
|
|
751
753
|
- 不要用占位实现假装完成。
|
|
@@ -766,7 +768,7 @@ const lightweightApplySteps = `**步骤**
|
|
|
766
768
|
- 如果还有未完成任务或阻塞点,明确列出下一步。
|
|
767
769
|
- 提示用户后续运行 \`zhuanspec review <change-id>\` 做验收。`;
|
|
768
770
|
const lightweightApplyGuardrails = `${baseGuardrails}
|
|
769
|
-
- **连续执行到底(红线)**:Apply 阶段一旦开始,就持续实施 tasks.md 中所有未完成任务,直到全部完成或遇到真正的阻塞。禁止在任务之间停下来询问用户"是否继续 / 要不要做下一个任务"
|
|
771
|
+
- **连续执行到底(红线)**:Apply 阶段一旦开始,就持续实施 tasks.md 中所有未完成任务,直到全部完成或遇到真正的阻塞。禁止在任务之间停下来询问用户"是否继续 / 要不要做下一个任务 / 已完成 Wave N,是否继续 Wave N+1"这类无需决策的确认。Wave 与 Wave 之间同样必须自动推进,不得停顿。只有范围/依赖不明确、需要用户决策、或出现无法自行解决的阻塞时才暂停。此约束优先于基础模型"做一段就停下来征求确认"的默认倾向。
|
|
770
772
|
- **Apply 只负责实施**:本阶段不执行完整审查门禁,不强制生成任务报告,不强制生成 Wave 集成报告。
|
|
771
773
|
- **默认不强制 subagent**:当前 Agent 可以直接完成任务。只有用户明确要求并行、任务明确要求委派,或当前上下文不足以安全完成时,才考虑启动 subagent。
|
|
772
774
|
- **重检查后移**:报告格式校验、外部依赖全量扫描、Scenario 与代码逐项核对、TC 全量验证、占位实现扫描、全局 Concerns 汇总由 \`zhuanspec review\` 或严格检查流程承接。
|
|
@@ -823,6 +825,7 @@ const designGuardrails = `${baseGuardrails}\n- **独立设计阶段**:techDesi
|
|
|
823
825
|
- **Skill 可用性前置检查(硬约束)**:在实际调用技术方案 Skill 前,**必须**先校验目标 Skill 是否已安装且可用;**若不可用,立即中断流程**并提示用户到 Skill 市场安装对应 Skill,禁止以人工编写/其他 Skill 代替。
|
|
824
826
|
- **Skill 调用为主**:技术方案生成主要通过 \`generate-tech-spec-md-skill\`(仅后端)或 \`generate-fullstack-tech-spec-skill\`(全栈)Skill 完成,而非直接运行 CLI 命令。
|
|
825
827
|
- **严格文件约束**:techDesign 阶段只能创建目录和 progress.json(phase=techDesign)。
|
|
828
|
+
- **技术方案落盘路径(红线)**:Skill 生成的技术方案文件**只允许**写入 \`zhuanspec/changes/{change-id}/techDesign/tech-spec.md\`;**严禁**将技术方案写入 \`./doc/\`、工作区根目录、或任何其他路径。Skill 执行完成后必须立即执行 CHECKPOINT [TECH-SPEC-LOCATION] 校验(见步骤 6.3),确认文件落盘位置正确;若 Skill 将文件写到了错误位置,**必须立即移动**到正确路径后才能继续后续步骤。
|
|
826
829
|
- **progress.json 初始化铁律**:**严禁使用 Write/Edit 工具手写 \`metrics/progress.json\`**,必须通过 \`zhuanspec progress set-phase <change-id> techDesign\` 初始化,否则 phaseDurations / phaseTransitions / stats.durationMs 全部缺失,techDesign 阶段耗时无法统计。
|
|
827
830
|
- **禁止创建提案文件**:禁止创建 .tech-design、design.md、proposal.md、tasks.md、specs/ 等。
|
|
828
831
|
- **Proposal 复用**:proposal 阶段通过 progress.json 的 phase 字段识别 techDesign 目录。`;
|
|
@@ -901,6 +904,17 @@ const designSteps = `**步骤**
|
|
|
901
904
|
- Skill 会通过飞书 CLI \`lark-cli\` 读取飞书文档内容并生成完整技术方案文档
|
|
902
905
|
- **禁止**:在未完成步骤 4 的开发范围确认和步骤 5 的 Skill 可用性校验前调用任何 Skill;禁止两个 Skill 同时调用。
|
|
903
906
|
|
|
907
|
+
6.3. **⚠️ CHECKPOINT [TECH-SPEC-LOCATION]:技术方案落盘位置强制校验(Skill 完成后立即执行)**:
|
|
908
|
+
- Skill 执行完成后,**必须立即**运行以下校验,禁止跳过:
|
|
909
|
+
1. 检查 \`zhuanspec/changes/{change-id}/techDesign/tech-spec.md\` 是否存在且内容非空
|
|
910
|
+
2. **若文件存在且非空**:校验通过,继续步骤 6.5
|
|
911
|
+
3. **若文件不存在或为空**:
|
|
912
|
+
- 在工作区内搜索 Skill 可能生成的技术方案文件(常见错误位置:\`./doc/*.md\`、\`./tech-spec.md\`、工作区根目录)
|
|
913
|
+
- 找到后**立即移动**到正确位置:\`zhuanspec/changes/{change-id}/techDesign/tech-spec.md\`
|
|
914
|
+
- 移动完成后再次确认文件存在
|
|
915
|
+
- 若仍找不到:**中断流程**,向用户报告"技术方案文件未生成到预期路径,Skill 执行可能失败",说明已搜索的位置和结果,不得继续后续步骤
|
|
916
|
+
- ⚠️ **红线**:任何情况下不得把非 \`zhuanspec/changes/{change-id}/techDesign/tech-spec.md\` 路径的文件视为正式技术方案,后续所有步骤(6.5、7、8)必须从上述路径读取。
|
|
917
|
+
|
|
904
918
|
6.5. **新增表澄清与数据存储策略(硬约束,存在新增表时必须执行)**:
|
|
905
919
|
- 从步骤 6 产出的 tech-spec.md 中提取所有 **新增/重构 DB 表**(关键词:CREATE TABLE / 新增表 / t_* / 新建业务表),形成候选表清单。若无新增表 → 跳过本步并在技术方案写明“无新增表,无需数据存储策略评估”
|
|
906
920
|
- 对每张新增表,**必须** 调用 \`AskQuestion\` 向用户批量澄清下列字段(可多表合并一次问答),严禁默认和代书填入:
|
|
@@ -1053,10 +1067,15 @@ const reviewSteps = `**步骤**
|
|
|
1053
1067
|
- **必须使用 Skill 工具调用** \`generate-mockito-unit-test\`,禁止以"人工快速写几个用例"或"只跑已有测试"的形式代替。
|
|
1054
1068
|
- Skill 须对本次改动涉及的所有 public 方法生成/补齐单测(若已有 TDD 测试则做增量补齐)。
|
|
1055
1069
|
- Skill 完成后运行测试命令并收集通过率、覆盖率、失败用例清单。
|
|
1070
|
+
- **pom.xml 注册校验(Java 项目必须执行,非 Java 跳过并记 \`"skipped"\`)**:Skill 生成新测试文件后,必须检查测试文件是否在 Maven 测试扫描范围内:
|
|
1071
|
+
1. 读取受影响模块的 \`pom.xml\`,检查 \`maven-surefire-plugin\` 的 \`<includes>\` 配置
|
|
1072
|
+
2. 若 \`<includes>\` 存在且为白名单模式,确认新文件路径与模式匹配;不匹配则自动在对应 pom.xml 中追加 \`<include>\` 条目
|
|
1073
|
+
3. 若 \`<includes>\` 未配置(Surefire 默认规则:\`**/*Test.java\`、\`**/*Tests.java\`、\`**/*TestCase.java\`),确认生成文件命名符合规则;不符合则重命名文件使其匹配默认规则
|
|
1074
|
+
4. 将校验结果记录到 \`unit-test-result.json\` 的 \`pomRegistrationCheck\` 字段(\`"passed"\` / \`"fixed"\` / \`"skipped"\`)
|
|
1056
1075
|
- 自闭环修复(最多 3 轮):出现失败用例或覆盖率低于阈值时,**再次使用 Skill 工具调用** \`generate-mockito-unit-test\` 进行补齐/修复,重跑测试;禁止手工跳过修复。
|
|
1057
1076
|
- 产物落盘:**AI 将 Skill 真实执行结果写入** \`zhuanspec/changes/<id>/review/unit-test-result.json\`,格式:
|
|
1058
1077
|
\`\`\`json
|
|
1059
|
-
{ "schemaVersion": 2, "testPassed": true, "passRate": 100, "coverage": 85, "coverageThreshold": 80, "newTestsGenerated": ["src/test/java/.../FooServiceTest.java"], "failedTests": [], "loopCount": 0 }
|
|
1078
|
+
{ "schemaVersion": 2, "testPassed": true, "passRate": 100, "coverage": 85, "coverageThreshold": 80, "newTestsGenerated": ["src/test/java/.../FooServiceTest.java"], "failedTests": [], "pomRegistrationCheck": "passed", "loopCount": 0 }
|
|
1060
1079
|
\`\`\`
|
|
1061
1080
|
- \`newTestsGenerated\` 必须登记 Skill 本轮实际新增或更新的测试文件路径(至少 1 项);若本次改动确实不涉及新增/修改 public 方法导致无需新增测试,必须改为在 JSON 中追加 \`"skipReason": "<说明>"\` 字段说明原因。
|
|
1062
1081
|
- 退出条件:\`testPassed === true\`、\`passRate === 100\`、\`coverage >= coverageThreshold\`,且 \`newTestsGenerated\` 非空或已给出 \`skipReason\`。未通过禁止进入 2.3。
|
|
@@ -1074,6 +1093,10 @@ const reviewSteps = `**步骤**
|
|
|
1074
1093
|
\`\`\`
|
|
1075
1094
|
- \`skillReportPath\` **必填**,必须指向上一步 Skill 生成的真实 markdown 报告文件(相对工作区根)。文件不存在时 CLI 会拒绝通过。
|
|
1076
1095
|
- 退出条件:\`criticalCount === 0\` 且 \`skillReportPath\` 对应文件真实存在。未通过禁止进入 2.4。
|
|
1096
|
+
- **代码格式规范(自闭环修复范围)**:Code Review 发现以下格式问题时,修复动作必须与代码逻辑修复一并在本轮自闭环中完成,不得延后到用户指出后再改:
|
|
1097
|
+
* 方法体内禁止使用全限定类名(除非存在同名歧义冲突),必须在文件顶部 import
|
|
1098
|
+
* 禁止相邻 import 块/方法块之间出现超过一个空行;类定义内方法间保持一个空行
|
|
1099
|
+
* 删除本次改动引入的无用 import、未使用变量、注释掉的死代码段
|
|
1077
1100
|
|
|
1078
1101
|
**2.4 轨道 4 — 功能闭环验收轨(AI 代码质量拦截)**
|
|
1079
1102
|
- 进入条件:2.3 已 PASS。
|
|
@@ -1154,10 +1177,10 @@ const reviewSteps = `**步骤**
|
|
|
1154
1177
|
- 全部通过时生成 \`zhuanspec/changes/<id>/review/review-report.md\`。
|
|
1155
1178
|
4. **审查结果处理**:
|
|
1156
1179
|
- **PASS**:前四轨顺序全部通过(Spec-Code → UT → CR → Closure)且 Critical=0、skeletonCodeCount=0、无未闭环功能,可以继续归档。
|
|
1157
|
-
- **FAIL**:根据 CLI
|
|
1180
|
+
- **FAIL**:根据 CLI 输出定位失败轨,**直接进入自闭环修复,不得停下来询问用户是否继续**,返回对应子步骤(2.1/2.2/2.3/2.4)继续修复直至通过或达到轮次上限。
|
|
1158
1181
|
5. **修复循环**(整体失败时):
|
|
1159
1182
|
- 按失败轨所在子步骤的自闭环修复流程处理;每轨内部最多 3 轮,超限则停止并向用户报告。
|
|
1160
|
-
-
|
|
1183
|
+
- 修复完成后**立即重新从失败轨开始顺序执行**,而非重置整个 Review,也不得在修复后停下来等待用户确认。
|
|
1161
1184
|
6. **确认通过后**:
|
|
1162
1185
|
- 告知用户审查已通过(最多六轨顺序串行 + CLI 汇总)。
|
|
1163
1186
|
- 提示可以使用 \`/zhuanspec:archive\` 进行归档。`;
|