soloforge 1.2.2 → 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.
Files changed (156) hide show
  1. package/README.md +78 -18
  2. package/dist/adapters/claude_code/tools.d.ts.map +1 -1
  3. package/dist/adapters/claude_code/tools.js +319 -5
  4. package/dist/adapters/claude_code/tools.js.map +1 -1
  5. package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
  6. package/dist/adapters/shared/workflow_template.js +25 -0
  7. package/dist/adapters/shared/workflow_template.js.map +1 -1
  8. package/dist/bin/soloforge.js +169 -13
  9. package/dist/bin/soloforge.js.map +1 -1
  10. package/dist/engine/audit_pool.d.ts +36 -0
  11. package/dist/engine/audit_pool.d.ts.map +1 -0
  12. package/dist/engine/audit_pool.js +83 -0
  13. package/dist/engine/audit_pool.js.map +1 -0
  14. package/dist/engine/audit_sampler.d.ts +15 -0
  15. package/dist/engine/audit_sampler.d.ts.map +1 -0
  16. package/dist/engine/audit_sampler.js +26 -0
  17. package/dist/engine/audit_sampler.js.map +1 -0
  18. package/dist/engine/capability_action_advisor.d.ts +24 -0
  19. package/dist/engine/capability_action_advisor.d.ts.map +1 -0
  20. package/dist/engine/capability_action_advisor.js +147 -0
  21. package/dist/engine/capability_action_advisor.js.map +1 -0
  22. package/dist/engine/capability_registry.d.ts +23 -1
  23. package/dist/engine/capability_registry.d.ts.map +1 -1
  24. package/dist/engine/capability_registry.js +511 -19
  25. package/dist/engine/capability_registry.js.map +1 -1
  26. package/dist/engine/capability_state_store.d.ts +50 -0
  27. package/dist/engine/capability_state_store.d.ts.map +1 -0
  28. package/dist/engine/capability_state_store.js +123 -0
  29. package/dist/engine/capability_state_store.js.map +1 -0
  30. package/dist/engine/cognitive_anchor.d.ts +59 -0
  31. package/dist/engine/cognitive_anchor.d.ts.map +1 -0
  32. package/dist/engine/cognitive_anchor.js +68 -0
  33. package/dist/engine/cognitive_anchor.js.map +1 -0
  34. package/dist/engine/conflict_gate.d.ts +36 -0
  35. package/dist/engine/conflict_gate.d.ts.map +1 -0
  36. package/dist/engine/conflict_gate.js +73 -0
  37. package/dist/engine/conflict_gate.js.map +1 -0
  38. package/dist/engine/decision_contract.d.ts +29 -0
  39. package/dist/engine/decision_contract.d.ts.map +1 -0
  40. package/dist/engine/decision_contract.js +41 -0
  41. package/dist/engine/decision_contract.js.map +1 -0
  42. package/dist/engine/delivery.d.ts.map +1 -1
  43. package/dist/engine/delivery.js +83 -0
  44. package/dist/engine/delivery.js.map +1 -1
  45. package/dist/engine/developer_sovereignty.d.ts +62 -0
  46. package/dist/engine/developer_sovereignty.d.ts.map +1 -0
  47. package/dist/engine/developer_sovereignty.js +134 -0
  48. package/dist/engine/developer_sovereignty.js.map +1 -0
  49. package/dist/engine/diff_ownership.d.ts +74 -0
  50. package/dist/engine/diff_ownership.d.ts.map +1 -0
  51. package/dist/engine/diff_ownership.js +143 -0
  52. package/dist/engine/diff_ownership.js.map +1 -0
  53. package/dist/engine/diff_ownership_store.d.ts +76 -0
  54. package/dist/engine/diff_ownership_store.d.ts.map +1 -0
  55. package/dist/engine/diff_ownership_store.js +264 -0
  56. package/dist/engine/diff_ownership_store.js.map +1 -0
  57. package/dist/engine/escape_report.d.ts +45 -0
  58. package/dist/engine/escape_report.d.ts.map +1 -0
  59. package/dist/engine/escape_report.js +97 -0
  60. package/dist/engine/escape_report.js.map +1 -0
  61. package/dist/engine/exploration.d.ts +54 -0
  62. package/dist/engine/exploration.d.ts.map +1 -1
  63. package/dist/engine/exploration.js +138 -0
  64. package/dist/engine/exploration.js.map +1 -1
  65. package/dist/engine/governance_report.d.ts +36 -0
  66. package/dist/engine/governance_report.d.ts.map +1 -0
  67. package/dist/engine/governance_report.js +79 -0
  68. package/dist/engine/governance_report.js.map +1 -0
  69. package/dist/engine/java_quality_guard.d.ts +52 -0
  70. package/dist/engine/java_quality_guard.d.ts.map +1 -0
  71. package/dist/engine/java_quality_guard.js +237 -0
  72. package/dist/engine/java_quality_guard.js.map +1 -0
  73. package/dist/engine/job_manager.d.ts +76 -0
  74. package/dist/engine/job_manager.d.ts.map +1 -0
  75. package/dist/engine/job_manager.js +225 -0
  76. package/dist/engine/job_manager.js.map +1 -0
  77. package/dist/engine/knowledge_sovereignty.d.ts +61 -0
  78. package/dist/engine/knowledge_sovereignty.d.ts.map +1 -0
  79. package/dist/engine/knowledge_sovereignty.js +190 -0
  80. package/dist/engine/knowledge_sovereignty.js.map +1 -0
  81. package/dist/engine/mutation_audit.d.ts +43 -0
  82. package/dist/engine/mutation_audit.d.ts.map +1 -0
  83. package/dist/engine/mutation_audit.js +118 -0
  84. package/dist/engine/mutation_audit.js.map +1 -0
  85. package/dist/engine/policy_drift_detector.d.ts +46 -0
  86. package/dist/engine/policy_drift_detector.d.ts.map +1 -0
  87. package/dist/engine/policy_drift_detector.js +181 -0
  88. package/dist/engine/policy_drift_detector.js.map +1 -0
  89. package/dist/engine/regression_matrix.d.ts +102 -0
  90. package/dist/engine/regression_matrix.d.ts.map +1 -0
  91. package/dist/engine/regression_matrix.js +380 -0
  92. package/dist/engine/regression_matrix.js.map +1 -0
  93. package/dist/engine/risk_sampler.d.ts +37 -0
  94. package/dist/engine/risk_sampler.d.ts.map +1 -0
  95. package/dist/engine/risk_sampler.js +69 -0
  96. package/dist/engine/risk_sampler.js.map +1 -0
  97. package/dist/engine/runtime_safety.d.ts +80 -0
  98. package/dist/engine/runtime_safety.d.ts.map +1 -0
  99. package/dist/engine/runtime_safety.js +195 -0
  100. package/dist/engine/runtime_safety.js.map +1 -0
  101. package/dist/engine/scope_lease.d.ts +45 -0
  102. package/dist/engine/scope_lease.d.ts.map +1 -0
  103. package/dist/engine/scope_lease.js +122 -0
  104. package/dist/engine/scope_lease.js.map +1 -0
  105. package/dist/engine/semantic_evidence.d.ts +23 -0
  106. package/dist/engine/semantic_evidence.d.ts.map +1 -0
  107. package/dist/engine/semantic_evidence.js +81 -0
  108. package/dist/engine/semantic_evidence.js.map +1 -0
  109. package/dist/engine/task_context.d.ts +16 -0
  110. package/dist/engine/task_context.d.ts.map +1 -1
  111. package/dist/engine/task_context.js +58 -0
  112. package/dist/engine/task_context.js.map +1 -1
  113. package/dist/engine/verifier.d.ts.map +1 -1
  114. package/dist/engine/verifier.js +22 -1
  115. package/dist/engine/verifier.js.map +1 -1
  116. package/dist/engine/workspace_resumer.d.ts +43 -0
  117. package/dist/engine/workspace_resumer.d.ts.map +1 -1
  118. package/dist/engine/workspace_resumer.js +119 -4
  119. package/dist/engine/workspace_resumer.js.map +1 -1
  120. package/dist/engine/zero_config_init.d.ts +87 -0
  121. package/dist/engine/zero_config_init.d.ts.map +1 -0
  122. package/dist/engine/zero_config_init.js +427 -0
  123. package/dist/engine/zero_config_init.js.map +1 -0
  124. package/dist/knowledge/index_manager.d.ts +19 -0
  125. package/dist/knowledge/index_manager.d.ts.map +1 -1
  126. package/dist/knowledge/index_manager.js +31 -0
  127. package/dist/knowledge/index_manager.js.map +1 -1
  128. package/dist/knowledge/writer.d.ts.map +1 -1
  129. package/dist/knowledge/writer.js +1 -0
  130. package/dist/knowledge/writer.js.map +1 -1
  131. package/dist/types.d.ts +61 -1
  132. package/dist/types.d.ts.map +1 -1
  133. package/package.json +2 -2
  134. package/templates/knowledge/patterns/core/Diff/345/275/222/345/261/236/350/277/275/350/270/252.md +47 -0
  135. package/templates/knowledge/patterns/core/Java/350/264/250/351/207/217/351/227/250/347/246/201.md +46 -0
  136. package/templates/knowledge/patterns/core/LLM/351/242/204/347/256/227/347/275/221/345/205/263.md +46 -0
  137. 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
  138. package/templates/knowledge/patterns/core//344/273/273/345/212/241/347/256/241/347/220/206/345/231/250.md +47 -0
  139. 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
  140. package/templates/knowledge/patterns/core//344/275/234/347/224/250/345/237/237/347/247/237/347/272/246.md +47 -0
  141. package/templates/knowledge/patterns/core//345/206/262/347/252/201/351/227/250/347/246/201.md +47 -0
  142. package/templates/knowledge/patterns/core//345/206/263/347/255/226/347/275/221/345/205/263.md +30 -11
  143. package/templates/knowledge/patterns/core//345/217/230/345/274/202/345/256/241/350/256/241.md +20 -0
  144. package/templates/knowledge/patterns/core//345/233/236/345/275/222/347/237/251/351/230/265.md +46 -0
  145. 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
  146. package/templates/knowledge/patterns/core//345/267/245/344/275/234/345/214/272/345/224/244/351/206/222.md +46 -0
  147. package/templates/knowledge/patterns/core//345/271/266/345/217/221/351/224/201.md +29 -16
  148. package/templates/knowledge/patterns/core//345/274/200/345/217/221/350/200/205/345/256/252/346/263/225.md +20 -0
  149. 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
  150. 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
  151. package/templates/knowledge/patterns/core//346/265/201/345/274/217/345/277/203/350/267/263.md +20 -0
  152. package/templates/knowledge/patterns/core//347/237/245/350/257/206/344/270/273/346/235/203.md +20 -0
  153. package/templates/knowledge/patterns/core//350/257/255/344/271/211/350/257/201/346/215/256.md +47 -0
  154. package/templates/knowledge/patterns/core//350/277/220/350/241/214/345/256/211/345/205/250/345/214/205.md +50 -0
  155. 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
  156. 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,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":"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"}
@@ -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":"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"}
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
  *
@@ -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
  /**