soloforge 1.1.40 → 1.1.42
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.
- package/README.md +57 -0
- package/dist/adapters/shared/workflow_template.js +1 -1
- package/dist/bin/commands/check_write.d.ts +1 -1
- package/dist/bin/commands/check_write.d.ts.map +1 -1
- package/dist/bin/commands/check_write.js +13 -34
- package/dist/bin/commands/check_write.js.map +1 -1
- package/dist/bin/commands/modify.d.ts +2 -1
- package/dist/bin/commands/modify.d.ts.map +1 -1
- package/dist/bin/commands/modify.js +29 -15
- package/dist/bin/commands/modify.js.map +1 -1
- package/dist/bin/commands/review.d.ts +3 -2
- package/dist/bin/commands/review.d.ts.map +1 -1
- package/dist/bin/commands/review.js +179 -46
- package/dist/bin/commands/review.js.map +1 -1
- package/dist/bin/soloforge.js +0 -18
- package/dist/bin/soloforge.js.map +1 -1
- package/dist/engine/context_engine/companion_injector.d.ts +16 -3
- package/dist/engine/context_engine/companion_injector.d.ts.map +1 -1
- package/dist/engine/context_engine/companion_injector.js +228 -35
- package/dist/engine/context_engine/companion_injector.js.map +1 -1
- package/dist/engine/contracts/artifact_contract_registry.d.ts +1 -43
- package/dist/engine/contracts/artifact_contract_registry.d.ts.map +1 -1
- package/dist/engine/contracts/artifact_contract_registry.js +24 -100
- package/dist/engine/contracts/artifact_contract_registry.js.map +1 -1
- package/dist/engine/contracts/artifact_process_rules.d.ts.map +1 -1
- package/dist/engine/contracts/artifact_process_rules.js +0 -12
- package/dist/engine/contracts/artifact_process_rules.js.map +1 -1
- package/dist/engine/contracts/artifact_schema_registry.d.ts.map +1 -1
- package/dist/engine/contracts/artifact_schema_registry.js +0 -24
- package/dist/engine/contracts/artifact_schema_registry.js.map +1 -1
- package/dist/engine/contracts/tool_invocation_contract_registry.d.ts +29 -0
- package/dist/engine/contracts/tool_invocation_contract_registry.d.ts.map +1 -1
- package/dist/engine/contracts/tool_invocation_contract_registry.js +32 -21
- package/dist/engine/contracts/tool_invocation_contract_registry.js.map +1 -1
- package/dist/engine/core/paths.d.ts +0 -2
- package/dist/engine/core/paths.d.ts.map +1 -1
- package/dist/engine/core/paths.js +0 -2
- package/dist/engine/core/paths.js.map +1 -1
- package/dist/engine/knowledge/knowledge_writer.js +1 -1
- package/dist/engine/pipeline/artifact_aliases.d.ts +56 -3
- package/dist/engine/pipeline/artifact_aliases.d.ts.map +1 -1
- package/dist/engine/pipeline/artifact_aliases.js +377 -24
- package/dist/engine/pipeline/artifact_aliases.js.map +1 -1
- package/dist/engine/pipeline/artifact_resolver.d.ts +82 -0
- package/dist/engine/pipeline/artifact_resolver.d.ts.map +1 -0
- package/dist/engine/pipeline/artifact_resolver.js +458 -0
- package/dist/engine/pipeline/artifact_resolver.js.map +1 -0
- package/dist/engine/pipeline/intent_expander/knowledge_resolution.d.ts +2 -2
- package/dist/engine/pipeline/intent_expander/knowledge_resolution.d.ts.map +1 -1
- package/dist/engine/pipeline/intent_expander/knowledge_resolution.js.map +1 -1
- package/dist/engine/pipeline/orchestrate_single_artifact.d.ts +185 -0
- package/dist/engine/pipeline/orchestrate_single_artifact.d.ts.map +1 -0
- package/dist/engine/pipeline/orchestrate_single_artifact.js +772 -0
- package/dist/engine/pipeline/orchestrate_single_artifact.js.map +1 -0
- package/dist/engine/pipeline/scope_resolver.js +1 -1
- package/dist/engine/pipeline/scope_resolver.js.map +1 -1
- package/dist/engine/pipeline/state_machine/certainty_gate.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/certainty_gate.js +122 -9
- package/dist/engine/pipeline/state_machine/certainty_gate.js.map +1 -1
- package/dist/engine/pipeline/state_machine/pipeline_state_machine.d.ts +1 -13
- package/dist/engine/pipeline/state_machine/pipeline_state_machine.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/pipeline_state_machine.js +65 -73
- package/dist/engine/pipeline/state_machine/pipeline_state_machine.js.map +1 -1
- package/dist/engine/pipeline/state_machine/sf_command_parser.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/sf_command_parser.js +24 -19
- package/dist/engine/pipeline/state_machine/sf_command_parser.js.map +1 -1
- package/dist/engine/pipeline/state_machine/stage_command_registry.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/stage_command_registry.js +7 -0
- package/dist/engine/pipeline/state_machine/stage_command_registry.js.map +1 -1
- package/dist/engine/pipeline/state_machine/stage_executor.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/stage_executor.js +5 -11
- package/dist/engine/pipeline/state_machine/stage_executor.js.map +1 -1
- package/dist/engine/pipeline/state_machine/static_route_table.d.ts +2 -0
- package/dist/engine/pipeline/state_machine/static_route_table.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/static_route_table.js +2 -0
- package/dist/engine/pipeline/state_machine/static_route_table.js.map +1 -1
- package/dist/engine/pipeline/state_machine/uncertainty_bridge.d.ts +25 -0
- package/dist/engine/pipeline/state_machine/uncertainty_bridge.d.ts.map +1 -1
- package/dist/engine/pipeline/state_machine/uncertainty_bridge.js +18 -0
- package/dist/engine/pipeline/state_machine/uncertainty_bridge.js.map +1 -1
- package/dist/engine/pipeline/target_classifier.d.ts +48 -0
- package/dist/engine/pipeline/target_classifier.d.ts.map +1 -0
- package/dist/engine/pipeline/target_classifier.js +129 -0
- package/dist/engine/pipeline/target_classifier.js.map +1 -0
- package/dist/engine/pipeline/task_planner.js +1 -1
- package/dist/engine/pipeline/task_planner.js.map +1 -1
- package/dist/engine/release/foundation_scenario_registry.js +1 -1
- package/dist/engine/release/foundation_scenario_registry.js.map +1 -1
- package/dist/engine/templates/asset_manifest.d.ts.map +1 -1
- package/dist/engine/templates/asset_manifest.js +1 -0
- package/dist/engine/templates/asset_manifest.js.map +1 -1
- package/dist/engine/templates/explicit_asset_registry/rules_shared.d.ts.map +1 -1
- package/dist/engine/templates/explicit_asset_registry/rules_shared.js +22 -0
- package/dist/engine/templates/explicit_asset_registry/rules_shared.js.map +1 -1
- package/dist/server/tools/cep_assessment.d.ts +6 -0
- package/dist/server/tools/cep_assessment.d.ts.map +1 -1
- package/dist/server/tools/cep_assessment.js +23 -0
- package/dist/server/tools/cep_assessment.js.map +1 -1
- package/dist/server/tools/middleware.d.ts.map +1 -1
- package/dist/server/tools/middleware.js +78 -1
- package/dist/server/tools/middleware.js.map +1 -1
- package/dist/server/tools/tool_groups/product_operations.d.ts +5 -3
- package/dist/server/tools/tool_groups/product_operations.d.ts.map +1 -1
- package/dist/server/tools/tool_groups/product_operations.js +5 -105
- package/dist/server/tools/tool_groups/product_operations.js.map +1 -1
- package/dist/server/tools/tool_groups/state_machine.d.ts +34 -3
- package/dist/server/tools/tool_groups/state_machine.d.ts.map +1 -1
- package/dist/server/tools/tool_groups/state_machine.js +454 -236
- package/dist/server/tools/tool_groups/state_machine.js.map +1 -1
- package/dist/server/tools/tool_names.d.ts +0 -3
- package/dist/server/tools/tool_names.d.ts.map +1 -1
- package/dist/server/tools/tool_names.js +1 -4
- package/dist/server/tools/tool_names.js.map +1 -1
- package/dist/types/state_machine.d.ts +28 -1
- package/dist/types/state_machine.d.ts.map +1 -1
- package/dist/types/state_machine.js +1 -1
- package/dist/types/state_machine.js.map +1 -1
- package/package.json +1 -1
- package/templates/artifacts/existing-system//344/270/200/351/224/256/345/274/200/345/205/263/351/205/215/347/275/256/346/250/241/347/211/210.json +2 -1
- package/templates/artifacts/existing-system//345/216/206/345/217/262/346/225/260/346/215/256/346/270/205/346/264/227/350/204/232/346/234/254/346/250/241/347/211/210.md +1 -0
- package/templates/artifacts/existing-system//345/216/206/345/217/262/351/201/227/347/225/231/351/233/267/345/214/272/346/270/205/345/215/225/346/250/241/347/211/210.md +3 -1
- package/templates/artifacts/existing-system//345/220/221/345/220/216/345/205/274/345/256/271/346/200/247/345/220/210/350/247/204/346/212/245/345/221/212/346/250/241/347/211/210.md +1 -0
- package/templates/artifacts/existing-system//345/242/236/351/207/217/350/276/271/347/225/214/347/225/214/345/256/232/346/226/207/346/241/243/346/250/241/347/211/210.md +1 -0
- package/templates/artifacts/existing-system//346/224/271/351/200/240/345/275/261/345/223/215/350/214/203/345/233/264/350/257/204/344/274/260/346/250/241/347/211/210.md +1 -0
- package/templates/artifacts/existing-system//346/225/260/346/215/256/350/241/200/347/274/230/345/233/276/346/250/241/347/211/210.md +3 -2
- package/templates/artifacts/existing-system//346/226/260/350/200/201/351/200/273/350/276/221/346/257/224/345/257/271/346/227/245/345/277/227/346/250/241/347/211/210.md +3 -1
- package/templates/artifacts/existing-system//347/264/247/346/200/245/345/233/236/346/273/232/346/211/213/345/206/214/346/250/241/347/211/210.md +3 -2
- package/templates/artifacts/existing-system//351/232/224/347/246/273/351/200/202/351/205/215/345/231/250/346/226/271/346/241/210/346/250/241/347/211/210.md +1 -0
- package/templates/artifacts/shared/API/346/216/245/345/217/243/350/247/204/346/240/274/346/226/207/346/241/243/346/250/241/347/211/210.md +3 -3
- package/templates/artifacts/shared//344/273/243/347/240/201/345/256/241/346/237/245/346/212/245/345/221/212/346/250/241/347/211/210.md +1 -1
- package/templates/artifacts/shared//345/210/207/347/211/207/350/256/241/345/210/222/346/250/241/347/211/210.md +6 -2
- package/templates/artifacts/shared//345/216/237/345/236/213/350/257/264/346/230/216/346/250/241/347/211/210.md +5 -3
- package/templates/artifacts/shared//346/216/245/345/217/243/345/257/271/346/216/245/346/226/271/346/241/210/346/250/241/347/211/210.md +2 -2
- package/templates/artifacts/shared//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/346/226/271/346/241/210/346/250/241/347/211/210.md +2 -2
- package/templates/artifacts/shared//346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/346/226/207/346/241/243/346/250/241/347/211/210.md +2 -2
- package/templates/artifacts/shared//346/236/266/346/236/204/350/256/276/350/256/241/346/250/241/347/211/210.md +6 -3
- package/templates/artifacts/shared//350/256/276/350/256/241/344/270/200/350/207/264/346/200/247/351/252/214/346/224/266/346/212/245/345/221/212/346/250/241/347/211/210.md +5 -5
- package/templates/artifacts/shared//350/257/246/347/273/206/350/256/276/350/256/241/346/250/241/347/211/210.md +3 -3
- package/templates/artifacts/shared//351/234/200/346/261/202/345/216/237/345/236/213/350/256/276/350/256/241/345/256/236/347/216/260/350/277/275/350/270/252/347/237/251/351/230/265/346/250/241/347/211/210.md +7 -6
- package/templates/checklists//344/274/232/350/257/235/346/201/242/345/244/215.md +1 -1
- package/templates/gates/shared/gate-/344/273/243/347/240/201/345/256/241/346/237/245.yaml +7 -0
- package/templates/gates/shared/gate-/345/210/207/347/211/207/345/256/241/346/237/245.yaml +14 -2
- package/templates/gates/shared/gate-/347/274/226/347/240/201/345/256/236/347/216/260.yaml +12 -0
- package/templates/internal/patterns/Hook/345/261/202/344/272/247/347/211/251/347/273/223/346/236/204/346/240/241/351/252/214.md +1 -1
- package/templates/procedures/Schema/345/217/230/346/233/264/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/procedures//345/256/211/345/205/250/345/212/240/345/233/272/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/procedures//346/200/247/350/203/275/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/procedures//346/216/245/345/217/243/351/233/206/346/210/220/346/265/201/346/260/264/347/272/277.md +1 -1
- package/templates/procedures//346/236/266/346/236/204/350/256/276/350/256/241/345/267/245/344/275/234/346/265/201.md +1 -2
- package/templates/procedures//346/246/202/345/277/265/351/252/214/350/257/201/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/procedures//346/272/220/347/240/201/345/216/237/345/236/213/344/272/244/344/273/230/346/265/201/347/250/213.md +2 -2
- package/templates/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/procedures//350/277/201/347/247/273/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/procedures//351/207/215/346/236/204/346/265/201/346/260/264/347/272/277.md +2 -2
- package/templates/rules/shared//344/273/243/347/240/201/345/217/257/347/273/264/346/212/244/346/200/247/344/270/216/345/217/257/350/247/202/346/265/213/346/200/247/345/256/241/346/237/245.md +21 -3
- package/templates/rules/shared//344/273/243/347/240/201/346/263/250/351/207/212/344/270/216/346/227/245/345/277/227/345/245/221/347/272/246/350/247/204/345/210/231.md +122 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 工具组: 状态机驱动路由 —
|
|
2
|
+
* 工具组: 状态机驱动路由 — MCP 工具集。
|
|
3
3
|
*
|
|
4
4
|
* sf_pipeline_init, sf_stage_execute, sf_stage_advance,
|
|
5
|
-
* sf_stage_rollback,
|
|
5
|
+
* sf_stage_rollback, sf_command,
|
|
6
6
|
* sf_next, sf_pipeline_status, sf_direct_answer,
|
|
7
7
|
* sf_single_artifact
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* 审查统一入口:[sf] 审查 通过 classifyTarget 路由到四层编排。
|
|
10
10
|
*/
|
|
11
11
|
import { z } from "zod";
|
|
12
|
-
import fss from "node:fs";
|
|
13
|
-
import path from "node:path";
|
|
14
12
|
import { createToolRegistrar } from "../middleware.js";
|
|
15
13
|
import { TOOL } from "../tool_names.js";
|
|
16
14
|
import { PipelineStateMachine } from "../../../engine/pipeline/state_machine/pipeline_state_machine.js";
|
|
@@ -19,7 +17,6 @@ import { TASK_STAGES } from "../../../engine/workflow/workflow_navigation_contra
|
|
|
19
17
|
import { lazyEvidenceGrounding } from "../lazy_loaders.js"; // evidence_grounding_contract 主链路消费(problem-60)
|
|
20
18
|
import { lazyArchitectureWorkshop } from "../lazy_loaders.js"; // architecture_decision_workshop 主链路消费(架构研讨场景)
|
|
21
19
|
import { lazyDecisionWorkshop } from "../lazy_loaders.js"; // decision_workshop 主链路消费(决策研讨场景)
|
|
22
|
-
import { lazyDesignArtifactPack } from "../lazy_loaders.js"; // design_artifact_pack 主链路消费(设计产物包场景)
|
|
23
20
|
/** 运行时校验并转换 stage 参数为 TaskStage 类型 */
|
|
24
21
|
function validateStage(value) {
|
|
25
22
|
if (!value)
|
|
@@ -67,7 +64,7 @@ export async function registerStateMachineTools(ctx) {
|
|
|
67
64
|
};
|
|
68
65
|
registerSafeTool(TOOL.stageExecute, "执行当前或指定阶段的工作。运行确定性门禁,注入知识,返回执行结果。阶段推进需调用 sf_stage_advance(通过 sf_command 调用)", StageExecuteSchema, async (args) => {
|
|
69
66
|
try {
|
|
70
|
-
// 证据接地门禁(problem-60
|
|
67
|
+
// 证据接地门禁(problem-60)— 写回失败不影响阻断判定
|
|
71
68
|
try {
|
|
72
69
|
const egMod = await lazyEvidenceGrounding();
|
|
73
70
|
const _evRiskLevel = egMod.assessTaskRisk(undefined, args.stage, args.description);
|
|
@@ -75,22 +72,25 @@ export async function registerStateMachineTools(ctx) {
|
|
|
75
72
|
const _evSystem = egMod.createEvidenceGroundingSystem();
|
|
76
73
|
const _evMatrix = _evSystem.builder.buildContext([], { target_claims: [], source_types: [], keywords: [], max_results: 0 });
|
|
77
74
|
const _evGateResult = _evSystem.gate.evaluate(_evMatrix, _evRiskLevel);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
if (!_evGateResult.allowed) {
|
|
76
|
+
// 门禁明确拒绝 — 写回失败也不影响阻断判定
|
|
77
|
+
try {
|
|
78
|
+
const _evPipeline = await sm.getCurrentPipeline();
|
|
79
|
+
if (_evPipeline?.pipeline_id) {
|
|
80
|
+
await taskContext.setEvidenceGroundingResult(_evPipeline.pipeline_id, {
|
|
81
|
+
evidence_matrix: _evMatrix,
|
|
82
|
+
evidence_gate_result: _evGateResult,
|
|
83
|
+
unsupported_claims: _evGateResult.unsupported_claims,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
87
86
|
}
|
|
88
|
-
|
|
87
|
+
catch { /* 写回失败不阻断门禁 */ }
|
|
88
|
+
return { result: { evidence_blocked: true, _evGate: _evGateResult } };
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
catch {
|
|
93
|
-
/*
|
|
93
|
+
/* 证据门禁模块加载/运行异常降级,不阻断 */
|
|
94
94
|
}
|
|
95
95
|
const result = await sm.executeStage({
|
|
96
96
|
stage: validateStage(args.stage),
|
|
@@ -121,7 +121,7 @@ export async function registerStateMachineTools(ctx) {
|
|
|
121
121
|
catch {
|
|
122
122
|
/* 写回失败不阻断主流程 */
|
|
123
123
|
}
|
|
124
|
-
// ──
|
|
124
|
+
// ── 架构决策研讨门禁(architecture_decision_workshop) ──
|
|
125
125
|
// 从管线描述/任务上下文中检测架构设计意图,创建/评估研讨契约
|
|
126
126
|
try {
|
|
127
127
|
const archMod = await lazyArchitectureWorkshop();
|
|
@@ -143,27 +143,34 @@ export async function registerStateMachineTools(ctx) {
|
|
|
143
143
|
// 二次调用: 用户确认后传入已确认的研讨契约
|
|
144
144
|
const contract = args.architecture_decision_workshop;
|
|
145
145
|
const evaluated = archMod.applyArchitectureWorkshopGate(contract);
|
|
146
|
-
result.architecture_decision_workshop = evaluated;
|
|
147
146
|
const gate = archMod.evaluateArchitectureDecisionWorkshop(evaluated);
|
|
148
147
|
if (!gate.allowed) {
|
|
149
|
-
|
|
148
|
+
// 确认后仍未通过门禁 — 阻断
|
|
149
|
+
return { result: {
|
|
150
|
+
blocked: true,
|
|
151
|
+
block_reason: "架构决策研讨门禁未通过,请检查决策项后重试",
|
|
152
|
+
architecture_decision_workshop: { ...evaluated, gate_result: gate },
|
|
153
|
+
} };
|
|
150
154
|
}
|
|
155
|
+
// 门禁通过 — 写入已确认结果
|
|
156
|
+
result.architecture_decision_workshop = { ...evaluated, status: "confirmed" };
|
|
151
157
|
}
|
|
152
158
|
else if (archMod.requiresArchitectureDecisionWorkshop(undefined, intentText)) {
|
|
153
|
-
// 首次调用:
|
|
159
|
+
// 首次调用: 创建新的研讨契约 → 阻断等待人类确认
|
|
154
160
|
const projectContext = /老系统|存量|改造|现有/.test(intentText) ? "existing_system" : "new_system";
|
|
155
161
|
const contract = archMod.createArchitectureDecisionWorkshop(result.pipeline_id ?? args.task_id ?? "unknown", projectContext);
|
|
156
162
|
const gate = archMod.evaluateArchitectureDecisionWorkshop(contract);
|
|
157
|
-
result
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
return { result: {
|
|
164
|
+
blocked: true,
|
|
165
|
+
block_reason: "架构决策需要人类确认后方可执行",
|
|
166
|
+
architecture_decision_workshop: { ...contract, status: "awaiting_confirmation", gate_result: gate },
|
|
167
|
+
} };
|
|
161
168
|
}
|
|
162
169
|
}
|
|
163
170
|
catch {
|
|
164
|
-
/*
|
|
171
|
+
/* 架构研讨模块加载失败降级,不阻断 */
|
|
165
172
|
}
|
|
166
|
-
// ──
|
|
173
|
+
// ── 通用决策研讨门禁(decision_workshop + activated_packs) ──
|
|
167
174
|
// 从管线描述/任务上下文中匹配决策包,创建/评估研讨契约
|
|
168
175
|
try {
|
|
169
176
|
const decMod = await lazyDecisionWorkshop();
|
|
@@ -188,12 +195,19 @@ export async function registerStateMachineTools(ctx) {
|
|
|
188
195
|
// 二次调用: 用户确认后传入已确认的研讨契约
|
|
189
196
|
const normalized = decMod.normalizeDecisionWorkshopContract(args.decision_workshop);
|
|
190
197
|
const evaluated = decMod.applyDecisionWorkshopGate(normalized);
|
|
191
|
-
result.decision_workshop = evaluated;
|
|
192
|
-
result.activated_packs = evaluated?.activated_packs ?? [];
|
|
193
198
|
const gate = decMod.evaluateDecisionWorkshop(evaluated);
|
|
194
199
|
if (!gate.allowed) {
|
|
195
|
-
|
|
200
|
+
// 确认后仍未通过门禁 — 阻断
|
|
201
|
+
return { result: {
|
|
202
|
+
blocked: true,
|
|
203
|
+
block_reason: "决策研讨门禁未通过,请检查决策项后重试",
|
|
204
|
+
decision_workshop: { ...evaluated, gate_result: gate },
|
|
205
|
+
activated_packs: evaluated?.activated_packs ?? [],
|
|
206
|
+
} };
|
|
196
207
|
}
|
|
208
|
+
// 门禁通过 — 写入已确认结果
|
|
209
|
+
result.decision_workshop = { ...evaluated, status: "confirmed" };
|
|
210
|
+
result.activated_packs = evaluated?.activated_packs ?? [];
|
|
197
211
|
}
|
|
198
212
|
else {
|
|
199
213
|
// 首次调用: 检测匹配的决策包(排除已通过架构研讨的 architecture 包)
|
|
@@ -204,16 +218,18 @@ export async function registerStateMachineTools(ctx) {
|
|
|
204
218
|
if (filteredPacks.length > 0) {
|
|
205
219
|
const contract = decMod.createDecisionWorkshop(result.pipeline_id ?? args.task_id ?? "unknown", filteredPacks, "new_system", match.reasons.join("; "));
|
|
206
220
|
const gate = decMod.evaluateDecisionWorkshop(contract);
|
|
207
|
-
|
|
208
|
-
result
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
221
|
+
// 首次创建的研讨契约 → 阻断等待人类确认
|
|
222
|
+
return { result: {
|
|
223
|
+
blocked: true,
|
|
224
|
+
block_reason: "决策研讨需要人类确认后方可执行",
|
|
225
|
+
decision_workshop: { ...contract, status: "awaiting_confirmation", gate_result: gate },
|
|
226
|
+
activated_packs: filteredPacks,
|
|
227
|
+
} };
|
|
212
228
|
}
|
|
213
229
|
}
|
|
214
230
|
}
|
|
215
231
|
catch {
|
|
216
|
-
/*
|
|
232
|
+
/* 决策研讨模块加载失败降级,不阻断 */
|
|
217
233
|
}
|
|
218
234
|
// ── 产出物检测(artifact_output) ──
|
|
219
235
|
// 根据意图关键词在任务上下文中写入 artifact_output,供后续修复指令场景消费
|
|
@@ -247,7 +263,17 @@ export async function registerStateMachineTools(ctx) {
|
|
|
247
263
|
catch {
|
|
248
264
|
/* 产出物检测失败不阻断主流程 */
|
|
249
265
|
}
|
|
250
|
-
|
|
266
|
+
// ── 将 companion_injection 提升为 must_follow + 添加执行指令 ──
|
|
267
|
+
// 原始返回 `return { result }` 将 companion_injection 埋在 result 中,AI 可忽略。
|
|
268
|
+
// 改造 8: 与 single_artifact 一致的返回格式,强制 AI 遵守规则。
|
|
269
|
+
const resultAsRecord = result;
|
|
270
|
+
const companionInjection = resultAsRecord.companion_injection;
|
|
271
|
+
const executeStageInstruction = buildExecuteStageInstruction(resultAsRecord);
|
|
272
|
+
return {
|
|
273
|
+
result,
|
|
274
|
+
must_follow: companionInjection || undefined,
|
|
275
|
+
instruction: executeStageInstruction,
|
|
276
|
+
};
|
|
251
277
|
}
|
|
252
278
|
catch (err) {
|
|
253
279
|
return { result: { error: String(err.message ?? err) } };
|
|
@@ -269,22 +295,28 @@ export async function registerStateMachineTools(ctx) {
|
|
|
269
295
|
try {
|
|
270
296
|
// 修复重验指令阻断 — 产物未通过验证时阻止推进
|
|
271
297
|
if (args.task_id) {
|
|
298
|
+
let tCtx;
|
|
272
299
|
try {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
300
|
+
tCtx = await taskContext.load(args.task_id);
|
|
301
|
+
}
|
|
302
|
+
catch (err) {
|
|
303
|
+
// 任务上下文加载失败时不可跳过重验检查 — 返回错误
|
|
304
|
+
return { result: {
|
|
305
|
+
error: `任务上下文加载失败,无法验证产物状态: ${err instanceof Error ? err.message : String(err)}`,
|
|
306
|
+
} };
|
|
307
|
+
}
|
|
308
|
+
if (tCtx?.repair_reverify_directive?.blocked && args.result !== "failure") {
|
|
309
|
+
return { result: { diagnostic_code: "SF-CONTRACT-0003", error: "产物未通过验证,请先修复并重验" } };
|
|
310
|
+
}
|
|
311
|
+
// failure 标记 — 不推进,仅记录失败状态
|
|
312
|
+
if (args.result === "failure") {
|
|
313
|
+
await taskContext.save({
|
|
314
|
+
...tCtx,
|
|
315
|
+
failure_type: args.failure_type ?? "unknown",
|
|
316
|
+
failed_at: new Date().toISOString(),
|
|
317
|
+
});
|
|
318
|
+
return { result: { status: "failure_recorded", failure_type: args.failure_type } };
|
|
286
319
|
}
|
|
287
|
-
catch { /* 非关键 */ }
|
|
288
320
|
}
|
|
289
321
|
const result = await sm.advanceStage({
|
|
290
322
|
confirmation: args.confirmation,
|
|
@@ -358,101 +390,6 @@ export async function registerStateMachineTools(ctx) {
|
|
|
358
390
|
}
|
|
359
391
|
});
|
|
360
392
|
// ══════════════════════════════════════════════════
|
|
361
|
-
// sf_gate_check — 门禁检查
|
|
362
|
-
// ══════════════════════════════════════════════════
|
|
363
|
-
const GateCheckSchema = {
|
|
364
|
-
stage: z.string().optional().describe("检查的阶段(中文),空=当前阶段"),
|
|
365
|
-
task_id: z.string().optional().describe("关联任务 ID(可选)"),
|
|
366
|
-
changed_files: z.array(z.string()).optional().describe("变更文件列表(可选)"),
|
|
367
|
-
confirm: z.boolean().optional().describe("是否确认(可选)"),
|
|
368
|
-
};
|
|
369
|
-
registerSafeTool(TOOL.gateCheck, "显式运行三级确定性门禁检查。返回知识覆盖、风险模式、人类确认三个级别的检查结果(通过 sf_command 调用)", GateCheckSchema, async (args) => {
|
|
370
|
-
try {
|
|
371
|
-
const result = await sm.checkGate({
|
|
372
|
-
stage: validateStage(args.stage),
|
|
373
|
-
task_id: args.task_id,
|
|
374
|
-
knowledgeIndex: ctx.knowledgeIndex,
|
|
375
|
-
config: ctx.config,
|
|
376
|
-
});
|
|
377
|
-
// 产物内容验证 — 检测 draft/非合规产物,创建修复重验指令
|
|
378
|
-
try {
|
|
379
|
-
if (args.task_id) {
|
|
380
|
-
const tCtx = await taskContext.load(args.task_id);
|
|
381
|
-
if (tCtx?.artifact_output) {
|
|
382
|
-
const projectPath = ctx.config?._projectPath ?? process.cwd();
|
|
383
|
-
const artifactAbs = path.join(projectPath, tCtx.artifact_output.path);
|
|
384
|
-
if (fss.existsSync(artifactAbs)) {
|
|
385
|
-
const content = fss.readFileSync(artifactAbs, "utf-8");
|
|
386
|
-
if (content.trimStart().startsWith("draft")) {
|
|
387
|
-
result.diagnostic_code = "SF-CONTRACT-DRAFT";
|
|
388
|
-
await taskContext.save({
|
|
389
|
-
...tCtx,
|
|
390
|
-
repair_reverify_directive: {
|
|
391
|
-
blocked: true,
|
|
392
|
-
reason: "产物包含 draft 标记,需修复后重验",
|
|
393
|
-
artifact_path: tCtx.artifact_output.path,
|
|
394
|
-
original_diagnostic: "SF-CONTRACT-DRAFT",
|
|
395
|
-
},
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
else if (tCtx.repair_reverify_directive?.blocked) {
|
|
399
|
-
// 产物合规且之前有阻断指令 → 清除指令,标记 verified
|
|
400
|
-
await taskContext.save({
|
|
401
|
-
...tCtx,
|
|
402
|
-
artifact_output: { ...tCtx.artifact_output, status: "verified" },
|
|
403
|
-
repair_reverify_directive: undefined,
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
catch {
|
|
411
|
-
/* 产物内容验证失败不阻断主流程 */
|
|
412
|
-
}
|
|
413
|
-
// 设计产物包验证 — 扫描项目设计文档,返回 findings 和 diagnostic_code
|
|
414
|
-
try {
|
|
415
|
-
const designMod = await lazyDesignArtifactPack();
|
|
416
|
-
const projectPath = ctx.config?._projectPath ?? process.cwd();
|
|
417
|
-
const pack = designMod.createDesignArtifactPack(args.task_id ?? "gate-check", designMod.defaultDesignArtifactPaths());
|
|
418
|
-
const verifyResult = designMod.verifyDesignArtifactPack(projectPath, pack);
|
|
419
|
-
result.design_artifact_findings = verifyResult.findings;
|
|
420
|
-
if (!verifyResult.passed && !result.diagnostic_code) {
|
|
421
|
-
result.diagnostic_code = "SF-DESIGN-PACK-VERIFY-FAILED";
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
catch {
|
|
425
|
-
/* 设计产物包验证失败不阻断主流程 */
|
|
426
|
-
}
|
|
427
|
-
// 确认时写入验证计划(供 sf_record_verification_execution 消费)
|
|
428
|
-
if (args.confirm && args.task_id) {
|
|
429
|
-
try {
|
|
430
|
-
const tCtx = await taskContext.load(args.task_id);
|
|
431
|
-
if (tCtx && !tCtx.verification_plan) {
|
|
432
|
-
const planId = `vp-${args.task_id}-${Date.now()}`;
|
|
433
|
-
const updatedCtx = {
|
|
434
|
-
...tCtx,
|
|
435
|
-
verification_plan: {
|
|
436
|
-
plan_id: planId,
|
|
437
|
-
commands: ["npm test", "npm run lint", "npm run build"],
|
|
438
|
-
created_at: new Date().toISOString(),
|
|
439
|
-
},
|
|
440
|
-
};
|
|
441
|
-
await taskContext.save(updatedCtx);
|
|
442
|
-
result.verification_plan_id = planId;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
catch {
|
|
446
|
-
/* 验证计划写入失败不阻断主流程 */
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
return { result };
|
|
450
|
-
}
|
|
451
|
-
catch (err) {
|
|
452
|
-
return { result: { error: String(err.message ?? err) } };
|
|
453
|
-
}
|
|
454
|
-
});
|
|
455
|
-
// ══════════════════════════════════════════════════
|
|
456
393
|
// sf_record_verification_execution — 记录验证执行结果
|
|
457
394
|
// ══════════════════════════════════════════════════
|
|
458
395
|
const RecordVerificationSchema = {
|
|
@@ -562,7 +499,7 @@ export async function registerStateMachineTools(ctx) {
|
|
|
562
499
|
last_tool_trace: {
|
|
563
500
|
tool_name: "sf_command",
|
|
564
501
|
next_allowed_tools: [
|
|
565
|
-
"sf_stage_execute", "sf_stage_advance",
|
|
502
|
+
"sf_stage_execute", "sf_stage_advance",
|
|
566
503
|
"sf_command", "sf_next", "sf_pipeline_status",
|
|
567
504
|
],
|
|
568
505
|
forbidden_tools: [],
|
|
@@ -614,13 +551,132 @@ export async function registerStateMachineTools(ctx) {
|
|
|
614
551
|
});
|
|
615
552
|
return { result: { parsed_command: parsed, execution_result: result, hint } };
|
|
616
553
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
554
|
+
// ── 审查统一入口 — 四层编排驱动(原 gate_check + single_artifact.review 合并) ──
|
|
555
|
+
case "review": {
|
|
556
|
+
const projectPath = ctx.config?._projectPath ?? process.cwd();
|
|
557
|
+
// 获取当前管线状态
|
|
558
|
+
let reviewSystemType;
|
|
559
|
+
let currentReviewStage = "需求分析";
|
|
560
|
+
try {
|
|
561
|
+
const pipeline = await sm.getCurrentPipeline();
|
|
562
|
+
if (pipeline) {
|
|
563
|
+
reviewSystemType = pipeline.system_type;
|
|
564
|
+
currentReviewStage = pipeline.current_stage;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
catch { /* 无管线时降级 */ }
|
|
568
|
+
// 1. 分类目标
|
|
569
|
+
const { classifyTarget, TargetClassificationError } = await import("../../../engine/pipeline/target_classifier.js");
|
|
570
|
+
let classified;
|
|
571
|
+
try {
|
|
572
|
+
classified = classifyTarget(parsed.stage || parsed.description, currentReviewStage, projectPath);
|
|
573
|
+
}
|
|
574
|
+
catch (err) {
|
|
575
|
+
if (err instanceof TargetClassificationError) {
|
|
576
|
+
return {
|
|
577
|
+
result: {
|
|
578
|
+
parsed_command: parsed,
|
|
579
|
+
execution_result: {
|
|
580
|
+
mode: "review",
|
|
581
|
+
status: "error",
|
|
582
|
+
error: err.message,
|
|
583
|
+
},
|
|
584
|
+
hint,
|
|
585
|
+
},
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
throw err;
|
|
589
|
+
}
|
|
590
|
+
// 2. 按类型路由到四层编排
|
|
591
|
+
if (classified.type === "stage" || classified.type === "current_stage") {
|
|
592
|
+
// ── 阶段级审查 ──
|
|
593
|
+
const { orchestrateStageReview } = await import("../../../engine/pipeline/orchestrate_single_artifact.js");
|
|
594
|
+
const stageResult = await orchestrateStageReview({
|
|
595
|
+
stage: classified.stage,
|
|
596
|
+
projectPath,
|
|
597
|
+
original_command: parsed.raw_text,
|
|
598
|
+
systemType: reviewSystemType,
|
|
599
|
+
});
|
|
600
|
+
return {
|
|
601
|
+
result: {
|
|
602
|
+
parsed_command: parsed,
|
|
603
|
+
execution_result: stageResult,
|
|
604
|
+
must_follow: stageResult.injection_text || undefined,
|
|
605
|
+
instruction: buildStageReviewInstruction(stageResult, parsed),
|
|
606
|
+
hint,
|
|
607
|
+
},
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
if (classified.type === "artifact") {
|
|
611
|
+
// ── 产物级审查 ──
|
|
612
|
+
const { orchestrateSingleArtifact } = await import("../../../engine/pipeline/orchestrate_single_artifact.js");
|
|
613
|
+
const orchestrateResult = await orchestrateSingleArtifact({
|
|
614
|
+
kind: classified.artifactKind,
|
|
615
|
+
operation: "review",
|
|
616
|
+
projectPath,
|
|
617
|
+
original_command: parsed.raw_text,
|
|
618
|
+
systemType: reviewSystemType,
|
|
619
|
+
});
|
|
620
|
+
return {
|
|
621
|
+
result: {
|
|
622
|
+
parsed_command: parsed,
|
|
623
|
+
execution_result: orchestrateResult,
|
|
624
|
+
must_follow: orchestrateResult.injection_text || undefined,
|
|
625
|
+
instruction: buildTopLevelInstruction(orchestrateResult, parsed),
|
|
626
|
+
hint,
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
if (classified.type === "slice") {
|
|
631
|
+
// ── 切片级审查 — 编码阶段 gate + 限定文件范围 ──
|
|
632
|
+
const { orchestrateSingleArtifact } = await import("../../../engine/pipeline/orchestrate_single_artifact.js");
|
|
633
|
+
const orchestrateResult = await orchestrateSingleArtifact({
|
|
634
|
+
kind: "source_code_package",
|
|
635
|
+
operation: "review",
|
|
636
|
+
projectPath,
|
|
637
|
+
original_command: parsed.raw_text,
|
|
638
|
+
systemType: reviewSystemType,
|
|
639
|
+
});
|
|
640
|
+
// 追加切片文件范围限定
|
|
641
|
+
const injectionParts = [];
|
|
642
|
+
if (orchestrateResult.injection_text) {
|
|
643
|
+
injectionParts.push(orchestrateResult.injection_text);
|
|
644
|
+
}
|
|
645
|
+
if (classified.files && classified.files.length > 0) {
|
|
646
|
+
injectionParts.push([
|
|
647
|
+
``,
|
|
648
|
+
`## 切片审查范围限定`,
|
|
649
|
+
``,
|
|
650
|
+
`审查仅限以下文件:`,
|
|
651
|
+
...classified.files.map(f => `- \`${f}\``),
|
|
652
|
+
``,
|
|
653
|
+
`忽略此范围外的文件变更。`,
|
|
654
|
+
].join("\n"));
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
injectionParts.push([
|
|
658
|
+
``,
|
|
659
|
+
`## 切片审查范围`,
|
|
660
|
+
``,
|
|
661
|
+
`⚠️ 未找到切片 ${classified.sliceId} 的文件列表。请检查 .soloforge/output/slice_plan.yaml 是否存在。`,
|
|
662
|
+
].join("\n"));
|
|
663
|
+
}
|
|
664
|
+
return {
|
|
665
|
+
result: {
|
|
666
|
+
parsed_command: parsed,
|
|
667
|
+
execution_result: {
|
|
668
|
+
...orchestrateResult,
|
|
669
|
+
slice_id: classified.sliceId,
|
|
670
|
+
slice_files: classified.files,
|
|
671
|
+
},
|
|
672
|
+
must_follow: injectionParts.join("\n") || undefined,
|
|
673
|
+
instruction: buildTopLevelInstruction(orchestrateResult, parsed),
|
|
674
|
+
hint,
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
// 兜底(不应到达)
|
|
679
|
+
return { result: { parsed_command: parsed, execution_result: { error: "未知的审查目标类型" }, hint } };
|
|
624
680
|
}
|
|
625
681
|
case "status": {
|
|
626
682
|
const pipeline = await sm.getCurrentPipeline();
|
|
@@ -686,69 +742,6 @@ export async function registerStateMachineTools(ctx) {
|
|
|
686
742
|
});
|
|
687
743
|
return { result: { parsed_command: parsed, execution_result: result, hint } };
|
|
688
744
|
}
|
|
689
|
-
case "brainstorm": {
|
|
690
|
-
return {
|
|
691
|
-
result: {
|
|
692
|
-
parsed_command: parsed,
|
|
693
|
-
execution_result: {
|
|
694
|
-
message: "头脑风暴流程已激活",
|
|
695
|
-
topic: parsed.description,
|
|
696
|
-
procedure_ref: "templates/procedures/不确定时头脑风暴流程.md",
|
|
697
|
-
steps: [
|
|
698
|
-
"1. 明确不确定的核心问题",
|
|
699
|
-
"2. 列出所有可能方案(至少 3 个)",
|
|
700
|
-
"3. 对照第一性原理推理规则(FP-01~04)逐条检查",
|
|
701
|
-
"4. 评估各方案的风险与收益",
|
|
702
|
-
"5. 选择最符合 fundamental_need 的方案",
|
|
703
|
-
"6. 记录决策理由与推理链",
|
|
704
|
-
],
|
|
705
|
-
fp_rules_ref: "templates/rules/shared/第一性原理推理规则.md",
|
|
706
|
-
note: "确定性门禁检测到风险模式时也会自动触发头脑风暴",
|
|
707
|
-
},
|
|
708
|
-
hint,
|
|
709
|
-
},
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
case "first_principles": {
|
|
713
|
-
return {
|
|
714
|
-
result: {
|
|
715
|
-
parsed_command: parsed,
|
|
716
|
-
execution_result: {
|
|
717
|
-
message: "第一性原理推理已激活",
|
|
718
|
-
topic: parsed.description,
|
|
719
|
-
rules_ref: "templates/rules/shared/第一性原理推理规则.md",
|
|
720
|
-
checklist: [
|
|
721
|
-
"FP-01 [error]: fundamental_need 是否已声明?用户目标 vs 解决方案",
|
|
722
|
-
"FP-02 [error]: 推理链是否完整?每个前提是否有证据支撑",
|
|
723
|
-
"FP-03 [warning]: 是否为表面修复?根因分析是否到位",
|
|
724
|
-
"FP-04 [warning]: 是否仅关键词替换?实质问题是否解决",
|
|
725
|
-
],
|
|
726
|
-
applicable_stages: ["需求分析", "架构设计", "详细设计", "编码与单元测试"],
|
|
727
|
-
note: "确定性门禁在 FIRST_PRINCIPLES_STAGES 阶段自动检测 FP 模式",
|
|
728
|
-
},
|
|
729
|
-
hint,
|
|
730
|
-
},
|
|
731
|
-
};
|
|
732
|
-
}
|
|
733
|
-
case "reasoning_log": {
|
|
734
|
-
return {
|
|
735
|
-
result: {
|
|
736
|
-
parsed_command: parsed,
|
|
737
|
-
execution_result: {
|
|
738
|
-
message: "推理记录查看",
|
|
739
|
-
topic: parsed.description,
|
|
740
|
-
note: "推理记录在确定性门禁评估时自动生成,包含 FP 规则命中和风险模式扫描结果",
|
|
741
|
-
fp_rules_triggered: "通过 sf_command 检查门禁 查看 level2.fp_rules_triggered",
|
|
742
|
-
brainstorm_history: "通过 sf_command 状态 查看管线历史中的头脑风暴记录",
|
|
743
|
-
knowledge_assets: [
|
|
744
|
-
"templates/rules/shared/第一性原理推理规则.md",
|
|
745
|
-
"templates/procedures/不确定时头脑风暴流程.md",
|
|
746
|
-
],
|
|
747
|
-
},
|
|
748
|
-
hint,
|
|
749
|
-
},
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
745
|
// D13: 快捷路径
|
|
753
746
|
case "direct_answer": {
|
|
754
747
|
return {
|
|
@@ -764,14 +757,51 @@ export async function registerStateMachineTools(ctx) {
|
|
|
764
757
|
};
|
|
765
758
|
}
|
|
766
759
|
case "single_artifact": {
|
|
760
|
+
// ── 委托共享内核 — 按方案四层编排 ──
|
|
761
|
+
const projectPath = ctx.config?._projectPath ?? process.cwd();
|
|
762
|
+
// ── 获取当前管线 system_type(用于老系统产物过滤) ──
|
|
763
|
+
let currentSystemType;
|
|
764
|
+
try {
|
|
765
|
+
const pipeline = await sm.getCurrentPipeline();
|
|
766
|
+
if (pipeline)
|
|
767
|
+
currentSystemType = pipeline.system_type;
|
|
768
|
+
}
|
|
769
|
+
catch { /* 无管线时降级 */ }
|
|
770
|
+
// ── 单产物路径(原有逻辑不变) ──
|
|
771
|
+
// 从描述匹配 artifact kind(优先 description,回退 raw_text + stage)
|
|
772
|
+
const { inferArtifactKindFromDescription } = await import("../../../engine/pipeline/artifact_resolver.js");
|
|
773
|
+
const kind = inferArtifactKindFromDescription(parsed.description)
|
|
774
|
+
|| inferArtifactKindFromDescription(parsed.raw_text)
|
|
775
|
+
|| (parsed.stage ? inferArtifactKindFromDescription(parsed.stage) : undefined);
|
|
776
|
+
if (!kind) {
|
|
777
|
+
return {
|
|
778
|
+
result: {
|
|
779
|
+
parsed_command: parsed,
|
|
780
|
+
execution_result: {
|
|
781
|
+
mode: "single_artifact",
|
|
782
|
+
status: "error",
|
|
783
|
+
error: `无法识别产物: "${parsed.description}"。可用的产物类型:原型说明、架构设计、详细设计、接口设计、数据库设计等`,
|
|
784
|
+
},
|
|
785
|
+
hint,
|
|
786
|
+
},
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
// 委托共享内核完成四层编排
|
|
790
|
+
const { orchestrateSingleArtifact } = await import("../../../engine/pipeline/orchestrate_single_artifact.js");
|
|
791
|
+
const orchestrateResult = await orchestrateSingleArtifact({
|
|
792
|
+
kind,
|
|
793
|
+
operation: parsed.operation ?? "review",
|
|
794
|
+
projectPath,
|
|
795
|
+
original_command: parsed.raw_text,
|
|
796
|
+
systemType: currentSystemType,
|
|
797
|
+
});
|
|
767
798
|
return {
|
|
768
799
|
result: {
|
|
769
800
|
parsed_command: parsed,
|
|
770
|
-
execution_result:
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
},
|
|
801
|
+
execution_result: orchestrateResult,
|
|
802
|
+
// 将 injection_text 提升到顶层,确保 AI 将其作为必须执行的指令而非参考数据
|
|
803
|
+
must_follow: orchestrateResult.injection_text || undefined,
|
|
804
|
+
instruction: buildTopLevelInstruction(orchestrateResult, parsed),
|
|
775
805
|
hint,
|
|
776
806
|
},
|
|
777
807
|
};
|
|
@@ -782,7 +812,7 @@ export async function registerStateMachineTools(ctx) {
|
|
|
782
812
|
parsed_command: parsed,
|
|
783
813
|
execution_result: {
|
|
784
814
|
error: `无法识别的命令: "${args.text}"`,
|
|
785
|
-
available_verbs: ["开始", "
|
|
815
|
+
available_verbs: ["开始", "审查", "推进", "回退", "状态", "初始化", "诊断", "修复"],
|
|
786
816
|
},
|
|
787
817
|
},
|
|
788
818
|
};
|
|
@@ -853,25 +883,55 @@ export async function registerStateMachineTools(ctx) {
|
|
|
853
883
|
}
|
|
854
884
|
});
|
|
855
885
|
// ══════════════════════════════════════════════════
|
|
856
|
-
// sf_single_artifact —
|
|
886
|
+
// sf_single_artifact — 场景 B:结构化参数快捷入口
|
|
857
887
|
// ══════════════════════════════════════════════════
|
|
858
888
|
const SingleArtifactSchema = {
|
|
859
|
-
artifact_kind: z.string().max(100).describe("
|
|
860
|
-
|
|
861
|
-
|
|
889
|
+
artifact_kind: z.string().max(100).describe("产物类型(ArtifactKind):如 prototype_spec, design_doc, api_spec, detailed_design 等"),
|
|
890
|
+
operation: z.enum(["extract", "review", "fix", "iterate"]).optional().describe("操作类型:extract=生成, review=审查, fix=修改, iterate=迭代。默认 extract"),
|
|
891
|
+
intent: z.string().max(10_000).optional().describe("操作意图描述(可选)"),
|
|
862
892
|
};
|
|
863
|
-
registerSafeTool(TOOL.singleArtifact, "
|
|
893
|
+
registerSafeTool(TOOL.singleArtifact, "场景 B 快捷入口:单产物四层编排。传入 artifact_kind 和 operation,委托共享内核完成模板→引擎→规则→门禁编排", SingleArtifactSchema, async (args) => {
|
|
864
894
|
try {
|
|
865
|
-
|
|
866
|
-
//
|
|
895
|
+
const projectPath = ctx.projectPath ?? process.cwd();
|
|
896
|
+
// 获取当前管线 system_type
|
|
897
|
+
let singleSystemType;
|
|
898
|
+
try {
|
|
899
|
+
const pipeline = await sm.getCurrentPipeline();
|
|
900
|
+
if (pipeline)
|
|
901
|
+
singleSystemType = pipeline.system_type;
|
|
902
|
+
}
|
|
903
|
+
catch { /* 无管线时降级 */ }
|
|
904
|
+
const { orchestrateSingleArtifact } = await import("../../../engine/pipeline/orchestrate_single_artifact.js");
|
|
905
|
+
const { inferArtifactKindFromDescription, hasArtifactAlias } = await import("../../../engine/pipeline/artifact_resolver.js");
|
|
906
|
+
// 解析 kind:优先直接匹配,否则从描述推断
|
|
907
|
+
let kind = args.artifact_kind;
|
|
908
|
+
if (kind && !hasArtifactAlias(kind)) {
|
|
909
|
+
kind = inferArtifactKindFromDescription(args.artifact_kind) ?? undefined;
|
|
910
|
+
}
|
|
911
|
+
if (!kind) {
|
|
912
|
+
return {
|
|
913
|
+
result: {
|
|
914
|
+
mode: "single_artifact",
|
|
915
|
+
status: "error",
|
|
916
|
+
error: `无法识别产物类型: "${args.artifact_kind}"`,
|
|
917
|
+
},
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
// 委托共享内核
|
|
921
|
+
const orchestrateResult = await orchestrateSingleArtifact({
|
|
922
|
+
kind: kind,
|
|
923
|
+
operation: args.operation ?? "extract",
|
|
924
|
+
projectPath,
|
|
925
|
+
original_command: args.intent,
|
|
926
|
+
systemType: singleSystemType,
|
|
927
|
+
});
|
|
867
928
|
return {
|
|
868
929
|
result: {
|
|
869
|
-
|
|
870
|
-
|
|
930
|
+
execution_result: orchestrateResult,
|
|
931
|
+
// 与场景 A 保持一致:将 injection_text 提升为必须执行的指令
|
|
932
|
+
must_follow: orchestrateResult.injection_text || undefined,
|
|
933
|
+
instruction: buildTopLevelInstruction(orchestrateResult, { operation: args.operation ?? "extract", raw_text: args.intent }),
|
|
871
934
|
intent: args.intent,
|
|
872
|
-
scope: args.scope ?? [],
|
|
873
|
-
note: "单产物快速生成模式:跳过管线阶段流转",
|
|
874
|
-
suggestion: "生成完成后建议调用 sf_gate_check 进行质量验证",
|
|
875
935
|
},
|
|
876
936
|
};
|
|
877
937
|
}
|
|
@@ -940,6 +1000,164 @@ export async function registerStateMachineTools(ctx) {
|
|
|
940
1000
|
});
|
|
941
1001
|
}
|
|
942
1002
|
// ── 辅助函数 ──
|
|
1003
|
+
/**
|
|
1004
|
+
* 为单产物编排结果生成顶层指令。
|
|
1005
|
+
*
|
|
1006
|
+
* 将四层编排的 injection_text 从"参考数据"提升为"必须执行的指令",
|
|
1007
|
+
* 确保 AI 不会在审查后停下来,而是自动执行 修复→重审→直到通过 的循环。
|
|
1008
|
+
*
|
|
1009
|
+
* @visibleForTesting — 仅用于防回归测试导出,不供外部消费者使用。
|
|
1010
|
+
*/
|
|
1011
|
+
export function buildTopLevelInstruction(result, parsed) {
|
|
1012
|
+
const status = result.status;
|
|
1013
|
+
const targetName = result.target_name;
|
|
1014
|
+
const targetPaths = result.target_paths;
|
|
1015
|
+
// 非 ready 状态 — 给出明确动作指引
|
|
1016
|
+
if (status === "missing_upstream") {
|
|
1017
|
+
const suggestedAction = result.suggested_action;
|
|
1018
|
+
const originalTask = result.original_task;
|
|
1019
|
+
return [
|
|
1020
|
+
`⚠️ 上游产物缺失,无法直接执行当前操作。`,
|
|
1021
|
+
``,
|
|
1022
|
+
suggestedAction?.produce_first ?? `请先产出缺失的上游产物。`,
|
|
1023
|
+
suggestedAction?.then_resume ?? `上游就绪后重新执行。`,
|
|
1024
|
+
originalTask?.command ? `\n原任务命令: ${originalTask.command}` : "",
|
|
1025
|
+
].filter(Boolean).join("\n");
|
|
1026
|
+
}
|
|
1027
|
+
if (status === "error" || status === "no_template") {
|
|
1028
|
+
return `❌ 编排失败: ${result.error ?? "未知错误"}`;
|
|
1029
|
+
}
|
|
1030
|
+
// ready 状态 — 构建明确执行指令
|
|
1031
|
+
const operation = result.operation ?? parsed.operation ?? "review";
|
|
1032
|
+
const pathList = targetPaths?.length ? targetPaths.join("、") : "产物文件";
|
|
1033
|
+
if (operation === "extract") {
|
|
1034
|
+
return [
|
|
1035
|
+
`📋 你现在必须执行「${targetName}」的创建。禁止产出空洞内容。`,
|
|
1036
|
+
``,
|
|
1037
|
+
`执行步骤(不可跳过、不可简化):`,
|
|
1038
|
+
`1. 阅读 execution_result.injection_text 中的规则和门禁(含万物执行基线)`,
|
|
1039
|
+
`2. 参考模板结构(template_body),每个章节必须填写完整内容`,
|
|
1040
|
+
`3. 结合上游产物内容(upstream_inputs),穷尽所有实体/流程/字段`,
|
|
1041
|
+
`4. 产出完整产物并写入: ${pathList}`,
|
|
1042
|
+
`5. 产出后执行完整性自检:逐条核对门禁,引用产物原文作为证据`,
|
|
1043
|
+
`6. 任何门禁无证据 → 立即补充内容,不要停下来`,
|
|
1044
|
+
``,
|
|
1045
|
+
`⚠️ 绝对不允许留空章节、使用占位符、或以「上游未提供」为由省略内容。`,
|
|
1046
|
+
`⚠️ 绝对不允许跳过完整性自检。`,
|
|
1047
|
+
].join("\n");
|
|
1048
|
+
}
|
|
1049
|
+
// review / fix / iterate — 对抗性审查-修复协议(强制)
|
|
1050
|
+
return [
|
|
1051
|
+
`🔥 你是严格的质量审查员。你的职责是发现问题,不是放行。`,
|
|
1052
|
+
``,
|
|
1053
|
+
`必须严格遵守 execution_result.must_follow 中的全部规则(含万物执行基线 + 对抗性审查协议)。`,
|
|
1054
|
+
``,
|
|
1055
|
+
`执行步骤(不可跳过、不可简化):`,
|
|
1056
|
+
`1. 逐条读取门禁检查项,对每条引用产物原文作为证据`,
|
|
1057
|
+
`2. 无证据的 ✅ 等同于 ❌ — 你必须引用章节名或行号`,
|
|
1058
|
+
`3. 对每一个 ❌/⚠️ 项:立即修复,不允许停下来问用户`,
|
|
1059
|
+
`4. 修复后重写完整产物到: ${pathList}`,
|
|
1060
|
+
`5. 修复完成后,必须调用 [sf] 审查 进行独立重审`,
|
|
1061
|
+
`6. 如果重审仍有问题 → 继续修复(最多 5 轮)`,
|
|
1062
|
+
``,
|
|
1063
|
+
`⚠️ 绝对不允许只输出审查报告就停下来。`,
|
|
1064
|
+
`⚠️ 绝对不允许无证据地批量标记 ✅。`,
|
|
1065
|
+
`⚠️ 独立重审是强制步骤,不是可选建议。`,
|
|
1066
|
+
].join("\n");
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* 为阶段级审查生成顶层指令。
|
|
1070
|
+
*
|
|
1071
|
+
* 告诉 AI 必须审查该阶段全部产出,发现问题后逐个修复,直到全部通过。
|
|
1072
|
+
*
|
|
1073
|
+
* @visibleForTesting — 仅用于防回归测试导出,不供外部消费者使用。
|
|
1074
|
+
*/
|
|
1075
|
+
export function buildStageReviewInstruction(result, parsed) {
|
|
1076
|
+
const status = result.status;
|
|
1077
|
+
const stage = result.stage ?? parsed.stage ?? "未知阶段";
|
|
1078
|
+
if (status === "no_artifacts" || status === "error") {
|
|
1079
|
+
return `❌ 阶段「${stage}」没有可审查的产物: ${result.error ?? "未知错误"}`;
|
|
1080
|
+
}
|
|
1081
|
+
const artifactResults = result.artifact_results;
|
|
1082
|
+
const readyCount = artifactResults?.filter((r) => r.status === "ready").length ?? 0;
|
|
1083
|
+
const partialCount = artifactResults?.filter((r) => r.status !== "ready").length ?? 0;
|
|
1084
|
+
return [
|
|
1085
|
+
`🔥 你是严格的质量审查员。你的职责是发现问题,不是放行。`,
|
|
1086
|
+
``,
|
|
1087
|
+
`阶段共 ${readyCount} 个产物需要审查${partialCount > 0 ? `,${partialCount} 个产物因缺失上游被跳过` : ""}。`,
|
|
1088
|
+
``,
|
|
1089
|
+
`必须严格遵守 execution_result.must_follow 中的全部规则(含万物执行基线 + 对抗性审查协议)。`,
|
|
1090
|
+
``,
|
|
1091
|
+
`审查原则(违反任何一条等同审查失败):`,
|
|
1092
|
+
`1. 默认立场:每一条门禁检查项都是 ❌,除非你能引用产物中的具体内容作为证据`,
|
|
1093
|
+
`2. 无证据的 ✅ 等同于 ❌ — 你必须引用章节名或行号 + 原文`,
|
|
1094
|
+
`3. 禁止批量标记 ✅ — 每条必须独立检查并附证据`,
|
|
1095
|
+
`4. 禁止跳过任何检查项`,
|
|
1096
|
+
``,
|
|
1097
|
+
`执行步骤(不可跳过、不可简化):`,
|
|
1098
|
+
`1. 逐个审查阶段内的所有产物,对每条门禁引用产物原文作为证据`,
|
|
1099
|
+
`2. 检查跨产物一致性(术语、引用、覆盖、冲突),引用两个产物中的对应内容`,
|
|
1100
|
+
`3. 对每一个 ❌/⚠️ 项:立即修复,不允许停下来问用户`,
|
|
1101
|
+
`4. 修复后重写完整产物到对应文件`,
|
|
1102
|
+
`5. 修复完成后,必须调用 [sf] 审查 ${stage} 进行独立重审`,
|
|
1103
|
+
`6. 如果重审仍有问题 → 继续修复(最多 5 轮)`,
|
|
1104
|
+
``,
|
|
1105
|
+
`⚠️ 绝对不允许只输出审查报告就停下来。`,
|
|
1106
|
+
`⚠️ 绝对不允许无证据地批量标记 ✅。`,
|
|
1107
|
+
`⚠️ 独立重审是强制步骤,不是可选建议。`,
|
|
1108
|
+
].join("\n");
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* 为 execute-stage 结果生成执行指令。
|
|
1112
|
+
*
|
|
1113
|
+
* 将 companion_injection 中的规则/门禁从"参考数据"提升为"必须执行",
|
|
1114
|
+
* 并将 trigger 信号(头脑风暴/第一性原理/抽象模型)转化为 AI 指令。
|
|
1115
|
+
*/
|
|
1116
|
+
export function buildExecuteStageInstruction(result) {
|
|
1117
|
+
const stage = result.stage ?? "当前阶段";
|
|
1118
|
+
const lines = [];
|
|
1119
|
+
lines.push(`🔧 你现在必须执行「${stage}」阶段的工作。`);
|
|
1120
|
+
lines.push("");
|
|
1121
|
+
lines.push("必须严格遵守以下规则和门禁(含万物执行基线):");
|
|
1122
|
+
lines.push("");
|
|
1123
|
+
// 头脑风暴触发
|
|
1124
|
+
const bsTrigger = result.brainstorm_trigger;
|
|
1125
|
+
if (bsTrigger) {
|
|
1126
|
+
lines.push("⚠️ **风险检测触发头脑风暴(强制)**");
|
|
1127
|
+
lines.push(`原因: ${bsTrigger.reason}`);
|
|
1128
|
+
lines.push(`要求: ${bsTrigger.suggestion}`);
|
|
1129
|
+
lines.push("在执行阶段工作前,你必须先完成头脑风暴方案探索。");
|
|
1130
|
+
lines.push("");
|
|
1131
|
+
}
|
|
1132
|
+
// 第一性原理触发
|
|
1133
|
+
const fpTrigger = result.first_principles_trigger;
|
|
1134
|
+
if (fpTrigger) {
|
|
1135
|
+
lines.push("⚠️ **FP 规则触发第一性原理推理(强制)**");
|
|
1136
|
+
lines.push(`原因: ${fpTrigger.reason}`);
|
|
1137
|
+
lines.push(`要求: ${fpTrigger.suggestion}`);
|
|
1138
|
+
lines.push("在执行阶段工作前,你必须先从第一性原理重新审视决策。");
|
|
1139
|
+
lines.push("");
|
|
1140
|
+
}
|
|
1141
|
+
// 抽象模型触发
|
|
1142
|
+
const amTrigger = result.abstract_model_trigger;
|
|
1143
|
+
if (amTrigger) {
|
|
1144
|
+
lines.push("⚠️ **抽象缺失触发抽象建模(强制)**");
|
|
1145
|
+
lines.push(`原因: ${amTrigger.reason}`);
|
|
1146
|
+
lines.push(`要求: ${amTrigger.suggestion}`);
|
|
1147
|
+
lines.push("在执行阶段工作前,你必须先对核心概念进行抽象建模:识别领域实体、提取通用模式、建立概念关系。");
|
|
1148
|
+
lines.push("");
|
|
1149
|
+
}
|
|
1150
|
+
lines.push("执行纪律(不可违反):");
|
|
1151
|
+
lines.push("1. 先读 must_follow 中的全部规则,理解每条规则的约束");
|
|
1152
|
+
lines.push("2. 执行阶段工作时,每一步都必须符合规则要求");
|
|
1153
|
+
lines.push("3. 如果规则要求提供证据 — 必须引用你产出的具体内容");
|
|
1154
|
+
lines.push("4. 如果门禁检查有 ❌ 项 — 立即修复,不允许跳过");
|
|
1155
|
+
lines.push("5. 不可以「简化」或「跳过」任何规则要求的步骤");
|
|
1156
|
+
lines.push("");
|
|
1157
|
+
lines.push("⚠️ 绝对不允许忽略 must_follow 中的任何规则。");
|
|
1158
|
+
lines.push("⚠️ 绝对不允许产出不完整的阶段交付物。");
|
|
1159
|
+
return lines.join("\n");
|
|
1160
|
+
}
|
|
943
1161
|
/** 应用 dot-path updates 到对象 */
|
|
944
1162
|
function applyDotPathUpdates(target, updates) {
|
|
945
1163
|
const result = { ...target };
|