feat: copy deliverables to audit-logs for self-contained audit trail
This commit is contained in:
+36
-1
@@ -187,14 +187,49 @@ export async function fileExists(filePath: string): Promise<boolean> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize audit directory structure for a session
|
* Initialize audit directory structure for a session
|
||||||
* Creates: audit-logs/{sessionId}/, agents/, prompts/
|
* Creates: audit-logs/{sessionId}/, agents/, prompts/, deliverables/
|
||||||
*/
|
*/
|
||||||
export async function initializeAuditStructure(sessionMetadata: SessionMetadata): Promise<void> {
|
export async function initializeAuditStructure(sessionMetadata: SessionMetadata): Promise<void> {
|
||||||
const auditPath = generateAuditPath(sessionMetadata);
|
const auditPath = generateAuditPath(sessionMetadata);
|
||||||
const agentsPath = path.join(auditPath, 'agents');
|
const agentsPath = path.join(auditPath, 'agents');
|
||||||
const promptsPath = path.join(auditPath, 'prompts');
|
const promptsPath = path.join(auditPath, 'prompts');
|
||||||
|
const deliverablesPath = path.join(auditPath, 'deliverables');
|
||||||
|
|
||||||
await ensureDirectory(auditPath);
|
await ensureDirectory(auditPath);
|
||||||
await ensureDirectory(agentsPath);
|
await ensureDirectory(agentsPath);
|
||||||
await ensureDirectory(promptsPath);
|
await ensureDirectory(promptsPath);
|
||||||
|
await ensureDirectory(deliverablesPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy deliverable files from repo to audit-logs for self-contained audit trail.
|
||||||
|
* No-ops if source directory doesn't exist. Idempotent and parallel-safe.
|
||||||
|
*/
|
||||||
|
export async function copyDeliverablesToAudit(
|
||||||
|
sessionMetadata: SessionMetadata,
|
||||||
|
repoPath: string
|
||||||
|
): Promise<void> {
|
||||||
|
const sourceDir = path.join(repoPath, 'deliverables');
|
||||||
|
const destDir = path.join(generateAuditPath(sessionMetadata), 'deliverables');
|
||||||
|
|
||||||
|
let entries: string[];
|
||||||
|
try {
|
||||||
|
entries = await fs.readdir(sourceDir);
|
||||||
|
} catch {
|
||||||
|
// Source directory doesn't exist yet — nothing to copy
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ensureDirectory(destDir);
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const sourcePath = path.join(sourceDir, entry);
|
||||||
|
const destPath = path.join(destDir, entry);
|
||||||
|
|
||||||
|
// Only copy files, skip subdirectories
|
||||||
|
const stat = await fs.stat(sourcePath);
|
||||||
|
if (stat.isFile()) {
|
||||||
|
await fs.copyFile(sourcePath, destPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ import type { WorkflowSummary } from '../audit/workflow-logger.js';
|
|||||||
import type { AgentName } from '../types/agents.js';
|
import type { AgentName } from '../types/agents.js';
|
||||||
import type { AgentMetrics } from './shared.js';
|
import type { AgentMetrics } from './shared.js';
|
||||||
import type { DistributedConfig } from '../types/config.js';
|
import type { DistributedConfig } from '../types/config.js';
|
||||||
import type { SessionMetadata } from '../audit/utils.js';
|
import { copyDeliverablesToAudit, type SessionMetadata } from '../audit/utils.js';
|
||||||
|
|
||||||
const HEARTBEAT_INTERVAL_MS = 2000; // Must be < heartbeatTimeout (10min production, 5min testing)
|
const HEARTBEAT_INTERVAL_MS = 2000; // Must be < heartbeatTimeout (10min production, 5min testing)
|
||||||
|
|
||||||
@@ -251,6 +251,13 @@ async function runAgentActivity(
|
|||||||
});
|
});
|
||||||
await commitGitSuccess(repoPath, agentName);
|
await commitGitSuccess(repoPath, agentName);
|
||||||
|
|
||||||
|
// 9.5. Copy deliverables to audit-logs (non-fatal)
|
||||||
|
try {
|
||||||
|
await copyDeliverablesToAudit(sessionMetadata, repoPath);
|
||||||
|
} catch (copyErr) {
|
||||||
|
console.error(`Failed to copy deliverables to audit-logs for ${agentName}:`, copyErr);
|
||||||
|
}
|
||||||
|
|
||||||
// 10. Return metrics
|
// 10. Return metrics
|
||||||
return {
|
return {
|
||||||
durationMs: Date.now() - startTime,
|
durationMs: Date.now() - startTime,
|
||||||
|
|||||||
Reference in New Issue
Block a user