soloforge 1.2.2 → 1.2.4
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 +229 -28
- package/dist/adapters/claude_code/tools.d.ts.map +1 -1
- package/dist/adapters/claude_code/tools.js +319 -5
- package/dist/adapters/claude_code/tools.js.map +1 -1
- package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
- package/dist/adapters/shared/workflow_template.js +26 -3
- package/dist/adapters/shared/workflow_template.js.map +1 -1
- package/dist/bin/soloforge.js +169 -13
- package/dist/bin/soloforge.js.map +1 -1
- package/dist/engine/audit_pool.d.ts +36 -0
- package/dist/engine/audit_pool.d.ts.map +1 -0
- package/dist/engine/audit_pool.js +83 -0
- package/dist/engine/audit_pool.js.map +1 -0
- package/dist/engine/audit_sampler.d.ts +15 -0
- package/dist/engine/audit_sampler.d.ts.map +1 -0
- package/dist/engine/audit_sampler.js +26 -0
- package/dist/engine/audit_sampler.js.map +1 -0
- package/dist/engine/capability_action_advisor.d.ts +24 -0
- package/dist/engine/capability_action_advisor.d.ts.map +1 -0
- package/dist/engine/capability_action_advisor.js +147 -0
- package/dist/engine/capability_action_advisor.js.map +1 -0
- package/dist/engine/capability_registry.d.ts +23 -1
- package/dist/engine/capability_registry.d.ts.map +1 -1
- package/dist/engine/capability_registry.js +511 -19
- package/dist/engine/capability_registry.js.map +1 -1
- package/dist/engine/capability_state_store.d.ts +50 -0
- package/dist/engine/capability_state_store.d.ts.map +1 -0
- package/dist/engine/capability_state_store.js +123 -0
- package/dist/engine/capability_state_store.js.map +1 -0
- package/dist/engine/cognitive_anchor.d.ts +59 -0
- package/dist/engine/cognitive_anchor.d.ts.map +1 -0
- package/dist/engine/cognitive_anchor.js +68 -0
- package/dist/engine/cognitive_anchor.js.map +1 -0
- package/dist/engine/conflict_gate.d.ts +36 -0
- package/dist/engine/conflict_gate.d.ts.map +1 -0
- package/dist/engine/conflict_gate.js +73 -0
- package/dist/engine/conflict_gate.js.map +1 -0
- package/dist/engine/decision_contract.d.ts +29 -0
- package/dist/engine/decision_contract.d.ts.map +1 -0
- package/dist/engine/decision_contract.js +41 -0
- package/dist/engine/decision_contract.js.map +1 -0
- package/dist/engine/delivery.d.ts.map +1 -1
- package/dist/engine/delivery.js +83 -0
- package/dist/engine/delivery.js.map +1 -1
- package/dist/engine/developer_sovereignty.d.ts +62 -0
- package/dist/engine/developer_sovereignty.d.ts.map +1 -0
- package/dist/engine/developer_sovereignty.js +134 -0
- package/dist/engine/developer_sovereignty.js.map +1 -0
- package/dist/engine/diff_ownership.d.ts +74 -0
- package/dist/engine/diff_ownership.d.ts.map +1 -0
- package/dist/engine/diff_ownership.js +143 -0
- package/dist/engine/diff_ownership.js.map +1 -0
- package/dist/engine/diff_ownership_store.d.ts +76 -0
- package/dist/engine/diff_ownership_store.d.ts.map +1 -0
- package/dist/engine/diff_ownership_store.js +264 -0
- package/dist/engine/diff_ownership_store.js.map +1 -0
- package/dist/engine/escape_report.d.ts +45 -0
- package/dist/engine/escape_report.d.ts.map +1 -0
- package/dist/engine/escape_report.js +97 -0
- package/dist/engine/escape_report.js.map +1 -0
- package/dist/engine/exploration.d.ts +54 -0
- package/dist/engine/exploration.d.ts.map +1 -1
- package/dist/engine/exploration.js +138 -0
- package/dist/engine/exploration.js.map +1 -1
- package/dist/engine/governance_report.d.ts +36 -0
- package/dist/engine/governance_report.d.ts.map +1 -0
- package/dist/engine/governance_report.js +79 -0
- package/dist/engine/governance_report.js.map +1 -0
- package/dist/engine/java_quality_guard.d.ts +52 -0
- package/dist/engine/java_quality_guard.d.ts.map +1 -0
- package/dist/engine/java_quality_guard.js +237 -0
- package/dist/engine/java_quality_guard.js.map +1 -0
- package/dist/engine/job_manager.d.ts +76 -0
- package/dist/engine/job_manager.d.ts.map +1 -0
- package/dist/engine/job_manager.js +225 -0
- package/dist/engine/job_manager.js.map +1 -0
- package/dist/engine/knowledge_sovereignty.d.ts +61 -0
- package/dist/engine/knowledge_sovereignty.d.ts.map +1 -0
- package/dist/engine/knowledge_sovereignty.js +190 -0
- package/dist/engine/knowledge_sovereignty.js.map +1 -0
- package/dist/engine/mutation_audit.d.ts +43 -0
- package/dist/engine/mutation_audit.d.ts.map +1 -0
- package/dist/engine/mutation_audit.js +118 -0
- package/dist/engine/mutation_audit.js.map +1 -0
- package/dist/engine/policy_drift_detector.d.ts +46 -0
- package/dist/engine/policy_drift_detector.d.ts.map +1 -0
- package/dist/engine/policy_drift_detector.js +181 -0
- package/dist/engine/policy_drift_detector.js.map +1 -0
- package/dist/engine/regression_matrix.d.ts +102 -0
- package/dist/engine/regression_matrix.d.ts.map +1 -0
- package/dist/engine/regression_matrix.js +380 -0
- package/dist/engine/regression_matrix.js.map +1 -0
- package/dist/engine/risk_sampler.d.ts +37 -0
- package/dist/engine/risk_sampler.d.ts.map +1 -0
- package/dist/engine/risk_sampler.js +69 -0
- package/dist/engine/risk_sampler.js.map +1 -0
- package/dist/engine/runtime_safety.d.ts +80 -0
- package/dist/engine/runtime_safety.d.ts.map +1 -0
- package/dist/engine/runtime_safety.js +195 -0
- package/dist/engine/runtime_safety.js.map +1 -0
- package/dist/engine/scope_lease.d.ts +45 -0
- package/dist/engine/scope_lease.d.ts.map +1 -0
- package/dist/engine/scope_lease.js +122 -0
- package/dist/engine/scope_lease.js.map +1 -0
- package/dist/engine/semantic_evidence.d.ts +23 -0
- package/dist/engine/semantic_evidence.d.ts.map +1 -0
- package/dist/engine/semantic_evidence.js +81 -0
- package/dist/engine/semantic_evidence.js.map +1 -0
- package/dist/engine/task_context.d.ts +16 -0
- package/dist/engine/task_context.d.ts.map +1 -1
- package/dist/engine/task_context.js +58 -0
- package/dist/engine/task_context.js.map +1 -1
- package/dist/engine/verifier.d.ts.map +1 -1
- package/dist/engine/verifier.js +22 -1
- package/dist/engine/verifier.js.map +1 -1
- package/dist/engine/workspace_resumer.d.ts +43 -0
- package/dist/engine/workspace_resumer.d.ts.map +1 -1
- package/dist/engine/workspace_resumer.js +119 -4
- package/dist/engine/workspace_resumer.js.map +1 -1
- package/dist/engine/zero_config_init.d.ts +87 -0
- package/dist/engine/zero_config_init.d.ts.map +1 -0
- package/dist/engine/zero_config_init.js +427 -0
- package/dist/engine/zero_config_init.js.map +1 -0
- package/dist/knowledge/index_manager.d.ts +19 -0
- package/dist/knowledge/index_manager.d.ts.map +1 -1
- package/dist/knowledge/index_manager.js +31 -0
- package/dist/knowledge/index_manager.js.map +1 -1
- package/dist/knowledge/writer.d.ts.map +1 -1
- package/dist/knowledge/writer.js +1 -0
- package/dist/knowledge/writer.js.map +1 -1
- package/dist/types.d.ts +61 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/templates/knowledge/patterns/core/Diff/345/275/222/345/261/236/350/277/275/350/270/252.md +47 -0
- package/templates/knowledge/patterns/core/Java/350/264/250/351/207/217/351/227/250/347/246/201.md +46 -0
- package/templates/knowledge/patterns/core/LLM/351/242/204/347/256/227/347/275/221/345/205/263.md +46 -0
- package/templates/knowledge/patterns/core//344/273/273/345/212/241/344/270/212/344/270/213/346/226/207/347/224/237/345/221/275/345/221/250/346/234/237.md +47 -0
- package/templates/knowledge/patterns/core//344/273/273/345/212/241/347/256/241/347/220/206/345/231/250.md +47 -0
- package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/344/270/216/345/257/206/351/222/245/346/213/246/346/210/252.md +46 -0
- package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/347/247/237/347/272/246.md +47 -0
- package/templates/knowledge/patterns/core//345/206/262/347/252/201/351/227/250/347/246/201.md +47 -0
- package/templates/knowledge/patterns/core//345/206/263/347/255/226/347/275/221/345/205/263.md +30 -11
- package/templates/knowledge/patterns/core//345/217/230/345/274/202/345/256/241/350/256/241.md +20 -0
- package/templates/knowledge/patterns/core//345/233/236/345/275/222/347/237/251/351/230/265.md +46 -0
- package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/344/272/222/346/226/245/351/224/201.md +44 -0
- package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/345/224/244/351/206/222.md +46 -0
- package/templates/knowledge/patterns/core//345/271/266/345/217/221/351/224/201.md +29 -16
- package/templates/knowledge/patterns/core//345/274/200/345/217/221/350/200/205/345/256/252/346/263/225.md +20 -0
- package/templates/knowledge/patterns/core//346/225/217/346/204/237/344/277/241/346/201/257/346/211/253/346/217/217.md +45 -0
- package/templates/knowledge/patterns/core//346/262/273/347/220/206/350/277/220/350/241/214/346/227/266/345/276/252/347/216/257.md +48 -0
- package/templates/knowledge/patterns/core//346/265/201/345/274/217/345/277/203/350/267/263.md +20 -0
- package/templates/knowledge/patterns/core//347/237/245/350/257/206/344/270/273/346/235/203.md +20 -0
- package/templates/knowledge/patterns/core//350/257/255/344/271/211/350/257/201/346/215/256.md +47 -0
- package/templates/knowledge/patterns/core//350/277/220/350/241/214/345/256/211/345/205/250/345/214/205.md +50 -0
- package/templates/knowledge/patterns/core//351/233/266/351/205/215/347/275/256/345/210/235/345/247/213/345/214/226.md +47 -0
- package/templates/knowledge/patterns/core//351/252/214/350/257/201/345/221/275/344/273/244/347/224/237/346/210/220.md +46 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Ownership Store — 持久化文件归属快照,绑定 stateDir。
|
|
3
|
+
* CAP-011 实验性: 只做 advisory 冲突报告,不 hard block。
|
|
4
|
+
*
|
|
5
|
+
* 存储: JSON 文件,原子写入,路径绑定 stateDir。
|
|
6
|
+
* 每个 task_id 下的快照按时间顺序追加。
|
|
7
|
+
*/
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { captureBaseline, recordTaskWrite, casCheck, findLatestSnapshot, summarizeOwnership, } from "./diff_ownership.js";
|
|
11
|
+
const DEFAULT_MAX_FILES = 500;
|
|
12
|
+
const DEFAULT_MAX_TOTAL_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
13
|
+
const EXCLUDED_DIRS = new Set([
|
|
14
|
+
".git", "node_modules", "dist", "build", "coverage",
|
|
15
|
+
".next", ".nuxt", ".cache", ".turbo", "out", "target",
|
|
16
|
+
"vendor", "__pycache__", ".venv", "venv",
|
|
17
|
+
]);
|
|
18
|
+
const EXCLUDED_EXTENSIONS = new Set([
|
|
19
|
+
".map", ".lock", ".woff", ".woff2", ".ttf", ".eot",
|
|
20
|
+
".ico", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg",
|
|
21
|
+
".mp4", ".mp3", ".wav", ".avi", ".mov",
|
|
22
|
+
".zip", ".tar", ".gz", ".rar", ".7z",
|
|
23
|
+
".wasm", ".exe", ".dll", ".so", ".dylib",
|
|
24
|
+
]);
|
|
25
|
+
const EXCLUDED_FILES = new Set([
|
|
26
|
+
"package-lock.json", "yarn.lock", "pnpm-lock.yaml",
|
|
27
|
+
"Gemfile.lock", "composer.lock", "Cargo.lock",
|
|
28
|
+
"go.sum", "poetry.lock",
|
|
29
|
+
]);
|
|
30
|
+
function isExcluded(filePath) {
|
|
31
|
+
const basename = path.basename(filePath);
|
|
32
|
+
if (EXCLUDED_FILES.has(basename))
|
|
33
|
+
return true;
|
|
34
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
35
|
+
if (EXCLUDED_EXTENSIONS.has(ext))
|
|
36
|
+
return true;
|
|
37
|
+
// Exclude hidden files (dotfiles)
|
|
38
|
+
if (basename.startsWith("."))
|
|
39
|
+
return true;
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
export class DiffOwnershipStore {
|
|
43
|
+
filePath;
|
|
44
|
+
states = new Map();
|
|
45
|
+
loaded = false;
|
|
46
|
+
constructor(stateDir) {
|
|
47
|
+
this.filePath = path.join(stateDir, "diff-ownership.json");
|
|
48
|
+
if (!fs.existsSync(stateDir)) {
|
|
49
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
ensureLoaded() {
|
|
53
|
+
if (this.loaded)
|
|
54
|
+
return;
|
|
55
|
+
this.loaded = true;
|
|
56
|
+
try {
|
|
57
|
+
const data = fs.readFileSync(this.filePath, "utf-8");
|
|
58
|
+
const entries = JSON.parse(data);
|
|
59
|
+
for (const e of entries) {
|
|
60
|
+
this.states.set(e.task_id, e);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
this.states = new Map();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
persist() {
|
|
68
|
+
const entries = [...this.states.values()];
|
|
69
|
+
const tmpPath = `${this.filePath}.tmp`;
|
|
70
|
+
fs.writeFileSync(tmpPath, JSON.stringify(entries, null, 2));
|
|
71
|
+
fs.renameSync(tmpPath, this.filePath);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Capture baseline for a task. Call once when task starts executing.
|
|
75
|
+
*/
|
|
76
|
+
captureBaseline(taskId, filePaths) {
|
|
77
|
+
this.ensureLoaded();
|
|
78
|
+
const snapshots = captureBaseline(filePaths, taskId);
|
|
79
|
+
let state = this.states.get(taskId);
|
|
80
|
+
if (!state) {
|
|
81
|
+
state = { task_id: taskId, baseline_captured_at: null, snapshots: [] };
|
|
82
|
+
this.states.set(taskId, state);
|
|
83
|
+
}
|
|
84
|
+
state.baseline_captured_at = snapshots[0]?.captured_at ?? new Date().toISOString();
|
|
85
|
+
state.snapshots.push(...snapshots);
|
|
86
|
+
this.persist();
|
|
87
|
+
return snapshots;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Capture baseline from scope paths, expanding directories into their existing files.
|
|
91
|
+
* Applies exclusion rules and size limits. Returns advisory summary if exceeded.
|
|
92
|
+
* Does NOT hard block — caller receives the summary and decides.
|
|
93
|
+
*/
|
|
94
|
+
captureBaselineFromScope(taskId, scopePaths, options) {
|
|
95
|
+
const maxFiles = options?.maxFiles ?? DEFAULT_MAX_FILES;
|
|
96
|
+
const maxTotalBytes = options?.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES;
|
|
97
|
+
const allFiles = [];
|
|
98
|
+
const excluded = [];
|
|
99
|
+
for (const p of scopePaths) {
|
|
100
|
+
const resolved = path.resolve(p);
|
|
101
|
+
let stat = null;
|
|
102
|
+
try {
|
|
103
|
+
stat = fs.statSync(resolved);
|
|
104
|
+
}
|
|
105
|
+
catch { /* doesn't exist yet */ }
|
|
106
|
+
if (stat?.isDirectory()) {
|
|
107
|
+
const files = listFilesRecursive(resolved);
|
|
108
|
+
allFiles.push(...files);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
allFiles.push(resolved);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Apply exclusion rules
|
|
115
|
+
const eligible = [];
|
|
116
|
+
for (const f of allFiles) {
|
|
117
|
+
if (isExcluded(f)) {
|
|
118
|
+
excluded.push(f);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
eligible.push(f);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Check size limits
|
|
125
|
+
let totalBytes = 0;
|
|
126
|
+
const withinLimit = [];
|
|
127
|
+
let exceededLimit = false;
|
|
128
|
+
for (const f of eligible) {
|
|
129
|
+
let fileSize = 0;
|
|
130
|
+
try {
|
|
131
|
+
fileSize = fs.statSync(f).size;
|
|
132
|
+
}
|
|
133
|
+
catch { /* non-existent */ }
|
|
134
|
+
if (withinLimit.length >= maxFiles || totalBytes + fileSize > maxTotalBytes) {
|
|
135
|
+
exceededLimit = true;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
totalBytes += fileSize;
|
|
139
|
+
withinLimit.push(f);
|
|
140
|
+
}
|
|
141
|
+
// Keep non-existent paths from original scopePaths (they are new file placeholders)
|
|
142
|
+
for (const p of scopePaths) {
|
|
143
|
+
const resolved = path.resolve(p);
|
|
144
|
+
try {
|
|
145
|
+
fs.statSync(resolved);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
if (!withinLimit.includes(resolved)) {
|
|
149
|
+
withinLimit.push(resolved);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let snapshots = [];
|
|
154
|
+
if (withinLimit.length > 0) {
|
|
155
|
+
snapshots = this.captureBaseline(taskId, withinLimit);
|
|
156
|
+
}
|
|
157
|
+
const advisorySummary = exceededLimit
|
|
158
|
+
? `baseline scope exceeded limits: ${eligible.length} eligible files found, captured ${withinLimit.length} (${maxFiles} files / ${Math.round(maxTotalBytes / 1024 / 1024)}MB limit). ${excluded.length} files excluded by rules.`
|
|
159
|
+
: excluded.length > 0
|
|
160
|
+
? `baseline captured ${withinLimit.length} files, ${excluded.length} excluded by rules`
|
|
161
|
+
: null;
|
|
162
|
+
return {
|
|
163
|
+
snapshots,
|
|
164
|
+
advisory_summary: advisorySummary,
|
|
165
|
+
total_files_found: allFiles.length,
|
|
166
|
+
files_excluded: excluded.length,
|
|
167
|
+
files_captured: snapshots.length,
|
|
168
|
+
exceeded_limit: exceededLimit,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Record a task-owned write for a file.
|
|
173
|
+
*/
|
|
174
|
+
recordWrite(taskId, filePath) {
|
|
175
|
+
this.ensureLoaded();
|
|
176
|
+
let state = this.states.get(taskId);
|
|
177
|
+
if (!state) {
|
|
178
|
+
state = { task_id: taskId, baseline_captured_at: null, snapshots: [] };
|
|
179
|
+
this.states.set(taskId, state);
|
|
180
|
+
}
|
|
181
|
+
const snap = recordTaskWrite(filePath, taskId);
|
|
182
|
+
state.snapshots.push(snap);
|
|
183
|
+
this.persist();
|
|
184
|
+
return snap;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Run CAS check before writing. Returns advisory conflict report if check fails.
|
|
188
|
+
* Does NOT block the write — caller decides what to do.
|
|
189
|
+
*/
|
|
190
|
+
preWriteCheck(taskId, filePath) {
|
|
191
|
+
this.ensureLoaded();
|
|
192
|
+
const state = this.states.get(taskId);
|
|
193
|
+
const snapshots = state?.snapshots ?? [];
|
|
194
|
+
const latest = findLatestSnapshot(filePath, snapshots);
|
|
195
|
+
const expectedHash = latest?.content_hash ?? null;
|
|
196
|
+
const cas = casCheck(filePath, expectedHash, taskId, snapshots);
|
|
197
|
+
if (cas.cas_ok) {
|
|
198
|
+
return { cas, conflict: null };
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
cas,
|
|
202
|
+
conflict: {
|
|
203
|
+
file_path: cas.file_path,
|
|
204
|
+
expected_hash: cas.expected_hash,
|
|
205
|
+
current_hash: cas.current_hash,
|
|
206
|
+
inferred_ownership: cas.inferred_ownership,
|
|
207
|
+
severity: "advisory",
|
|
208
|
+
message: `advisory: ${cas.conflict_reason}`,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get all snapshots for a task.
|
|
214
|
+
*/
|
|
215
|
+
getSnapshots(taskId) {
|
|
216
|
+
this.ensureLoaded();
|
|
217
|
+
const state = this.states.get(taskId);
|
|
218
|
+
return state ? [...state.snapshots] : [];
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get ownership summary for a task.
|
|
222
|
+
*/
|
|
223
|
+
getOwnershipSummary(taskId) {
|
|
224
|
+
return summarizeOwnership(this.getSnapshots(taskId));
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Clean up state for a completed/failed task.
|
|
228
|
+
*/
|
|
229
|
+
clearTask(taskId) {
|
|
230
|
+
this.ensureLoaded();
|
|
231
|
+
this.states.delete(taskId);
|
|
232
|
+
this.persist();
|
|
233
|
+
}
|
|
234
|
+
clear() {
|
|
235
|
+
this.states.clear();
|
|
236
|
+
this.loaded = true;
|
|
237
|
+
this.persist();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function listFilesRecursive(dir) {
|
|
241
|
+
const result = [];
|
|
242
|
+
function walk(d) {
|
|
243
|
+
let entries;
|
|
244
|
+
try {
|
|
245
|
+
entries = fs.readdirSync(d, { withFileTypes: true });
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
for (const e of entries) {
|
|
251
|
+
if (e.isDirectory()) {
|
|
252
|
+
if (!EXCLUDED_DIRS.has(e.name) && !e.name.startsWith(".")) {
|
|
253
|
+
walk(path.join(d, e.name));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
else if (e.isFile()) {
|
|
257
|
+
result.push(path.join(d, e.name));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
walk(dir);
|
|
262
|
+
return result;
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=diff_ownership_store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff_ownership_store.js","sourceRoot":"","sources":["../../src/engine/diff_ownership_store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 逃逸报告 — 结构化记录抽检失败、误伤、工具故障。
|
|
3
|
+
* P2-3 范围: 只落盘记录,不自动降级,不改 capability 状态。
|
|
4
|
+
* 存储: JSON 数组文件,原子写入,路径绑定 stateDir。
|
|
5
|
+
*/
|
|
6
|
+
export type EscapeType = "rule_gap" | "weak_test" | "bad_evidence" | "ai_escape" | "human_miss" | "tool_bug" | "false_positive";
|
|
7
|
+
export type CapabilityAction = "keep" | "downgrade" | "disable" | "promote_blocked";
|
|
8
|
+
export interface EscapeReport {
|
|
9
|
+
escape_id: string;
|
|
10
|
+
task_id: string;
|
|
11
|
+
policy_id: string;
|
|
12
|
+
failure_type: EscapeType;
|
|
13
|
+
expected_guard: string;
|
|
14
|
+
actual_escape: string;
|
|
15
|
+
evidence: string;
|
|
16
|
+
root_cause: string;
|
|
17
|
+
fix_required: string;
|
|
18
|
+
owner: string;
|
|
19
|
+
due_date: string;
|
|
20
|
+
capability_action: CapabilityAction;
|
|
21
|
+
created_at: string;
|
|
22
|
+
}
|
|
23
|
+
export interface EscapeReportStats {
|
|
24
|
+
total: number;
|
|
25
|
+
by_type: Record<EscapeType, number>;
|
|
26
|
+
by_action: Record<CapabilityAction, number>;
|
|
27
|
+
}
|
|
28
|
+
export declare class EscapeReportStore {
|
|
29
|
+
private filePath;
|
|
30
|
+
private reports;
|
|
31
|
+
private loaded;
|
|
32
|
+
constructor(stateDir: string);
|
|
33
|
+
private ensureLoaded;
|
|
34
|
+
private persist;
|
|
35
|
+
append(report: EscapeReport): void;
|
|
36
|
+
list(filter?: {
|
|
37
|
+
failure_type?: EscapeType;
|
|
38
|
+
policy_id?: string;
|
|
39
|
+
task_id?: string;
|
|
40
|
+
}): EscapeReport[];
|
|
41
|
+
stats(): EscapeReportStats;
|
|
42
|
+
clear(): void;
|
|
43
|
+
getFilePath(): string;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=escape_report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape_report.d.ts","sourceRoot":"","sources":["../../src/engine/escape_report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,WAAW,GACX,cAAc,GACd,WAAW,GACX,YAAY,GACZ,UAAU,GACV,gBAAgB,CAAC;AAErB,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,WAAW,GACX,SAAS,GACT,iBAAiB,CAAC;AAEtB,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,UAAU,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;CAC7C;AA+BD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM;IAO5B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,OAAO;IAMf,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAMlC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,UAAU,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,EAAE;IAelG,KAAK,IAAI,iBAAiB;IAW1B,KAAK,IAAI,IAAI;IAMb,WAAW,IAAI,MAAM;CAGtB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 逃逸报告 — 结构化记录抽检失败、误伤、工具故障。
|
|
3
|
+
* P2-3 范围: 只落盘记录,不自动降级,不改 capability 状态。
|
|
4
|
+
* 存储: JSON 数组文件,原子写入,路径绑定 stateDir。
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
const ALL_ESCAPE_TYPES = [
|
|
9
|
+
"rule_gap",
|
|
10
|
+
"weak_test",
|
|
11
|
+
"bad_evidence",
|
|
12
|
+
"ai_escape",
|
|
13
|
+
"human_miss",
|
|
14
|
+
"tool_bug",
|
|
15
|
+
"false_positive",
|
|
16
|
+
];
|
|
17
|
+
const ALL_CAPABILITY_ACTIONS = [
|
|
18
|
+
"keep",
|
|
19
|
+
"downgrade",
|
|
20
|
+
"disable",
|
|
21
|
+
"promote_blocked",
|
|
22
|
+
];
|
|
23
|
+
function emptyByType() {
|
|
24
|
+
return Object.fromEntries(ALL_ESCAPE_TYPES.map((t) => [t, 0]));
|
|
25
|
+
}
|
|
26
|
+
function emptyByAction() {
|
|
27
|
+
return Object.fromEntries(ALL_CAPABILITY_ACTIONS.map((a) => [a, 0]));
|
|
28
|
+
}
|
|
29
|
+
function deepCopy(report) {
|
|
30
|
+
return { ...report };
|
|
31
|
+
}
|
|
32
|
+
export class EscapeReportStore {
|
|
33
|
+
filePath;
|
|
34
|
+
reports = [];
|
|
35
|
+
loaded = false;
|
|
36
|
+
constructor(stateDir) {
|
|
37
|
+
this.filePath = path.join(stateDir, "escape-reports.json");
|
|
38
|
+
if (!fs.existsSync(stateDir)) {
|
|
39
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
ensureLoaded() {
|
|
43
|
+
if (this.loaded)
|
|
44
|
+
return;
|
|
45
|
+
this.loaded = true;
|
|
46
|
+
try {
|
|
47
|
+
const data = fs.readFileSync(this.filePath, "utf-8");
|
|
48
|
+
this.reports = JSON.parse(data);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
this.reports = [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
persist() {
|
|
55
|
+
const tmpPath = `${this.filePath}.tmp`;
|
|
56
|
+
fs.writeFileSync(tmpPath, JSON.stringify(this.reports, null, 2));
|
|
57
|
+
fs.renameSync(tmpPath, this.filePath);
|
|
58
|
+
}
|
|
59
|
+
append(report) {
|
|
60
|
+
this.ensureLoaded();
|
|
61
|
+
this.reports.push(deepCopy(report));
|
|
62
|
+
this.persist();
|
|
63
|
+
}
|
|
64
|
+
list(filter) {
|
|
65
|
+
this.ensureLoaded();
|
|
66
|
+
let result = this.reports;
|
|
67
|
+
if (filter?.failure_type) {
|
|
68
|
+
result = result.filter((r) => r.failure_type === filter.failure_type);
|
|
69
|
+
}
|
|
70
|
+
if (filter?.policy_id) {
|
|
71
|
+
result = result.filter((r) => r.policy_id === filter.policy_id);
|
|
72
|
+
}
|
|
73
|
+
if (filter?.task_id) {
|
|
74
|
+
result = result.filter((r) => r.task_id === filter.task_id);
|
|
75
|
+
}
|
|
76
|
+
return result.map(deepCopy);
|
|
77
|
+
}
|
|
78
|
+
stats() {
|
|
79
|
+
this.ensureLoaded();
|
|
80
|
+
const by_type = emptyByType();
|
|
81
|
+
const by_action = emptyByAction();
|
|
82
|
+
for (const r of this.reports) {
|
|
83
|
+
by_type[r.failure_type]++;
|
|
84
|
+
by_action[r.capability_action]++;
|
|
85
|
+
}
|
|
86
|
+
return { total: this.reports.length, by_type, by_action };
|
|
87
|
+
}
|
|
88
|
+
clear() {
|
|
89
|
+
this.reports = [];
|
|
90
|
+
this.loaded = true;
|
|
91
|
+
this.persist();
|
|
92
|
+
}
|
|
93
|
+
getFilePath() {
|
|
94
|
+
return this.filePath;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=escape_report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape_report.js","sourceRoot":"","sources":["../../src/engine/escape_report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAuC7B,MAAM,gBAAgB,GAAiB;IACrC,UAAU;IACV,WAAW;IACX,cAAc;IACd,WAAW;IACX,YAAY;IACZ,UAAU;IACV,gBAAgB;CACjB,CAAC;AAEF,MAAM,sBAAsB,GAAuB;IACjD,MAAM;IACN,WAAW;IACX,SAAS;IACT,iBAAiB;CAClB,CAAC;AAEF,SAAS,WAAW;IAClB,OAAO,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAA+B,CAAC;AAC/F,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,MAAM,CAAC,WAAW,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAqC,CAAC;AAC3G,CAAC;AAED,SAAS,QAAQ,CAAC,MAAoB;IACpC,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,OAAO,iBAAiB;IACpB,QAAQ,CAAS;IACjB,OAAO,GAAmB,EAAE,CAAC;IAC7B,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;QAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAEO,OAAO;QACb,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,QAAQ,MAAM,CAAC;QACvC,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,MAAoB;QACzB,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,MAA4E;QAC/E,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC1B,IAAI,MAAM,EAAE,YAAY,EAAE,CAAC;YACzB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,MAAM,CAAC,YAAY,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,MAAM,EAAE,SAAS,EAAE,CAAC;YACtB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC5D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -79,6 +79,40 @@ export interface ExplorationResult {
|
|
|
79
79
|
boundary_summary: string;
|
|
80
80
|
/** 时效性信息 */
|
|
81
81
|
timeliness?: TimelinessInfo;
|
|
82
|
+
/** 契约字段: 当前项目约束和已有栈 */
|
|
83
|
+
local_constraints: string;
|
|
84
|
+
/** 契约字段: 分层证据列表 */
|
|
85
|
+
evidence_sources: EvidenceSource[];
|
|
86
|
+
/** 契约字段: 被拒绝方案及原因 */
|
|
87
|
+
rejected_options: RejectedOption[];
|
|
88
|
+
/** 契约字段: 知识过时/新方案不稳定风险 */
|
|
89
|
+
freshness_risk: string;
|
|
90
|
+
/** 契约字段: 维护/安全/许可证/迁移退出成本 */
|
|
91
|
+
adoption_risk: string;
|
|
92
|
+
/** 契约字段: spike/测试/兼容性验证/回滚路径 */
|
|
93
|
+
validation_plan: string;
|
|
94
|
+
/** 契约字段: 结论何时需重新验证 */
|
|
95
|
+
decision_expiry: string;
|
|
96
|
+
/** 默认推荐方案,可直接执行 */
|
|
97
|
+
recommended_option: string;
|
|
98
|
+
/** 为什么选它,结合代码库和约束 */
|
|
99
|
+
why_this: string;
|
|
100
|
+
/** 被放弃的方案及放弃原因 */
|
|
101
|
+
rejected_decision_options: string[];
|
|
102
|
+
/** 对备选方案公平强化 */
|
|
103
|
+
steelman_alternatives: string;
|
|
104
|
+
/** 主动攻击推荐方案,列出失败条件 */
|
|
105
|
+
attack_recommended_option: string;
|
|
106
|
+
/** 如何证明推荐方案不成立 */
|
|
107
|
+
falsification_tests: string;
|
|
108
|
+
/** 执行步骤 */
|
|
109
|
+
execution_plan: string;
|
|
110
|
+
/** 验证命令和成功标准 */
|
|
111
|
+
verification_plan: string;
|
|
112
|
+
/** 失败后如何撤回 */
|
|
113
|
+
rollback_plan: string;
|
|
114
|
+
/** 是否需要人工确认 */
|
|
115
|
+
human_confirmation_required: boolean;
|
|
82
116
|
}
|
|
83
117
|
/** 时效性信息 */
|
|
84
118
|
export interface TimelinessInfo {
|
|
@@ -91,6 +125,26 @@ export interface TimelinessInfo {
|
|
|
91
125
|
/** 提示信息 */
|
|
92
126
|
message: string;
|
|
93
127
|
}
|
|
128
|
+
/** 证据来源条目 */
|
|
129
|
+
export interface EvidenceSource {
|
|
130
|
+
/** 来源名称 */
|
|
131
|
+
name: string;
|
|
132
|
+
/** 证据分层: local_code / official_docs / standards / maintainer_sources / community_practice / trend_signal */
|
|
133
|
+
tier: "local_code" | "official_docs" | "standards" | "maintainer_sources" | "community_practice" | "trend_signal";
|
|
134
|
+
/** 可信度: high / medium / low */
|
|
135
|
+
credibility: "high" | "medium" | "low";
|
|
136
|
+
/** 来源描述 */
|
|
137
|
+
description: string;
|
|
138
|
+
}
|
|
139
|
+
/** 被拒绝方案 */
|
|
140
|
+
export interface RejectedOption {
|
|
141
|
+
/** 方案名称 */
|
|
142
|
+
name: string;
|
|
143
|
+
/** 拒绝原因 */
|
|
144
|
+
reason: string;
|
|
145
|
+
/** steelman: 公平强化该方案的优点 */
|
|
146
|
+
steelman: string;
|
|
147
|
+
}
|
|
94
148
|
/** 对比矩阵 */
|
|
95
149
|
export interface ComparisonMatrix {
|
|
96
150
|
/** 维度列表 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exploration.d.ts","sourceRoot":"","sources":["../../src/engine/exploration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E;;;;;;;;;;GAUG;AAIH,aAAa;AACb,MAAM,WAAW,YAAY;IAC3B,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;IAC/C,YAAY;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,WAAW;AACX,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,WAAW;AACX,MAAM,WAAW,mBAAmB;IAClC,WAAW;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa;IACb,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,aAAa;IACb,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY;IACZ,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,eAAe;AACf,MAAM,WAAW,cAAc;IAC7B,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS;IACT,MAAM,EAAE,MAAM,CAAC;IACf,WAAW;IACX,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,WAAW;AACX,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,aAAa;IACb,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,YAAY;IACZ,wBAAwB,EAAE,uBAAuB,CAAC;IAClD,WAAW;IACX,oBAAoB,EAAE,mBAAmB,EAAE,CAAC;IAC5C,eAAe;IACf,gBAAgB,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IACnD,eAAe;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY;IACZ,UAAU,CAAC,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"exploration.d.ts","sourceRoot":"","sources":["../../src/engine/exploration.ts"],"names":[],"mappings":"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"}
|
|
@@ -236,6 +236,23 @@ export function exploreSolutions(params) {
|
|
|
236
236
|
const timeliness = computeTimeliness(benchmarks);
|
|
237
237
|
// 环境感知提示
|
|
238
238
|
const envHints = computeEnvironmentHints(projectConfig, benchmarks);
|
|
239
|
+
// 契约字段: local_constraints
|
|
240
|
+
const localConstraints = buildLocalConstraints(projectConfig);
|
|
241
|
+
// 契约字段: evidence_sources
|
|
242
|
+
const evidenceSources = buildEvidenceSources(benchmarks, knowledgeIndex);
|
|
243
|
+
// 契约字段: rejected_options
|
|
244
|
+
const rejectedOptions = buildRejectedOptions(benchmarks, recommendation);
|
|
245
|
+
// 契约字段: freshness_risk
|
|
246
|
+
const freshnessRisk = buildFreshnessRisk(timeliness, benchmarks);
|
|
247
|
+
// 契约字段: adoption_risk
|
|
248
|
+
const adoptionRisk = buildAdoptionRisk(recommendation, benchmarks);
|
|
249
|
+
// 契约字段: validation_plan
|
|
250
|
+
const validationPlan = buildValidationPlan(recommendation, benchmarks);
|
|
251
|
+
// 契约字段: decision_expiry
|
|
252
|
+
const decisionExpiry = buildDecisionExpiry(timeliness);
|
|
253
|
+
// 默认决策输出契约
|
|
254
|
+
const recommendedSolution = benchmarks.find((b) => b.name === recommendation.recommended) ?? benchmarks[0];
|
|
255
|
+
const recommendedFalsification = falsifications.find((f) => f.solution_name === recommendation.recommended);
|
|
239
256
|
return {
|
|
240
257
|
domain: benchmarks[0]?.name || domain_query,
|
|
241
258
|
benchmarks,
|
|
@@ -245,6 +262,24 @@ export function exploreSolutions(params) {
|
|
|
245
262
|
decision_options: decisionOptions,
|
|
246
263
|
boundary_summary: boundarySummary + (envHints ? "\n" + envHints : ""),
|
|
247
264
|
timeliness,
|
|
265
|
+
local_constraints: localConstraints,
|
|
266
|
+
evidence_sources: evidenceSources,
|
|
267
|
+
rejected_options: rejectedOptions,
|
|
268
|
+
freshness_risk: freshnessRisk,
|
|
269
|
+
adoption_risk: adoptionRisk,
|
|
270
|
+
validation_plan: validationPlan,
|
|
271
|
+
decision_expiry: decisionExpiry,
|
|
272
|
+
// 默认决策契约 10 字段
|
|
273
|
+
recommended_option: recommendation.recommended,
|
|
274
|
+
why_this: recommendation.reason + ";规避了: " + recommendation.fatal_weakness_mitigation,
|
|
275
|
+
rejected_decision_options: rejectedOptions.map((r) => `${r.name}: ${r.reason}`),
|
|
276
|
+
steelman_alternatives: rejectedOptions.map((r) => r.steelman).join(";"),
|
|
277
|
+
attack_recommended_option: recommendedFalsification?.self_destruct_scenarios.join(";") ?? "无已知自毁场景",
|
|
278
|
+
falsification_tests: recommendedFalsification?.ceiling_description ?? "未设置天花板测试",
|
|
279
|
+
execution_plan: decisionOptions[0].reason + ";" + decisionOptions[0].suitable_for,
|
|
280
|
+
verification_plan: validationPlan,
|
|
281
|
+
rollback_plan: `移除「${recommendedSolution.name}」相关代码和配置即可恢复原状`,
|
|
282
|
+
human_confirmation_required: recommendedSolution.source === "heuristic",
|
|
248
283
|
};
|
|
249
284
|
}
|
|
250
285
|
// ── 行业基准检索 ──
|
|
@@ -469,4 +504,107 @@ function computeEnvironmentHints(config, benchmarks) {
|
|
|
469
504
|
}
|
|
470
505
|
return null;
|
|
471
506
|
}
|
|
507
|
+
// ── 契约字段构建 ──
|
|
508
|
+
function buildLocalConstraints(config) {
|
|
509
|
+
const b = config.tech_stack.backend;
|
|
510
|
+
const f = config.tech_stack.frontend;
|
|
511
|
+
const parts = [];
|
|
512
|
+
if (b.framework && b.framework !== "unknown") {
|
|
513
|
+
parts.push(`后端: ${b.lang}/${b.framework} ${b.version}`);
|
|
514
|
+
}
|
|
515
|
+
if (f.framework && f.framework !== "unknown") {
|
|
516
|
+
parts.push(`前端: ${f.lang}/${f.framework} ${f.version}`);
|
|
517
|
+
}
|
|
518
|
+
if (config.scope?.backend?.length) {
|
|
519
|
+
parts.push(`后端 scope: ${config.scope.backend.join(", ")}`);
|
|
520
|
+
}
|
|
521
|
+
if (config.scope?.frontend?.length) {
|
|
522
|
+
parts.push(`前端 scope: ${config.scope.frontend.join(", ")}`);
|
|
523
|
+
}
|
|
524
|
+
return parts.length > 0 ? parts.join(";") : "未检测到技术栈约束";
|
|
525
|
+
}
|
|
526
|
+
function buildEvidenceSources(benchmarks, _knowledgeIndex) {
|
|
527
|
+
const sources = [];
|
|
528
|
+
sources.push({
|
|
529
|
+
name: "项目配置",
|
|
530
|
+
tier: "local_code",
|
|
531
|
+
credibility: "high",
|
|
532
|
+
description: "当前项目的技术栈、scope 和构建命令配置",
|
|
533
|
+
});
|
|
534
|
+
for (const b of benchmarks) {
|
|
535
|
+
if (b.source === "industry") {
|
|
536
|
+
sources.push({
|
|
537
|
+
name: b.name,
|
|
538
|
+
tier: "community_practice",
|
|
539
|
+
credibility: "medium",
|
|
540
|
+
description: `行业基准方案: ${b.description}`,
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (_knowledgeIndex) {
|
|
545
|
+
sources.push({
|
|
546
|
+
name: "项目知识库",
|
|
547
|
+
tier: "local_code",
|
|
548
|
+
credibility: "high",
|
|
549
|
+
description: "项目积累的知识模板和决策规则",
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return sources;
|
|
553
|
+
}
|
|
554
|
+
function buildRejectedOptions(benchmarks, recommendation) {
|
|
555
|
+
const rejected = benchmarks.filter((b) => b.name !== recommendation.recommended);
|
|
556
|
+
return rejected.map((b) => ({
|
|
557
|
+
name: b.name,
|
|
558
|
+
reason: `致命缺点: ${b.fatal_weakness}`,
|
|
559
|
+
steelman: `适用场景: ${b.best_for}(评分: ${RATING_KEYS.reduce((s, k) => s + b.ratings[k], 0)}/20)`,
|
|
560
|
+
}));
|
|
561
|
+
}
|
|
562
|
+
function buildFreshnessRisk(timeliness, benchmarks) {
|
|
563
|
+
const parts = [];
|
|
564
|
+
if (timeliness.stale_warning) {
|
|
565
|
+
parts.push(`基准数据已 ${timeliness.days_since_review} 天未更新,行业方案可能已有新版本`);
|
|
566
|
+
}
|
|
567
|
+
const industryCount = benchmarks.filter((b) => b.source === "industry").length;
|
|
568
|
+
if (industryCount === 0) {
|
|
569
|
+
parts.push("未匹配到行业标准方案,使用启发式兜底");
|
|
570
|
+
}
|
|
571
|
+
if (timeliness.days_since_review > 90 && !timeliness.stale_warning) {
|
|
572
|
+
parts.push(`基准数据 ${timeliness.days_since_review} 天未更新,建议关注新版本发布`);
|
|
573
|
+
}
|
|
574
|
+
return parts.length > 0 ? parts.join(";") : "基准数据较新,知识过时风险低";
|
|
575
|
+
}
|
|
576
|
+
function buildAdoptionRisk(recommendation, benchmarks) {
|
|
577
|
+
const recommended = benchmarks.find((b) => b.name === recommendation.recommended);
|
|
578
|
+
if (!recommended)
|
|
579
|
+
return "无法评估采用风险";
|
|
580
|
+
const parts = [];
|
|
581
|
+
parts.push(`推荐方案「${recommended.name}」最差场景: ${recommended.worst_for}`);
|
|
582
|
+
if (recommended.fatal_weakness) {
|
|
583
|
+
parts.push(`致命弱点: ${recommended.fatal_weakness}`);
|
|
584
|
+
}
|
|
585
|
+
if (recommendation.prerequisites.length > 0) {
|
|
586
|
+
parts.push(`前提条件: ${recommendation.prerequisites.join(";")}`);
|
|
587
|
+
}
|
|
588
|
+
return parts.join(";");
|
|
589
|
+
}
|
|
590
|
+
function buildValidationPlan(recommendation, benchmarks) {
|
|
591
|
+
const recommended = benchmarks.find((b) => b.name === recommendation.recommended);
|
|
592
|
+
const parts = [];
|
|
593
|
+
parts.push("1. 确认项目环境满足推荐方案的前提条件");
|
|
594
|
+
if (recommended) {
|
|
595
|
+
parts.push(`2. 在非关键路径上做最小 spike 验证「${recommended.name}」`);
|
|
596
|
+
parts.push(`3. 验证推荐方案不触发致命弱点: ${recommended?.fatal_weakness ?? "无"}`);
|
|
597
|
+
}
|
|
598
|
+
parts.push("4. 执行构建和测试验证");
|
|
599
|
+
parts.push("5. 回滚路径: 移除新增代码和配置即可恢复原状");
|
|
600
|
+
return parts.join("\n");
|
|
601
|
+
}
|
|
602
|
+
function buildDecisionExpiry(timeliness) {
|
|
603
|
+
const days = timeliness.days_since_review;
|
|
604
|
+
if (days > 180)
|
|
605
|
+
return "基准数据已过期,决策结论需立即重新验证";
|
|
606
|
+
if (days > 90)
|
|
607
|
+
return `建议 ${180 - days} 天内重新验证(基准数据 ${days} 天前审核)`;
|
|
608
|
+
return `决策结论有效期至 ${new Date(Date.now() + (180 - days) * 86400000).toISOString().slice(0, 10)}`;
|
|
609
|
+
}
|
|
472
610
|
//# sourceMappingURL=exploration.js.map
|