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,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 能力状态覆盖存储 — 持久化人工确认的能力状态变更。
|
|
3
|
+
* P2-8 范围: 显式更新(dry_run + 证据校验 + 人工确认),不自动改状态。
|
|
4
|
+
* 存储: JSON 文件,原子写入,路径绑定 stateDir。
|
|
5
|
+
*/
|
|
6
|
+
import type { CapabilityState } from "./capability_registry.js";
|
|
7
|
+
import type { EscapeReport } from "./escape_report.js";
|
|
8
|
+
export interface StateOverride {
|
|
9
|
+
policy_id: string;
|
|
10
|
+
previous_state: CapabilityState;
|
|
11
|
+
new_state: CapabilityState;
|
|
12
|
+
reason: string;
|
|
13
|
+
evidence_ids: string[];
|
|
14
|
+
confirmed_by: string;
|
|
15
|
+
updated_at: string;
|
|
16
|
+
}
|
|
17
|
+
export interface UpdateRequest {
|
|
18
|
+
policy_id: string;
|
|
19
|
+
target_state: CapabilityState;
|
|
20
|
+
reason: string;
|
|
21
|
+
evidence_ids: string[];
|
|
22
|
+
confirmed_by: string;
|
|
23
|
+
dry_run: boolean;
|
|
24
|
+
confirm: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface UpdateResult {
|
|
27
|
+
policy_id: string;
|
|
28
|
+
capability_id: string | null;
|
|
29
|
+
previous_state: CapabilityState;
|
|
30
|
+
new_state: CapabilityState;
|
|
31
|
+
updated: boolean;
|
|
32
|
+
dry_run: boolean;
|
|
33
|
+
validation_errors: string[];
|
|
34
|
+
evidence_matched: boolean;
|
|
35
|
+
override: StateOverride | null;
|
|
36
|
+
}
|
|
37
|
+
export declare class CapabilityStateStore {
|
|
38
|
+
private filePath;
|
|
39
|
+
private overrides;
|
|
40
|
+
private loaded;
|
|
41
|
+
constructor(stateDir: string);
|
|
42
|
+
private ensureLoaded;
|
|
43
|
+
private persist;
|
|
44
|
+
getEffectiveState(policyId: string, defaultState: CapabilityState): CapabilityState;
|
|
45
|
+
list(): StateOverride[];
|
|
46
|
+
validate(request: UpdateRequest, currentState: CapabilityState, capabilityId: string | null, escapeReports: EscapeReport[]): UpdateResult;
|
|
47
|
+
apply(request: UpdateRequest, currentState: CapabilityState, capabilityId: string | null, escapeReports: EscapeReport[]): UpdateResult;
|
|
48
|
+
clear(): void;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=capability_state_store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability_state_store.d.ts","sourceRoot":"","sources":["../../src/engine/capability_state_store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,eAAe,CAAC;IAChC,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,eAAe,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,eAAe,CAAC;IAChC,SAAS,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAChC;AASD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM;IAO5B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,OAAO;IAMf,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,GAAG,eAAe;IASnF,IAAI,IAAI,aAAa,EAAE;IAKvB,QAAQ,CACN,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,eAAe,EAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,aAAa,EAAE,YAAY,EAAE,GAC5B,YAAY;IAoEf,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,YAAY;IActI,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 能力状态覆盖存储 — 持久化人工确认的能力状态变更。
|
|
3
|
+
* P2-8 范围: 显式更新(dry_run + 证据校验 + 人工确认),不自动改状态。
|
|
4
|
+
* 存储: JSON 文件,原子写入,路径绑定 stateDir。
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
const VALID_TRANSITIONS = {
|
|
9
|
+
enforced: ["advisory", "removed"],
|
|
10
|
+
advisory: ["enforced", "experimental", "removed"],
|
|
11
|
+
experimental: ["advisory", "removed"],
|
|
12
|
+
removed: ["experimental"],
|
|
13
|
+
};
|
|
14
|
+
export class CapabilityStateStore {
|
|
15
|
+
filePath;
|
|
16
|
+
overrides = [];
|
|
17
|
+
loaded = false;
|
|
18
|
+
constructor(stateDir) {
|
|
19
|
+
this.filePath = path.join(stateDir, "capability-state-overrides.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
|
+
this.overrides = JSON.parse(data);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
this.overrides = [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
persist() {
|
|
37
|
+
const tmpPath = `${this.filePath}.tmp`;
|
|
38
|
+
fs.writeFileSync(tmpPath, JSON.stringify(this.overrides, null, 2));
|
|
39
|
+
fs.renameSync(tmpPath, this.filePath);
|
|
40
|
+
}
|
|
41
|
+
getEffectiveState(policyId, defaultState) {
|
|
42
|
+
this.ensureLoaded();
|
|
43
|
+
let latest;
|
|
44
|
+
for (const o of this.overrides) {
|
|
45
|
+
if (o.policy_id === policyId)
|
|
46
|
+
latest = o;
|
|
47
|
+
}
|
|
48
|
+
return latest ? latest.new_state : defaultState;
|
|
49
|
+
}
|
|
50
|
+
list() {
|
|
51
|
+
this.ensureLoaded();
|
|
52
|
+
return this.overrides.map((o) => ({ ...o, evidence_ids: [...o.evidence_ids] }));
|
|
53
|
+
}
|
|
54
|
+
validate(request, currentState, capabilityId, escapeReports) {
|
|
55
|
+
const errors = [];
|
|
56
|
+
if (!capabilityId) {
|
|
57
|
+
errors.push(`policy_id ${request.policy_id} not found in capability registry`);
|
|
58
|
+
}
|
|
59
|
+
if (request.target_state === currentState) {
|
|
60
|
+
errors.push(`target_state (${request.target_state}) same as current state, no change needed`);
|
|
61
|
+
}
|
|
62
|
+
if (capabilityId && request.target_state !== currentState) {
|
|
63
|
+
const allowed = VALID_TRANSITIONS[currentState];
|
|
64
|
+
if (!allowed.includes(request.target_state)) {
|
|
65
|
+
errors.push(`${currentState} → ${request.target_state} is not a valid transition (allowed: ${allowed.join(", ")})`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (request.evidence_ids.length === 0) {
|
|
69
|
+
errors.push("at least one evidence_id is required");
|
|
70
|
+
}
|
|
71
|
+
const matchedEvidence = request.evidence_ids.filter((eid) => escapeReports.some((r) => r.escape_id === eid && r.policy_id === request.policy_id));
|
|
72
|
+
const unmatchedEvidence = request.evidence_ids.filter((eid) => !matchedEvidence.includes(eid));
|
|
73
|
+
if (request.evidence_ids.length > 0 && unmatchedEvidence.length > 0) {
|
|
74
|
+
errors.push(`evidence_ids not found for policy ${request.policy_id}: ${unmatchedEvidence.join(", ")}`);
|
|
75
|
+
}
|
|
76
|
+
if (!request.confirm) {
|
|
77
|
+
errors.push("confirm=true required for state changes; human confirmation mandatory");
|
|
78
|
+
}
|
|
79
|
+
if (!request.confirmed_by.trim()) {
|
|
80
|
+
errors.push("confirmed_by is required");
|
|
81
|
+
}
|
|
82
|
+
if (!request.reason.trim()) {
|
|
83
|
+
errors.push("reason is required");
|
|
84
|
+
}
|
|
85
|
+
const evidenceMatched = matchedEvidence.length > 0;
|
|
86
|
+
const override = {
|
|
87
|
+
policy_id: request.policy_id,
|
|
88
|
+
previous_state: currentState,
|
|
89
|
+
new_state: request.target_state,
|
|
90
|
+
reason: request.reason,
|
|
91
|
+
evidence_ids: [...request.evidence_ids],
|
|
92
|
+
confirmed_by: request.confirmed_by,
|
|
93
|
+
updated_at: new Date().toISOString(),
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
policy_id: request.policy_id,
|
|
97
|
+
capability_id: capabilityId,
|
|
98
|
+
previous_state: currentState,
|
|
99
|
+
new_state: request.target_state,
|
|
100
|
+
updated: false,
|
|
101
|
+
dry_run: request.dry_run,
|
|
102
|
+
validation_errors: errors,
|
|
103
|
+
evidence_matched: evidenceMatched,
|
|
104
|
+
override: errors.length === 0 ? override : null,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
apply(request, currentState, capabilityId, escapeReports) {
|
|
108
|
+
this.ensureLoaded();
|
|
109
|
+
const result = this.validate(request, currentState, capabilityId, escapeReports);
|
|
110
|
+
if (result.validation_errors.length > 0 || request.dry_run || !result.override) {
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
this.overrides.push(result.override);
|
|
114
|
+
this.persist();
|
|
115
|
+
return { ...result, updated: true };
|
|
116
|
+
}
|
|
117
|
+
clear() {
|
|
118
|
+
this.overrides = [];
|
|
119
|
+
this.loaded = true;
|
|
120
|
+
this.persist();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=capability_state_store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability_state_store.js","sourceRoot":"","sources":["../../src/engine/capability_state_store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .map.json 认知锚点 — 结构化可追溯压缩。
|
|
3
|
+
* 备忘录要求: 每个锚点必须有 source_refs, confidence, last_verified_at。
|
|
4
|
+
* 自动生成的锚点默认 advisory,核心锚点更新需人工确认。
|
|
5
|
+
*/
|
|
6
|
+
export interface CognitiveMapAnchor {
|
|
7
|
+
/** 锚点 ID */
|
|
8
|
+
anchor_id: string;
|
|
9
|
+
/** 所属模块 */
|
|
10
|
+
module: string;
|
|
11
|
+
/** 核心契约列表 */
|
|
12
|
+
core_contracts: string[];
|
|
13
|
+
/** 已知副作用 */
|
|
14
|
+
side_effects: string[];
|
|
15
|
+
/** 不变量 */
|
|
16
|
+
invariants: string[];
|
|
17
|
+
/** 决策原因 */
|
|
18
|
+
decision_reasons: string[];
|
|
19
|
+
/** 风险标注 */
|
|
20
|
+
risk_notes: string[];
|
|
21
|
+
/** 证据引用: 文件/commit/task/diff/命令输出 */
|
|
22
|
+
source_refs: Array<{
|
|
23
|
+
type: "file" | "commit" | "task" | "diff" | "command_output" | "audit";
|
|
24
|
+
ref: string;
|
|
25
|
+
}>;
|
|
26
|
+
/** 置信度 */
|
|
27
|
+
confidence: "high" | "medium" | "low";
|
|
28
|
+
/** 上次验证时间 */
|
|
29
|
+
last_verified_at: string;
|
|
30
|
+
/** 是否过时 */
|
|
31
|
+
stale_anchor?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface MapJsonFile {
|
|
34
|
+
version: 1;
|
|
35
|
+
anchors: CognitiveMapAnchor[];
|
|
36
|
+
generated_at: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 写入 .map.json 文件。
|
|
40
|
+
*/
|
|
41
|
+
export declare function writeMapJson(filePath: string, anchors: CognitiveMapAnchor[]): void;
|
|
42
|
+
/**
|
|
43
|
+
* 读取 .map.json 文件。文件不存在时返回空锚点列表。
|
|
44
|
+
*/
|
|
45
|
+
export declare function readMapJson(filePath: string): MapJsonFile | null;
|
|
46
|
+
/**
|
|
47
|
+
* 检查锚点是否过时 — 与当前文件列表比对 source_refs。
|
|
48
|
+
* 文件不存在的 source_ref 标记 stale_anchor。
|
|
49
|
+
*/
|
|
50
|
+
export declare function checkAnchorStaleness(anchors: CognitiveMapAnchor[], existingFiles: Set<string>): CognitiveMapAnchor[];
|
|
51
|
+
/**
|
|
52
|
+
* 按相关性筛选锚点 — 根据模块名或文件路径前缀匹配。
|
|
53
|
+
* 不全量加载,避免污染上下文。
|
|
54
|
+
*/
|
|
55
|
+
export declare function filterRelevantAnchors(anchors: CognitiveMapAnchor[], query: {
|
|
56
|
+
module?: string;
|
|
57
|
+
file_path?: string;
|
|
58
|
+
}): CognitiveMapAnchor[];
|
|
59
|
+
//# sourceMappingURL=cognitive_anchor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cognitive_anchor.d.ts","sourceRoot":"","sources":["../../src/engine/cognitive_anchor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,kBAAkB;IACjC,YAAY;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,MAAM,EAAE,MAAM,CAAC;IACf,aAAa;IACb,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY;IACZ,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU;IACV,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW;IACX,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW;IACX,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qCAAqC;IACrC,WAAW,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,gBAAgB,GAAG,OAAO,CAAC;QACvE,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,UAAU;IACV,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,aAAa;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW;IACX,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAalF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAOhE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,kBAAkB,EAAE,EAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB,kBAAkB,EAAE,CAYtB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,EAAE,EAC7B,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,kBAAkB,EAAE,CAWtB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .map.json 认知锚点 — 结构化可追溯压缩。
|
|
3
|
+
* 备忘录要求: 每个锚点必须有 source_refs, confidence, last_verified_at。
|
|
4
|
+
* 自动生成的锚点默认 advisory,核心锚点更新需人工确认。
|
|
5
|
+
*/
|
|
6
|
+
import fss from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
/**
|
|
9
|
+
* 写入 .map.json 文件。
|
|
10
|
+
*/
|
|
11
|
+
export function writeMapJson(filePath, anchors) {
|
|
12
|
+
const dir = path.dirname(filePath);
|
|
13
|
+
fss.mkdirSync(dir, { recursive: true });
|
|
14
|
+
const data = {
|
|
15
|
+
version: 1,
|
|
16
|
+
anchors,
|
|
17
|
+
generated_at: new Date().toISOString(),
|
|
18
|
+
};
|
|
19
|
+
const tmpPath = `${filePath}.tmp`;
|
|
20
|
+
fss.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
|
|
21
|
+
fss.renameSync(tmpPath, filePath);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 读取 .map.json 文件。文件不存在时返回空锚点列表。
|
|
25
|
+
*/
|
|
26
|
+
export function readMapJson(filePath) {
|
|
27
|
+
if (!fss.existsSync(filePath))
|
|
28
|
+
return null;
|
|
29
|
+
try {
|
|
30
|
+
return JSON.parse(fss.readFileSync(filePath, "utf-8"));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 检查锚点是否过时 — 与当前文件列表比对 source_refs。
|
|
38
|
+
* 文件不存在的 source_ref 标记 stale_anchor。
|
|
39
|
+
*/
|
|
40
|
+
export function checkAnchorStaleness(anchors, existingFiles) {
|
|
41
|
+
for (const anchor of anchors) {
|
|
42
|
+
const hasMissing = anchor.source_refs.some((ref) => ref.type === "file" && !existingFiles.has(ref.ref));
|
|
43
|
+
if (hasMissing) {
|
|
44
|
+
anchor.stale_anchor = true;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
anchor.stale_anchor = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return anchors;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 按相关性筛选锚点 — 根据模块名或文件路径前缀匹配。
|
|
54
|
+
* 不全量加载,避免污染上下文。
|
|
55
|
+
*/
|
|
56
|
+
export function filterRelevantAnchors(anchors, query) {
|
|
57
|
+
return anchors.filter((anchor) => {
|
|
58
|
+
if (query.module && anchor.module === query.module)
|
|
59
|
+
return true;
|
|
60
|
+
if (query.file_path) {
|
|
61
|
+
const matchesRef = anchor.source_refs.some((ref) => ref.type === "file" && (query.file_path.startsWith(ref.ref) || ref.ref.startsWith(query.file_path)));
|
|
62
|
+
if (matchesRef)
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=cognitive_anchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cognitive_anchor.js","sourceRoot":"","sources":["../../src/engine/cognitive_anchor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,GAAG,MAAM,SAAS,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAoC7B;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,OAA6B;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,MAAM,IAAI,GAAgB;QACxB,OAAO,EAAE,CAAC;QACV,OAAO;QACP,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACvC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,QAAQ,MAAM,CAAC;IAClC,GAAG,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1D,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAgB,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAA6B,EAC7B,aAA0B;IAE1B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CACxC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAC5D,CAAC;QACF,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAA6B,EAC7B,KAA8C;IAE9C,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QAC/B,IAAI,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAChE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CACxC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,SAAU,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,SAAU,CAAC,CAAC,CAC/G,CAAC;YACF,IAAI,UAAU;gBAAE,OAAO,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 冲突合并门 — 统一 diff ownership CAS 冲突 + scope lease 冲突的 advisory 报告。
|
|
3
|
+
* CAP-011 实验性: advisory only, 不 hard block。
|
|
4
|
+
*
|
|
5
|
+
* 职责:
|
|
6
|
+
* - preWriteGate: 写前统一检查 CAS + Lease 冲突
|
|
7
|
+
* - 返回 ConflictGateResult 含所有冲突和建议操作
|
|
8
|
+
* - human_confirm: 标记人工确认(advisory, 可忽略)
|
|
9
|
+
*/
|
|
10
|
+
import type { DiffOwnershipStore, ConflictReport } from "./diff_ownership_store.js";
|
|
11
|
+
import type { ScopeLeaseStore, LeaseConflict } from "./scope_lease.js";
|
|
12
|
+
export type GateSeverity = "advisory";
|
|
13
|
+
export type RecommendedAction = "proceed" | "confirm_recommended" | "escalate";
|
|
14
|
+
export interface ConflictGateEntry {
|
|
15
|
+
source: "cas" | "lease";
|
|
16
|
+
severity: GateSeverity;
|
|
17
|
+
file_path: string;
|
|
18
|
+
message: string;
|
|
19
|
+
detail: ConflictReport | LeaseConflict;
|
|
20
|
+
}
|
|
21
|
+
export interface ConflictGateResult {
|
|
22
|
+
file_path: string;
|
|
23
|
+
has_conflict: boolean;
|
|
24
|
+
entries: ConflictGateEntry[];
|
|
25
|
+
recommended_action: RecommendedAction;
|
|
26
|
+
summary: string;
|
|
27
|
+
confirmed_at: string | null;
|
|
28
|
+
}
|
|
29
|
+
export declare class ConflictGate {
|
|
30
|
+
private diffOwnership;
|
|
31
|
+
private scopeLease;
|
|
32
|
+
constructor(diffOwnership: DiffOwnershipStore, scopeLease: ScopeLeaseStore);
|
|
33
|
+
preWriteGate(taskId: string, filePath: string): ConflictGateResult;
|
|
34
|
+
markConfirmed(result: ConflictGateResult): ConflictGateResult;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=conflict_gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict_gate.d.ts","sourceRoot":"","sources":["../../src/engine/conflict_gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC;AACtC,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,qBAAqB,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;IACxB,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,GAAG,aAAa,CAAC;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,UAAU,CAAkB;gBAExB,aAAa,EAAE,kBAAkB,EAAE,UAAU,EAAE,eAAe;IAK1E,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,kBAAkB;IA4ClE,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB;CAM9D"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 冲突合并门 — 统一 diff ownership CAS 冲突 + scope lease 冲突的 advisory 报告。
|
|
3
|
+
* CAP-011 实验性: advisory only, 不 hard block。
|
|
4
|
+
*
|
|
5
|
+
* 职责:
|
|
6
|
+
* - preWriteGate: 写前统一检查 CAS + Lease 冲突
|
|
7
|
+
* - 返回 ConflictGateResult 含所有冲突和建议操作
|
|
8
|
+
* - human_confirm: 标记人工确认(advisory, 可忽略)
|
|
9
|
+
*/
|
|
10
|
+
export class ConflictGate {
|
|
11
|
+
diffOwnership;
|
|
12
|
+
scopeLease;
|
|
13
|
+
constructor(diffOwnership, scopeLease) {
|
|
14
|
+
this.diffOwnership = diffOwnership;
|
|
15
|
+
this.scopeLease = scopeLease;
|
|
16
|
+
}
|
|
17
|
+
preWriteGate(taskId, filePath) {
|
|
18
|
+
const entries = [];
|
|
19
|
+
// CAS check
|
|
20
|
+
const { cas, conflict } = this.diffOwnership.preWriteCheck(taskId, filePath);
|
|
21
|
+
if (conflict) {
|
|
22
|
+
entries.push({
|
|
23
|
+
source: "cas",
|
|
24
|
+
severity: "advisory",
|
|
25
|
+
file_path: filePath,
|
|
26
|
+
message: conflict.message,
|
|
27
|
+
detail: conflict,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
// Lease check
|
|
31
|
+
const leaseConflict = this.scopeLease.queryLease(taskId, filePath);
|
|
32
|
+
if (leaseConflict) {
|
|
33
|
+
entries.push({
|
|
34
|
+
source: "lease",
|
|
35
|
+
severity: "advisory",
|
|
36
|
+
file_path: filePath,
|
|
37
|
+
message: leaseConflict.message,
|
|
38
|
+
detail: leaseConflict,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const hasConflict = entries.length > 0;
|
|
42
|
+
const recommendedAction = inferRecommendedAction(entries);
|
|
43
|
+
const summary = hasConflict
|
|
44
|
+
? entries.map(e => `[${e.source}] ${e.message}`).join("; ")
|
|
45
|
+
: "no conflicts";
|
|
46
|
+
return {
|
|
47
|
+
file_path: filePath,
|
|
48
|
+
has_conflict: hasConflict,
|
|
49
|
+
entries,
|
|
50
|
+
recommended_action: recommendedAction,
|
|
51
|
+
summary,
|
|
52
|
+
confirmed_at: null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
markConfirmed(result) {
|
|
56
|
+
return {
|
|
57
|
+
...result,
|
|
58
|
+
confirmed_at: new Date().toISOString(),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function inferRecommendedAction(entries) {
|
|
63
|
+
if (entries.length === 0)
|
|
64
|
+
return "proceed";
|
|
65
|
+
const hasCas = entries.some(e => e.source === "cas");
|
|
66
|
+
const hasLease = entries.some(e => e.source === "lease");
|
|
67
|
+
if (hasCas && hasLease)
|
|
68
|
+
return "escalate";
|
|
69
|
+
if (hasCas)
|
|
70
|
+
return "confirm_recommended";
|
|
71
|
+
return "confirm_recommended";
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=conflict_gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict_gate.js","sourceRoot":"","sources":["../../src/engine/conflict_gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH,MAAM,OAAO,YAAY;IACf,aAAa,CAAqB;IAClC,UAAU,CAAkB;IAEpC,YAAY,aAAiC,EAAE,UAA2B;QACxE,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,YAAY,CAAC,MAAc,EAAE,QAAgB;QAC3C,MAAM,OAAO,GAAwB,EAAE,CAAC;QAExC,YAAY;QACZ,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7E,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,QAAQ;gBACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,MAAM,EAAE,QAAQ;aACjB,CAAC,CAAC;QACL,CAAC;QAED,cAAc;QACd,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnE,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,QAAQ;gBACnB,OAAO,EAAE,aAAa,CAAC,OAAO;gBAC9B,MAAM,EAAE,aAAa;aACtB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACvC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAE1D,MAAM,OAAO,GAAG,WAAW;YACzB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC3D,CAAC,CAAC,cAAc,CAAC;QAEnB,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,YAAY,EAAE,WAAW;YACzB,OAAO;YACP,kBAAkB,EAAE,iBAAiB;YACrC,OAAO;YACP,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,MAA0B;QACtC,OAAO;YACL,GAAG,MAAM;YACT,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAC;IACJ,CAAC;CACF;AAED,SAAS,sBAAsB,CAAC,OAA4B;IAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;IACzD,IAAI,MAAM,IAAI,QAAQ;QAAE,OAAO,UAAU,CAAC;IAC1C,IAAI,MAAM;QAAE,OAAO,qBAAqB,CAAC;IACzC,OAAO,qBAAqB,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认决策输出契约 — advisory 状态。
|
|
3
|
+
* 校验 sf_expand / sf_review / sf_analyze / sf_explore 的输出是否包含
|
|
4
|
+
* 备忘录要求的 10 个决策字段。不 hard block,只出 advisory 告警。
|
|
5
|
+
*/
|
|
6
|
+
export declare const DECISION_FIELDS: readonly ["recommended_option", "why_this", "rejected_options", "steelman_alternatives", "attack_recommended_option", "falsification_tests", "execution_plan", "verification_plan", "rollback_plan", "human_confirmation_required"];
|
|
7
|
+
export type DecisionField = (typeof DECISION_FIELDS)[number];
|
|
8
|
+
export interface DecisionContractResult {
|
|
9
|
+
/** 是否通过契约校验(advisory) */
|
|
10
|
+
passed: boolean;
|
|
11
|
+
/** 缺失字段列表 */
|
|
12
|
+
missing_fields: DecisionField[];
|
|
13
|
+
/** 当前覆盖率 */
|
|
14
|
+
coverage: number;
|
|
15
|
+
/** advisory 消息 */
|
|
16
|
+
advisory: string;
|
|
17
|
+
/** 各字段存在状态 */
|
|
18
|
+
field_status: Array<{
|
|
19
|
+
field: DecisionField;
|
|
20
|
+
present: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 校验决策输出是否满足契约。
|
|
25
|
+
* 输入为任意对象,检查其顶层键是否覆盖 DECISION_FIELDS。
|
|
26
|
+
* advisory: 不 hard block,missing_fields 仅为建议。
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateDecisionOutput(output: Record<string, unknown>): DecisionContractResult;
|
|
29
|
+
//# sourceMappingURL=decision_contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision_contract.d.ts","sourceRoot":"","sources":["../../src/engine/decision_contract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,eAAe,qOAWlB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,sBAAsB;IACrC,yBAAyB;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa;IACb,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,YAAY;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc;IACd,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,aAAa,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,sBAAsB,CAmB9F"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 默认决策输出契约 — advisory 状态。
|
|
3
|
+
* 校验 sf_expand / sf_review / sf_analyze / sf_explore 的输出是否包含
|
|
4
|
+
* 备忘录要求的 10 个决策字段。不 hard block,只出 advisory 告警。
|
|
5
|
+
*/
|
|
6
|
+
export const DECISION_FIELDS = [
|
|
7
|
+
"recommended_option",
|
|
8
|
+
"why_this",
|
|
9
|
+
"rejected_options",
|
|
10
|
+
"steelman_alternatives",
|
|
11
|
+
"attack_recommended_option",
|
|
12
|
+
"falsification_tests",
|
|
13
|
+
"execution_plan",
|
|
14
|
+
"verification_plan",
|
|
15
|
+
"rollback_plan",
|
|
16
|
+
"human_confirmation_required",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* 校验决策输出是否满足契约。
|
|
20
|
+
* 输入为任意对象,检查其顶层键是否覆盖 DECISION_FIELDS。
|
|
21
|
+
* advisory: 不 hard block,missing_fields 仅为建议。
|
|
22
|
+
*/
|
|
23
|
+
export function validateDecisionOutput(output) {
|
|
24
|
+
const fieldStatus = DECISION_FIELDS.map((field) => ({
|
|
25
|
+
field,
|
|
26
|
+
present: field in output && output[field] != null && output[field] !== "",
|
|
27
|
+
}));
|
|
28
|
+
const presentCount = fieldStatus.filter((f) => f.present).length;
|
|
29
|
+
const missing = fieldStatus.filter((f) => !f.present).map((f) => f.field);
|
|
30
|
+
const coverage = presentCount / DECISION_FIELDS.length;
|
|
31
|
+
return {
|
|
32
|
+
passed: missing.length === 0,
|
|
33
|
+
missing_fields: missing,
|
|
34
|
+
coverage,
|
|
35
|
+
advisory: missing.length === 0
|
|
36
|
+
? `决策输出契约完整 (${presentCount}/${DECISION_FIELDS.length})`
|
|
37
|
+
: `advisory: 决策输出缺少 ${missing.length} 个字段 (${missing.join(", ")})`,
|
|
38
|
+
field_status: fieldStatus,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=decision_contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision_contract.js","sourceRoot":"","sources":["../../src/engine/decision_contract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,oBAAoB;IACpB,UAAU;IACV,kBAAkB;IAClB,uBAAuB;IACvB,2BAA2B;IAC3B,qBAAqB;IACrB,gBAAgB;IAChB,mBAAmB;IACnB,eAAe;IACf,6BAA6B;CACrB,CAAC;AAiBX;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA+B;IACpE,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClD,KAAK;QACL,OAAO,EAAE,KAAK,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;KAC1E,CAAC,CAAC,CAAC;IAEJ,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAG,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC;IAEvD,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAC5B,cAAc,EAAE,OAAO;QACvB,QAAQ;QACR,QAAQ,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;YAC5B,CAAC,CAAC,aAAa,YAAY,IAAI,eAAe,CAAC,MAAM,GAAG;YACxD,CAAC,CAAC,oBAAoB,OAAO,CAAC,MAAM,SAAS,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACpE,YAAY,EAAE,WAAW;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/engine/delivery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EAEb,cAAc,EAEd,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"delivery.d.ts","sourceRoot":"","sources":["../../src/engine/delivery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,aAAa,EAEb,cAAc,EAEd,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAKnD;;;;GAIG;AAIH;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,cAAc,EAAE,qBAAqB,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAwP3E;AAcD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,WAAW,GAAG,cAAc,CAmB/E"}
|
package/dist/engine/delivery.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import YAML from "yaml";
|
|
2
|
+
import { buildDeliveryEvidenceChain } from "./semantic_evidence.js";
|
|
3
|
+
import { classifyCommand, checkSupplyChain } from "./runtime_safety.js";
|
|
4
|
+
import { preDeliveryReview } from "./developer_sovereignty.js";
|
|
2
5
|
/**
|
|
3
6
|
* 执行完整的交付流程:提交代码、推送到远程、生成 PR 命令和变更日志。
|
|
4
7
|
* 流程按顺序执行,每一步失败后记录错误并继续后续步骤。
|
|
@@ -28,6 +31,79 @@ export async function deliver(input) {
|
|
|
28
31
|
// 3. 根据任务信息构建变更日志条目和提交消息
|
|
29
32
|
const entry = generateChangelogEntry(taskContext);
|
|
30
33
|
result.commit_message = formatCommitMessage(entry);
|
|
34
|
+
// 3.5. R12: 运行安全包 — 命令分级 advisory(不 hard block)
|
|
35
|
+
const safetyAdvisories = [];
|
|
36
|
+
// 检查验证命令是否有 destructive 级别
|
|
37
|
+
const verifyCommands = taskContext.verification?.checks
|
|
38
|
+
? [
|
|
39
|
+
...taskContext.verification.checks.build,
|
|
40
|
+
...taskContext.verification.checks.tests,
|
|
41
|
+
]
|
|
42
|
+
: [];
|
|
43
|
+
for (const cmd of verifyCommands) {
|
|
44
|
+
const classified = classifyCommand(cmd.command);
|
|
45
|
+
if (classified.risk === "destructive") {
|
|
46
|
+
safetyAdvisories.push(`advisory: destructive verify command detected: ${cmd.command} — ${classified.advisory}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// 检查推送命令风险
|
|
50
|
+
const pushClassified = classifyCommand(`git push origin ${result.branch}`);
|
|
51
|
+
if (pushClassified.risk !== "read_only") {
|
|
52
|
+
safetyAdvisories.push(`advisory: push is ${pushClassified.risk} — ${pushClassified.advisory}`);
|
|
53
|
+
}
|
|
54
|
+
// 供应链检查: 依赖变更时调用 checkSupplyChain 检查 lockfile/integrity
|
|
55
|
+
const changedFiles = taskContext.execution?.changed_files ?? [];
|
|
56
|
+
const depFiles = changedFiles.filter((f) => f.endsWith("package.json") || f.endsWith("package-lock.json") ||
|
|
57
|
+
f.endsWith("pnpm-lock.yaml") || f.endsWith("yarn.lock") ||
|
|
58
|
+
f.endsWith("go.mod") || f.endsWith("go.sum") ||
|
|
59
|
+
f.endsWith("Cargo.toml") || f.endsWith("Cargo.lock"));
|
|
60
|
+
if (depFiles.length > 0) {
|
|
61
|
+
try {
|
|
62
|
+
// Use filesystem root dir listing for lockfile detection (not git status)
|
|
63
|
+
const fss = await import("node:fs");
|
|
64
|
+
const nodePath = await import("node:path");
|
|
65
|
+
const rootEntries = fss.readdirSync(projectPath);
|
|
66
|
+
const rootFiles = rootEntries.filter((e) => e.endsWith(".json") || e.endsWith(".yaml") || e.endsWith(".yarn") ||
|
|
67
|
+
e.endsWith(".lock") || e.endsWith(".sum") || e.endsWith(".toml"));
|
|
68
|
+
// Read package.json for dependency list if present
|
|
69
|
+
const fsAsync = await import("node:fs/promises");
|
|
70
|
+
const deps = [];
|
|
71
|
+
const pkgPath = nodePath.join(projectPath, "package.json");
|
|
72
|
+
try {
|
|
73
|
+
const pkg = JSON.parse(await fsAsync.readFile(pkgPath, "utf-8"));
|
|
74
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
75
|
+
for (const [name, version] of Object.entries(allDeps)) {
|
|
76
|
+
deps.push({ name, version: String(version) });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch { /* no package.json or parse error */ }
|
|
80
|
+
if (deps.length > 0) {
|
|
81
|
+
const scReport = checkSupplyChain(rootFiles, deps);
|
|
82
|
+
for (const check of scReport.checks) {
|
|
83
|
+
if (!check.has_lockfile) {
|
|
84
|
+
safetyAdvisories.push(`advisory: ${check.package_name}@${check.version} — no lockfile/integrity`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
safetyAdvisories.push("advisory: dependency files changed — recommend running supply chain check (sf_dependency_scan)");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
safetyAdvisories.push("advisory: dependency files changed — supply chain check failed");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (safetyAdvisories.length > 0) {
|
|
97
|
+
result.safety_advisories = safetyAdvisories;
|
|
98
|
+
}
|
|
99
|
+
// 3.6. R11: Developer Sovereignty — pre-delivery review(advisory, 不 hard block)
|
|
100
|
+
try {
|
|
101
|
+
const review = await preDeliveryReview(taskContext, gitOps, projectPath);
|
|
102
|
+
result.pre_delivery_review = review;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// review failure is advisory, don't block delivery
|
|
106
|
+
}
|
|
31
107
|
// 4. 执行 git commit(如果配置允许自动提交)
|
|
32
108
|
if (deliveryConfig.auto_commit) {
|
|
33
109
|
try {
|
|
@@ -55,6 +131,11 @@ export async function deliver(input) {
|
|
|
55
131
|
}
|
|
56
132
|
}
|
|
57
133
|
result.actions_performed.push("commit");
|
|
134
|
+
// Update rollback command in pre_delivery_review to point to this commit
|
|
135
|
+
if (result.pre_delivery_review && result.commit_hash) {
|
|
136
|
+
result.pre_delivery_review.rollback_command =
|
|
137
|
+
`git revert ${result.commit_hash} --no-edit`;
|
|
138
|
+
}
|
|
58
139
|
}
|
|
59
140
|
catch (e) {
|
|
60
141
|
result.errors.push(`提交失败: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -134,6 +215,8 @@ export async function deliver(input) {
|
|
|
134
215
|
// 7. 生成变更日志
|
|
135
216
|
result.changelog = formatChangelog(entry);
|
|
136
217
|
result.actions_performed.push("changelog");
|
|
218
|
+
// 8. R9: 构建语义交付证据链(advisory, 不 hard block)
|
|
219
|
+
result.evidence_chain = buildDeliveryEvidenceChain(taskContext) ?? undefined;
|
|
137
220
|
return result;
|
|
138
221
|
}
|
|
139
222
|
// ── Shell 转义辅助函数 ──
|