@hongmaple0820/scale-engine 0.18.0 → 0.19.0
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.en.md +296 -237
- package/README.md +157 -63
- package/dist/api/cli.js +448 -27
- package/dist/api/cli.js.map +1 -1
- package/dist/api/doctor.d.ts +4 -1
- package/dist/api/doctor.js +85 -1
- package/dist/api/doctor.js.map +1 -1
- package/dist/api/quickstart.d.ts +3 -0
- package/dist/api/quickstart.js +9 -4
- package/dist/api/quickstart.js.map +1 -1
- package/dist/cli/phaseCommands.js +7 -0
- package/dist/cli/phaseCommands.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/MemoryFabric.d.ts +118 -0
- package/dist/memory/MemoryFabric.js +281 -0
- package/dist/memory/MemoryFabric.js.map +1 -0
- package/dist/memory/MemoryLearning.d.ts +61 -0
- package/dist/memory/MemoryLearning.js +203 -0
- package/dist/memory/MemoryLearning.js.map +1 -0
- package/dist/memory/index.d.ts +2 -0
- package/dist/memory/index.js +3 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/output/HTMLArtifactLayer.js +31 -31
- package/dist/prompts/VibeTemplateGallery.js +121 -121
- package/dist/runtime/FinalReportGuard.d.ts +16 -0
- package/dist/runtime/FinalReportGuard.js +14 -0
- package/dist/runtime/FinalReportGuard.js.map +1 -0
- package/dist/runtime/RuntimeDoctor.d.ts +23 -0
- package/dist/runtime/RuntimeDoctor.js +151 -0
- package/dist/runtime/RuntimeDoctor.js.map +1 -0
- package/dist/runtime/RuntimeEvidenceLedger.d.ts +50 -0
- package/dist/runtime/RuntimeEvidenceLedger.js +89 -0
- package/dist/runtime/RuntimeEvidenceLedger.js.map +1 -0
- package/dist/runtime/SessionLedger.d.ts +53 -0
- package/dist/runtime/SessionLedger.js +104 -0
- package/dist/runtime/SessionLedger.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/workflow/EngineeringStandards.js +69 -66
- package/dist/workflow/EngineeringStandards.js.map +1 -1
- package/dist/workflow/GovernanceTemplatePacks.js +126 -126
- package/dist/workflow/GovernanceTemplates.d.ts +1 -1
- package/dist/workflow/GovernanceTemplates.js +489 -218
- package/dist/workflow/GovernanceTemplates.js.map +1 -1
- package/dist/workflow/ResourceGovernance.js +27 -18
- package/dist/workflow/ResourceGovernance.js.map +1 -1
- package/dist/workflow/VerificationCommands.d.ts +11 -0
- package/dist/workflow/VerificationCommands.js +2 -0
- package/dist/workflow/VerificationCommands.js.map +1 -1
- package/dist/workflow/VerificationProfile.d.ts +2 -1
- package/dist/workflow/VerificationProfile.js +3 -0
- package/dist/workflow/VerificationProfile.js.map +1 -1
- package/dist/workflow/WorkflowArtifactWriter.js +2 -1
- package/dist/workflow/WorkflowArtifactWriter.js.map +1 -1
- package/dist/workflow/WorkflowEngine.js +4 -1
- package/dist/workflow/WorkflowEngine.js.map +1 -1
- package/dist/workflow/WorkspaceSafety.d.ts +9 -0
- package/dist/workflow/WorkspaceSafety.js +49 -0
- package/dist/workflow/WorkspaceSafety.js.map +1 -0
- package/dist/workflow/gates/GateSystem.d.ts +12 -1
- package/dist/workflow/gates/GateSystem.js +106 -0
- package/dist/workflow/gates/GateSystem.js.map +1 -1
- package/dist/workflow/types.d.ts +1 -1
- package/docs/MEMORY_FABRIC.md +107 -0
- package/docs/README.md +68 -0
- package/docs/RUNTIME_EVIDENCE.md +101 -0
- package/docs/start/README.md +42 -0
- package/docs/start/agent-governance-demo.md +107 -0
- package/docs/start/quickstart.md +127 -0
- package/examples/demo-projects/agent-governance-demo/README.md +37 -0
- package/examples/demo-projects/agent-governance-demo/package.json +16 -0
- package/examples/demo-projects/agent-governance-demo/src/oauth-state.ts +39 -0
- package/examples/demo-projects/agent-governance-demo/tests/oauth-state.test.ts +52 -0
- package/package.json +8 -3
|
@@ -310,11 +310,11 @@ function renderPurposeSection(template, sections) {
|
|
|
310
310
|
const missing = sections.missing.length
|
|
311
311
|
? `<p class="doc-warning">Missing source artifacts: ${sections.missing.map(item => `<code>${escapeHtml(item)}</code>`).join(', ')}</p>`
|
|
312
312
|
: '<p>All configured source artifacts were found.</p>';
|
|
313
|
-
return `
|
|
314
|
-
<p>${escapeHtml(template.description)}</p>
|
|
315
|
-
<h3>Source Artifacts</h3>
|
|
316
|
-
${present}
|
|
317
|
-
${missing}
|
|
313
|
+
return `
|
|
314
|
+
<p>${escapeHtml(template.description)}</p>
|
|
315
|
+
<h3>Source Artifacts</h3>
|
|
316
|
+
${present}
|
|
317
|
+
${missing}
|
|
318
318
|
`;
|
|
319
319
|
}
|
|
320
320
|
function markdownToHtml(markdown) {
|
|
@@ -427,12 +427,12 @@ function writeArtifactIndex(projectDir, taskDir, policy, manifest) {
|
|
|
427
427
|
});
|
|
428
428
|
const rows = manifest.artifacts.map(artifact => {
|
|
429
429
|
const href = basename(artifact.path);
|
|
430
|
-
return `<tr>
|
|
431
|
-
<td><a href="${escapeAttribute(href)}">${escapeHtml(artifact.type)}</a></td>
|
|
432
|
-
<td>${escapeHtml(artifact.title)}</td>
|
|
433
|
-
<td>${escapeHtml(artifact.gitPolicy)}</td>
|
|
434
|
-
<td>${escapeHtml(artifact.generatedAt)}</td>
|
|
435
|
-
<td>${artifact.missingSources.length ? artifact.missingSources.map(item => `<code>${escapeHtml(item)}</code>`).join(', ') : 'none'}</td>
|
|
430
|
+
return `<tr>
|
|
431
|
+
<td><a href="${escapeAttribute(href)}">${escapeHtml(artifact.type)}</a></td>
|
|
432
|
+
<td>${escapeHtml(artifact.title)}</td>
|
|
433
|
+
<td>${escapeHtml(artifact.gitPolicy)}</td>
|
|
434
|
+
<td>${escapeHtml(artifact.generatedAt)}</td>
|
|
435
|
+
<td>${artifact.missingSources.length ? artifact.missingSources.map(item => `<code>${escapeHtml(item)}</code>`).join(', ') : 'none'}</td>
|
|
436
436
|
</tr>`;
|
|
437
437
|
}).join('\n');
|
|
438
438
|
const html = renderer.renderReport({
|
|
@@ -445,9 +445,9 @@ function writeArtifactIndex(projectDir, taskDir, policy, manifest) {
|
|
|
445
445
|
},
|
|
446
446
|
sections: [{
|
|
447
447
|
heading: 'Artifact Index',
|
|
448
|
-
content: `<table>
|
|
449
|
-
<thead><tr><th>Type</th><th>Title</th><th>Git Policy</th><th>Generated</th><th>Missing Sources</th></tr></thead>
|
|
450
|
-
<tbody>${rows}</tbody>
|
|
448
|
+
content: `<table>
|
|
449
|
+
<thead><tr><th>Type</th><th>Title</th><th>Git Policy</th><th>Generated</th><th>Missing Sources</th></tr></thead>
|
|
450
|
+
<tbody>${rows}</tbody>
|
|
451
451
|
</table>`,
|
|
452
452
|
}],
|
|
453
453
|
});
|
|
@@ -520,23 +520,23 @@ function htmlArtifactSettlementMarkdown(taskId, doctor) {
|
|
|
520
520
|
const artifacts = doctor.artifacts.length
|
|
521
521
|
? doctor.artifacts.map(artifact => `| ${artifact.type} | ${escapeCell(artifact.path)} | ${artifact.sourcePaths.length} | ${artifact.missingSources.length} | ${artifact.gitPolicy} |`).join('\n')
|
|
522
522
|
: '| none | | 0 | 0 | |';
|
|
523
|
-
return `# HTML Artifacts
|
|
524
|
-
|
|
525
|
-
Task: ${taskId ?? 'unspecified'}
|
|
526
|
-
Status: ${doctor.ok ? 'passed' : 'blocked'}
|
|
527
|
-
Generated: ${new Date().toISOString()}
|
|
528
|
-
|
|
529
|
-
## Artifacts
|
|
530
|
-
|
|
531
|
-
| Type | Path | Sources | Missing | Git policy |
|
|
532
|
-
| --- | --- | ---: | ---: | --- |
|
|
533
|
-
${artifacts}
|
|
534
|
-
|
|
535
|
-
## Findings
|
|
536
|
-
|
|
537
|
-
| Severity | Code | Path | Message |
|
|
538
|
-
| --- | --- | --- | --- |
|
|
539
|
-
${findings}
|
|
523
|
+
return `# HTML Artifacts
|
|
524
|
+
|
|
525
|
+
Task: ${taskId ?? 'unspecified'}
|
|
526
|
+
Status: ${doctor.ok ? 'passed' : 'blocked'}
|
|
527
|
+
Generated: ${new Date().toISOString()}
|
|
528
|
+
|
|
529
|
+
## Artifacts
|
|
530
|
+
|
|
531
|
+
| Type | Path | Sources | Missing | Git policy |
|
|
532
|
+
| --- | --- | ---: | ---: | --- |
|
|
533
|
+
${artifacts}
|
|
534
|
+
|
|
535
|
+
## Findings
|
|
536
|
+
|
|
537
|
+
| Severity | Code | Path | Message |
|
|
538
|
+
| --- | --- | --- | --- |
|
|
539
|
+
${findings}
|
|
540
540
|
`;
|
|
541
541
|
}
|
|
542
542
|
function sourceHeading(path) {
|
|
@@ -20,29 +20,29 @@ export const VISUAL_VIBE_TEMPLATES = [
|
|
|
20
20
|
'如果只上线一个最小闭环,必须包含哪三个能力?',
|
|
21
21
|
'哪些需求现在看起来诱人,但应该明确列为非目标?',
|
|
22
22
|
],
|
|
23
|
-
copyPrompt: `请作为 CEO 和产品负责人,主导 {{appName}} 的产品发现工作。
|
|
24
|
-
|
|
25
|
-
场景:{{scenario}}
|
|
26
|
-
我当前身份:{{userRole}}
|
|
27
|
-
|
|
28
|
-
请按 SCALE 工作流执行:
|
|
29
|
-
1. explore:先明确用户、业务目标、约束、竞品或替代方案,不确定的事实必须标注 [UNCERTAIN]。
|
|
30
|
-
2. plan:输出 Mini-PRD,包含用户路径、非目标、权限/数据影响、异常场景和验收标准。
|
|
31
|
-
3. verify:逐条检查成功标准是否可测试、是否能形成端到端闭环。
|
|
32
|
-
|
|
33
|
-
必须主动使用 skills/MCP/CLI:
|
|
34
|
-
- 如需联网资料,主动使用 web-access 或等价联网能力,并引用来源。
|
|
35
|
-
- 如需求模糊,主动使用 deep-interview / idea-refine 类 Skill。
|
|
36
|
-
- 如涉及用户界面,联动 UI/UX Skill 形成体验标准。
|
|
37
|
-
|
|
38
|
-
安全边界:
|
|
39
|
-
- 不允许凭空编造市场数据、竞品能力或用户需求。
|
|
40
|
-
- 不允许把临时想法写成确定需求。
|
|
41
|
-
- 不允许跳过权限、隐私、数据生命周期和失败场景。
|
|
42
|
-
|
|
43
|
-
成功标准:
|
|
44
|
-
- 产出一份可落地 Mini-PRD。
|
|
45
|
-
- 每条验收标准都能被测试或人工验证。
|
|
23
|
+
copyPrompt: `请作为 CEO 和产品负责人,主导 {{appName}} 的产品发现工作。
|
|
24
|
+
|
|
25
|
+
场景:{{scenario}}
|
|
26
|
+
我当前身份:{{userRole}}
|
|
27
|
+
|
|
28
|
+
请按 SCALE 工作流执行:
|
|
29
|
+
1. explore:先明确用户、业务目标、约束、竞品或替代方案,不确定的事实必须标注 [UNCERTAIN]。
|
|
30
|
+
2. plan:输出 Mini-PRD,包含用户路径、非目标、权限/数据影响、异常场景和验收标准。
|
|
31
|
+
3. verify:逐条检查成功标准是否可测试、是否能形成端到端闭环。
|
|
32
|
+
|
|
33
|
+
必须主动使用 skills/MCP/CLI:
|
|
34
|
+
- 如需联网资料,主动使用 web-access 或等价联网能力,并引用来源。
|
|
35
|
+
- 如需求模糊,主动使用 deep-interview / idea-refine 类 Skill。
|
|
36
|
+
- 如涉及用户界面,联动 UI/UX Skill 形成体验标准。
|
|
37
|
+
|
|
38
|
+
安全边界:
|
|
39
|
+
- 不允许凭空编造市场数据、竞品能力或用户需求。
|
|
40
|
+
- 不允许把临时想法写成确定需求。
|
|
41
|
+
- 不允许跳过权限、隐私、数据生命周期和失败场景。
|
|
42
|
+
|
|
43
|
+
成功标准:
|
|
44
|
+
- 产出一份可落地 Mini-PRD。
|
|
45
|
+
- 每条验收标准都能被测试或人工验证。
|
|
46
46
|
- 明确本阶段要做什么、不做什么、后续如何验证。`,
|
|
47
47
|
},
|
|
48
48
|
{
|
|
@@ -61,30 +61,30 @@ export const VISUAL_VIBE_TEMPLATES = [
|
|
|
61
61
|
'界面应该更像运营后台、消费产品、创作工具,还是管理系统?',
|
|
62
62
|
'哪些状态必须完整设计:空态、加载、错误、权限不足、移动端?',
|
|
63
63
|
],
|
|
64
|
-
copyPrompt: `请作为 UX Director 和高级视觉设计负责人,主导 {{appName}} 的 UI/UX 方案。
|
|
65
|
-
|
|
66
|
-
场景:{{scenario}}
|
|
67
|
-
我当前身份:{{userRole}}
|
|
68
|
-
|
|
69
|
-
请按 SCALE 工作流执行:
|
|
70
|
-
1. explore:阅读现有产品、页面、组件、品牌和设计系统,识别当前视觉语言。
|
|
71
|
-
2. plan:输出 UI-SPEC,包含信息架构、核心用户路径、组件状态、响应式规则、可访问性要求。
|
|
72
|
-
3. build:只给出可执行设计方案或实现切片,不要写营销式空话。
|
|
73
|
-
4. verify:要求截图、浏览器检查、控制台/网络检查和移动端适配证据。
|
|
74
|
-
|
|
75
|
-
必须主动使用 skills/MCP/CLI:
|
|
76
|
-
- 设计方向用 awesome-design-md / ui-ux-pro-max / frontend-design。
|
|
77
|
-
- 浏览器验证用 agent-browser / Chrome DevTools MCP / webapp-testing。
|
|
78
|
-
- 如需真实网页或竞品参考,使用 web-access 并记录来源。
|
|
79
|
-
|
|
80
|
-
安全边界:
|
|
81
|
-
- 不允许默认套用紫蓝渐变、模板化卡片堆叠或无意义装饰。
|
|
82
|
-
- 不允许只描述功能而不定义状态、布局和交互。
|
|
83
|
-
- 不允许未验证截图就声称 UI 完成。
|
|
84
|
-
|
|
85
|
-
成功标准:
|
|
86
|
-
- 产出一份可以直接指导实现的 UI-SPEC。
|
|
87
|
-
- 每个关键页面包含状态、布局、交互、移动端和验收规则。
|
|
64
|
+
copyPrompt: `请作为 UX Director 和高级视觉设计负责人,主导 {{appName}} 的 UI/UX 方案。
|
|
65
|
+
|
|
66
|
+
场景:{{scenario}}
|
|
67
|
+
我当前身份:{{userRole}}
|
|
68
|
+
|
|
69
|
+
请按 SCALE 工作流执行:
|
|
70
|
+
1. explore:阅读现有产品、页面、组件、品牌和设计系统,识别当前视觉语言。
|
|
71
|
+
2. plan:输出 UI-SPEC,包含信息架构、核心用户路径、组件状态、响应式规则、可访问性要求。
|
|
72
|
+
3. build:只给出可执行设计方案或实现切片,不要写营销式空话。
|
|
73
|
+
4. verify:要求截图、浏览器检查、控制台/网络检查和移动端适配证据。
|
|
74
|
+
|
|
75
|
+
必须主动使用 skills/MCP/CLI:
|
|
76
|
+
- 设计方向用 awesome-design-md / ui-ux-pro-max / frontend-design。
|
|
77
|
+
- 浏览器验证用 agent-browser / Chrome DevTools MCP / webapp-testing。
|
|
78
|
+
- 如需真实网页或竞品参考,使用 web-access 并记录来源。
|
|
79
|
+
|
|
80
|
+
安全边界:
|
|
81
|
+
- 不允许默认套用紫蓝渐变、模板化卡片堆叠或无意义装饰。
|
|
82
|
+
- 不允许只描述功能而不定义状态、布局和交互。
|
|
83
|
+
- 不允许未验证截图就声称 UI 完成。
|
|
84
|
+
|
|
85
|
+
成功标准:
|
|
86
|
+
- 产出一份可以直接指导实现的 UI-SPEC。
|
|
87
|
+
- 每个关键页面包含状态、布局、交互、移动端和验收规则。
|
|
88
88
|
- 明确需要哪些浏览器证据证明体验达标。`,
|
|
89
89
|
},
|
|
90
90
|
{
|
|
@@ -103,32 +103,32 @@ export const VISUAL_VIBE_TEMPLATES = [
|
|
|
103
103
|
'哪些契约一旦变更会影响其他服务、前端或数据迁移?',
|
|
104
104
|
'失败、回滚、兼容、观测和权限边界如何设计?',
|
|
105
105
|
],
|
|
106
|
-
copyPrompt: `请作为 CTO 和首席架构师,主导 {{appName}} 的技术实现架构方案。
|
|
107
|
-
|
|
108
|
-
场景:{{scenario}}
|
|
109
|
-
我当前身份:{{userRole}}
|
|
110
|
-
|
|
111
|
-
请按 SCALE 工作流执行:
|
|
112
|
-
1. explore:先读现有代码、目录、模块文档、接口和验证命令,列出事实证据。
|
|
113
|
-
2. plan:输出架构方案,包含模块边界、接口契约、数据影响、异常契约、回滚策略和测试策略。
|
|
114
|
-
3. build:把方案拆成可独立验证的实现切片,避免一次性大爆炸改动。
|
|
115
|
-
4. review:主动做架构、代码质量、安全和文档影响评审。
|
|
116
|
-
5. verify:给出必须运行的命令、预期证据和无法验证时的降级说明。
|
|
117
|
-
|
|
118
|
-
必须主动使用 skills/MCP/CLI:
|
|
119
|
-
- 需要框架/SDK 当前用法时,主动查官方文档或 Context7。
|
|
120
|
-
- 需要模块关系时,使用 rg/graphify 或代码图谱能力。
|
|
121
|
-
- 需要交叉评审时,可使用 codex/gemini/opencode CLI,但必须记录版本、命令和输出摘要。
|
|
122
|
-
- 工具与 Skill 编排必须写入 skill-plan 或 verification 证据。
|
|
123
|
-
|
|
124
|
-
安全边界:
|
|
125
|
-
- 不允许编造调用链、接口或测试结果。
|
|
126
|
-
- 不允许绕过 ORM、框架约定、日志脱敏、安全校验和权限边界。
|
|
127
|
-
- 不允许把临时脚本、报告或调试日志混入长期资产。
|
|
128
|
-
|
|
129
|
-
成功标准:
|
|
130
|
-
- 产出一份可执行架构方案。
|
|
131
|
-
- 每个实现切片都有边界、风险、验证命令和回滚思路。
|
|
106
|
+
copyPrompt: `请作为 CTO 和首席架构师,主导 {{appName}} 的技术实现架构方案。
|
|
107
|
+
|
|
108
|
+
场景:{{scenario}}
|
|
109
|
+
我当前身份:{{userRole}}
|
|
110
|
+
|
|
111
|
+
请按 SCALE 工作流执行:
|
|
112
|
+
1. explore:先读现有代码、目录、模块文档、接口和验证命令,列出事实证据。
|
|
113
|
+
2. plan:输出架构方案,包含模块边界、接口契约、数据影响、异常契约、回滚策略和测试策略。
|
|
114
|
+
3. build:把方案拆成可独立验证的实现切片,避免一次性大爆炸改动。
|
|
115
|
+
4. review:主动做架构、代码质量、安全和文档影响评审。
|
|
116
|
+
5. verify:给出必须运行的命令、预期证据和无法验证时的降级说明。
|
|
117
|
+
|
|
118
|
+
必须主动使用 skills/MCP/CLI:
|
|
119
|
+
- 需要框架/SDK 当前用法时,主动查官方文档或 Context7。
|
|
120
|
+
- 需要模块关系时,使用 rg/graphify 或代码图谱能力。
|
|
121
|
+
- 需要交叉评审时,可使用 codex/gemini/opencode CLI,但必须记录版本、命令和输出摘要。
|
|
122
|
+
- 工具与 Skill 编排必须写入 skill-plan 或 verification 证据。
|
|
123
|
+
|
|
124
|
+
安全边界:
|
|
125
|
+
- 不允许编造调用链、接口或测试结果。
|
|
126
|
+
- 不允许绕过 ORM、框架约定、日志脱敏、安全校验和权限边界。
|
|
127
|
+
- 不允许把临时脚本、报告或调试日志混入长期资产。
|
|
128
|
+
|
|
129
|
+
成功标准:
|
|
130
|
+
- 产出一份可执行架构方案。
|
|
131
|
+
- 每个实现切片都有边界、风险、验证命令和回滚思路。
|
|
132
132
|
- 明确哪些文档需要长期维护,哪些产物是临时证据。`,
|
|
133
133
|
},
|
|
134
134
|
{
|
|
@@ -147,30 +147,30 @@ export const VISUAL_VIBE_TEMPLATES = [
|
|
|
147
147
|
'哪些同类问题需要一起扫描,但不一定一起修改?',
|
|
148
148
|
'验证失败时如何定位是实现问题、环境问题还是既有债务?',
|
|
149
149
|
],
|
|
150
|
-
copyPrompt: `请作为 Engineering Lead,主导 {{appName}} 的实现切片。
|
|
151
|
-
|
|
152
|
-
场景:{{scenario}}
|
|
153
|
-
我当前身份:{{userRole}}
|
|
154
|
-
|
|
155
|
-
请按 SCALE 工作流执行:
|
|
156
|
-
1. explore:读相关代码、测试、规范和历史上下文,输出影响面。
|
|
157
|
-
2. plan:把工作拆成最小实现切片,每个切片有文件范围和验证方式。
|
|
158
|
-
3. build:优先 TDD 或补回归测试,保持改动可追溯。
|
|
159
|
-
4. verify:运行真实命令,记录 exit code、失败项、修复迭代和未验证项。
|
|
160
|
-
|
|
161
|
-
必须主动使用 skills/MCP/CLI:
|
|
162
|
-
- 新逻辑或 Bug 修复使用 TDD / systematic-debugging。
|
|
163
|
-
- 多文件变更使用 incremental-implementation。
|
|
164
|
-
- 需要外部工具时先做安全扫描,再执行。
|
|
165
|
-
|
|
166
|
-
安全边界:
|
|
167
|
-
- 不允许随手重构无关代码。
|
|
168
|
-
- 不允许增加无脱敏日志、硬编码密钥、危险默认值或绕过框架约定。
|
|
169
|
-
- 不允许测试未运行却声称通过。
|
|
170
|
-
|
|
171
|
-
成功标准:
|
|
172
|
-
- 改动范围和用户请求可追溯。
|
|
173
|
-
- 必要测试、lint、构建或人工验证有证据。
|
|
150
|
+
copyPrompt: `请作为 Engineering Lead,主导 {{appName}} 的实现切片。
|
|
151
|
+
|
|
152
|
+
场景:{{scenario}}
|
|
153
|
+
我当前身份:{{userRole}}
|
|
154
|
+
|
|
155
|
+
请按 SCALE 工作流执行:
|
|
156
|
+
1. explore:读相关代码、测试、规范和历史上下文,输出影响面。
|
|
157
|
+
2. plan:把工作拆成最小实现切片,每个切片有文件范围和验证方式。
|
|
158
|
+
3. build:优先 TDD 或补回归测试,保持改动可追溯。
|
|
159
|
+
4. verify:运行真实命令,记录 exit code、失败项、修复迭代和未验证项。
|
|
160
|
+
|
|
161
|
+
必须主动使用 skills/MCP/CLI:
|
|
162
|
+
- 新逻辑或 Bug 修复使用 TDD / systematic-debugging。
|
|
163
|
+
- 多文件变更使用 incremental-implementation。
|
|
164
|
+
- 需要外部工具时先做安全扫描,再执行。
|
|
165
|
+
|
|
166
|
+
安全边界:
|
|
167
|
+
- 不允许随手重构无关代码。
|
|
168
|
+
- 不允许增加无脱敏日志、硬编码密钥、危险默认值或绕过框架约定。
|
|
169
|
+
- 不允许测试未运行却声称通过。
|
|
170
|
+
|
|
171
|
+
成功标准:
|
|
172
|
+
- 改动范围和用户请求可追溯。
|
|
173
|
+
- 必要测试、lint、构建或人工验证有证据。
|
|
174
174
|
- 交付说明包含完成内容、验证结果和未验证项。`,
|
|
175
175
|
},
|
|
176
176
|
{
|
|
@@ -189,30 +189,30 @@ export const VISUAL_VIBE_TEMPLATES = [
|
|
|
189
189
|
'失败和跳过项是否被明确记录?',
|
|
190
190
|
'是否存在临时文件、测试报告、截图或日志不应提交?',
|
|
191
191
|
],
|
|
192
|
-
copyPrompt: `请作为 QA Lead 和 Release Manager,主导 {{appName}} 的验收与发版前检查。
|
|
193
|
-
|
|
194
|
-
场景:{{scenario}}
|
|
195
|
-
我当前身份:{{userRole}}
|
|
196
|
-
|
|
197
|
-
请按 SCALE 工作流执行:
|
|
198
|
-
1. explore:读取当前任务产物、git diff、测试配置和已知风险。
|
|
199
|
-
2. verify:运行最小相关验证和发版前门控,记录真实输出摘要。
|
|
200
|
-
3. review:执行代码质量、安全、文档资产和资源治理检查。
|
|
201
|
-
4. ship:只有证据闭环后才建议合并、打 tag 或发布。
|
|
202
|
-
|
|
203
|
-
必须主动使用 skills/MCP/CLI:
|
|
204
|
-
- 使用 verification / code-reviewer / security review 类 Skill。
|
|
205
|
-
- UI 或浏览器功能必须补截图、控制台和网络证据。
|
|
206
|
-
- 发版必须记录版本、commit、tag、registry 或远程状态。
|
|
207
|
-
|
|
208
|
-
安全边界:
|
|
209
|
-
- 不允许隐藏失败命令。
|
|
210
|
-
- 不允许把 dry-run 当成真实通过。
|
|
211
|
-
- 不允许提交临时脚本、敏感日志、未归档测试报告或本地配置。
|
|
212
|
-
|
|
213
|
-
成功标准:
|
|
214
|
-
- 产出完整 verification/review/release evidence。
|
|
215
|
-
- 所有 required gates 通过,optional gates 的缺失有说明。
|
|
192
|
+
copyPrompt: `请作为 QA Lead 和 Release Manager,主导 {{appName}} 的验收与发版前检查。
|
|
193
|
+
|
|
194
|
+
场景:{{scenario}}
|
|
195
|
+
我当前身份:{{userRole}}
|
|
196
|
+
|
|
197
|
+
请按 SCALE 工作流执行:
|
|
198
|
+
1. explore:读取当前任务产物、git diff、测试配置和已知风险。
|
|
199
|
+
2. verify:运行最小相关验证和发版前门控,记录真实输出摘要。
|
|
200
|
+
3. review:执行代码质量、安全、文档资产和资源治理检查。
|
|
201
|
+
4. ship:只有证据闭环后才建议合并、打 tag 或发布。
|
|
202
|
+
|
|
203
|
+
必须主动使用 skills/MCP/CLI:
|
|
204
|
+
- 使用 verification / code-reviewer / security review 类 Skill。
|
|
205
|
+
- UI 或浏览器功能必须补截图、控制台和网络证据。
|
|
206
|
+
- 发版必须记录版本、commit、tag、registry 或远程状态。
|
|
207
|
+
|
|
208
|
+
安全边界:
|
|
209
|
+
- 不允许隐藏失败命令。
|
|
210
|
+
- 不允许把 dry-run 当成真实通过。
|
|
211
|
+
- 不允许提交临时脚本、敏感日志、未归档测试报告或本地配置。
|
|
212
|
+
|
|
213
|
+
成功标准:
|
|
214
|
+
- 产出完整 verification/review/release evidence。
|
|
215
|
+
- 所有 required gates 通过,optional gates 的缺失有说明。
|
|
216
216
|
- 明确是否可发版,以及剩余风险。`,
|
|
217
217
|
},
|
|
218
218
|
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RuntimeSessionLevel } from './SessionLedger.js';
|
|
2
|
+
import { type RuntimeDoctorReport } from './RuntimeDoctor.js';
|
|
3
|
+
export interface FinalReportReadinessOptions {
|
|
4
|
+
projectDir?: string;
|
|
5
|
+
scaleDir?: string;
|
|
6
|
+
taskId?: string;
|
|
7
|
+
sessionId?: string;
|
|
8
|
+
level?: RuntimeSessionLevel;
|
|
9
|
+
}
|
|
10
|
+
export interface FinalReportReadiness {
|
|
11
|
+
ready: boolean;
|
|
12
|
+
blocked: boolean;
|
|
13
|
+
reasons: string[];
|
|
14
|
+
report: RuntimeDoctorReport;
|
|
15
|
+
}
|
|
16
|
+
export declare function evaluateFinalReportReadiness(options?: FinalReportReadinessOptions): FinalReportReadiness;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { doctorRuntimeEvidence } from './RuntimeDoctor.js';
|
|
2
|
+
export function evaluateFinalReportReadiness(options = {}) {
|
|
3
|
+
const report = doctorRuntimeEvidence(options);
|
|
4
|
+
const reasons = report.checks
|
|
5
|
+
.filter(check => check.status === 'fail' || check.name === 'Runtime completion evidence' && check.status === 'warn')
|
|
6
|
+
.map(check => check.message);
|
|
7
|
+
return {
|
|
8
|
+
ready: reasons.length === 0,
|
|
9
|
+
blocked: report.blocked || reasons.length > 0,
|
|
10
|
+
reasons,
|
|
11
|
+
report,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=FinalReportGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FinalReportGuard.js","sourceRoot":"","sources":["../../src/runtime/FinalReportGuard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAA4B,MAAM,oBAAoB,CAAA;AAiBpF,MAAM,UAAU,4BAA4B,CAAC,UAAuC,EAAE;IACpF,MAAM,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM;SAC1B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,6BAA6B,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC;SACnH,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAE9B,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAC7C,OAAO;QACP,MAAM;KACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type RuntimeEvidenceSummary } from './RuntimeEvidenceLedger.js';
|
|
2
|
+
import { type RuntimeSessionLevel } from './SessionLedger.js';
|
|
3
|
+
export type RuntimeDoctorStatus = 'ok' | 'warn' | 'fail';
|
|
4
|
+
export interface RuntimeDoctorCheck {
|
|
5
|
+
name: string;
|
|
6
|
+
status: RuntimeDoctorStatus;
|
|
7
|
+
message: string;
|
|
8
|
+
fix?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RuntimeDoctorOptions {
|
|
11
|
+
projectDir?: string;
|
|
12
|
+
scaleDir?: string;
|
|
13
|
+
taskId?: string;
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
level?: RuntimeSessionLevel;
|
|
16
|
+
}
|
|
17
|
+
export interface RuntimeDoctorReport {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
blocked: boolean;
|
|
20
|
+
checks: RuntimeDoctorCheck[];
|
|
21
|
+
evidence: RuntimeEvidenceSummary;
|
|
22
|
+
}
|
|
23
|
+
export declare function doctorRuntimeEvidence(options?: RuntimeDoctorOptions): RuntimeDoctorReport;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
|
+
import { RuntimeEvidenceLedger } from './RuntimeEvidenceLedger.js';
|
|
4
|
+
import { SessionLedger } from './SessionLedger.js';
|
|
5
|
+
import { loadVerificationMatrix, resolveVerificationPolicy } from '../workflow/VerificationProfile.js';
|
|
6
|
+
export function doctorRuntimeEvidence(options = {}) {
|
|
7
|
+
const projectDir = resolve(options.projectDir ?? process.cwd());
|
|
8
|
+
const scaleRoot = isAbsolute(options.scaleDir ?? '')
|
|
9
|
+
? options.scaleDir
|
|
10
|
+
: join(projectDir, options.scaleDir ?? '.scale');
|
|
11
|
+
const evidenceDir = join(scaleRoot, 'evidence', 'runtime');
|
|
12
|
+
const sessionsDir = join(scaleRoot, 'events', 'sessions');
|
|
13
|
+
const evidenceLedger = new RuntimeEvidenceLedger({ projectDir, scaleDir: scaleRoot, createDirs: false });
|
|
14
|
+
const sessionLedger = new SessionLedger({ projectDir, scaleDir: scaleRoot, createDirs: false });
|
|
15
|
+
const policy = resolveVerificationPolicy(loadVerificationMatrix(projectDir, scaleRoot));
|
|
16
|
+
const evidence = evidenceLedger.summary({
|
|
17
|
+
taskId: options.taskId,
|
|
18
|
+
sessionId: options.sessionId,
|
|
19
|
+
});
|
|
20
|
+
const evidenceRecords = evidenceLedger.list({
|
|
21
|
+
taskId: options.taskId,
|
|
22
|
+
sessionId: options.sessionId,
|
|
23
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
24
|
+
});
|
|
25
|
+
const checks = [];
|
|
26
|
+
checks.push(checkDirectory('Runtime evidence directory', evidenceDir, 'Run: scale runtime record ...'));
|
|
27
|
+
checks.push(checkDirectory('Runtime session directory', sessionsDir, 'Run: scale runtime start --session-id <id>'));
|
|
28
|
+
checks.push(checkSessionJsonl(sessionsDir, options.sessionId));
|
|
29
|
+
if (options.sessionId) {
|
|
30
|
+
const events = sessionLedger.listEvents(options.sessionId);
|
|
31
|
+
checks.push(events.length > 0
|
|
32
|
+
? { name: 'Runtime session events', status: 'ok', message: `${events.length} event(s) for ${options.sessionId}` }
|
|
33
|
+
: { name: 'Runtime session events', status: 'warn', message: `No events recorded for ${options.sessionId}`, fix: 'Run: scale runtime start or append runtime events' });
|
|
34
|
+
}
|
|
35
|
+
if (evidence.failed > 0) {
|
|
36
|
+
checks.push({
|
|
37
|
+
name: 'Runtime failed evidence',
|
|
38
|
+
status: 'fail',
|
|
39
|
+
message: `${evidence.failed} failed runtime evidence record(s)`,
|
|
40
|
+
fix: 'Fix the failing command/tool output and record a passing evidence item',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
checks.push({
|
|
45
|
+
name: 'Runtime failed evidence',
|
|
46
|
+
status: 'ok',
|
|
47
|
+
message: evidence.expectedRed > 0
|
|
48
|
+
? `No unresolved failed runtime evidence records; ${evidence.expectedRed} expected red reproduction record(s)`
|
|
49
|
+
: 'No failed runtime evidence records',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const level = options.level ?? 'M';
|
|
53
|
+
if (level !== 'S' && evidence.passed === 0) {
|
|
54
|
+
checks.push({
|
|
55
|
+
name: 'Runtime completion evidence',
|
|
56
|
+
status: 'warn',
|
|
57
|
+
message: `No passed evidence recorded for ${scopeLabel(options)}`,
|
|
58
|
+
fix: 'Record at least one passed command, gate, tool, browser, or skill evidence before claiming completion',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
checks.push({
|
|
63
|
+
name: 'Runtime completion evidence',
|
|
64
|
+
status: 'ok',
|
|
65
|
+
message: `${evidence.passed} passed evidence record(s)`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const productSmokeMode = policy.productSmokeGate ?? 'warn';
|
|
69
|
+
if (level !== 'S' && productSmokeMode !== 'off') {
|
|
70
|
+
const productSmokePassed = evidenceRecords.some(record => record.status === 'passed' && isProductSmokeEvidence(record));
|
|
71
|
+
const productSmokeFailed = evidenceRecords.some(record => record.status === 'failed' && isProductSmokeEvidence(record));
|
|
72
|
+
if (productSmokePassed) {
|
|
73
|
+
checks.push({
|
|
74
|
+
name: 'Runtime product smoke evidence',
|
|
75
|
+
status: 'ok',
|
|
76
|
+
message: 'Passed product smoke evidence recorded',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
checks.push({
|
|
81
|
+
name: 'Runtime product smoke evidence',
|
|
82
|
+
status: productSmokeMode === 'block' || productSmokeFailed ? 'fail' : 'warn',
|
|
83
|
+
message: productSmokeFailed
|
|
84
|
+
? 'Product smoke evidence failed and no later passed product smoke evidence was recorded'
|
|
85
|
+
: 'No passed product smoke evidence recorded for this M/L/CRITICAL task',
|
|
86
|
+
fix: 'Run a real product-path smoke check and record it with metadata.productSmoke=true or metadata.realProductPath=true',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const blocked = checks.some(check => check.status === 'fail');
|
|
91
|
+
return {
|
|
92
|
+
ok: !blocked,
|
|
93
|
+
blocked,
|
|
94
|
+
checks,
|
|
95
|
+
evidence,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function isProductSmokeEvidence(record) {
|
|
99
|
+
const metadata = record.metadata ?? {};
|
|
100
|
+
if (metadata.productSmoke === true || metadata.realProductPath === true)
|
|
101
|
+
return true;
|
|
102
|
+
if (metadata.gate === 'G8' || metadata.gate === 'productSmoke')
|
|
103
|
+
return true;
|
|
104
|
+
const text = `${record.title}\n${record.summary}`.toLowerCase();
|
|
105
|
+
return text.includes('product smoke') || text.includes('real product path');
|
|
106
|
+
}
|
|
107
|
+
function checkDirectory(name, dir, fix) {
|
|
108
|
+
if (!existsSync(dir)) {
|
|
109
|
+
return { name, status: 'warn', message: `Missing ${dir}`, fix };
|
|
110
|
+
}
|
|
111
|
+
return { name, status: 'ok', message: `Found ${dir}` };
|
|
112
|
+
}
|
|
113
|
+
function checkSessionJsonl(sessionsDir, sessionId) {
|
|
114
|
+
if (!existsSync(sessionsDir)) {
|
|
115
|
+
return { name: 'Runtime session JSONL', status: 'warn', message: 'No session JSONL directory yet' };
|
|
116
|
+
}
|
|
117
|
+
const files = sessionId
|
|
118
|
+
? [`${safePathSegment(sessionId)}.jsonl`].filter(file => existsSync(join(sessionsDir, file)))
|
|
119
|
+
: readdirSync(sessionsDir).filter(file => file.endsWith('.jsonl'));
|
|
120
|
+
for (const file of files) {
|
|
121
|
+
const path = join(sessionsDir, file);
|
|
122
|
+
const lines = readFileSync(path, 'utf-8').split(/\r?\n/).filter(Boolean);
|
|
123
|
+
for (const line of lines) {
|
|
124
|
+
try {
|
|
125
|
+
JSON.parse(line);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return {
|
|
129
|
+
name: 'Runtime session JSONL',
|
|
130
|
+
status: 'fail',
|
|
131
|
+
message: `${file} contains invalid JSONL`,
|
|
132
|
+
fix: 'Remove or repair the invalid session event line',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
name: 'Runtime session JSONL',
|
|
139
|
+
status: 'ok',
|
|
140
|
+
message: `${files.length} session file(s) parse cleanly`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function scopeLabel(options) {
|
|
144
|
+
if (options.taskId && options.sessionId)
|
|
145
|
+
return `${options.taskId}/${options.sessionId}`;
|
|
146
|
+
return options.taskId ?? options.sessionId ?? 'current scope';
|
|
147
|
+
}
|
|
148
|
+
function safePathSegment(value) {
|
|
149
|
+
return value.replace(/[^a-zA-Z0-9._-]/g, '-').slice(0, 120) || 'unknown-session';
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=RuntimeDoctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RuntimeDoctor.js","sourceRoot":"","sources":["../../src/runtime/RuntimeDoctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type RuntimeEvidenceKind = 'command' | 'gate' | 'tool' | 'skill' | 'mcp' | 'browser' | 'desktop' | 'manual' | 'final-report';
|
|
2
|
+
export type RuntimeEvidenceStatus = 'passed' | 'failed' | 'skipped';
|
|
3
|
+
export interface RuntimeEvidenceInput {
|
|
4
|
+
taskId?: string;
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
kind: RuntimeEvidenceKind;
|
|
7
|
+
title: string;
|
|
8
|
+
status: RuntimeEvidenceStatus;
|
|
9
|
+
command?: string;
|
|
10
|
+
exitCode?: number;
|
|
11
|
+
summary: string;
|
|
12
|
+
artifacts?: string[];
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export interface RuntimeEvidenceRecord extends RuntimeEvidenceInput {
|
|
16
|
+
id: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
sequence: number;
|
|
19
|
+
redactionApplied: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface RuntimeEvidenceQuery {
|
|
22
|
+
taskId?: string;
|
|
23
|
+
sessionId?: string;
|
|
24
|
+
limit?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface RuntimeEvidenceSummary {
|
|
27
|
+
total: number;
|
|
28
|
+
passed: number;
|
|
29
|
+
failed: number;
|
|
30
|
+
skipped: number;
|
|
31
|
+
expectedRed: number;
|
|
32
|
+
ok: boolean;
|
|
33
|
+
latestFailure?: RuntimeEvidenceRecord;
|
|
34
|
+
}
|
|
35
|
+
export interface RuntimeEvidenceLedgerOptions {
|
|
36
|
+
projectDir?: string;
|
|
37
|
+
scaleDir?: string;
|
|
38
|
+
now?: () => Date;
|
|
39
|
+
createDirs?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare class RuntimeEvidenceLedger {
|
|
42
|
+
private rootDir;
|
|
43
|
+
private now;
|
|
44
|
+
private sequence;
|
|
45
|
+
constructor(options?: RuntimeEvidenceLedgerOptions);
|
|
46
|
+
record(input: RuntimeEvidenceInput): RuntimeEvidenceRecord;
|
|
47
|
+
list(query?: RuntimeEvidenceQuery): RuntimeEvidenceRecord[];
|
|
48
|
+
get(id: string): RuntimeEvidenceRecord | null;
|
|
49
|
+
summary(query?: RuntimeEvidenceQuery): RuntimeEvidenceSummary;
|
|
50
|
+
}
|