soloforge 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -18
- package/dist/adapters/claude_code/server.d.ts.map +1 -1
- package/dist/adapters/claude_code/server.js +2 -25
- package/dist/adapters/claude_code/server.js.map +1 -1
- package/dist/adapters/claude_code/tools.d.ts +8 -13
- package/dist/adapters/claude_code/tools.d.ts.map +1 -1
- package/dist/adapters/claude_code/tools.js +508 -87
- package/dist/adapters/claude_code/tools.js.map +1 -1
- package/dist/adapters/codex/codex_rules.d.ts.map +1 -1
- package/dist/adapters/codex/codex_rules.js +23 -1
- package/dist/adapters/codex/codex_rules.js.map +1 -1
- package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
- package/dist/adapters/shared/workflow_template.js +25 -0
- package/dist/adapters/shared/workflow_template.js.map +1 -1
- package/dist/bin/soloforge.js +169 -18
- 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/audit_verifier.d.ts +1 -1
- package/dist/engine/audit_verifier.js +1 -1
- package/dist/engine/audit_verifier.js.map +1 -1
- 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 +58 -0
- package/dist/engine/capability_registry.d.ts.map +1 -0
- package/dist/engine/capability_registry.js +625 -0
- package/dist/engine/capability_registry.js.map +1 -0
- 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_config_loader.d.ts +1 -1
- package/dist/engine/knowledge_config_loader.js +1 -1
- 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/llm_gateway.js +2 -2
- package/dist/engine/llm_gateway.js.map +1 -1
- 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 +59 -1
- package/dist/engine/task_context.js.map +1 -1
- package/dist/engine/test_quality.js +2 -2
- package/dist/engine/test_quality.js.map +1 -1
- package/dist/engine/verifier.d.ts.map +1 -1
- package/dist/engine/verifier.js +113 -20
- 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 -85
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/templates/knowledge/domain//345/256/241/350/256/241/346/227/245/345/277/227.md +6 -7
- package/templates/knowledge/domain//345/257/274/345/205/245/345/257/274/345/207/272/350/247/204/345/210/231.md +3 -3
- package/templates/knowledge/domain//351/200/232/347/224/250/346/234/272/346/242/260/346/235/241/346/254/276.md +24 -14
- 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 +52 -0
- package/templates/knowledge/patterns/core/{mutation_audit.md → /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 +49 -0
- package/templates/knowledge/patterns/core/{developer_constitution.md → /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/{streaming_protocol.md → /346/265/201/345/274/217/345/277/203/350/267/263.md} +20 -0
- package/templates/knowledge/patterns/core/{authority.md → /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
- package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +1 -1
- package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/347/250/213.md +1 -1
- package/templates/knowledge/review_rules//345/271/266/345/217/221/345/256/241/346/237/245/350/247/204/345/210/231.md +1 -1
- package/templates/knowledge/review_rules//346/200/247/350/203/275/345/256/241/346/237/245/350/247/204/345/210/231.md +1 -1
- package/templates/knowledge/review_rules//346/216/245/345/217/243/345/245/221/347/272/246/345/256/241/346/237/245/350/247/204/345/210/231.md +1 -1
- package/templates/knowledge/review_rules//346/236/266/346/236/204/345/256/241/346/237/245/350/247/204/345/210/231.md +1 -1
- package/templates/knowledge/review_rules//350/264/250/351/207/217/345/256/241/346/237/245/350/247/204/345/210/231.md +1 -1
- package/templates/knowledge/patterns/core/concurrency_lock.md +0 -36
- package/templates/knowledge/patterns/core/decision_gateway.md +0 -33
- /package/templates/knowledge/checklists/{session_recovery.md → /344/274/232/350/257/235/346/201/242/345/244/215.md"} +0 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 运行安全包 — 证据 hash chain、命令副作用分级、供应链治理、迁移回滚契约。
|
|
3
|
+
* advisory: 不 hard block(除 destructive 命令需人工确认)。
|
|
4
|
+
*/
|
|
5
|
+
import crypto from "node:crypto";
|
|
6
|
+
/**
|
|
7
|
+
* 构建证据链 — 每个步骤产出带 hash 的证据块,与前一个块链式连接。
|
|
8
|
+
*/
|
|
9
|
+
export function buildEvidenceChain(steps) {
|
|
10
|
+
const chain = [];
|
|
11
|
+
let prevHash = null;
|
|
12
|
+
for (const s of steps) {
|
|
13
|
+
const timestamp = s.timestamp ?? new Date().toISOString();
|
|
14
|
+
const dataHash = crypto
|
|
15
|
+
.createHash("sha256")
|
|
16
|
+
.update(s.payload)
|
|
17
|
+
.digest("hex")
|
|
18
|
+
.slice(0, 16);
|
|
19
|
+
const chainInput = `${s.step}:${timestamp}:${dataHash}:${prevHash ?? "genesis"}`;
|
|
20
|
+
const chainHash = crypto
|
|
21
|
+
.createHash("sha256")
|
|
22
|
+
.update(chainInput)
|
|
23
|
+
.digest("hex")
|
|
24
|
+
.slice(0, 16);
|
|
25
|
+
const block = {
|
|
26
|
+
step: s.step,
|
|
27
|
+
timestamp,
|
|
28
|
+
data_hash: dataHash,
|
|
29
|
+
prev_hash: prevHash,
|
|
30
|
+
chain_hash: chainHash,
|
|
31
|
+
payload: s.payload,
|
|
32
|
+
};
|
|
33
|
+
chain.push(block);
|
|
34
|
+
prevHash = chainHash;
|
|
35
|
+
}
|
|
36
|
+
return chain;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 验证证据链完整性 — 检查每个块的 chain_hash 是否与重算结果一致。
|
|
40
|
+
*/
|
|
41
|
+
export function verifyEvidenceChain(chain) {
|
|
42
|
+
if (chain.length === 0) {
|
|
43
|
+
return { valid: true, broken_at: null, advisory: "empty chain" };
|
|
44
|
+
}
|
|
45
|
+
for (let i = 0; i < chain.length; i++) {
|
|
46
|
+
const block = chain[i];
|
|
47
|
+
const expectedPrev = i === 0 ? null : chain[i - 1].chain_hash;
|
|
48
|
+
if (block.prev_hash !== expectedPrev) {
|
|
49
|
+
return {
|
|
50
|
+
valid: false,
|
|
51
|
+
broken_at: i,
|
|
52
|
+
advisory: `chain broken at step ${i}: prev_hash mismatch`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Recompute data_hash from payload to detect tampering
|
|
56
|
+
const expectedDataHash = crypto
|
|
57
|
+
.createHash("sha256")
|
|
58
|
+
.update(block.payload)
|
|
59
|
+
.digest("hex")
|
|
60
|
+
.slice(0, 16);
|
|
61
|
+
if (block.data_hash !== expectedDataHash) {
|
|
62
|
+
return {
|
|
63
|
+
valid: false,
|
|
64
|
+
broken_at: i,
|
|
65
|
+
advisory: `chain broken at step ${i}: data_hash mismatch (payload tampered)`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const chainInput = `${block.step}:${block.timestamp}:${block.data_hash}:${block.prev_hash ?? "genesis"}`;
|
|
69
|
+
const expectedHash = crypto
|
|
70
|
+
.createHash("sha256")
|
|
71
|
+
.update(chainInput)
|
|
72
|
+
.digest("hex")
|
|
73
|
+
.slice(0, 16);
|
|
74
|
+
if (block.chain_hash !== expectedHash) {
|
|
75
|
+
return {
|
|
76
|
+
valid: false,
|
|
77
|
+
broken_at: i,
|
|
78
|
+
advisory: `chain broken at step ${i}: chain_hash mismatch`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
valid: true,
|
|
84
|
+
broken_at: null,
|
|
85
|
+
advisory: `chain intact: ${chain.length} blocks verified`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const DESTRUCTIVE_PATTERNS = [
|
|
89
|
+
{ pattern: /\brm\s+(-[rf]+\s+|--no-preserve-root)/, example: "rm -rf" },
|
|
90
|
+
{ pattern: /\bgit\s+(push\s+--force|reset\s+--hard|clean\s+-fd)/, example: "git push --force" },
|
|
91
|
+
{ pattern: /\bdd\s+if=/, example: "dd" },
|
|
92
|
+
{ pattern: /\b(format|mkfs)\b/, example: "format" },
|
|
93
|
+
{ pattern: /\bdrop\s+(table|database|schema)\b/i, example: "DROP TABLE" },
|
|
94
|
+
{ pattern: /\bTRUNCATE\b/i, example: "TRUNCATE" },
|
|
95
|
+
{ pattern: /\bDELETE\s+FROM\b/i, example: "DELETE FROM" },
|
|
96
|
+
{ pattern: /\b(npm\s+publish|yarn\s+publish|pnpm\s+publish)\b/, example: "npm publish" },
|
|
97
|
+
];
|
|
98
|
+
const MUTATING_PATTERNS = [
|
|
99
|
+
{ pattern: /\bgit\s+(add|commit|push|merge|rebase|checkout)\b/, example: "git commit" },
|
|
100
|
+
{ pattern: /\b(npm\s+install|yarn\s+add|pnpm\s+add)\b/, example: "npm install" },
|
|
101
|
+
{ pattern: /\bmv\s+/, example: "mv" },
|
|
102
|
+
{ pattern: /\bcp\s+/, example: "cp" },
|
|
103
|
+
{ pattern: /\bmkdir\s+/, example: "mkdir" },
|
|
104
|
+
{ pattern: /\bdocker\s+(run|build|push|rmi|rm)\b/, example: "docker run" },
|
|
105
|
+
{ pattern: /\b(INSERT|UPDATE|ALTER|CREATE)\b/i, example: "INSERT" },
|
|
106
|
+
];
|
|
107
|
+
/**
|
|
108
|
+
* 分类命令的副作用级别。
|
|
109
|
+
*/
|
|
110
|
+
export function classifyCommand(command) {
|
|
111
|
+
for (const dp of DESTRUCTIVE_PATTERNS) {
|
|
112
|
+
if (dp.pattern.test(command)) {
|
|
113
|
+
return {
|
|
114
|
+
command,
|
|
115
|
+
risk: "destructive",
|
|
116
|
+
advisory: `destructive command detected: ${dp.example} — requires human confirmation`,
|
|
117
|
+
requires_human_confirm: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
for (const mp of MUTATING_PATTERNS) {
|
|
122
|
+
if (mp.pattern.test(command)) {
|
|
123
|
+
return {
|
|
124
|
+
command,
|
|
125
|
+
risk: "mutating",
|
|
126
|
+
advisory: `mutating command: ${mp.example}`,
|
|
127
|
+
requires_human_confirm: false,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
command,
|
|
133
|
+
risk: "read_only",
|
|
134
|
+
advisory: "read-only command",
|
|
135
|
+
requires_human_confirm: false,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 检查迁移契约 — 确保 schema 变更有回滚路径。
|
|
140
|
+
*/
|
|
141
|
+
export function checkMigrationContract(migration) {
|
|
142
|
+
const forwardClassified = classifyCommand(migration.forward_command);
|
|
143
|
+
const rollbackClassified = classifyCommand(migration.rollback_command);
|
|
144
|
+
if (!migration.rollback_command || migration.rollback_command.trim().length === 0) {
|
|
145
|
+
return {
|
|
146
|
+
migration_id: migration.migration_id,
|
|
147
|
+
has_rollback: false,
|
|
148
|
+
rollback_valid: false,
|
|
149
|
+
advisory: `advisory: migration "${migration.migration_id}" has no rollback command — manual recovery required if it fails`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// Rollback should be the inverse operation
|
|
153
|
+
const rollbackValid = migration.rollback_command.length > 0;
|
|
154
|
+
return {
|
|
155
|
+
migration_id: migration.migration_id,
|
|
156
|
+
has_rollback: true,
|
|
157
|
+
rollback_valid: rollbackValid,
|
|
158
|
+
advisory: `migration "${migration.migration_id}": forward=${forwardClassified.risk}, rollback=${rollbackClassified.risk}`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const LOCKFILE_NAMES = [
|
|
162
|
+
"package-lock.json",
|
|
163
|
+
"pnpm-lock.yaml",
|
|
164
|
+
"yarn.lock",
|
|
165
|
+
"go.sum",
|
|
166
|
+
"Cargo.lock",
|
|
167
|
+
];
|
|
168
|
+
/**
|
|
169
|
+
* 检查供应链安全 — 验证依赖有 lockfile 和完整性 hash。
|
|
170
|
+
* 此为轻量级检查,不读取实际文件内容。
|
|
171
|
+
*/
|
|
172
|
+
export function checkSupplyChain(rootDirFiles, dependencies) {
|
|
173
|
+
const hasLockfile = LOCKFILE_NAMES.some((lf) => rootDirFiles.includes(lf));
|
|
174
|
+
const checks = dependencies.map((dep) => ({
|
|
175
|
+
package_name: dep.name,
|
|
176
|
+
version: dep.version,
|
|
177
|
+
has_lockfile: hasLockfile,
|
|
178
|
+
has_integrity_hash: hasLockfile, // lockfile implies integrity hashes
|
|
179
|
+
advisory: hasLockfile
|
|
180
|
+
? "locked with integrity hash"
|
|
181
|
+
: `advisory: ${dep.name}@${dep.version} not locked — supply chain risk`,
|
|
182
|
+
}));
|
|
183
|
+
const locked = checks.filter((c) => c.has_lockfile).length;
|
|
184
|
+
const unlocked = checks.length - locked;
|
|
185
|
+
return {
|
|
186
|
+
total_dependencies: dependencies.length,
|
|
187
|
+
locked_dependencies: locked,
|
|
188
|
+
unlocked_dependencies: unlocked,
|
|
189
|
+
checks,
|
|
190
|
+
advisory: unlocked > 0
|
|
191
|
+
? `advisory: ${unlocked}/${dependencies.length} dependencies not locked — recommend adding lockfile`
|
|
192
|
+
: `all ${dependencies.length} dependencies locked`,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=runtime_safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime_safety.js","sourceRoot":"","sources":["../../src/engine/runtime_safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope Lease — 追踪任务对文件的 advisory 租约。
|
|
3
|
+
*
|
|
4
|
+
* CAP-011 实验性: advisory only, 不 hard block, 不阻止写入。
|
|
5
|
+
* 职责: 记录哪个任务正在操作哪些文件,供其他任务查询冲突。
|
|
6
|
+
*
|
|
7
|
+
* 生命周期:
|
|
8
|
+
* - 任务进入 executing 时 acquire
|
|
9
|
+
* - 任务完成/失败/取消时 release
|
|
10
|
+
* - 其他任务写前可 queryLease 查询 advisory 冲突
|
|
11
|
+
*/
|
|
12
|
+
export interface LeaseEntry {
|
|
13
|
+
task_id: string;
|
|
14
|
+
file_paths: string[];
|
|
15
|
+
acquired_at: string;
|
|
16
|
+
released_at: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface LeaseConflict {
|
|
19
|
+
file_path: string;
|
|
20
|
+
leased_by: string;
|
|
21
|
+
lease_acquired_at: string;
|
|
22
|
+
severity: "advisory";
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
25
|
+
export interface LeaseSummary {
|
|
26
|
+
active_leases: number;
|
|
27
|
+
total_files_leased: number;
|
|
28
|
+
leased_by_task: Record<string, string[]>;
|
|
29
|
+
}
|
|
30
|
+
export declare class ScopeLeaseStore {
|
|
31
|
+
private filePath;
|
|
32
|
+
private leases;
|
|
33
|
+
private loaded;
|
|
34
|
+
constructor(stateDir: string);
|
|
35
|
+
private ensureLoaded;
|
|
36
|
+
private persist;
|
|
37
|
+
acquire(taskId: string, filePaths: string[]): LeaseEntry;
|
|
38
|
+
release(taskId: string): LeaseEntry | null;
|
|
39
|
+
queryLease(taskId: string, filePath: string): LeaseConflict | null;
|
|
40
|
+
getActiveLeases(): LeaseEntry[];
|
|
41
|
+
getLeaseForTask(taskId: string): LeaseEntry | null;
|
|
42
|
+
getSummary(): LeaseSummary;
|
|
43
|
+
clear(): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=scope_lease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope_lease.d.ts","sourceRoot":"","sources":["../../src/engine/scope_lease.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC1C;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM;IAO5B,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU;IAcxD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAU1C,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAoBlE,eAAe,IAAI,UAAU,EAAE;IAK/B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAKlD,UAAU,IAAI,YAAY;IAe1B,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope Lease — 追踪任务对文件的 advisory 租约。
|
|
3
|
+
*
|
|
4
|
+
* CAP-011 实验性: advisory only, 不 hard block, 不阻止写入。
|
|
5
|
+
* 职责: 记录哪个任务正在操作哪些文件,供其他任务查询冲突。
|
|
6
|
+
*
|
|
7
|
+
* 生命周期:
|
|
8
|
+
* - 任务进入 executing 时 acquire
|
|
9
|
+
* - 任务完成/失败/取消时 release
|
|
10
|
+
* - 其他任务写前可 queryLease 查询 advisory 冲突
|
|
11
|
+
*/
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
export class ScopeLeaseStore {
|
|
15
|
+
filePath;
|
|
16
|
+
leases = new Map();
|
|
17
|
+
loaded = false;
|
|
18
|
+
constructor(stateDir) {
|
|
19
|
+
this.filePath = path.join(stateDir, "scope-leases.json");
|
|
20
|
+
if (!fs.existsSync(stateDir)) {
|
|
21
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
ensureLoaded() {
|
|
25
|
+
if (this.loaded)
|
|
26
|
+
return;
|
|
27
|
+
this.loaded = true;
|
|
28
|
+
try {
|
|
29
|
+
const data = fs.readFileSync(this.filePath, "utf-8");
|
|
30
|
+
const entries = JSON.parse(data);
|
|
31
|
+
for (const e of entries) {
|
|
32
|
+
if (e.released_at === null) {
|
|
33
|
+
this.leases.set(e.task_id, e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
this.leases = new Map();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
persist() {
|
|
42
|
+
const entries = [...this.leases.values()];
|
|
43
|
+
const tmpPath = `${this.filePath}.tmp`;
|
|
44
|
+
fs.writeFileSync(tmpPath, JSON.stringify(entries, null, 2));
|
|
45
|
+
fs.renameSync(tmpPath, this.filePath);
|
|
46
|
+
}
|
|
47
|
+
acquire(taskId, filePaths) {
|
|
48
|
+
this.ensureLoaded();
|
|
49
|
+
const resolved = filePaths.map(f => path.resolve(f));
|
|
50
|
+
const entry = {
|
|
51
|
+
task_id: taskId,
|
|
52
|
+
file_paths: resolved,
|
|
53
|
+
acquired_at: new Date().toISOString(),
|
|
54
|
+
released_at: null,
|
|
55
|
+
};
|
|
56
|
+
this.leases.set(taskId, entry);
|
|
57
|
+
this.persist();
|
|
58
|
+
return entry;
|
|
59
|
+
}
|
|
60
|
+
release(taskId) {
|
|
61
|
+
this.ensureLoaded();
|
|
62
|
+
const entry = this.leases.get(taskId);
|
|
63
|
+
if (!entry)
|
|
64
|
+
return null;
|
|
65
|
+
entry.released_at = new Date().toISOString();
|
|
66
|
+
this.leases.delete(taskId);
|
|
67
|
+
this.persist();
|
|
68
|
+
return entry;
|
|
69
|
+
}
|
|
70
|
+
queryLease(taskId, filePath) {
|
|
71
|
+
this.ensureLoaded();
|
|
72
|
+
const resolved = path.resolve(filePath);
|
|
73
|
+
for (const [ownerId, entry] of this.leases) {
|
|
74
|
+
if (ownerId === taskId)
|
|
75
|
+
continue;
|
|
76
|
+
for (const leased of entry.file_paths) {
|
|
77
|
+
if (leased === resolved || isParentPath(leased, resolved)) {
|
|
78
|
+
return {
|
|
79
|
+
file_path: resolved,
|
|
80
|
+
leased_by: ownerId,
|
|
81
|
+
lease_acquired_at: entry.acquired_at,
|
|
82
|
+
severity: "advisory",
|
|
83
|
+
message: `advisory: file is in scope of task ${ownerId} (leased since ${entry.acquired_at})`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
getActiveLeases() {
|
|
91
|
+
this.ensureLoaded();
|
|
92
|
+
return [...this.leases.values()];
|
|
93
|
+
}
|
|
94
|
+
getLeaseForTask(taskId) {
|
|
95
|
+
this.ensureLoaded();
|
|
96
|
+
return this.leases.get(taskId) ?? null;
|
|
97
|
+
}
|
|
98
|
+
getSummary() {
|
|
99
|
+
this.ensureLoaded();
|
|
100
|
+
const leasedByTask = {};
|
|
101
|
+
let totalFiles = 0;
|
|
102
|
+
for (const [taskId, entry] of this.leases) {
|
|
103
|
+
leasedByTask[taskId] = [...entry.file_paths];
|
|
104
|
+
totalFiles += entry.file_paths.length;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
active_leases: this.leases.size,
|
|
108
|
+
total_files_leased: totalFiles,
|
|
109
|
+
leased_by_task: leasedByTask,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
clear() {
|
|
113
|
+
this.leases.clear();
|
|
114
|
+
this.loaded = true;
|
|
115
|
+
this.persist();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function isParentPath(parent, child) {
|
|
119
|
+
const rel = path.relative(parent, child);
|
|
120
|
+
return rel.length > 0 && !rel.startsWith("..");
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=scope_lease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope_lease.js","sourceRoot":"","sources":["../../src/engine/scope_lease.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 语义交付证据 — R9 需求→语义 diff→断言→变异证据链。
|
|
3
|
+
* CAP-011 advisory: 不 hard block,只产出 advisory 报告。
|
|
4
|
+
*
|
|
5
|
+
* 职责:
|
|
6
|
+
* - computeSemanticEvidence: 从变更文件 + 需求点计算语义证据
|
|
7
|
+
* - buildDeliveryEvidenceChain: 从任务上下文构建完整交付证据链
|
|
8
|
+
*/
|
|
9
|
+
import type { TaskContext, RequirementPoint, SemanticEvidence, DeliveryEvidenceChain } from "../types.js";
|
|
10
|
+
/**
|
|
11
|
+
* 从任务上下文计算语义证据。
|
|
12
|
+
* 基于变更文件和需求点,推断变更行为和需求覆盖状态。
|
|
13
|
+
*/
|
|
14
|
+
export declare function computeSemanticEvidence(changedFiles: string[], requirementPoints: RequirementPoint[], acceptanceResults?: Array<{
|
|
15
|
+
id: string;
|
|
16
|
+
passed: boolean;
|
|
17
|
+
}>): SemanticEvidence;
|
|
18
|
+
/**
|
|
19
|
+
* 从任务上下文构建完整交付证据链。
|
|
20
|
+
* 聚合 expand 的需求点、verify 的语义证据、execution 的变更文件。
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildDeliveryEvidenceChain(taskContext: TaskContext): DeliveryEvidenceChain | null;
|
|
23
|
+
//# sourceMappingURL=semantic_evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic_evidence.d.ts","sourceRoot":"","sources":["../../src/engine/semantic_evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EAAE,EACtB,iBAAiB,EAAE,gBAAgB,EAAE,EACrC,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC,GACzD,gBAAgB,CA0ClB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,WAAW,GACvB,qBAAqB,GAAG,IAAI,CA8C9B"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 语义交付证据 — R9 需求→语义 diff→断言→变异证据链。
|
|
3
|
+
* CAP-011 advisory: 不 hard block,只产出 advisory 报告。
|
|
4
|
+
*
|
|
5
|
+
* 职责:
|
|
6
|
+
* - computeSemanticEvidence: 从变更文件 + 需求点计算语义证据
|
|
7
|
+
* - buildDeliveryEvidenceChain: 从任务上下文构建完整交付证据链
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 从任务上下文计算语义证据。
|
|
11
|
+
* 基于变更文件和需求点,推断变更行为和需求覆盖状态。
|
|
12
|
+
*/
|
|
13
|
+
export function computeSemanticEvidence(changedFiles, requirementPoints, acceptanceResults) {
|
|
14
|
+
const changedBehaviors = changedFiles.map((f) => {
|
|
15
|
+
const matchedReq = requirementPoints.find((rp) => rp.acceptance_test_ids?.some((tid) => f.toLowerCase().includes(tid.toLowerCase().replace(/[^a-z0-9]/g, ""))));
|
|
16
|
+
return {
|
|
17
|
+
file_path: f,
|
|
18
|
+
description: `modified: ${f}`,
|
|
19
|
+
requirement_point_id: matchedReq?.id,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
const requirementCoverage = requirementPoints.map((rp) => {
|
|
23
|
+
const hasMatchingFile = changedBehaviors.some((cb) => cb.requirement_point_id === rp.id);
|
|
24
|
+
const acceptancePassed = acceptanceResults?.filter((ar) => rp.acceptance_test_ids?.includes(ar.id));
|
|
25
|
+
const allAcceptancePassed = acceptancePassed
|
|
26
|
+
? acceptancePassed.length > 0 && acceptancePassed.every((a) => a.passed)
|
|
27
|
+
: false;
|
|
28
|
+
const covered = hasMatchingFile || allAcceptancePassed;
|
|
29
|
+
return {
|
|
30
|
+
requirement_point_id: rp.id,
|
|
31
|
+
covered,
|
|
32
|
+
evidence: covered
|
|
33
|
+
? hasMatchingFile
|
|
34
|
+
? "file change matched"
|
|
35
|
+
: "acceptance tests passed"
|
|
36
|
+
: "no matching evidence",
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
changed_behaviors: changedBehaviors,
|
|
41
|
+
unchanged_assertions: [],
|
|
42
|
+
requirement_coverage: requirementCoverage,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 从任务上下文构建完整交付证据链。
|
|
47
|
+
* 聚合 expand 的需求点、verify 的语义证据、execution 的变更文件。
|
|
48
|
+
*/
|
|
49
|
+
export function buildDeliveryEvidenceChain(taskContext) {
|
|
50
|
+
const requirementPoints = taskContext.expansion?.requirement_points ?? [];
|
|
51
|
+
const semanticEvidence = taskContext.verification?.semantic_evidence;
|
|
52
|
+
const changedFiles = taskContext.execution?.changed_files ?? [];
|
|
53
|
+
if (requirementPoints.length === 0 && changedFiles.length === 0) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const fileToRequirements = changedFiles.map((f) => ({
|
|
57
|
+
file_path: f,
|
|
58
|
+
requirement_point_ids: requirementPoints
|
|
59
|
+
.filter((rp) => semanticEvidence?.changed_behaviors.some((cb) => cb.file_path === f && cb.requirement_point_id === rp.id))
|
|
60
|
+
.map((rp) => rp.id),
|
|
61
|
+
}));
|
|
62
|
+
const uncoveredPoints = requirementPoints
|
|
63
|
+
.filter((rp) => {
|
|
64
|
+
const coverage = semanticEvidence?.requirement_coverage?.find((rc) => rc.requirement_point_id === rp.id);
|
|
65
|
+
return !coverage?.covered;
|
|
66
|
+
})
|
|
67
|
+
.map((rp) => rp.id);
|
|
68
|
+
return {
|
|
69
|
+
requirement_points: requirementPoints,
|
|
70
|
+
semantic_evidence: semanticEvidence ?? undefined,
|
|
71
|
+
file_to_requirements: fileToRequirements,
|
|
72
|
+
completeness: {
|
|
73
|
+
all_requirements_covered: uncoveredPoints.length === 0,
|
|
74
|
+
uncovered_points: uncoveredPoints,
|
|
75
|
+
advisory: uncoveredPoints.length > 0
|
|
76
|
+
? `advisory: ${uncoveredPoints.length} requirement point(s) not covered by evidence: ${uncoveredPoints.join(", ")}`
|
|
77
|
+
: "all requirement points covered",
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=semantic_evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic_evidence.js","sourceRoot":"","sources":["../../src/engine/semantic_evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,YAAsB,EACtB,iBAAqC,EACrC,iBAA0D;IAE1D,MAAM,gBAAgB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC9C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAC/C,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACnC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CACtE,CACF,CAAC;QACF,OAAO;YACL,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,aAAa,CAAC,EAAE;YAC7B,oBAAoB,EAAE,UAAU,EAAE,EAAE;SACrC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACvD,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAC3C,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,oBAAoB,KAAK,EAAE,CAAC,EAAE,CAC1C,CAAC;QACF,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CACxD,EAAE,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CACxC,CAAC;QACF,MAAM,mBAAmB,GAAG,gBAAgB;YAC1C,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YACxE,CAAC,CAAC,KAAK,CAAC;QAEV,MAAM,OAAO,GAAG,eAAe,IAAI,mBAAmB,CAAC;QACvD,OAAO;YACL,oBAAoB,EAAE,EAAE,CAAC,EAAE;YAC3B,OAAO;YACP,QAAQ,EAAE,OAAO;gBACf,CAAC,CAAC,eAAe;oBACf,CAAC,CAAC,qBAAqB;oBACvB,CAAC,CAAC,yBAAyB;gBAC7B,CAAC,CAAC,sBAAsB;SAC3B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,iBAAiB,EAAE,gBAAgB;QACnC,oBAAoB,EAAE,EAAE;QACxB,oBAAoB,EAAE,mBAAmB;KAC1C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,WAAwB;IAExB,MAAM,iBAAiB,GACrB,WAAW,CAAC,SAAS,EAAE,kBAAkB,IAAI,EAAE,CAAC;IAClD,MAAM,gBAAgB,GACpB,WAAW,CAAC,YAAY,EAAE,iBAAiB,CAAC;IAC9C,MAAM,YAAY,GAChB,WAAW,CAAC,SAAS,EAAE,aAAa,IAAI,EAAE,CAAC;IAE7C,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,kBAAkB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClD,SAAS,EAAE,CAAC;QACZ,qBAAqB,EAAE,iBAAiB;aACrC,MAAM,CACL,CAAC,EAAE,EAAE,EAAE,CACL,gBAAgB,EAAE,iBAAiB,CAAC,IAAI,CACtC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC,oBAAoB,KAAK,EAAE,CAAC,EAAE,CAChE,CACJ;aACA,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACtB,CAAC,CAAC,CAAC;IAEJ,MAAM,eAAe,GAAG,iBAAiB;SACtC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;QACb,MAAM,QAAQ,GAAG,gBAAgB,EAAE,oBAAoB,EAAE,IAAI,CAC3D,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,oBAAoB,KAAK,EAAE,CAAC,EAAE,CAC1C,CAAC;QACF,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC5B,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAEtB,OAAO;QACL,kBAAkB,EAAE,iBAAiB;QACrC,iBAAiB,EAAE,gBAAgB,IAAI,SAAS;QAChD,oBAAoB,EAAE,kBAAkB;QACxC,YAAY,EAAE;YACZ,wBAAwB,EAAE,eAAe,CAAC,MAAM,KAAK,CAAC;YACtD,gBAAgB,EAAE,eAAe;YACjC,QAAQ,EACN,eAAe,CAAC,MAAM,GAAG,CAAC;gBACxB,CAAC,CAAC,aAAa,eAAe,CAAC,MAAM,kDAAkD,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACnH,CAAC,CAAC,gCAAgC;SACvC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { TaskContext, ClassifyResult, ExpandResult, VerifyResult, FailureRecord, PlanResult, CodeReviewResult, DeliveryResult } from "../types.js";
|
|
2
|
+
import { AuditPool } from "./audit_pool.js";
|
|
3
|
+
import { DiffOwnershipStore } from "./diff_ownership_store.js";
|
|
4
|
+
import { ScopeLeaseStore } from "./scope_lease.js";
|
|
5
|
+
import { ConflictGate } from "./conflict_gate.js";
|
|
2
6
|
/**
|
|
3
7
|
* 任务上下文管理器 — 负责任务状态的创建、持久化、查询和生命周期管理。
|
|
4
8
|
* 状态文件存储在 stateDir 目录下,每个任务一个 JSON 文件。
|
|
@@ -6,9 +10,21 @@ import type { TaskContext, ClassifyResult, ExpandResult, VerifyResult, FailureRe
|
|
|
6
10
|
*/
|
|
7
11
|
export declare class TaskContextManager {
|
|
8
12
|
private stateDir;
|
|
13
|
+
private auditPool;
|
|
14
|
+
private diffOwnership;
|
|
15
|
+
private scopeLease;
|
|
16
|
+
private conflictGate;
|
|
9
17
|
constructor(stateDir: string);
|
|
10
18
|
/** 获取状态存储目录路径 */
|
|
11
19
|
getStateDir(): string;
|
|
20
|
+
/** 获取审计池实例 */
|
|
21
|
+
getAuditPool(): AuditPool;
|
|
22
|
+
/** 获取 Diff 归属追踪实例 */
|
|
23
|
+
getDiffOwnership(): DiffOwnershipStore;
|
|
24
|
+
/** 获取 Scope Lease 实例 */
|
|
25
|
+
getScopeLease(): ScopeLeaseStore;
|
|
26
|
+
/** 获取冲突合并门实例 */
|
|
27
|
+
getConflictGate(): ConflictGate;
|
|
12
28
|
/**
|
|
13
29
|
* 创建新任务上下文,生成唯一 ID 并持久化到磁盘。
|
|
14
30
|
* @param intent - 用户意图文本
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task_context.d.ts","sourceRoot":"","sources":["../../src/engine/task_context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAkD,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"task_context.d.ts","sourceRoot":"","sources":["../../src/engine/task_context.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,10 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import fss from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
|
+
import { AuditPool } from "./audit_pool.js";
|
|
6
|
+
import { DiffOwnershipStore } from "./diff_ownership_store.js";
|
|
7
|
+
import { ScopeLeaseStore } from "./scope_lease.js";
|
|
8
|
+
import { ConflictGate } from "./conflict_gate.js";
|
|
5
9
|
/**
|
|
6
10
|
* 任务上下文管理器 — 管理任务的完整生命周期状态持久化。
|
|
7
11
|
*
|
|
@@ -20,7 +24,7 @@ const MAX_TASKS = 100;
|
|
|
20
24
|
const MAX_REWORK = 3;
|
|
21
25
|
// 状态转换表: 定义每个状态允许的合法后继状态
|
|
22
26
|
const VALID_TRANSITIONS = {
|
|
23
|
-
classifying: ["expanding", "failed"],
|
|
27
|
+
classifying: ["expanding", "done", "failed"],
|
|
24
28
|
expanding: ["executing", "failed"],
|
|
25
29
|
executing: ["verifying", "retrying", "reworking", "failed"],
|
|
26
30
|
verifying: ["learning", "retrying", "reworking", "done", "failed"],
|
|
@@ -37,14 +41,38 @@ const VALID_TRANSITIONS = {
|
|
|
37
41
|
*/
|
|
38
42
|
export class TaskContextManager {
|
|
39
43
|
stateDir;
|
|
44
|
+
auditPool;
|
|
45
|
+
diffOwnership;
|
|
46
|
+
scopeLease;
|
|
47
|
+
conflictGate;
|
|
40
48
|
constructor(stateDir) {
|
|
41
49
|
this.stateDir = stateDir;
|
|
42
50
|
fss.mkdirSync(stateDir, { recursive: true });
|
|
51
|
+
this.auditPool = new AuditPool(stateDir);
|
|
52
|
+
this.diffOwnership = new DiffOwnershipStore(stateDir);
|
|
53
|
+
this.scopeLease = new ScopeLeaseStore(stateDir);
|
|
54
|
+
this.conflictGate = new ConflictGate(this.diffOwnership, this.scopeLease);
|
|
43
55
|
}
|
|
44
56
|
/** 获取状态存储目录路径 */
|
|
45
57
|
getStateDir() {
|
|
46
58
|
return this.stateDir;
|
|
47
59
|
}
|
|
60
|
+
/** 获取审计池实例 */
|
|
61
|
+
getAuditPool() {
|
|
62
|
+
return this.auditPool;
|
|
63
|
+
}
|
|
64
|
+
/** 获取 Diff 归属追踪实例 */
|
|
65
|
+
getDiffOwnership() {
|
|
66
|
+
return this.diffOwnership;
|
|
67
|
+
}
|
|
68
|
+
/** 获取 Scope Lease 实例 */
|
|
69
|
+
getScopeLease() {
|
|
70
|
+
return this.scopeLease;
|
|
71
|
+
}
|
|
72
|
+
/** 获取冲突合并门实例 */
|
|
73
|
+
getConflictGate() {
|
|
74
|
+
return this.conflictGate;
|
|
75
|
+
}
|
|
48
76
|
/**
|
|
49
77
|
* 创建新任务上下文,生成唯一 ID 并持久化到磁盘。
|
|
50
78
|
* @param intent - 用户意图文本
|
|
@@ -106,6 +134,29 @@ export class TaskContextManager {
|
|
|
106
134
|
}
|
|
107
135
|
ctx.status = status;
|
|
108
136
|
await this.save(ctx);
|
|
137
|
+
if (status === "executing") {
|
|
138
|
+
// CAP-011: Auto-capture baseline from expansion scope when entering executing
|
|
139
|
+
const scopePaths = ctx.expansion?.scope?.allowed_paths;
|
|
140
|
+
if (scopePaths && scopePaths.length > 0) {
|
|
141
|
+
this.diffOwnership.captureBaselineFromScope(taskId, scopePaths);
|
|
142
|
+
this.scopeLease.acquire(taskId, scopePaths);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (status === "done" || status === "failed") {
|
|
146
|
+
if (status === "done") {
|
|
147
|
+
this.auditPool.append({
|
|
148
|
+
task_id: ctx.task_id,
|
|
149
|
+
risk: (ctx.classification?.risk ?? "low"),
|
|
150
|
+
changed_files: ctx.execution?.changed_files ?? [],
|
|
151
|
+
evidence: ctx.classification?.strategy ?? "",
|
|
152
|
+
capability_refs: [],
|
|
153
|
+
created_at: new Date().toISOString(),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// CAP-011: Clean up diff ownership + scope lease for terminal states
|
|
157
|
+
this.diffOwnership.clearTask(taskId);
|
|
158
|
+
this.scopeLease.release(taskId);
|
|
159
|
+
}
|
|
109
160
|
return ctx;
|
|
110
161
|
}
|
|
111
162
|
/**
|
|
@@ -163,6 +214,10 @@ export class TaskContextManager {
|
|
|
163
214
|
ctx.execution.attempt_count++;
|
|
164
215
|
ctx.execution.failure_history.push(failure);
|
|
165
216
|
}
|
|
217
|
+
// CAP-011: Record task-owned writes for diff ownership tracking (advisory)
|
|
218
|
+
for (const f of changedFiles) {
|
|
219
|
+
this.diffOwnership.recordWrite(taskId, f);
|
|
220
|
+
}
|
|
166
221
|
await this.save(ctx);
|
|
167
222
|
return ctx;
|
|
168
223
|
}
|
|
@@ -207,6 +262,9 @@ export class TaskContextManager {
|
|
|
207
262
|
return false;
|
|
208
263
|
ctx.status = "failed";
|
|
209
264
|
await this.save(ctx);
|
|
265
|
+
// CAP-011: Clean up diff ownership + scope lease for cancelled task
|
|
266
|
+
this.diffOwnership.clearTask(taskId);
|
|
267
|
+
this.scopeLease.release(taskId);
|
|
210
268
|
return true;
|
|
211
269
|
}
|
|
212
270
|
/**
|