feat: copy deliverables to audit-logs for self-contained audit trail

This commit is contained in:
ajmallesh
2026-02-11 19:06:31 -08:00
parent c90993e1bc
commit ef7b4ddf30
2 changed files with 44 additions and 2 deletions

View File

@@ -187,14 +187,49 @@ export async function fileExists(filePath: string): Promise<boolean> {
/**
* 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> {
const auditPath = generateAuditPath(sessionMetadata);
const agentsPath = path.join(auditPath, 'agents');
const promptsPath = path.join(auditPath, 'prompts');
const deliverablesPath = path.join(auditPath, 'deliverables');
await ensureDirectory(auditPath);
await ensureDirectory(agentsPath);
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);
}
}
}

View File

@@ -74,7 +74,7 @@ import type { WorkflowSummary } from '../audit/workflow-logger.js';
import type { AgentName } from '../types/agents.js';
import type { AgentMetrics } from './shared.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)
@@ -251,6 +251,13 @@ async function runAgentActivity(
});
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
return {
durationMs: Date.now() - startTime,