pm-orchestrator-runner 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +108 -0
- package/dist/cli/cli-interface.d.ts +150 -0
- package/dist/cli/cli-interface.d.ts.map +1 -0
- package/dist/cli/cli-interface.js +606 -0
- package/dist/cli/cli-interface.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +243 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/llm-sentinel.d.ts +15 -0
- package/dist/cli/llm-sentinel.d.ts.map +1 -0
- package/dist/cli/llm-sentinel.js +184 -0
- package/dist/cli/llm-sentinel.js.map +1 -0
- package/dist/config/configuration-manager.d.ts +149 -0
- package/dist/config/configuration-manager.d.ts.map +1 -0
- package/dist/config/configuration-manager.js +241 -0
- package/dist/config/configuration-manager.js.map +1 -0
- package/dist/continuation/continuation-control-manager.d.ts +154 -0
- package/dist/continuation/continuation-control-manager.d.ts.map +1 -0
- package/dist/continuation/continuation-control-manager.js +303 -0
- package/dist/continuation/continuation-control-manager.js.map +1 -0
- package/dist/core/runner-core.d.ts +474 -0
- package/dist/core/runner-core.d.ts.map +1 -0
- package/dist/core/runner-core.js +1311 -0
- package/dist/core/runner-core.js.map +1 -0
- package/dist/errors/error-codes.d.ts +105 -0
- package/dist/errors/error-codes.d.ts.map +1 -0
- package/dist/errors/error-codes.js +198 -0
- package/dist/errors/error-codes.js.map +1 -0
- package/dist/errors/runner-error.d.ts +14 -0
- package/dist/errors/runner-error.d.ts.map +1 -0
- package/dist/errors/runner-error.js +33 -0
- package/dist/errors/runner-error.js.map +1 -0
- package/dist/evidence/evidence-manager.d.ts +112 -0
- package/dist/evidence/evidence-manager.d.ts.map +1 -0
- package/dist/evidence/evidence-manager.js +337 -0
- package/dist/evidence/evidence-manager.js.map +1 -0
- package/dist/executor/claude-code-executor.d.ts +136 -0
- package/dist/executor/claude-code-executor.d.ts.map +1 -0
- package/dist/executor/claude-code-executor.js +643 -0
- package/dist/executor/claude-code-executor.js.map +1 -0
- package/dist/executor/deterministic-executor.d.ts +40 -0
- package/dist/executor/deterministic-executor.d.ts.map +1 -0
- package/dist/executor/deterministic-executor.js +269 -0
- package/dist/executor/deterministic-executor.js.map +1 -0
- package/dist/lifecycle/lifecycle-controller.d.ts +270 -0
- package/dist/lifecycle/lifecycle-controller.d.ts.map +1 -0
- package/dist/lifecycle/lifecycle-controller.js +596 -0
- package/dist/lifecycle/lifecycle-controller.js.map +1 -0
- package/dist/limits/resource-limit-manager.d.ts +200 -0
- package/dist/limits/resource-limit-manager.d.ts.map +1 -0
- package/dist/limits/resource-limit-manager.js +376 -0
- package/dist/limits/resource-limit-manager.js.map +1 -0
- package/dist/locks/lock-manager.d.ts +116 -0
- package/dist/locks/lock-manager.d.ts.map +1 -0
- package/dist/locks/lock-manager.js +306 -0
- package/dist/locks/lock-manager.js.map +1 -0
- package/dist/logging/index.d.ts +8 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +22 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/sensitive-data-masker.d.ts +90 -0
- package/dist/logging/sensitive-data-masker.d.ts.map +1 -0
- package/dist/logging/sensitive-data-masker.js +228 -0
- package/dist/logging/sensitive-data-masker.js.map +1 -0
- package/dist/logging/task-log-manager.d.ts +215 -0
- package/dist/logging/task-log-manager.d.ts.map +1 -0
- package/dist/logging/task-log-manager.js +743 -0
- package/dist/logging/task-log-manager.js.map +1 -0
- package/dist/mediation/fail-closed-runner.d.ts +131 -0
- package/dist/mediation/fail-closed-runner.d.ts.map +1 -0
- package/dist/mediation/fail-closed-runner.js +245 -0
- package/dist/mediation/fail-closed-runner.js.map +1 -0
- package/dist/mediation/llm-client-with-evidence.d.ts +123 -0
- package/dist/mediation/llm-client-with-evidence.d.ts.map +1 -0
- package/dist/mediation/llm-client-with-evidence.js +245 -0
- package/dist/mediation/llm-client-with-evidence.js.map +1 -0
- package/dist/mediation/llm-client.d.ts +102 -0
- package/dist/mediation/llm-client.d.ts.map +1 -0
- package/dist/mediation/llm-client.js +206 -0
- package/dist/mediation/llm-client.js.map +1 -0
- package/dist/mediation/llm-evidence-manager.d.ts +108 -0
- package/dist/mediation/llm-evidence-manager.d.ts.map +1 -0
- package/dist/mediation/llm-evidence-manager.js +230 -0
- package/dist/mediation/llm-evidence-manager.js.map +1 -0
- package/dist/mediation/llm-mediation-layer.d.ts +175 -0
- package/dist/mediation/llm-mediation-layer.d.ts.map +1 -0
- package/dist/mediation/llm-mediation-layer.js +315 -0
- package/dist/mediation/llm-mediation-layer.js.map +1 -0
- package/dist/mediation/llm-sentinel.d.ts +107 -0
- package/dist/mediation/llm-sentinel.d.ts.map +1 -0
- package/dist/mediation/llm-sentinel.js +187 -0
- package/dist/mediation/llm-sentinel.js.map +1 -0
- package/dist/mediation/real-llm-mediation-layer.d.ts +104 -0
- package/dist/mediation/real-llm-mediation-layer.d.ts.map +1 -0
- package/dist/mediation/real-llm-mediation-layer.js +322 -0
- package/dist/mediation/real-llm-mediation-layer.js.map +1 -0
- package/dist/mediation/verdict-reporter.d.ts +61 -0
- package/dist/mediation/verdict-reporter.d.ts.map +1 -0
- package/dist/mediation/verdict-reporter.js +178 -0
- package/dist/mediation/verdict-reporter.js.map +1 -0
- package/dist/models/enums.d.ts +133 -0
- package/dist/models/enums.d.ts.map +1 -0
- package/dist/models/enums.js +201 -0
- package/dist/models/enums.js.map +1 -0
- package/dist/models/evidence.d.ts +60 -0
- package/dist/models/evidence.d.ts.map +1 -0
- package/dist/models/evidence.js +135 -0
- package/dist/models/evidence.js.map +1 -0
- package/dist/models/execution-result.d.ts +89 -0
- package/dist/models/execution-result.d.ts.map +1 -0
- package/dist/models/execution-result.js +197 -0
- package/dist/models/execution-result.js.map +1 -0
- package/dist/models/file-lock.d.ts +62 -0
- package/dist/models/file-lock.d.ts.map +1 -0
- package/dist/models/file-lock.js +133 -0
- package/dist/models/file-lock.js.map +1 -0
- package/dist/models/index.d.ts +12 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +91 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/repl/index.d.ts +7 -0
- package/dist/models/repl/index.d.ts.map +1 -0
- package/dist/models/repl/index.js +32 -0
- package/dist/models/repl/index.js.map +1 -0
- package/dist/models/repl/model-registry.d.ts +73 -0
- package/dist/models/repl/model-registry.d.ts.map +1 -0
- package/dist/models/repl/model-registry.js +116 -0
- package/dist/models/repl/model-registry.js.map +1 -0
- package/dist/models/repl/repl-state.d.ts +86 -0
- package/dist/models/repl/repl-state.d.ts.map +1 -0
- package/dist/models/repl/repl-state.js +152 -0
- package/dist/models/repl/repl-state.js.map +1 -0
- package/dist/models/repl/task-log.d.ts +247 -0
- package/dist/models/repl/task-log.d.ts.map +1 -0
- package/dist/models/repl/task-log.js +178 -0
- package/dist/models/repl/task-log.js.map +1 -0
- package/dist/models/session.d.ts +71 -0
- package/dist/models/session.d.ts.map +1 -0
- package/dist/models/session.js +140 -0
- package/dist/models/session.js.map +1 -0
- package/dist/models/supporting.d.ts +97 -0
- package/dist/models/supporting.d.ts.map +1 -0
- package/dist/models/supporting.js +208 -0
- package/dist/models/supporting.js.map +1 -0
- package/dist/models/task.d.ts +77 -0
- package/dist/models/task.d.ts.map +1 -0
- package/dist/models/task.js +170 -0
- package/dist/models/task.js.map +1 -0
- package/dist/output/output-control-manager.d.ts +217 -0
- package/dist/output/output-control-manager.d.ts.map +1 -0
- package/dist/output/output-control-manager.js +378 -0
- package/dist/output/output-control-manager.js.map +1 -0
- package/dist/pool/agent-pool.d.ts +284 -0
- package/dist/pool/agent-pool.d.ts.map +1 -0
- package/dist/pool/agent-pool.js +451 -0
- package/dist/pool/agent-pool.js.map +1 -0
- package/dist/repl/commands/index.d.ts +12 -0
- package/dist/repl/commands/index.d.ts.map +1 -0
- package/dist/repl/commands/index.js +26 -0
- package/dist/repl/commands/index.js.map +1 -0
- package/dist/repl/commands/init.d.ts +31 -0
- package/dist/repl/commands/init.d.ts.map +1 -0
- package/dist/repl/commands/init.js +234 -0
- package/dist/repl/commands/init.js.map +1 -0
- package/dist/repl/commands/keys.d.ts +63 -0
- package/dist/repl/commands/keys.d.ts.map +1 -0
- package/dist/repl/commands/keys.js +114 -0
- package/dist/repl/commands/keys.js.map +1 -0
- package/dist/repl/commands/logs.d.ts +91 -0
- package/dist/repl/commands/logs.d.ts.map +1 -0
- package/dist/repl/commands/logs.js +200 -0
- package/dist/repl/commands/logs.js.map +1 -0
- package/dist/repl/commands/model.d.ts +85 -0
- package/dist/repl/commands/model.d.ts.map +1 -0
- package/dist/repl/commands/model.js +225 -0
- package/dist/repl/commands/model.js.map +1 -0
- package/dist/repl/commands/models.d.ts +50 -0
- package/dist/repl/commands/models.d.ts.map +1 -0
- package/dist/repl/commands/models.js +180 -0
- package/dist/repl/commands/models.js.map +1 -0
- package/dist/repl/commands/provider.d.ts +79 -0
- package/dist/repl/commands/provider.d.ts.map +1 -0
- package/dist/repl/commands/provider.js +291 -0
- package/dist/repl/commands/provider.js.map +1 -0
- package/dist/repl/commands/session.d.ts +50 -0
- package/dist/repl/commands/session.d.ts.map +1 -0
- package/dist/repl/commands/session.js +152 -0
- package/dist/repl/commands/session.js.map +1 -0
- package/dist/repl/commands/status.d.ts +55 -0
- package/dist/repl/commands/status.d.ts.map +1 -0
- package/dist/repl/commands/status.js +182 -0
- package/dist/repl/commands/status.js.map +1 -0
- package/dist/repl/index.d.ts +6 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/repl/index.js +25 -0
- package/dist/repl/index.js.map +1 -0
- package/dist/repl/repl-interface.d.ts +371 -0
- package/dist/repl/repl-interface.d.ts.map +1 -0
- package/dist/repl/repl-interface.js +1214 -0
- package/dist/repl/repl-interface.js.map +1 -0
- package/dist/session/session-manager.d.ts +85 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +217 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/supervisor/executor-supervisor.d.ts +90 -0
- package/dist/supervisor/executor-supervisor.d.ts.map +1 -0
- package/dist/supervisor/executor-supervisor.js +223 -0
- package/dist/supervisor/executor-supervisor.js.map +1 -0
- package/dist/supervisor/index.d.ts +5 -0
- package/dist/supervisor/index.d.ts.map +1 -0
- package/dist/supervisor/index.js +9 -0
- package/dist/supervisor/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Evidence Manager
|
|
4
|
+
* Based on 04_COMPONENTS.md L133-154
|
|
5
|
+
*
|
|
6
|
+
* Responsible for:
|
|
7
|
+
* - Evidence collection and storage
|
|
8
|
+
* - Hash verification
|
|
9
|
+
* - Evidence index management
|
|
10
|
+
* - Atomic evidence recording
|
|
11
|
+
* - Evidence inventory tracking
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.EvidenceManager = exports.EvidenceManagerError = void 0;
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const crypto = __importStar(require("crypto"));
|
|
51
|
+
const error_codes_1 = require("../errors/error-codes");
|
|
52
|
+
/**
|
|
53
|
+
* Evidence Manager Error
|
|
54
|
+
*/
|
|
55
|
+
class EvidenceManagerError extends Error {
|
|
56
|
+
code;
|
|
57
|
+
details;
|
|
58
|
+
constructor(code, message, details) {
|
|
59
|
+
super(message || (0, error_codes_1.getErrorMessage)(code));
|
|
60
|
+
this.name = 'EvidenceManagerError';
|
|
61
|
+
this.code = code;
|
|
62
|
+
this.details = details;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.EvidenceManagerError = EvidenceManagerError;
|
|
66
|
+
/**
|
|
67
|
+
* Evidence Manager class
|
|
68
|
+
*/
|
|
69
|
+
class EvidenceManager {
|
|
70
|
+
baseDir;
|
|
71
|
+
sessions;
|
|
72
|
+
/**
|
|
73
|
+
* Create a new EvidenceManager
|
|
74
|
+
* @param baseDir Base directory for evidence storage
|
|
75
|
+
*/
|
|
76
|
+
constructor(baseDir) {
|
|
77
|
+
this.baseDir = baseDir;
|
|
78
|
+
this.sessions = new Map();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Initialize evidence directory for a session
|
|
82
|
+
*/
|
|
83
|
+
initializeSession(sessionId) {
|
|
84
|
+
const sessionDir = path.join(this.baseDir, sessionId);
|
|
85
|
+
const rawLogsDir = path.join(sessionDir, 'raw_logs');
|
|
86
|
+
fs.mkdirSync(sessionDir, { recursive: true });
|
|
87
|
+
fs.mkdirSync(rawLogsDir, { recursive: true });
|
|
88
|
+
// Initialize session data
|
|
89
|
+
this.sessions.set(sessionId, {
|
|
90
|
+
evidenceMap: new Map(),
|
|
91
|
+
registeredOperations: new Set(),
|
|
92
|
+
operationToEvidence: new Map(),
|
|
93
|
+
integrityFailures: new Set(),
|
|
94
|
+
rawLogFiles: [],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Record evidence for a session
|
|
99
|
+
* @throws EvidenceManagerError with E301 if session not found or validation fails
|
|
100
|
+
*/
|
|
101
|
+
recordEvidence(sessionId, evidence) {
|
|
102
|
+
const sessionData = this.sessions.get(sessionId);
|
|
103
|
+
if (!sessionData) {
|
|
104
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E301_EVIDENCE_COLLECTION_FAILURE, `Session not initialized: ${sessionId}`, { sessionId });
|
|
105
|
+
}
|
|
106
|
+
// Check for atomic operation requirement (Property 18)
|
|
107
|
+
if (!evidence.atomic_operation) {
|
|
108
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E301_EVIDENCE_COLLECTION_FAILURE, 'Evidence must be from atomic operation (atomic_operation must be true)', { evidenceId: evidence.evidence_id });
|
|
109
|
+
}
|
|
110
|
+
// Reject aggregated evidence (Property 18)
|
|
111
|
+
if (evidence.aggregated === true) {
|
|
112
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E301_EVIDENCE_COLLECTION_FAILURE, 'Evidence aggregation is prohibited', { evidenceId: evidence.evidence_id });
|
|
113
|
+
}
|
|
114
|
+
// Store evidence
|
|
115
|
+
sessionData.evidenceMap.set(evidence.evidence_id, evidence);
|
|
116
|
+
// Associate with operation if operation_id provided
|
|
117
|
+
if (evidence.operation_id) {
|
|
118
|
+
sessionData.operationToEvidence.set(evidence.operation_id, evidence.evidence_id);
|
|
119
|
+
}
|
|
120
|
+
// Persist evidence to disk
|
|
121
|
+
const sessionDir = path.join(this.baseDir, sessionId);
|
|
122
|
+
const evidencePath = path.join(sessionDir, `${evidence.evidence_id}.json`);
|
|
123
|
+
fs.writeFileSync(evidencePath, JSON.stringify(evidence, null, 2), 'utf-8');
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get evidence by ID
|
|
127
|
+
* @throws EvidenceManagerError if evidence not found
|
|
128
|
+
*/
|
|
129
|
+
getEvidence(sessionId, evidenceId) {
|
|
130
|
+
const sessionData = this.sessions.get(sessionId);
|
|
131
|
+
if (!sessionData) {
|
|
132
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E301_EVIDENCE_COLLECTION_FAILURE, `Session not initialized: ${sessionId}`, { sessionId });
|
|
133
|
+
}
|
|
134
|
+
const evidence = sessionData.evidenceMap.get(evidenceId);
|
|
135
|
+
if (!evidence) {
|
|
136
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E301_EVIDENCE_COLLECTION_FAILURE, `Evidence not found: ${evidenceId}`, { sessionId, evidenceId });
|
|
137
|
+
}
|
|
138
|
+
return evidence;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* List all evidence for a session
|
|
142
|
+
*/
|
|
143
|
+
listEvidence(sessionId) {
|
|
144
|
+
const sessionData = this.sessions.get(sessionId);
|
|
145
|
+
if (!sessionData) {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
return Array.from(sessionData.evidenceMap.values());
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Verify evidence hash
|
|
152
|
+
* @throws EvidenceManagerError with E304 on hash mismatch
|
|
153
|
+
*/
|
|
154
|
+
verifyEvidence(sessionId, evidenceId) {
|
|
155
|
+
const sessionData = this.sessions.get(sessionId);
|
|
156
|
+
const evidence = this.getEvidence(sessionId, evidenceId);
|
|
157
|
+
// Calculate hash from artifacts content
|
|
158
|
+
const content = this.getEvidenceContent(evidence);
|
|
159
|
+
const calculatedHash = 'sha256:' + crypto.createHash('sha256').update(content).digest('hex');
|
|
160
|
+
if (calculatedHash !== evidence.hash) {
|
|
161
|
+
// Track integrity failure
|
|
162
|
+
sessionData?.integrityFailures.add(evidenceId);
|
|
163
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E304_EVIDENCE_HASH_MISMATCH, `Hash mismatch for evidence: ${evidenceId}`, { evidenceId, expectedHash: evidence.hash, calculatedHash });
|
|
164
|
+
}
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get content for hash calculation
|
|
169
|
+
*/
|
|
170
|
+
getEvidenceContent(evidence) {
|
|
171
|
+
if (evidence.artifacts.length === 0) {
|
|
172
|
+
return '';
|
|
173
|
+
}
|
|
174
|
+
// Concatenate artifact contents
|
|
175
|
+
return evidence.artifacts
|
|
176
|
+
.map((a) => a.content || '')
|
|
177
|
+
.join('');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Finalize session - create evidence_index.json and evidence_index.sha256
|
|
181
|
+
*/
|
|
182
|
+
finalizeSession(sessionId) {
|
|
183
|
+
const sessionData = this.sessions.get(sessionId);
|
|
184
|
+
if (!sessionData) {
|
|
185
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E301_EVIDENCE_COLLECTION_FAILURE, `Session not initialized: ${sessionId}`, { sessionId });
|
|
186
|
+
}
|
|
187
|
+
const sessionDir = path.join(this.baseDir, sessionId);
|
|
188
|
+
// Create evidence index
|
|
189
|
+
const evidenceItems = Array.from(sessionData.evidenceMap.values()).map(e => ({
|
|
190
|
+
evidence_id: e.evidence_id,
|
|
191
|
+
operation_type: e.operation_type,
|
|
192
|
+
timestamp: e.timestamp,
|
|
193
|
+
hash: e.hash,
|
|
194
|
+
}));
|
|
195
|
+
const index = {
|
|
196
|
+
session_id: sessionId,
|
|
197
|
+
created_at: new Date().toISOString(),
|
|
198
|
+
finalized_at: new Date().toISOString(),
|
|
199
|
+
evidence_items: evidenceItems,
|
|
200
|
+
total_items: evidenceItems.length,
|
|
201
|
+
};
|
|
202
|
+
// Write evidence_index.json
|
|
203
|
+
const indexPath = path.join(sessionDir, 'evidence_index.json');
|
|
204
|
+
const indexContent = JSON.stringify(index, null, 2);
|
|
205
|
+
fs.writeFileSync(indexPath, indexContent, 'utf-8');
|
|
206
|
+
// Write evidence_index.sha256 (hash of evidence_index.json ONLY - user clarification)
|
|
207
|
+
const indexHash = crypto.createHash('sha256').update(indexContent).digest('hex');
|
|
208
|
+
const sha256Path = path.join(sessionDir, 'evidence_index.sha256');
|
|
209
|
+
fs.writeFileSync(sha256Path, indexHash, 'utf-8');
|
|
210
|
+
// Create report.json
|
|
211
|
+
const reportPath = path.join(sessionDir, 'report.json');
|
|
212
|
+
const report = {
|
|
213
|
+
session_id: sessionId,
|
|
214
|
+
generated_at: new Date().toISOString(),
|
|
215
|
+
total_evidence_items: evidenceItems.length,
|
|
216
|
+
integrity_verified: sessionData.integrityFailures.size === 0,
|
|
217
|
+
summary: {
|
|
218
|
+
operations: evidenceItems.map(e => e.operation_type),
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf-8');
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Verify session integrity (check evidence_index.json hash)
|
|
225
|
+
* @throws EvidenceManagerError with E304 if tampered
|
|
226
|
+
*/
|
|
227
|
+
verifySessionIntegrity(sessionId) {
|
|
228
|
+
const sessionDir = path.join(this.baseDir, sessionId);
|
|
229
|
+
const indexPath = path.join(sessionDir, 'evidence_index.json');
|
|
230
|
+
const sha256Path = path.join(sessionDir, 'evidence_index.sha256');
|
|
231
|
+
if (!fs.existsSync(indexPath) || !fs.existsSync(sha256Path)) {
|
|
232
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E302_EVIDENCE_INDEX_CORRUPTION, 'Evidence index files missing', { sessionId });
|
|
233
|
+
}
|
|
234
|
+
const indexContent = fs.readFileSync(indexPath, 'utf-8');
|
|
235
|
+
const storedHash = fs.readFileSync(sha256Path, 'utf-8').trim();
|
|
236
|
+
const calculatedHash = crypto.createHash('sha256').update(indexContent).digest('hex');
|
|
237
|
+
if (storedHash !== calculatedHash) {
|
|
238
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E304_EVIDENCE_HASH_MISMATCH, 'Evidence index has been modified after finalization', { sessionId, expectedHash: storedHash, calculatedHash });
|
|
239
|
+
}
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Load evidence index from disk
|
|
244
|
+
* @throws EvidenceManagerError with E302 if corrupted
|
|
245
|
+
*/
|
|
246
|
+
loadEvidenceIndex(sessionId) {
|
|
247
|
+
const sessionDir = path.join(this.baseDir, sessionId);
|
|
248
|
+
const indexPath = path.join(sessionDir, 'evidence_index.json');
|
|
249
|
+
if (!fs.existsSync(indexPath)) {
|
|
250
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E302_EVIDENCE_INDEX_CORRUPTION, 'Evidence index not found', { sessionId });
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
const content = fs.readFileSync(indexPath, 'utf-8');
|
|
254
|
+
return JSON.parse(content);
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E302_EVIDENCE_INDEX_CORRUPTION, 'Evidence index is corrupted', { sessionId, error: error.message });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Store raw log for an executor
|
|
262
|
+
*/
|
|
263
|
+
storeRawLog(sessionId, executorId, content) {
|
|
264
|
+
const sessionData = this.sessions.get(sessionId);
|
|
265
|
+
const sessionDir = path.join(this.baseDir, sessionId);
|
|
266
|
+
const rawLogsDir = path.join(sessionDir, 'raw_logs');
|
|
267
|
+
// Ensure raw_logs directory exists
|
|
268
|
+
if (!fs.existsSync(rawLogsDir)) {
|
|
269
|
+
fs.mkdirSync(rawLogsDir, { recursive: true });
|
|
270
|
+
}
|
|
271
|
+
const timestamp = Date.now();
|
|
272
|
+
const logFileName = `${executorId}-${timestamp}.log`;
|
|
273
|
+
const logPath = path.join(rawLogsDir, logFileName);
|
|
274
|
+
fs.writeFileSync(logPath, content, 'utf-8');
|
|
275
|
+
// Track raw log file
|
|
276
|
+
if (sessionData) {
|
|
277
|
+
sessionData.rawLogFiles.push(logPath);
|
|
278
|
+
}
|
|
279
|
+
return logPath;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Verify raw logs exist
|
|
283
|
+
* @throws EvidenceManagerError with E303 if raw log missing
|
|
284
|
+
*/
|
|
285
|
+
verifyRawLogs(sessionId, evidenceId) {
|
|
286
|
+
const evidence = this.getEvidence(sessionId, evidenceId);
|
|
287
|
+
// Check main raw_logs path
|
|
288
|
+
if (evidence.raw_logs && !fs.existsSync(evidence.raw_logs)) {
|
|
289
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E303_RAW_LOG_MISSING, `Raw log file not found: ${evidence.raw_logs}`, { sessionId, evidenceId, rawLogs: evidence.raw_logs });
|
|
290
|
+
}
|
|
291
|
+
// Check raw_evidence_refs
|
|
292
|
+
for (const ref of evidence.raw_evidence_refs) {
|
|
293
|
+
if (!fs.existsSync(ref)) {
|
|
294
|
+
throw new EvidenceManagerError(error_codes_1.ErrorCode.E303_RAW_LOG_MISSING, `Raw evidence reference not found: ${ref}`, { sessionId, evidenceId, missingRef: ref });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Register an operation for evidence tracking
|
|
301
|
+
*/
|
|
302
|
+
registerOperation(sessionId, operationId) {
|
|
303
|
+
const sessionData = this.sessions.get(sessionId);
|
|
304
|
+
if (sessionData) {
|
|
305
|
+
sessionData.registeredOperations.add(operationId);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Get evidence inventory for a session
|
|
310
|
+
*/
|
|
311
|
+
getEvidenceInventory(sessionId) {
|
|
312
|
+
const sessionData = this.sessions.get(sessionId);
|
|
313
|
+
if (!sessionData) {
|
|
314
|
+
return {
|
|
315
|
+
total_evidence_items: 0,
|
|
316
|
+
missing_evidence_operations: [],
|
|
317
|
+
integrity_failures: [],
|
|
318
|
+
raw_evidence_files: [],
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
// Find operations without evidence
|
|
322
|
+
const missingOperations = [];
|
|
323
|
+
for (const opId of sessionData.registeredOperations) {
|
|
324
|
+
if (!sessionData.operationToEvidence.has(opId)) {
|
|
325
|
+
missingOperations.push(opId);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
total_evidence_items: sessionData.evidenceMap.size,
|
|
330
|
+
missing_evidence_operations: missingOperations,
|
|
331
|
+
integrity_failures: Array.from(sessionData.integrityFailures),
|
|
332
|
+
raw_evidence_files: sessionData.rawLogFiles,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
exports.EvidenceManager = EvidenceManager;
|
|
337
|
+
//# sourceMappingURL=evidence-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-manager.js","sourceRoot":"","sources":["../../src/evidence/evidence-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes tasks via Claude Code CLI subprocess.
|
|
5
|
+
* Per spec 04_COMPONENTS.md: L2 Executor must use Claude Code CLI for task execution.
|
|
6
|
+
* Per spec 10_REPL_UX.md Section 10: Non-interactive mode guarantees (Property 34-36).
|
|
7
|
+
*
|
|
8
|
+
* This is NOT a simulation - it actually spawns the `claude` CLI process.
|
|
9
|
+
*
|
|
10
|
+
* Timeout Design (v2 - Production Ready):
|
|
11
|
+
* - SOFT_TIMEOUT: Warning only, continue execution
|
|
12
|
+
* - HARD_TIMEOUT: No output for extended period, terminate
|
|
13
|
+
* - OVERALL_TIMEOUT: Total execution time limit
|
|
14
|
+
* - Process state monitoring: Check if process is still alive
|
|
15
|
+
*/
|
|
16
|
+
import type { BlockedReason, TerminatedBy } from '../models/enums';
|
|
17
|
+
/**
|
|
18
|
+
* Executor configuration
|
|
19
|
+
*/
|
|
20
|
+
export interface ExecutorConfig {
|
|
21
|
+
projectPath: string;
|
|
22
|
+
timeout: number;
|
|
23
|
+
cliPath?: string;
|
|
24
|
+
softTimeoutMs?: number;
|
|
25
|
+
hardTimeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Task to execute
|
|
29
|
+
*
|
|
30
|
+
* Per spec 10_REPL_UX.md L117-118: Model selection is REPL-local.
|
|
31
|
+
* The selectedModel is passed to Claude Code CLI via --model flag.
|
|
32
|
+
* This is a "thin wrapper" - no prompt modification, no result interpretation.
|
|
33
|
+
*/
|
|
34
|
+
export interface ExecutorTask {
|
|
35
|
+
id: string;
|
|
36
|
+
prompt: string;
|
|
37
|
+
workingDir: string;
|
|
38
|
+
/** Model to use (from .claude/repl.json). Undefined means use CLI default. */
|
|
39
|
+
selectedModel?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Verified file information
|
|
43
|
+
*/
|
|
44
|
+
export interface VerifiedFile {
|
|
45
|
+
path: string;
|
|
46
|
+
exists: boolean;
|
|
47
|
+
size?: number;
|
|
48
|
+
content_preview?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Execution result
|
|
52
|
+
* Per spec 10_REPL_UX.md Section 10: Includes blocking detection info (Property 34-36)
|
|
53
|
+
*/
|
|
54
|
+
export interface ExecutorResult {
|
|
55
|
+
executed: boolean;
|
|
56
|
+
output: string;
|
|
57
|
+
error?: string;
|
|
58
|
+
files_modified: string[];
|
|
59
|
+
duration_ms: number;
|
|
60
|
+
status: 'COMPLETE' | 'INCOMPLETE' | 'NO_EVIDENCE' | 'ERROR' | 'BLOCKED';
|
|
61
|
+
/** cwd used for execution - must be projectPath */
|
|
62
|
+
cwd: string;
|
|
63
|
+
/** Files that were verified to exist after execution */
|
|
64
|
+
verified_files: VerifiedFile[];
|
|
65
|
+
/** Files that were claimed but don't exist (fail-closed detection) */
|
|
66
|
+
unverified_files: string[];
|
|
67
|
+
/** Executor blocked in non-interactive mode (Property 34-36) */
|
|
68
|
+
executor_blocked?: boolean;
|
|
69
|
+
/** Blocking reason when executor_blocked is true */
|
|
70
|
+
blocked_reason?: BlockedReason;
|
|
71
|
+
/** Time until blocking was detected (ms) */
|
|
72
|
+
timeout_ms?: number;
|
|
73
|
+
/** How the executor was terminated */
|
|
74
|
+
terminated_by?: TerminatedBy;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Executor interface for dependency injection
|
|
78
|
+
*
|
|
79
|
+
* Allows substituting the real ClaudeCodeExecutor with mocks for testing.
|
|
80
|
+
*/
|
|
81
|
+
export interface IExecutor {
|
|
82
|
+
execute(task: ExecutorTask): Promise<ExecutorResult>;
|
|
83
|
+
isClaudeCodeAvailable(): Promise<boolean>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Claude Code Executor class
|
|
87
|
+
*
|
|
88
|
+
* Spawns Claude Code CLI to execute natural language tasks.
|
|
89
|
+
* Fail-closed: If CLI is not available, returns error status.
|
|
90
|
+
* Property 34-36: Detects blocking in non-interactive mode and terminates.
|
|
91
|
+
*
|
|
92
|
+
* v2 Improvements:
|
|
93
|
+
* - Two-stage timeout (soft/hard)
|
|
94
|
+
* - Process state monitoring
|
|
95
|
+
* - Extended interactive prompt detection
|
|
96
|
+
* - Better error recovery
|
|
97
|
+
*/
|
|
98
|
+
export declare class ClaudeCodeExecutor implements IExecutor {
|
|
99
|
+
private readonly config;
|
|
100
|
+
private readonly cliPath;
|
|
101
|
+
private readonly softTimeoutMs;
|
|
102
|
+
private readonly hardTimeoutMs;
|
|
103
|
+
constructor(config: ExecutorConfig);
|
|
104
|
+
/**
|
|
105
|
+
* Check if Claude Code CLI is available
|
|
106
|
+
*
|
|
107
|
+
* @returns true if CLI is available, false otherwise
|
|
108
|
+
*/
|
|
109
|
+
isClaudeCodeAvailable(): Promise<boolean>;
|
|
110
|
+
/**
|
|
111
|
+
* Execute a task via Claude Code CLI
|
|
112
|
+
*
|
|
113
|
+
* Fail-closed behavior:
|
|
114
|
+
* - If CLI not available → error status
|
|
115
|
+
* - If no files modified → INCOMPLETE status
|
|
116
|
+
* - If timeout → error status
|
|
117
|
+
*
|
|
118
|
+
* v2 Timeout behavior:
|
|
119
|
+
* - Soft timeout: Warning only, continue execution
|
|
120
|
+
* - Hard timeout: No output for extended period, terminate
|
|
121
|
+
* - Overall timeout: Total execution time limit
|
|
122
|
+
*
|
|
123
|
+
* @param task - Task to execute
|
|
124
|
+
* @returns Execution result
|
|
125
|
+
*/
|
|
126
|
+
execute(task: ExecutorTask): Promise<ExecutorResult>;
|
|
127
|
+
/**
|
|
128
|
+
* List all files in a directory (recursively)
|
|
129
|
+
*/
|
|
130
|
+
private listFiles;
|
|
131
|
+
/**
|
|
132
|
+
* Detect files that were modified or created
|
|
133
|
+
*/
|
|
134
|
+
private detectModifiedFiles;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=claude-code-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code-executor.d.ts","sourceRoot":"","sources":["../../src/executor/claude-code-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;IACxE,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,sEAAsE;IACtE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oDAAoD;IACpD,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACrD,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C;AAuED;;;;;;;;;;;;GAYG;AACH,qBAAa,kBAAmB,YAAW,SAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,MAAM,EAAE,cAAc;IAUlC;;;;OAIG;IACG,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IA2B/C;;;;;;;;;;;;;;;OAeG;IACG,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IA+a1D;;OAEG;YACW,SAAS;IAsCvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAwB5B"}
|