soloforge 1.3.0 → 1.3.1

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.
Files changed (84) hide show
  1. package/README.md +10 -0
  2. package/dist/adapters/claude_code/tools.d.ts +27 -0
  3. package/dist/adapters/claude_code/tools.d.ts.map +1 -1
  4. package/dist/adapters/claude_code/tools.js +513 -3
  5. package/dist/adapters/claude_code/tools.js.map +1 -1
  6. package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
  7. package/dist/adapters/shared/workflow_template.js +6 -0
  8. package/dist/adapters/shared/workflow_template.js.map +1 -1
  9. package/dist/bin/soloforge.d.ts.map +1 -1
  10. package/dist/bin/soloforge.js +147 -4
  11. package/dist/bin/soloforge.js.map +1 -1
  12. package/dist/engine/architecture_decision_workshop.d.ts +58 -0
  13. package/dist/engine/architecture_decision_workshop.d.ts.map +1 -0
  14. package/dist/engine/architecture_decision_workshop.js +118 -0
  15. package/dist/engine/architecture_decision_workshop.js.map +1 -0
  16. package/dist/engine/asset_manifest.d.ts.map +1 -1
  17. package/dist/engine/asset_manifest.js +11 -0
  18. package/dist/engine/asset_manifest.js.map +1 -1
  19. package/dist/engine/consumable_asset_registry.d.ts.map +1 -1
  20. package/dist/engine/consumable_asset_registry.js +64 -1
  21. package/dist/engine/consumable_asset_registry.js.map +1 -1
  22. package/dist/engine/design_artifact_pack.d.ts +44 -0
  23. package/dist/engine/design_artifact_pack.d.ts.map +1 -0
  24. package/dist/engine/design_artifact_pack.js +167 -0
  25. package/dist/engine/design_artifact_pack.js.map +1 -0
  26. package/dist/engine/dual_layer_mechanism_registry.d.ts.map +1 -1
  27. package/dist/engine/dual_layer_mechanism_registry.js +120 -0
  28. package/dist/engine/dual_layer_mechanism_registry.js.map +1 -1
  29. package/dist/engine/evidence_grounding_contract.d.ts +137 -0
  30. package/dist/engine/evidence_grounding_contract.d.ts.map +1 -0
  31. package/dist/engine/evidence_grounding_contract.js +410 -0
  32. package/dist/engine/evidence_grounding_contract.js.map +1 -0
  33. package/dist/engine/implementation_roadmap_registry.d.ts +1 -1
  34. package/dist/engine/implementation_roadmap_registry.d.ts.map +1 -1
  35. package/dist/engine/implementation_roadmap_registry.js +134 -5
  36. package/dist/engine/implementation_roadmap_registry.js.map +1 -1
  37. package/dist/engine/instruction_contract.d.ts +8 -1
  38. package/dist/engine/instruction_contract.d.ts.map +1 -1
  39. package/dist/engine/instruction_contract.js +63 -1
  40. package/dist/engine/instruction_contract.js.map +1 -1
  41. package/dist/engine/intent_expander.d.ts.map +1 -1
  42. package/dist/engine/intent_expander.js +14 -0
  43. package/dist/engine/intent_expander.js.map +1 -1
  44. package/dist/engine/mechanism_contract_registry.d.ts.map +1 -1
  45. package/dist/engine/mechanism_contract_registry.js +66 -0
  46. package/dist/engine/mechanism_contract_registry.js.map +1 -1
  47. package/dist/engine/platform_context.d.ts.map +1 -1
  48. package/dist/engine/platform_context.js +6 -2
  49. package/dist/engine/platform_context.js.map +1 -1
  50. package/dist/engine/release_gate_scenario_registry.d.ts +16 -1
  51. package/dist/engine/release_gate_scenario_registry.d.ts.map +1 -1
  52. package/dist/engine/release_gate_scenario_registry.js +205 -2
  53. package/dist/engine/release_gate_scenario_registry.js.map +1 -1
  54. package/dist/engine/release_readiness_gate.d.ts +8 -0
  55. package/dist/engine/release_readiness_gate.d.ts.map +1 -1
  56. package/dist/engine/release_readiness_gate.js +616 -6
  57. package/dist/engine/release_readiness_gate.js.map +1 -1
  58. package/dist/engine/task_context.d.ts +9 -2
  59. package/dist/engine/task_context.d.ts.map +1 -1
  60. package/dist/engine/task_context.js +49 -12
  61. package/dist/engine/task_context.js.map +1 -1
  62. package/dist/engine/verifier.d.ts.map +1 -1
  63. package/dist/engine/verifier.js +3 -40
  64. package/dist/engine/verifier.js.map +1 -1
  65. package/dist/engine/workflow_contract_registry.d.ts.map +1 -1
  66. package/dist/engine/workflow_contract_registry.js +4 -3
  67. package/dist/engine/workflow_contract_registry.js.map +1 -1
  68. package/dist/types.d.ts +12 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/package.json +4 -3
  71. package/templates/knowledge/acceptance_templates/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 +74 -0
  72. package/templates/knowledge/acceptance_templates//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 +59 -0
  73. package/templates/knowledge/acceptance_templates//346/236/266/346/236/204/350/256/276/350/256/241/346/250/241/347/211/210.md +27 -7
  74. package/templates/knowledge/acceptance_templates//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 +47 -0
  75. package/templates/knowledge/procedures//346/236/266/346/236/204/345/206/263/347/255/226/347/240/224/350/256/250/345/267/245/344/275/234/346/265/201.md +51 -0
  76. package/templates/knowledge/procedures//346/236/266/346/236/204/350/256/276/350/256/241/345/267/245/344/275/234/346/265/201.md +16 -7
  77. package/templates/knowledge/procedures//350/256/276/350/256/241/344/272/247/347/211/251/347/224/237/346/210/220/344/270/216/345/244/215/351/252/214/345/267/245/344/275/234/346/265/201.md +45 -0
  78. package/templates/knowledge/rules//345/267/245/344/275/234/346/265/201/346/250/241/346/235/277/345/214/205/350/247/204/345/210/231.md +10 -0
  79. package/templates/knowledge/rules//346/211/251/345/261/225/347/224/237/345/221/275/345/221/250/346/234/237/350/247/204/345/210/231.md +10 -0
  80. package/templates/knowledge/rules//346/226/275/345/267/245/346/214/207/344/273/244/345/245/221/347/272/246/350/247/204/345/210/231.md +33 -4
  81. package/templates/knowledge/rules//346/236/266/346/236/204/345/206/263/347/255/226/347/240/224/350/256/250/350/247/204/345/210/231.md +49 -0
  82. package/templates/knowledge/rules//350/256/276/350/256/241/344/272/247/347/211/251/345/214/205/350/247/204/345/210/231.md +55 -0
  83. package/templates/knowledge/rules//350/257/201/346/215/256/351/251/261/345/212/250/344/270/216/345/217/215/345/271/273/350/247/211/350/247/204/345/210/231.md +75 -0
  84. package/templates/knowledge/rules//350/267/250/345/271/263/345/217/260/350/267/257/345/276/204/345/256/211/345/205/250/350/247/204/345/210/231.md +10 -0
@@ -78,6 +78,8 @@ const lazyTechnologyDecision = createLazy(() => import("../../engine/technology_
78
78
  const lazyDetailDiscipline = createLazy(() => import("../../engine/detail_discipline.js"));
79
79
  const lazyFirstPrinciples = createLazy(() => import("../../engine/first_principles.js"));
80
80
  const lazyBrainstormContract = createLazy(() => import("../../engine/brainstorm_contract.js"));
81
+ const lazyArchitectureWorkshop = createLazy(() => import("../../engine/architecture_decision_workshop.js"));
82
+ const lazyDesignArtifactPack = createLazy(() => import("../../engine/design_artifact_pack.js"));
81
83
  // ── Zod Schema 定义 ──
82
84
  const ClassifySchema = {
83
85
  intent: z.string().describe("开发者意图描述"),
@@ -87,6 +89,8 @@ const ExpandSchema = {
87
89
  task_id: z.string().describe("sf_classify 返回的任务 ID"),
88
90
  clarification_answers: z.array(z.string()).optional().describe("对澄清问题的回答"),
89
91
  input_material_confirmations: z.array(z.string()).optional().describe("已确认安全的输入材料路径列表"),
92
+ architecture_decision_workshop: z.unknown().optional().describe("架构设计前已讨论并确认的六域决策记录"),
93
+ design_artifact_pack: z.unknown().optional().describe("设计产物包路径映射或已复验状态"),
90
94
  };
91
95
  const VerifySchema = {
92
96
  task_id: z.string().describe("任务 ID"),
@@ -245,7 +249,7 @@ export async function checkInstructionContractGate(params) {
245
249
  if (!instruction)
246
250
  return { allowed: true };
247
251
  // 消费 enforceInstructionBeforeImplementation(链式消费 checkInstructionCompleteness + validateInstructionContract)
248
- const result = instrModule.enforceInstructionBeforeImplementation(instruction, params.toolName);
252
+ const result = await instrModule.enforceInstructionBeforeImplementation(instruction, params.toolName);
249
253
  // Draft 状态不阻断 — 仅在 confirmed/executing/blocked 状态时强制
250
254
  if (instruction.status === "draft") {
251
255
  return { allowed: true, findings: result.allowed ? [] : [result.reason_zh] };
@@ -260,6 +264,22 @@ export async function checkInstructionContractGate(params) {
260
264
  }
261
265
  return { allowed: true };
262
266
  }
267
+ /**
268
+ * 设计产物编码门 — 依赖设计包的任务,在真实复验完成前不得写入业务实现。
269
+ * 仅阻断文件/配置/外部交付写入;任务状态、设计文档复验和讨论本身仍可推进。
270
+ */
271
+ export function checkDesignArtifactWriteGate(params) {
272
+ const implementationWrite = params.sideEffects.some((effect) => ["file_write", "config_write", "external_write", "git_commit", "git_push", "pr_create"].includes(effect));
273
+ if (!implementationWrite || !params.ctx?.design_artifact_pack)
274
+ return { allowed: true };
275
+ if (params.ctx.design_artifact_pack.status === "implementation_ready")
276
+ return { allowed: true };
277
+ return {
278
+ allowed: false,
279
+ diagnostic_code: "SF-DESIGN-PACK-NOT-READY",
280
+ reason: `工具 ${params.toolName} 依赖的设计产物包状态为 ${params.ctx.design_artifact_pack.status},未完成真实复验,不得写入实现或交付`,
281
+ };
282
+ }
263
283
  /**
264
284
  * 架构设计门 — 架构设计类任务膨胀前执行 reviewArchitectureDesign。
265
285
  * 问题四十九: Architecture Design Contract enforcement。
@@ -287,6 +307,30 @@ export async function checkArchitectureDesignGate(params) {
287
307
  }
288
308
  return { allowed: true };
289
309
  }
310
+ /**
311
+ * 架构决策研讨门 — 正式架构设计前六域决策必须闭合。
312
+ * 问题六十一: 与是否存在施工指令契约无关,架构设计路由必经此门。
313
+ */
314
+ export async function checkArchitectureDecisionWorkshopGate(params) {
315
+ const workshopModule = await lazyArchitectureWorkshop();
316
+ if (!workshopModule.requiresArchitectureDecisionWorkshop(params.workflowIntent, params.ctx.intent)) {
317
+ return { allowed: true };
318
+ }
319
+ const existing = params.ctx.architecture_decision_workshop;
320
+ const contract = existing ?? workshopModule.createArchitectureDecisionWorkshop(params.ctx.task_id, params.projectContext ?? "new_system");
321
+ if (params.projectContext === "existing_system" && contract.project_context !== "existing_system") {
322
+ contract.project_context = "existing_system";
323
+ }
324
+ const evaluatedContract = workshopModule.applyArchitectureWorkshopGate(contract) ?? contract;
325
+ const gate = workshopModule.evaluateArchitectureDecisionWorkshop(evaluatedContract);
326
+ params.ctx.architecture_decision_workshop = evaluatedContract;
327
+ return {
328
+ allowed: gate.allowed,
329
+ findings: gate.blocking_findings,
330
+ next_domain: gate.next_domain,
331
+ contract: evaluatedContract,
332
+ };
333
+ }
290
334
  /**
291
335
  * 现有系统分析门 — 现有项目编码前必须先做分析。
292
336
  * 问题五十: Existing System Analysis Contract enforcement。
@@ -956,6 +1000,35 @@ export async function registerTools(server, deps) {
956
1000
  };
957
1001
  }
958
1002
  }
1003
+ // 问题六十二: MCP 写入路径同样必须消费设计产物包状态,不能绕开 CLI hook。
1004
+ if (hasWriteEffect && taskId) {
1005
+ const designWriteGate = checkDesignArtifactWriteGate({ ctx, toolName: name, sideEffects: effectiveSideEffects });
1006
+ if (!designWriteGate.allowed) {
1007
+ const designViolation = {
1008
+ invocation_id: invocationId, tool_name: name,
1009
+ violation_type: "guard_blocked", severity: "hard_fail",
1010
+ reason: designWriteGate.reason ?? "设计产物包未达到实现就绪状态",
1011
+ recovery: "仅可继续补充设计资产并执行 sf_verify 真实复验;通过前不得写入业务实现",
1012
+ };
1013
+ const designTrace = createToolTrace({
1014
+ tool_name: name, invocation_id: invocationId, task_id: taskId,
1015
+ actual_side_effects: effectiveSideEffects,
1016
+ next_allowed_tools: contract.default_next_tools,
1017
+ forbidden_tools: contract.forbidden_next_tools,
1018
+ authorization, bypass,
1019
+ });
1020
+ await taskContext.setToolTrace(taskId, designTrace, [designViolation]);
1021
+ return {
1022
+ content: [{ type: "text", text: JSON.stringify({
1023
+ error: designViolation.reason,
1024
+ violation: designViolation,
1025
+ diagnostic_code: designWriteGate.diagnostic_code,
1026
+ recovery: designViolation.recovery,
1027
+ }) }],
1028
+ isError: true,
1029
+ };
1030
+ }
1031
+ }
959
1032
  // 合同验证
960
1033
  const lastTrace = ctx?.last_tool_trace;
961
1034
  // 为动态工具构建有效的合同覆盖(如 sf_status cancel)
@@ -1168,9 +1241,19 @@ export async function registerTools(server, deps) {
1168
1241
  if (!ctx || !ctx.classification) {
1169
1242
  return { result: { error: "任务不存在或尚未分类,请先调用 sf_classify" } };
1170
1243
  }
1244
+ if (args.architecture_decision_workshop) {
1245
+ ctx.architecture_decision_workshop = args.architecture_decision_workshop;
1246
+ }
1247
+ if (args.design_artifact_pack) {
1248
+ ctx.design_artifact_pack = args.design_artifact_pack;
1249
+ }
1250
+ if (args.architecture_decision_workshop || args.design_artifact_pack) {
1251
+ await taskContext.save(ctx);
1252
+ }
1171
1253
  // 状态守卫:classifying/expanding/clarifying → expanding
1172
1254
  if (ctx.status === "classifying" || ctx.status === "clarifying") {
1173
1255
  await taskContext.updateStatus(args.task_id, "expanding");
1256
+ ctx.status = "expanding";
1174
1257
  }
1175
1258
  else if (ctx.status !== "expanding") {
1176
1259
  return {
@@ -1247,7 +1330,140 @@ export async function registerTools(server, deps) {
1247
1330
  gateway.endTask();
1248
1331
  }
1249
1332
  expansion.task_id = args.task_id;
1250
- // 问题四十九/五十: 架构设计 Contract + 现有系统分析门 — 仅在有施工指令契约时强制执行
1333
+ const workflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification.route_decision?.workflow_intent;
1334
+ // 问题六十: 高风险项目事实声明先过证据门,避免后续架构研讨门遮蔽无证据问题。
1335
+ {
1336
+ const evRoute = ctx.route_decision?.route ?? ctx.classification?.route_decision?.route;
1337
+ const evWorkflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification?.route_decision?.workflow_intent;
1338
+ const evRisk = (await import("../../engine/evidence_grounding_contract.js")).assessTaskRisk(ctx.classification?.task_type, evRoute, ctx.intent);
1339
+ const isArchitectureContext = evWorkflowIntent === "architecture_design"
1340
+ || evWorkflowIntent === "existing_system_gap_analysis"
1341
+ || evRoute === "artifact_generation"
1342
+ || /架构|architecture|系统设计|技术方案|现有系统|差距分析|gap.?analysis/i.test(ctx.intent ?? "");
1343
+ if (isArchitectureContext && (evRisk === "high" || evRisk === "critical")) {
1344
+ const { createEvidenceGroundingSystem } = await import("../../engine/evidence_grounding_contract.js");
1345
+ const evg = createEvidenceGroundingSystem();
1346
+ evg.registry.register({
1347
+ source_type: "task_context",
1348
+ evidence_role: "classification",
1349
+ authority: "authoritative",
1350
+ freshness: "current",
1351
+ permission: "allowed",
1352
+ scope: "classification",
1353
+ description: "任务分类结果",
1354
+ source_ref: `task:${args.task_id}`,
1355
+ });
1356
+ if (knowledgeIndex) {
1357
+ const { project } = knowledgeIndex.getAllEntries();
1358
+ for (const entry of project) {
1359
+ if (entry.status !== "active")
1360
+ continue;
1361
+ evg.registry.register({
1362
+ source_type: "knowledge_asset",
1363
+ evidence_role: "template_guidance",
1364
+ authority: "trusted",
1365
+ freshness: "current",
1366
+ permission: "allowed",
1367
+ scope: entry.scope?.join(",") ?? "knowledge",
1368
+ description: entry.name,
1369
+ source_ref: entry.file_path,
1370
+ });
1371
+ }
1372
+ }
1373
+ const tdc = ctx?.technology_decision_contract;
1374
+ if (tdc?.human_gate_evidence) {
1375
+ evg.registry.register({
1376
+ source_type: "user_confirmation",
1377
+ evidence_role: "user_confirmation",
1378
+ authority: "authoritative",
1379
+ freshness: "current",
1380
+ permission: "allowed",
1381
+ scope: "technology_decision",
1382
+ description: `技术决策确认: ${tdc.decision_scope ?? "general"}`,
1383
+ source_ref: `decision:${tdc.decision_id ?? args.task_id}`,
1384
+ });
1385
+ }
1386
+ const evClaims = [
1387
+ {
1388
+ id: "claim-expand-0",
1389
+ category: "user_confirmation",
1390
+ claim_text: "任务路由和执行范围已确认",
1391
+ evidence_ids: evg.registry.query({ source_type: "task_context" }).map((e) => e.id),
1392
+ is_uncertain: false,
1393
+ risk_level: evRisk,
1394
+ },
1395
+ {
1396
+ id: "claim-expand-1",
1397
+ category: "architecture",
1398
+ claim_text: "技术方案基于现有系统分析",
1399
+ evidence_ids: evg.registry.query({}).filter((e) => e.evidence_role && e.evidence_role !== "template_guidance" && e.evidence_role !== "classification").map((e) => e.id),
1400
+ is_uncertain: false,
1401
+ risk_level: evRisk,
1402
+ },
1403
+ ];
1404
+ const evMatrix = evg.builder.buildContext(evClaims, {
1405
+ target_claims: evClaims.map((c) => c.claim_text),
1406
+ source_types: [],
1407
+ keywords: [],
1408
+ max_results: 10,
1409
+ });
1410
+ evMatrix.task_id = args.task_id;
1411
+ const evGate = evg.gate.evaluate(evMatrix, evRisk);
1412
+ await taskContext.setEvidenceGroundingResult(args.task_id, {
1413
+ evidence_matrix: evMatrix,
1414
+ evidence_gate_result: evGate,
1415
+ unsupported_claims: evGate.unsupported_claims,
1416
+ conflict_resolutions: evMatrix.conflicts,
1417
+ });
1418
+ if (!evGate.allowed) {
1419
+ return {
1420
+ result: {
1421
+ error: `证据驱动门禁阻断: ${evGate.reason_zh}`,
1422
+ diagnostic_code: evGate.diagnostic_code,
1423
+ reason_zh: evGate.reason_zh,
1424
+ unsupported_claims: evGate.unsupported_claims,
1425
+ missing_evidence: evGate.missing_evidence,
1426
+ status: "blocked",
1427
+ recovery: "请提供项目文件、命令输出或其他权威证据支撑关键声明后重新 sf_expand",
1428
+ },
1429
+ };
1430
+ }
1431
+ }
1432
+ }
1433
+ // 问题六十一: 架构设计前的六域研讨门独立执行,不得被施工指令契约有无绕过。
1434
+ const existingSourceRoot = ["src", "backend", "frontend", "apps", "services"].some((candidate) => fss.existsSync(path.join(projectPath, candidate)));
1435
+ const existingManifest = ["package.json", "pom.xml", "build.gradle", "settings.gradle"].some((candidate) => fss.existsSync(path.join(projectPath, candidate)));
1436
+ const detectedArchitectureContext = existingSourceRoot && existingManifest
1437
+ ? "existing_system"
1438
+ : (!existingSourceRoot && !existingManifest ? "empty_project" : "new_system");
1439
+ const workshopGate = await checkArchitectureDecisionWorkshopGate({
1440
+ ctx,
1441
+ workflowIntent,
1442
+ projectContext: detectedArchitectureContext,
1443
+ });
1444
+ await taskContext.save(ctx);
1445
+ if (!workshopGate.allowed) {
1446
+ return {
1447
+ result: {
1448
+ error: "架构设计前必须先完成六类架构决策研讨与用户确认",
1449
+ status: "awaiting_confirmation",
1450
+ architecture_decision_workshop: workshopGate.contract,
1451
+ blocking_findings: workshopGate.findings,
1452
+ next_domain: workshopGate.next_domain,
1453
+ recovery: "请从当前待讨论域开始,提供候选方案、推荐理由、风险和用户确认后重新调用 sf_expand",
1454
+ },
1455
+ };
1456
+ }
1457
+ // 六域决策闭合后创建设计产物生命周期;正式设计与后续实现必须以其复验结果为准。
1458
+ if (workflowIntent === "architecture_design" && !ctx.design_artifact_pack) {
1459
+ const designModule = await lazyDesignArtifactPack();
1460
+ ctx.design_artifact_pack = designModule.createDesignArtifactPack(args.task_id);
1461
+ ctx.design_artifact_pack.status = "awaiting_decisions";
1462
+ ctx.design_artifact_pack.decision_workshop_ref = `task:${args.task_id}:architecture_decision_workshop`;
1463
+ ctx.design_artifact_pack.user_confirmation_ref = ctx.architecture_decision_workshop?.document_output_confirmation_ref;
1464
+ await taskContext.save(ctx);
1465
+ }
1466
+ // 问题四十九/五十: 已有架构合同或现有系统证据的进一步审查。
1251
1467
  const expansionRoute = expansion.workflow_trace
1252
1468
  ? expansion.workflow_trace?.route
1253
1469
  : undefined;
@@ -1361,7 +1577,124 @@ export async function registerTools(server, deps) {
1361
1577
  advisories.h1_advisory = h1Warning;
1362
1578
  if (h4LockWarning)
1363
1579
  advisories.h4_advisory = h4LockWarning;
1364
- // 配置优先级警告
1580
+ // 问题六十:证据驱动门禁 — 高风险任务必须阻断无证据声明
1581
+ const _evRoute = ctx.route_decision?.route ?? ctx.classification?.route_decision?.route;
1582
+ const _evRisk = (await import("../../engine/evidence_grounding_contract.js")).assessTaskRisk(ctx.classification?.task_type, _evRoute, ctx.intent);
1583
+ if (_evRisk === "high" || _evRisk === "critical") {
1584
+ const { createEvidenceGroundingSystem } = await import("../../engine/evidence_grounding_contract.js");
1585
+ const _evg = createEvidenceGroundingSystem();
1586
+ if (ctx.classification) {
1587
+ _evg.registry.register({
1588
+ source_type: "task_context",
1589
+ evidence_role: "classification",
1590
+ authority: "authoritative",
1591
+ freshness: "current",
1592
+ permission: "allowed",
1593
+ scope: "classification",
1594
+ description: "任务分类结果",
1595
+ source_ref: `task:${args.task_id}`,
1596
+ });
1597
+ }
1598
+ // 注册知识索引中的项目知识作为证据(仅项目级,不含全局通用规则)
1599
+ // 所有知识索引条目都是 template_guidance 角色,不得支撑项目事实声明
1600
+ if (knowledgeIndex) {
1601
+ const { project } = knowledgeIndex.getAllEntries();
1602
+ for (const entry of project) {
1603
+ if (entry.status !== "active")
1604
+ continue;
1605
+ _evg.registry.register({
1606
+ source_type: "knowledge_asset",
1607
+ evidence_role: "template_guidance",
1608
+ authority: "trusted",
1609
+ freshness: "current",
1610
+ permission: "allowed",
1611
+ scope: entry.scope?.join(",") ?? "knowledge",
1612
+ description: entry.name,
1613
+ source_ref: entry.file_path,
1614
+ });
1615
+ }
1616
+ }
1617
+ // 技术决策契约含 human_gate_evidence → 注册为 user_confirmation(真实项目证据)
1618
+ const _tdc = ctx?.technology_decision_contract;
1619
+ if (_tdc?.human_gate_evidence) {
1620
+ _evg.registry.register({
1621
+ source_type: "user_confirmation",
1622
+ evidence_role: "user_confirmation",
1623
+ authority: "authoritative",
1624
+ freshness: "current",
1625
+ permission: "allowed",
1626
+ scope: "technology_decision",
1627
+ description: `技术决策确认: ${_tdc.decision_scope ?? "general"}`,
1628
+ source_ref: `decision:${_tdc.decision_id ?? args.task_id}`,
1629
+ });
1630
+ }
1631
+ const _evClaims = [
1632
+ {
1633
+ id: "claim-expand-0",
1634
+ category: "user_confirmation",
1635
+ claim_text: "任务路由和执行范围已确认",
1636
+ evidence_ids: _evg.registry.query({ source_type: "task_context" }).map((e) => e.id),
1637
+ is_uncertain: false,
1638
+ risk_level: _evRisk,
1639
+ },
1640
+ ];
1641
+ // 只在架构设计/现有系统分析场景生成 architecture claim
1642
+ const _evWorkflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification?.route_decision?.workflow_intent;
1643
+ const _evIntentText = (ctx.intent ?? "").toLowerCase();
1644
+ const _isArchitectureContext = _evWorkflowIntent === "architecture_design"
1645
+ || _evWorkflowIntent === "existing_system_gap_analysis"
1646
+ || _evRoute === "artifact_generation"
1647
+ || /架构|architecture|系统设计|技术方案|现有系统|差距分析|gap.?analysis/i.test(_evIntentText);
1648
+ if (_isArchitectureContext) {
1649
+ _evClaims.push({
1650
+ id: "claim-expand-1",
1651
+ category: "architecture",
1652
+ claim_text: "技术方案基于现有系统分析",
1653
+ evidence_ids: _evg.registry.query({}).filter((e) => e.evidence_role && e.evidence_role !== "template_guidance" && e.evidence_role !== "classification").map((e) => e.id),
1654
+ is_uncertain: false,
1655
+ risk_level: _evRisk,
1656
+ });
1657
+ }
1658
+ const _evVerify = _evg.verifier.verify(_evClaims, _evRisk);
1659
+ const _evMatrix = _evg.builder.buildContext(_evClaims, {
1660
+ target_claims: _evClaims.map((c) => c.claim_text),
1661
+ source_types: [], keywords: [], max_results: 10,
1662
+ });
1663
+ _evMatrix.task_id = args.task_id;
1664
+ const _evGate = _evg.gate.evaluate(_evMatrix, _evRisk);
1665
+ // 写回 TaskContext(blocked 也保存)
1666
+ await taskContext.setEvidenceGroundingResult(args.task_id, {
1667
+ evidence_matrix: _evMatrix,
1668
+ evidence_gate_result: _evGate,
1669
+ unsupported_claims: _evGate.unsupported_claims,
1670
+ conflict_resolutions: _evMatrix.conflicts,
1671
+ });
1672
+ if (!_evGate.allowed) {
1673
+ return {
1674
+ result: {
1675
+ error: `证据驱动门禁阻断: ${_evGate.reason_zh}`,
1676
+ diagnostic_code: _evGate.diagnostic_code,
1677
+ reason_zh: _evGate.reason_zh,
1678
+ unsupported_claims: _evGate.unsupported_claims,
1679
+ missing_evidence: _evGate.missing_evidence,
1680
+ status: "blocked",
1681
+ recovery: "请提供项目文件、命令输出或其他权威证据支撑关键声明后重新 sf_expand",
1682
+ },
1683
+ };
1684
+ }
1685
+ if (_evGate.requires_user_confirmation.length > 0) {
1686
+ advisories.evidence_advisory = {
1687
+ level: "requires_confirmation",
1688
+ items: _evGate.requires_user_confirmation,
1689
+ diagnostic_code: _evGate.diagnostic_code,
1690
+ };
1691
+ }
1692
+ }
1693
+ else {
1694
+ // 低风险通用问答:标注为通用建议
1695
+ advisories.evidence_advisory = "通用建议,非项目事实;证据驱动门禁低风险放行";
1696
+ }
1697
+ // 配置优先级警告
1365
1698
  if (expansion.config_resolution_reports && expansion.config_resolution_reports.length > 0) {
1366
1699
  const configWarnings = expansion.config_resolution_reports
1367
1700
  .filter(r => r.conflicts.length > 0)
@@ -1428,6 +1761,34 @@ export async function registerTools(server, deps) {
1428
1761
  result: { error: "任务不存在" },
1429
1762
  };
1430
1763
  }
1764
+ // 问题六十二: 设计产物验证必须读取用户项目真实文件,不接受占位合同自证通过。
1765
+ const verifyWorkflowIntent = ctx.route_decision?.workflow_intent ?? ctx.classification?.route_decision?.workflow_intent;
1766
+ const touchesDesignArtifacts = args.changed_files.some((file) => /docs\/architecture\/|docs\/api\/|openapi|db\/(?:migrations|schema)|架构设计|数据库设计|API接口规格/i.test(file));
1767
+ if (verifyWorkflowIntent === "architecture_design" || touchesDesignArtifacts) {
1768
+ const designModule = await lazyDesignArtifactPack();
1769
+ const designPack = ctx.design_artifact_pack ?? designModule.createDesignArtifactPack(args.task_id);
1770
+ const designVerification = designModule.verifyDesignArtifactPack(projectPath, designPack);
1771
+ ctx.design_artifact_pack = {
1772
+ ...designPack,
1773
+ status: designVerification.status,
1774
+ findings: designVerification.findings,
1775
+ baseline_hashes: designVerification.hashes,
1776
+ verified_at: new Date().toISOString(),
1777
+ };
1778
+ await taskContext.save(ctx);
1779
+ if (!designVerification.passed) {
1780
+ return {
1781
+ result: {
1782
+ error: "设计产物包复验未通过,不得继续生成编码或交付结论",
1783
+ status: "blocked",
1784
+ diagnostic_code: "SF-DESIGN-PACK-VERIFY-FAILED",
1785
+ design_artifact_findings: designVerification.findings,
1786
+ checked_files: designVerification.checked_files,
1787
+ recovery: "修复设计产物、补充用户确认并重新执行 sf_verify;不得只提交报告绕过缺口",
1788
+ },
1789
+ };
1790
+ }
1791
+ }
1431
1792
  // RouteDecision 合同验证 — 无条件,在状态预检之前
1432
1793
  const rdFromCtx = ctx.route_decision ?? ctx.classification?.route_decision ?? null;
1433
1794
  const wtFromCtx = ctx.workflow_trace ?? ctx.expansion?.workflow_trace ?? null;
@@ -1580,6 +1941,82 @@ export async function registerTools(server, deps) {
1580
1941
  // 附加验证契约引用到返回结果
1581
1942
  verifyPayload.verification_plan = vPlan;
1582
1943
  verifyPayload.verification_result = vResult;
1944
+ // 问题六十:验证结论必须经过 FactClaimVerifier,不得把计划当结果
1945
+ {
1946
+ const { createEvidenceGroundingSystem, assessTaskRisk } = await import("../../engine/evidence_grounding_contract.js");
1947
+ const _vRoute = ctx.route_decision?.route ?? ctx.classification?.route_decision?.route;
1948
+ const _vRisk = assessTaskRisk(ctx.classification?.task_type, _vRoute, ctx.intent);
1949
+ if (_vRisk !== "low") {
1950
+ const _veg = createEvidenceGroundingSystem();
1951
+ // 只有真实执行结果才能作为 validation_result 证据
1952
+ const _hasRealPassed = ctx.verification_result && ctx.verification_result.status === "passed";
1953
+ if (_hasRealPassed) {
1954
+ _veg.registry.register({
1955
+ source_type: "validation_result",
1956
+ authority: "authoritative",
1957
+ freshness: "current",
1958
+ permission: "allowed",
1959
+ scope: "verification",
1960
+ description: `验证状态: ${ctx.verification_result.status}`,
1961
+ source_ref: `verification:${args.task_id}`,
1962
+ });
1963
+ }
1964
+ // 验证计划注册为 task_context,不冒充 validation_result
1965
+ _veg.registry.register({
1966
+ source_type: "task_context",
1967
+ authority: "supporting",
1968
+ freshness: "current",
1969
+ permission: "allowed",
1970
+ scope: "verification_plan",
1971
+ description: `验证计划: ${vPlan ? "已生成" : "未生成"}`,
1972
+ source_ref: `verification-plan:${args.task_id}`,
1973
+ });
1974
+ if (args.changed_files.length > 0) {
1975
+ _veg.registry.register({
1976
+ source_type: "project_file",
1977
+ authority: "authoritative",
1978
+ freshness: "current",
1979
+ permission: "allowed",
1980
+ scope: "changed_files",
1981
+ description: `变更文件: ${args.changed_files.join(", ")}`,
1982
+ source_ref: `files:${args.changed_files.join(",")}`,
1983
+ });
1984
+ }
1985
+ const _vClaims = [{
1986
+ id: "claim-verify-1",
1987
+ category: "validation_result",
1988
+ claim_text: "验证结果基于真实命令执行",
1989
+ evidence_ids: _veg.registry.query({ source_type: "validation_result" }).map((e) => e.id),
1990
+ is_uncertain: false,
1991
+ risk_level: _vRisk,
1992
+ }];
1993
+ const _vVerResult = _veg.verifier.verify(_vClaims, _vRisk);
1994
+ const _vMatrix = _veg.builder.buildContext(_vClaims, {
1995
+ target_claims: _vClaims.map((c) => c.claim_text),
1996
+ source_types: [], keywords: [], max_results: 10,
1997
+ });
1998
+ _vMatrix.task_id = args.task_id;
1999
+ const _vGate = _veg.gate.evaluate(_vMatrix, _vRisk);
2000
+ // 写回 TaskContext
2001
+ await taskContext.setEvidenceGroundingResult(args.task_id, {
2002
+ evidence_matrix: _vMatrix,
2003
+ evidence_gate_result: _vGate,
2004
+ unsupported_claims: _vGate.unsupported_claims,
2005
+ conflict_resolutions: _vMatrix.conflicts,
2006
+ });
2007
+ if (_vVerResult.unsupported.length > 0) {
2008
+ // 高风险:只有 plan 无 result → 写入 payload(不用 verifyExtras)
2009
+ verifyPayload._evidence_status = "not_verified";
2010
+ verifyPayload._evidence_reason = "验证结论需真实命令执行结果支撑,验证计划不能当作验证结果。请通过 sf_record_verification_execution 录入真实验证结果。";
2011
+ if (_vRisk === "high" || _vRisk === "critical") {
2012
+ verifyPayload._evidence_blocked = true;
2013
+ }
2014
+ else {
2015
+ verifyPayload._evidence_advisory = "验证结论需真实命令执行结果支撑,验证计划不能当作验证结果";
2016
+ }
2017
+ }
2018
+ }
2019
+ }
1583
2020
  // 验证后核心体验评估
1584
2021
  try {
1585
2022
  const hasVerificationEvidence = (verifyResult.checks?.build?.length ?? 0) > 0 || (verifyResult.checks?.tests?.length ?? 0) > 0;
@@ -2091,6 +2528,17 @@ export async function registerTools(server, deps) {
2091
2528
  }
2092
2529
  }
2093
2530
  }
2531
+ // 问题六十二: 依赖设计产物的任务只有 implementation_ready 后才可交付。
2532
+ if (ctx.design_artifact_pack && ctx.design_artifact_pack.status !== "implementation_ready") {
2533
+ return {
2534
+ result: {
2535
+ error: `设计产物包状态为 ${ctx.design_artifact_pack.status},未达到 implementation_ready,不得交付`,
2536
+ diagnostic_code: "SF-DESIGN-PACK-NOT-READY",
2537
+ findings: ctx.design_artifact_pack.findings,
2538
+ recovery: "请完成设计产物真实复验并修复所有阻断项后重新交付",
2539
+ },
2540
+ };
2541
+ }
2094
2542
  // 交付 lease 互斥检查
2095
2543
  const leaseModule = await lazyWorkspaceLease();
2096
2544
  const deliverLease = leaseModule.acquireLease(args.task_id, "delivery", [projectPath]);
@@ -2173,6 +2621,68 @@ export async function registerTools(server, deps) {
2173
2621
  };
2174
2622
  }
2175
2623
  }
2624
+ // 问题六十:交付结论必须经过 UnsupportedClaimGate
2625
+ {
2626
+ const { createEvidenceGroundingSystem, assessTaskRisk } = await import("../../engine/evidence_grounding_contract.js");
2627
+ const _dRoute = ctx.route_decision?.route ?? ctx.classification?.route_decision?.route;
2628
+ const _dRisk = assessTaskRisk(ctx.classification?.task_type, _dRoute, ctx.intent);
2629
+ if (_dRisk !== "low") {
2630
+ const _deg = createEvidenceGroundingSystem();
2631
+ // 注册验证结果和交付上下文
2632
+ if (currentVResult) {
2633
+ _deg.registry.register({
2634
+ source_type: "validation_result",
2635
+ authority: "authoritative",
2636
+ freshness: "current",
2637
+ permission: "allowed",
2638
+ scope: "verification",
2639
+ description: `验证状态: ${currentVResult.status}`,
2640
+ source_ref: `verification:${args.task_id}`,
2641
+ });
2642
+ }
2643
+ _deg.registry.register({
2644
+ source_type: "task_context",
2645
+ authority: "authoritative",
2646
+ freshness: "current",
2647
+ permission: "allowed",
2648
+ scope: "delivery",
2649
+ description: "交付上下文",
2650
+ source_ref: `task:${args.task_id}`,
2651
+ });
2652
+ const _dClaims = [
2653
+ {
2654
+ id: "claim-deliver-1",
2655
+ category: "release_status",
2656
+ claim_text: "交付基于真实验证结果",
2657
+ evidence_ids: _deg.registry.query({ source_type: "validation_result" }).map((e) => e.id),
2658
+ is_uncertain: false,
2659
+ risk_level: _dRisk,
2660
+ },
2661
+ ];
2662
+ const _dMatrix = _deg.builder.buildContext(_dClaims, { target_claims: ["交付验证"], source_types: ["validation_result", "task_context"], keywords: ["验证", "交付"], max_results: 10 });
2663
+ _dMatrix.task_id = args.task_id;
2664
+ const _dGateResult = _deg.gate.evaluate(_dMatrix, _dRisk);
2665
+ // 写回 TaskContext(blocked 也保存)
2666
+ await taskContext.setEvidenceGroundingResult(args.task_id, {
2667
+ evidence_matrix: _dMatrix,
2668
+ evidence_gate_result: _dGateResult,
2669
+ unsupported_claims: _dGateResult.unsupported_claims,
2670
+ conflict_resolutions: _dMatrix.conflicts,
2671
+ });
2672
+ if (!_dGateResult.allowed) {
2673
+ if (deliverLease.lease) {
2674
+ leaseModule.releaseLease(deliverLease.lease.lease_id);
2675
+ }
2676
+ return {
2677
+ result: {
2678
+ error: `证据驱动门禁未通过: ${_dGateResult.reason_zh}`,
2679
+ diagnostic_code: _dGateResult.diagnostic_code,
2680
+ unsupported_claims: _dGateResult.unsupported_claims,
2681
+ },
2682
+ };
2683
+ }
2684
+ }
2685
+ }
2176
2686
  // 交付前检查 false completion(通过提取的主链路函数)
2177
2687
  const cepNfcResult = await assessCepBeforeDelivery({
2178
2688
  task_id: args.task_id,