@provos/ironcurtain 0.1.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 +202 -0
- package/README.md +311 -0
- package/dist/agent/index.d.ts +10 -0
- package/dist/agent/index.js +71 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/prompts.d.ts +5 -0
- package/dist/agent/prompts.js +26 -0
- package/dist/agent/prompts.js.map +1 -0
- package/dist/agent/tools.d.ts +13 -0
- package/dist/agent/tools.js +51 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +78 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/constitution.md +16 -0
- package/dist/config/generated/compiled-policy.json +236 -0
- package/dist/config/generated/test-scenarios.json +765 -0
- package/dist/config/generated/tool-annotations.json +955 -0
- package/dist/config/index.d.ts +25 -0
- package/dist/config/index.js +151 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/mcp-servers.json +22 -0
- package/dist/config/model-provider.d.ts +49 -0
- package/dist/config/model-provider.js +78 -0
- package/dist/config/model-provider.js.map +1 -0
- package/dist/config/paths.d.ts +59 -0
- package/dist/config/paths.js +96 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/types.d.ts +89 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/user-config.d.ts +93 -0
- package/dist/config/user-config.js +309 -0
- package/dist/config/user-config.js.map +1 -0
- package/dist/hash.d.ts +17 -0
- package/dist/hash.js +34 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +11 -0
- package/dist/logger.js +93 -0
- package/dist/logger.js.map +1 -0
- package/dist/pipeline/annotate.d.ts +9 -0
- package/dist/pipeline/annotate.js +136 -0
- package/dist/pipeline/annotate.js.map +1 -0
- package/dist/pipeline/compile.d.ts +23 -0
- package/dist/pipeline/compile.js +386 -0
- package/dist/pipeline/compile.js.map +1 -0
- package/dist/pipeline/constitution-compiler.d.ts +22 -0
- package/dist/pipeline/constitution-compiler.js +197 -0
- package/dist/pipeline/constitution-compiler.js.map +1 -0
- package/dist/pipeline/generate-with-repair.d.ts +22 -0
- package/dist/pipeline/generate-with-repair.js +64 -0
- package/dist/pipeline/generate-with-repair.js.map +1 -0
- package/dist/pipeline/handwritten-scenarios.d.ts +9 -0
- package/dist/pipeline/handwritten-scenarios.js +321 -0
- package/dist/pipeline/handwritten-scenarios.js.map +1 -0
- package/dist/pipeline/llm-logger.d.ts +42 -0
- package/dist/pipeline/llm-logger.js +78 -0
- package/dist/pipeline/llm-logger.js.map +1 -0
- package/dist/pipeline/pipeline-shared.d.ts +47 -0
- package/dist/pipeline/pipeline-shared.js +145 -0
- package/dist/pipeline/pipeline-shared.js.map +1 -0
- package/dist/pipeline/policy-verifier.d.ts +46 -0
- package/dist/pipeline/policy-verifier.js +277 -0
- package/dist/pipeline/policy-verifier.js.map +1 -0
- package/dist/pipeline/scenario-generator.d.ts +11 -0
- package/dist/pipeline/scenario-generator.js +128 -0
- package/dist/pipeline/scenario-generator.js.map +1 -0
- package/dist/pipeline/tool-annotator.d.ts +24 -0
- package/dist/pipeline/tool-annotator.js +201 -0
- package/dist/pipeline/tool-annotator.js.map +1 -0
- package/dist/pipeline/types.d.ts +122 -0
- package/dist/pipeline/types.js +10 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/sandbox/index.d.ts +39 -0
- package/dist/sandbox/index.js +178 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/session/agent-session.d.ts +83 -0
- package/dist/session/agent-session.js +382 -0
- package/dist/session/agent-session.js.map +1 -0
- package/dist/session/cli-transport.d.ts +61 -0
- package/dist/session/cli-transport.js +320 -0
- package/dist/session/cli-transport.js.map +1 -0
- package/dist/session/errors.d.ts +19 -0
- package/dist/session/errors.js +33 -0
- package/dist/session/errors.js.map +1 -0
- package/dist/session/index.d.ts +29 -0
- package/dist/session/index.js +104 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/message-compactor.d.ts +32 -0
- package/dist/session/message-compactor.js +81 -0
- package/dist/session/message-compactor.js.map +1 -0
- package/dist/session/prompts.d.ts +5 -0
- package/dist/session/prompts.js +62 -0
- package/dist/session/prompts.js.map +1 -0
- package/dist/session/resource-budget-tracker.d.ts +124 -0
- package/dist/session/resource-budget-tracker.js +327 -0
- package/dist/session/resource-budget-tracker.js.map +1 -0
- package/dist/session/step-loop-detector.d.ts +63 -0
- package/dist/session/step-loop-detector.js +136 -0
- package/dist/session/step-loop-detector.js.map +1 -0
- package/dist/session/transport.d.ts +24 -0
- package/dist/session/transport.js +2 -0
- package/dist/session/transport.js.map +1 -0
- package/dist/session/truncate-result.d.ts +35 -0
- package/dist/session/truncate-result.js +71 -0
- package/dist/session/truncate-result.js.map +1 -0
- package/dist/session/types.d.ts +220 -0
- package/dist/session/types.js +6 -0
- package/dist/session/types.js.map +1 -0
- package/dist/trusted-process/audit-log.d.ts +7 -0
- package/dist/trusted-process/audit-log.js +21 -0
- package/dist/trusted-process/audit-log.js.map +1 -0
- package/dist/trusted-process/call-circuit-breaker.d.ts +33 -0
- package/dist/trusted-process/call-circuit-breaker.js +61 -0
- package/dist/trusted-process/call-circuit-breaker.js.map +1 -0
- package/dist/trusted-process/escalation.d.ts +7 -0
- package/dist/trusted-process/escalation.js +38 -0
- package/dist/trusted-process/escalation.js.map +1 -0
- package/dist/trusted-process/index.d.ts +32 -0
- package/dist/trusted-process/index.js +151 -0
- package/dist/trusted-process/index.js.map +1 -0
- package/dist/trusted-process/mcp-client-manager.d.ts +25 -0
- package/dist/trusted-process/mcp-client-manager.js +90 -0
- package/dist/trusted-process/mcp-client-manager.js.map +1 -0
- package/dist/trusted-process/mcp-proxy-server.d.ts +24 -0
- package/dist/trusted-process/mcp-proxy-server.js +451 -0
- package/dist/trusted-process/mcp-proxy-server.js.map +1 -0
- package/dist/trusted-process/path-utils.d.ts +50 -0
- package/dist/trusted-process/path-utils.js +158 -0
- package/dist/trusted-process/path-utils.js.map +1 -0
- package/dist/trusted-process/policy-engine.d.ts +88 -0
- package/dist/trusted-process/policy-engine.js +523 -0
- package/dist/trusted-process/policy-engine.js.map +1 -0
- package/dist/trusted-process/policy-roots.d.ts +50 -0
- package/dist/trusted-process/policy-roots.js +67 -0
- package/dist/trusted-process/policy-roots.js.map +1 -0
- package/dist/trusted-process/policy-types.d.ts +6 -0
- package/dist/trusted-process/policy-types.js +2 -0
- package/dist/trusted-process/policy-types.js.map +1 -0
- package/dist/trusted-process/sandbox-integration.d.ts +92 -0
- package/dist/trusted-process/sandbox-integration.js +184 -0
- package/dist/trusted-process/sandbox-integration.js.map +1 -0
- package/dist/types/argument-roles.d.ts +112 -0
- package/dist/types/argument-roles.js +344 -0
- package/dist/types/argument-roles.js.map +1 -0
- package/dist/types/audit.d.ts +18 -0
- package/dist/types/audit.js +2 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/mcp.d.ts +20 -0
- package/dist/types/mcp.js +2 -0
- package/dist/types/mcp.js.map +1 -0
- package/package.json +83 -0
- package/src/config/constitution.md +16 -0
- package/src/config/generated/compiled-policy.json +236 -0
- package/src/config/generated/test-scenarios.json +765 -0
- package/src/config/generated/tool-annotations.json +955 -0
- package/src/config/mcp-servers.json +22 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI entry point for `ironcurtain annotate-tools`.
|
|
3
|
+
*
|
|
4
|
+
* Connects to MCP servers, classifies tool arguments via LLM, and writes
|
|
5
|
+
* the tool-annotations.json artifact. This is a developer task that only
|
|
6
|
+
* needs to run when MCP servers, their tools, or the argument role
|
|
7
|
+
* registry change.
|
|
8
|
+
*/
|
|
9
|
+
export declare function main(): Promise<void>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI entry point for `ironcurtain annotate-tools`.
|
|
3
|
+
*
|
|
4
|
+
* Connects to MCP servers, classifies tool arguments via LLM, and writes
|
|
5
|
+
* the tool-annotations.json artifact. This is a developer task that only
|
|
6
|
+
* needs to run when MCP servers, their tools, or the argument role
|
|
7
|
+
* registry change.
|
|
8
|
+
*/
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
12
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
13
|
+
import chalk from 'chalk';
|
|
14
|
+
import { computeHash, createPipelineLlm, loadExistingArtifact, loadPipelineConfig, showCached, writeArtifact, withSpinner, } from './pipeline-shared.js';
|
|
15
|
+
import { annotateTools, buildAnnotationPrompt, validateAnnotationsHeuristic } from './tool-annotator.js';
|
|
16
|
+
async function connectAndDiscoverTools(mcpServers) {
|
|
17
|
+
const { result } = await withSpinner('[1/2] Connecting to MCP servers', async (spinner) => {
|
|
18
|
+
const connections = new Map();
|
|
19
|
+
let totalTools = 0;
|
|
20
|
+
for (const [serverName, config] of Object.entries(mcpServers)) {
|
|
21
|
+
spinner.text = `[1/2] Connecting to MCP server: ${serverName}...`;
|
|
22
|
+
const transport = new StdioClientTransport({
|
|
23
|
+
command: config.command,
|
|
24
|
+
args: config.args,
|
|
25
|
+
env: config.env
|
|
26
|
+
? { ...process.env, ...config.env }
|
|
27
|
+
: undefined,
|
|
28
|
+
stderr: 'pipe',
|
|
29
|
+
});
|
|
30
|
+
// Drain piped stderr to prevent backpressure (logs are discarded)
|
|
31
|
+
if (transport.stderr) {
|
|
32
|
+
transport.stderr.on('data', () => { });
|
|
33
|
+
}
|
|
34
|
+
const client = new Client({ name: 'ironcurtain-annotator', version: '0.1.0' });
|
|
35
|
+
await client.connect(transport);
|
|
36
|
+
const toolsResult = await client.listTools();
|
|
37
|
+
totalTools += toolsResult.tools.length;
|
|
38
|
+
connections.set(serverName, { client, tools: toolsResult.tools });
|
|
39
|
+
}
|
|
40
|
+
return { connections, totalTools };
|
|
41
|
+
}, (r, elapsed) => `[1/2] Found ${r.totalTools} tools (${elapsed.toFixed(1)}s)`);
|
|
42
|
+
return result.connections;
|
|
43
|
+
}
|
|
44
|
+
function computeAnnotationHash(serverName, tools) {
|
|
45
|
+
return computeHash(serverName, JSON.stringify(tools), buildAnnotationPrompt(serverName, tools));
|
|
46
|
+
}
|
|
47
|
+
async function annotateServerTools(serverName, tools, existingAnnotations, llm) {
|
|
48
|
+
const inputHash = computeAnnotationHash(serverName, tools);
|
|
49
|
+
const stepText = `[2/2] Annotating tools for ${serverName}`;
|
|
50
|
+
// Check cache: skip LLM call if inputs haven't changed
|
|
51
|
+
const cached = existingAnnotations?.servers[serverName];
|
|
52
|
+
if (cached && cached.inputHash === inputHash) {
|
|
53
|
+
showCached(stepText);
|
|
54
|
+
return { annotations: cached.tools, inputHash };
|
|
55
|
+
}
|
|
56
|
+
const { result } = await withSpinner(stepText, async (spinner) => {
|
|
57
|
+
const annotations = await annotateTools(serverName, tools, llm, (msg) => { spinner.text = `${stepText} — ${msg}`; });
|
|
58
|
+
const validation = validateAnnotationsHeuristic(tools, annotations);
|
|
59
|
+
if (!validation.valid) {
|
|
60
|
+
for (const w of validation.warnings) {
|
|
61
|
+
spinner.text = `${stepText} — WARNING: ${w}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return annotations;
|
|
65
|
+
}, (annotations, elapsed) => `${stepText}: ${annotations.length} tools annotated (${elapsed.toFixed(1)}s)`);
|
|
66
|
+
return { annotations: result, inputHash };
|
|
67
|
+
}
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Artifact Construction & Output
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
function buildAnnotationsArtifact(annotationResults) {
|
|
72
|
+
const servers = {};
|
|
73
|
+
for (const [serverName, result] of annotationResults) {
|
|
74
|
+
servers[serverName] = {
|
|
75
|
+
inputHash: result.inputHash,
|
|
76
|
+
tools: result.annotations,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return { generatedAt: new Date().toISOString(), servers };
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// MCP Client Cleanup
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
async function disconnectAll(connections) {
|
|
85
|
+
for (const conn of connections.values()) {
|
|
86
|
+
try {
|
|
87
|
+
await conn.client.close();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Ignore cleanup errors
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Main
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
export async function main() {
|
|
98
|
+
const config = loadPipelineConfig();
|
|
99
|
+
console.error(chalk.bold('Tool Annotation Pipeline'));
|
|
100
|
+
console.error(chalk.bold('========================'));
|
|
101
|
+
console.error(`Output: ${chalk.dim(config.generatedDir + '/')}`);
|
|
102
|
+
console.error('');
|
|
103
|
+
const { model: llm, logContext, logPath } = await createPipelineLlm(config.generatedDir, 'annotate');
|
|
104
|
+
const connections = await connectAndDiscoverTools(config.mcpServers);
|
|
105
|
+
try {
|
|
106
|
+
const existingAnnotations = loadExistingArtifact(config.generatedDir, 'tool-annotations.json', config.packageGeneratedDir);
|
|
107
|
+
const annotationResults = new Map();
|
|
108
|
+
for (const [serverName, conn] of connections) {
|
|
109
|
+
logContext.stepName = `annotate-${serverName}`;
|
|
110
|
+
const result = await annotateServerTools(serverName, conn.tools, existingAnnotations, llm);
|
|
111
|
+
annotationResults.set(serverName, result);
|
|
112
|
+
}
|
|
113
|
+
const toolAnnotationsFile = buildAnnotationsArtifact(annotationResults);
|
|
114
|
+
writeArtifact(config.generatedDir, 'tool-annotations.json', toolAnnotationsFile);
|
|
115
|
+
const totalTools = [...annotationResults.values()]
|
|
116
|
+
.reduce((sum, r) => sum + r.annotations.length, 0);
|
|
117
|
+
console.error('');
|
|
118
|
+
console.error(` Tools annotated: ${totalTools}`);
|
|
119
|
+
console.error(` Artifact written to: ${chalk.dim(config.generatedDir + '/tool-annotations.json')}`);
|
|
120
|
+
console.error(` LLM interaction log: ${chalk.dim(logPath)}`);
|
|
121
|
+
console.error('');
|
|
122
|
+
console.error(chalk.green.bold('Tool annotation successful!'));
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
await disconnectAll(connections);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Only run when executed directly (not when imported by cli.ts)
|
|
129
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
130
|
+
await import('dotenv/config');
|
|
131
|
+
main().catch((err) => {
|
|
132
|
+
console.error(chalk.red.bold('Tool annotation failed:'), err);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=annotate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotate.js","sourceRoot":"","sources":["../../src/pipeline/annotate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI entry point for `ironcurtain compile-policy`.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the policy compilation pipeline (stages 1-3):
|
|
5
|
+
* 1. Compile constitution into declarative rules via LLM
|
|
6
|
+
* 2. Generate test scenarios via LLM
|
|
7
|
+
* 3. Verify compiled policy against real engine + LLM judge
|
|
8
|
+
*
|
|
9
|
+
* Requires tool-annotations.json to exist on disk. Run
|
|
10
|
+
* `npm run annotate-tools` first to generate it.
|
|
11
|
+
*/
|
|
12
|
+
import type { CompiledRule } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Resolves all `paths.within` values in compiled rules to their real
|
|
15
|
+
* filesystem paths, following symlinks. This ensures that symlinked
|
|
16
|
+
* directories (e.g., ~/Downloads -> /mnt/c/.../Downloads on WSL) are
|
|
17
|
+
* resolved to their canonical form so that runtime path comparisons
|
|
18
|
+
* match correctly.
|
|
19
|
+
*
|
|
20
|
+
* Falls back to path.resolve() if the path does not exist on disk.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveRulePaths(rules: CompiledRule[]): CompiledRule[];
|
|
23
|
+
export declare function main(): Promise<void>;
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI entry point for `ironcurtain compile-policy`.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the policy compilation pipeline (stages 1-3):
|
|
5
|
+
* 1. Compile constitution into declarative rules via LLM
|
|
6
|
+
* 2. Generate test scenarios via LLM
|
|
7
|
+
* 3. Verify compiled policy against real engine + LLM judge
|
|
8
|
+
*
|
|
9
|
+
* Requires tool-annotations.json to exist on disk. Run
|
|
10
|
+
* `npm run annotate-tools` first to generate it.
|
|
11
|
+
*/
|
|
12
|
+
import { resolve } from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
import { PolicyEngine } from '../trusted-process/policy-engine.js';
|
|
16
|
+
import { resolveRealPath } from '../types/argument-roles.js';
|
|
17
|
+
import { buildCompilerPrompt, compileConstitution, validateCompiledRules } from './constitution-compiler.js';
|
|
18
|
+
import { getHandwrittenScenarios } from './handwritten-scenarios.js';
|
|
19
|
+
import { computeHash, createPipelineLlm, loadExistingArtifact, loadPipelineConfig, showCached, writeArtifact, withSpinner, } from './pipeline-shared.js';
|
|
20
|
+
import { applyScenarioCorrections, extractScenarioCorrections, filterStructuralConflicts, verifyPolicy, } from './policy-verifier.js';
|
|
21
|
+
import { buildGeneratorPrompt, generateScenarios } from './scenario-generator.js';
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Content-Hash Caching (compile-specific)
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
function computePolicyHash(constitutionText, allAnnotations, protectedPaths) {
|
|
26
|
+
const prompt = buildCompilerPrompt(constitutionText, allAnnotations, {
|
|
27
|
+
protectedPaths,
|
|
28
|
+
});
|
|
29
|
+
return computeHash(constitutionText, JSON.stringify(allAnnotations), prompt);
|
|
30
|
+
}
|
|
31
|
+
function computeScenariosHash(constitutionText, annotations, handwrittenScenarios, sandboxDirectory, protectedPaths, permittedDirectories) {
|
|
32
|
+
const prompt = buildGeneratorPrompt(constitutionText, annotations, sandboxDirectory, protectedPaths, permittedDirectories);
|
|
33
|
+
return computeHash(prompt, constitutionText, JSON.stringify(annotations), JSON.stringify(handwrittenScenarios), JSON.stringify({ sandboxDirectory }), JSON.stringify(protectedPaths), JSON.stringify(permittedDirectories));
|
|
34
|
+
}
|
|
35
|
+
function extractPermittedDirectories(rules) {
|
|
36
|
+
const dirs = new Set();
|
|
37
|
+
for (const rule of rules) {
|
|
38
|
+
if (rule.if.paths?.within) {
|
|
39
|
+
dirs.add(rule.if.paths.within);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return [...dirs].sort();
|
|
43
|
+
}
|
|
44
|
+
function collectProbeScenarios(result) {
|
|
45
|
+
return result.rounds.flatMap(round => round.newScenarios);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Filters scenarios against structural invariants and logs any discarded ones.
|
|
49
|
+
* Returns the valid scenarios and the full list of discarded scenarios.
|
|
50
|
+
*/
|
|
51
|
+
function filterAndLogStructuralConflicts(engine, scenarios, label = 'Discarded scenario (structural conflict)') {
|
|
52
|
+
const { valid, discarded } = filterStructuralConflicts(engine, scenarios);
|
|
53
|
+
for (const d of discarded) {
|
|
54
|
+
const prefix = d.scenario.source === 'handwritten'
|
|
55
|
+
? chalk.yellow('Warning: handwritten scenario conflicts with structural invariant:')
|
|
56
|
+
: chalk.dim(`${label}:`);
|
|
57
|
+
console.error(` ${prefix} "${d.scenario.description}" — ${d.rule} always returns ${d.actual}`);
|
|
58
|
+
}
|
|
59
|
+
return { valid, discarded };
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Path Resolution (post-LLM normalization)
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
/**
|
|
65
|
+
* Resolves all `paths.within` values in compiled rules to their real
|
|
66
|
+
* filesystem paths, following symlinks. This ensures that symlinked
|
|
67
|
+
* directories (e.g., ~/Downloads -> /mnt/c/.../Downloads on WSL) are
|
|
68
|
+
* resolved to their canonical form so that runtime path comparisons
|
|
69
|
+
* match correctly.
|
|
70
|
+
*
|
|
71
|
+
* Falls back to path.resolve() if the path does not exist on disk.
|
|
72
|
+
*/
|
|
73
|
+
export function resolveRulePaths(rules) {
|
|
74
|
+
return rules.map(rule => {
|
|
75
|
+
if (!rule.if.paths?.within)
|
|
76
|
+
return rule;
|
|
77
|
+
const resolved = resolveRealPath(rule.if.paths.within);
|
|
78
|
+
if (resolved === rule.if.paths.within)
|
|
79
|
+
return rule;
|
|
80
|
+
return {
|
|
81
|
+
...rule,
|
|
82
|
+
if: {
|
|
83
|
+
...rule.if,
|
|
84
|
+
paths: { ...rule.if.paths, within: resolved },
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async function compilePolicyRules(constitutionText, annotations, protectedPaths, existingPolicy, llm) {
|
|
90
|
+
const inputHash = computePolicyHash(constitutionText, annotations, protectedPaths);
|
|
91
|
+
const stepText = '[1/3] Compiling constitution';
|
|
92
|
+
// Check cache: skip LLM call if inputs haven't changed.
|
|
93
|
+
// Still resolve paths in case symlink targets changed since last run.
|
|
94
|
+
if (existingPolicy && existingPolicy.inputHash === inputHash) {
|
|
95
|
+
showCached(stepText);
|
|
96
|
+
return { rules: resolveRulePaths(existingPolicy.rules), inputHash };
|
|
97
|
+
}
|
|
98
|
+
const { result: compiledRules } = await withSpinner(stepText, async (spinner) => {
|
|
99
|
+
const rules = resolveRulePaths(await compileConstitution(constitutionText, annotations, { protectedPaths }, llm, undefined, (msg) => { spinner.text = `${stepText} — ${msg}`; }));
|
|
100
|
+
validateRulesOrThrow(rules);
|
|
101
|
+
return rules;
|
|
102
|
+
}, (rules, elapsed) => `${stepText}: ${rules.length} rules compiled (${elapsed.toFixed(1)}s)`);
|
|
103
|
+
return { rules: compiledRules, inputHash };
|
|
104
|
+
}
|
|
105
|
+
class RuleValidationError extends Error {
|
|
106
|
+
errors;
|
|
107
|
+
constructor(errors) {
|
|
108
|
+
super('Compiled rule validation failed');
|
|
109
|
+
this.errors = errors;
|
|
110
|
+
this.name = 'RuleValidationError';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function validateRulesOrThrow(rules) {
|
|
114
|
+
const ruleValidation = validateCompiledRules(rules);
|
|
115
|
+
if (ruleValidation.warnings.length > 0) {
|
|
116
|
+
for (const w of ruleValidation.warnings) {
|
|
117
|
+
console.error(` ${chalk.yellow('Warning:')} ${w}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (!ruleValidation.valid) {
|
|
121
|
+
throw new RuleValidationError(ruleValidation.errors);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function compilePolicyRulesWithRepair(constitutionText, annotations, protectedPaths, baseInputHash, repairContext, llm, onProgress) {
|
|
125
|
+
const compiledRules = resolveRulePaths(await compileConstitution(constitutionText, annotations, { protectedPaths }, llm, repairContext, onProgress));
|
|
126
|
+
validateRulesOrThrow(compiledRules);
|
|
127
|
+
return { rules: compiledRules, inputHash: `${baseInputHash}-repair` };
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Artifact Construction (pure data transformation)
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
function buildPolicyArtifact(constitutionHash, compilationResult) {
|
|
133
|
+
return {
|
|
134
|
+
generatedAt: new Date().toISOString(),
|
|
135
|
+
constitutionHash,
|
|
136
|
+
inputHash: compilationResult.inputHash,
|
|
137
|
+
rules: compilationResult.rules,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async function generateTestScenarios(constitutionText, annotations, allowedDirectory, protectedPaths, permittedDirectories, existingScenarios, llm) {
|
|
141
|
+
const handwrittenScenarios = getHandwrittenScenarios(allowedDirectory);
|
|
142
|
+
const inputHash = computeScenariosHash(constitutionText, annotations, handwrittenScenarios, allowedDirectory, protectedPaths, permittedDirectories);
|
|
143
|
+
const stepText = '[2/3] Generating test scenarios';
|
|
144
|
+
// Check cache: skip LLM call if inputs haven't changed
|
|
145
|
+
if (existingScenarios && existingScenarios.inputHash === inputHash) {
|
|
146
|
+
showCached(stepText);
|
|
147
|
+
return { scenarios: existingScenarios.scenarios, inputHash };
|
|
148
|
+
}
|
|
149
|
+
const { result: scenarios } = await withSpinner(stepText, async (spinner) => {
|
|
150
|
+
return await generateScenarios(constitutionText, annotations, handwrittenScenarios, allowedDirectory, protectedPaths, llm, permittedDirectories, (msg) => { spinner.text = `${stepText} — ${msg}`; });
|
|
151
|
+
}, (scenarios, elapsed) => {
|
|
152
|
+
const generatedCount = scenarios.length - handwrittenScenarios.length;
|
|
153
|
+
return `${stepText}: ${scenarios.length} scenarios (${handwrittenScenarios.length} handwritten + ${generatedCount} generated) (${elapsed.toFixed(1)}s)`;
|
|
154
|
+
});
|
|
155
|
+
return { scenarios, inputHash };
|
|
156
|
+
}
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Policy Verification (LLM step)
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
async function verifyCompiledPolicy(constitutionText, compiledPolicyFile, toolAnnotationsFile, protectedPaths, scenarios, llm, allowedDirectory, maxRounds = 3, verbose = true, onProgress) {
|
|
161
|
+
const result = await verifyPolicy(constitutionText, compiledPolicyFile, toolAnnotationsFile, protectedPaths, scenarios, llm, maxRounds, allowedDirectory, onProgress);
|
|
162
|
+
if (!result.pass) {
|
|
163
|
+
if (verbose) {
|
|
164
|
+
console.error('');
|
|
165
|
+
console.error(chalk.red('Verification FAILED:'));
|
|
166
|
+
console.error(result.summary);
|
|
167
|
+
console.error('');
|
|
168
|
+
for (const f of result.failedScenarios) {
|
|
169
|
+
console.error(` ${chalk.red('FAIL:')} ${f.scenario.description}`);
|
|
170
|
+
console.error(` Expected: ${f.scenario.expectedDecision}, Got: ${f.actualDecision} (rule: ${f.matchingRule})`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
console.error(` ${result.failedScenarios.length} scenario(s) failed.`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Artifact Output
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
function writeScenariosArtifact(generatedDir, constitutionHash, scenarioResult) {
|
|
183
|
+
const scenariosFile = {
|
|
184
|
+
generatedAt: new Date().toISOString(),
|
|
185
|
+
constitutionHash,
|
|
186
|
+
inputHash: scenarioResult.inputHash,
|
|
187
|
+
scenarios: scenarioResult.scenarios,
|
|
188
|
+
};
|
|
189
|
+
writeArtifact(generatedDir, 'test-scenarios.json', scenariosFile);
|
|
190
|
+
}
|
|
191
|
+
function writePolicyArtifact(generatedDir, compiledPolicyFile) {
|
|
192
|
+
writeArtifact(generatedDir, 'compiled-policy.json', compiledPolicyFile);
|
|
193
|
+
}
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
// Main Pipeline
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
export async function main() {
|
|
198
|
+
const config = loadPipelineConfig();
|
|
199
|
+
// Load tool annotations from disk (produced by `npm run annotate-tools`)
|
|
200
|
+
const toolAnnotationsFile = loadExistingArtifact(config.generatedDir, 'tool-annotations.json', config.packageGeneratedDir);
|
|
201
|
+
if (!toolAnnotationsFile) {
|
|
202
|
+
console.error(chalk.red.bold("Error: tool-annotations.json not found. Run 'npm run annotate-tools' first to generate tool annotations."));
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
// Flatten annotations from all servers
|
|
206
|
+
const allAnnotations = Object.values(toolAnnotationsFile.servers)
|
|
207
|
+
.flatMap(server => server.tools);
|
|
208
|
+
console.error(chalk.bold('Policy Compilation Pipeline'));
|
|
209
|
+
console.error(chalk.bold('==========================='));
|
|
210
|
+
console.error(`Constitution: ${chalk.dim(config.constitutionPath)}`);
|
|
211
|
+
console.error(`Sandbox: ${chalk.dim(config.allowedDirectory)}`);
|
|
212
|
+
console.error(`Output: ${chalk.dim(config.generatedDir + '/')}`);
|
|
213
|
+
console.error(`Annotations: ${chalk.dim(`${allAnnotations.length} tools from ${Object.keys(toolAnnotationsFile.servers).length} server(s)`)}`);
|
|
214
|
+
console.error('');
|
|
215
|
+
const { model: llm, logContext, logPath } = await createPipelineLlm(config.generatedDir, 'unknown');
|
|
216
|
+
// Load existing artifacts for cache comparison
|
|
217
|
+
const existingPolicy = loadExistingArtifact(config.generatedDir, 'compiled-policy.json', config.packageGeneratedDir);
|
|
218
|
+
const existingScenarios = loadExistingArtifact(config.generatedDir, 'test-scenarios.json', config.packageGeneratedDir);
|
|
219
|
+
// Compile constitution into policy rules (LLM-cacheable)
|
|
220
|
+
logContext.stepName = 'compile-constitution';
|
|
221
|
+
let compilationResult = await compilePolicyRules(config.constitutionText, allAnnotations, config.protectedPaths, existingPolicy, llm);
|
|
222
|
+
// Build and write policy artifact immediately so it's available for
|
|
223
|
+
// inspection even if verification fails, and cached for next run.
|
|
224
|
+
let compiledPolicyFile = buildPolicyArtifact(config.constitutionHash, compilationResult);
|
|
225
|
+
writePolicyArtifact(config.generatedDir, compiledPolicyFile);
|
|
226
|
+
// Extract permitted directories from compiled rules for scenario generation
|
|
227
|
+
const permittedDirectories = extractPermittedDirectories(compilationResult.rules);
|
|
228
|
+
// Generate test scenarios (LLM-cacheable)
|
|
229
|
+
logContext.stepName = 'generate-scenarios';
|
|
230
|
+
const scenarioResult = await generateTestScenarios(config.constitutionText, allAnnotations, config.allowedDirectory, config.protectedPaths, permittedDirectories, existingScenarios, llm);
|
|
231
|
+
// Write scenarios to disk immediately so they're available for
|
|
232
|
+
// inspection even if verification fails, and cached for next run.
|
|
233
|
+
writeScenariosArtifact(config.generatedDir, config.constitutionHash, scenarioResult);
|
|
234
|
+
// Filter out scenarios that conflict with structural invariants
|
|
235
|
+
const filterEngine = new PolicyEngine(compiledPolicyFile, toolAnnotationsFile, config.protectedPaths, config.allowedDirectory);
|
|
236
|
+
const { valid: initialValid, discarded: discardedScenarios } = filterAndLogStructuralConflicts(filterEngine, scenarioResult.scenarios, 'Discarded scenario (structural conflict)');
|
|
237
|
+
let filteredScenarios = initialValid;
|
|
238
|
+
// Verify compiled policy against scenarios (full depth)
|
|
239
|
+
logContext.stepName = 'verify-policy';
|
|
240
|
+
const { result: verificationResultInitial } = await withSpinner('[3/3] Verifying policy', async (spinner) => {
|
|
241
|
+
return await verifyCompiledPolicy(config.constitutionText, compiledPolicyFile, toolAnnotationsFile, config.protectedPaths, filteredScenarios, llm, config.allowedDirectory, 3, true, (msg) => { spinner.text = `[3/3] Verifying policy — ${msg}`; });
|
|
242
|
+
}, (r, elapsed) => r.pass
|
|
243
|
+
? `[3/3] Verified policy: ${r.rounds.length} round(s) (${elapsed.toFixed(1)}s)`
|
|
244
|
+
: `[3/3] Verification completed with failures (${elapsed.toFixed(1)}s)`);
|
|
245
|
+
let verificationResult = verificationResultInitial;
|
|
246
|
+
// Collect probe scenarios from verifier across all attempts, filtering
|
|
247
|
+
// out any that conflict with structural invariants
|
|
248
|
+
const { valid: filteredInitialProbes } = filterAndLogStructuralConflicts(filterEngine, collectProbeScenarios(verificationResult), 'Discarded probe (structural conflict)');
|
|
249
|
+
const accumulatedProbes = filteredInitialProbes;
|
|
250
|
+
// Dual-channel compile-verify-repair loop (up to 2 repair attempts)
|
|
251
|
+
// The judge attributes each failure to 'rule', 'scenario', or 'both':
|
|
252
|
+
// - scenario-blamed: patch the test expectation
|
|
253
|
+
// - rule-blamed: recompile rules with failure feedback
|
|
254
|
+
// - both: patch scenario AND recompile
|
|
255
|
+
const MAX_REPAIRS = 2;
|
|
256
|
+
let repairAttempts = 0;
|
|
257
|
+
let scenarioCorrectionsApplied = 0;
|
|
258
|
+
if (!verificationResult.pass) {
|
|
259
|
+
const baseInputHash = compilationResult.inputHash;
|
|
260
|
+
for (let attempt = 1; attempt <= MAX_REPAIRS; attempt++) {
|
|
261
|
+
console.error('');
|
|
262
|
+
// Gather judge analysis and attributions from the most recent verification
|
|
263
|
+
const lastRound = verificationResult.rounds[verificationResult.rounds.length - 1];
|
|
264
|
+
const judgeAnalysis = lastRound?.llmAnalysis ?? verificationResult.summary;
|
|
265
|
+
const attributedFailures = lastRound?.attributedFailures ?? [];
|
|
266
|
+
// Split failures into scenario corrections and rule-blamed failures
|
|
267
|
+
const allScenarios = [...scenarioResult.scenarios, ...accumulatedProbes];
|
|
268
|
+
const { corrections, handwrittenWarnings } = extractScenarioCorrections(attributedFailures, allScenarios);
|
|
269
|
+
for (const warning of handwrittenWarnings) {
|
|
270
|
+
console.error(` ${chalk.yellow('Warning:')} ${warning}`);
|
|
271
|
+
}
|
|
272
|
+
// Apply scenario corrections (patch expectations on generated scenarios)
|
|
273
|
+
if (corrections.length > 0) {
|
|
274
|
+
scenarioResult.scenarios = applyScenarioCorrections(scenarioResult.scenarios, corrections);
|
|
275
|
+
const correctedProbes = applyScenarioCorrections(accumulatedProbes, corrections);
|
|
276
|
+
accumulatedProbes.splice(0, accumulatedProbes.length, ...correctedProbes);
|
|
277
|
+
scenarioCorrectionsApplied += corrections.length;
|
|
278
|
+
console.error(` ${chalk.dim(`Corrected ${corrections.length} scenario expectation(s)`)}`);
|
|
279
|
+
// Re-filter after corrections (a corrected expected decision might
|
|
280
|
+
// now match a structural invariant result, making it valid)
|
|
281
|
+
({ valid: filteredScenarios } = filterAndLogStructuralConflicts(filterEngine, scenarioResult.scenarios));
|
|
282
|
+
}
|
|
283
|
+
// Determine which failures need rule recompilation:
|
|
284
|
+
// - no attribution or blamed on 'rule'/'both' (conservative default)
|
|
285
|
+
// - handwritten scenarios blamed on 'scenario' (reclassified as rule issues)
|
|
286
|
+
const allRuleBlamedFailures = verificationResult.failedScenarios.filter(f => {
|
|
287
|
+
const attr = attributedFailures.find(a => a.scenarioDescription === f.scenario.description);
|
|
288
|
+
if (!attr || attr.blame.kind === 'rule' || attr.blame.kind === 'both')
|
|
289
|
+
return true;
|
|
290
|
+
return handwrittenWarnings.some(w => w.includes(f.scenario.description));
|
|
291
|
+
});
|
|
292
|
+
if (allRuleBlamedFailures.length > 0) {
|
|
293
|
+
// Recompile with failure feedback (always calls LLM, no cache)
|
|
294
|
+
const repairContext = {
|
|
295
|
+
previousRules: compilationResult.rules,
|
|
296
|
+
failedScenarios: allRuleBlamedFailures,
|
|
297
|
+
judgeAnalysis,
|
|
298
|
+
attemptNumber: attempt,
|
|
299
|
+
};
|
|
300
|
+
logContext.stepName = `repair-compile-${attempt}`;
|
|
301
|
+
const repairCompileText = `Repair ${attempt}/${MAX_REPAIRS}: Recompiling`;
|
|
302
|
+
const { result: repairCompileResult } = await withSpinner(repairCompileText, async (spinner) => {
|
|
303
|
+
return await compilePolicyRulesWithRepair(config.constitutionText, allAnnotations, config.protectedPaths, baseInputHash, repairContext, llm, (msg) => { spinner.text = `${repairCompileText} — ${msg}`; });
|
|
304
|
+
}, (r, elapsed) => `Repair ${attempt}/${MAX_REPAIRS}: Recompiled ${r.rules.length} rules (${elapsed.toFixed(1)}s)`);
|
|
305
|
+
compilationResult = repairCompileResult;
|
|
306
|
+
// Write updated policy artifact
|
|
307
|
+
compiledPolicyFile = buildPolicyArtifact(config.constitutionHash, compilationResult);
|
|
308
|
+
writePolicyArtifact(config.generatedDir, compiledPolicyFile);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
console.error(` ${chalk.dim('No rule-blamed failures — skipping recompilation')}`);
|
|
312
|
+
}
|
|
313
|
+
// Verify with reduced depth, using base scenarios + accumulated probes
|
|
314
|
+
logContext.stepName = `repair-verify-${attempt}`;
|
|
315
|
+
const repairScenarios = [...filteredScenarios, ...accumulatedProbes];
|
|
316
|
+
const repairVerifyText = `Repair ${attempt}/${MAX_REPAIRS}: Verifying`;
|
|
317
|
+
const { result: repairVerifyResult } = await withSpinner(repairVerifyText, async (spinner) => {
|
|
318
|
+
return await verifyCompiledPolicy(config.constitutionText, compiledPolicyFile, toolAnnotationsFile, config.protectedPaths, repairScenarios, llm, config.allowedDirectory, 1, false, (msg) => { spinner.text = `${repairVerifyText} — ${msg}`; });
|
|
319
|
+
}, (r, elapsed) => r.pass
|
|
320
|
+
? `Repair ${attempt}/${MAX_REPAIRS}: Verified (${elapsed.toFixed(1)}s)`
|
|
321
|
+
: `Repair ${attempt}/${MAX_REPAIRS}: ${r.failedScenarios.length} failure(s) (${elapsed.toFixed(1)}s)`);
|
|
322
|
+
verificationResult = repairVerifyResult;
|
|
323
|
+
// Accumulate any new probe scenarios, filtering structural conflicts
|
|
324
|
+
const { valid: validRepairProbes } = filterAndLogStructuralConflicts(filterEngine, collectProbeScenarios(verificationResult), 'Discarded probe (structural conflict)');
|
|
325
|
+
accumulatedProbes.push(...validRepairProbes);
|
|
326
|
+
repairAttempts = attempt;
|
|
327
|
+
if (verificationResult.pass) {
|
|
328
|
+
// Run final full verification with all accumulated scenarios
|
|
329
|
+
logContext.stepName = 'final-verify';
|
|
330
|
+
const finalScenarios = [...filteredScenarios, ...accumulatedProbes];
|
|
331
|
+
const { result: finalVerifyResult } = await withSpinner('Final full verification', async (spinner) => {
|
|
332
|
+
return await verifyCompiledPolicy(config.constitutionText, compiledPolicyFile, toolAnnotationsFile, config.protectedPaths, finalScenarios, llm, config.allowedDirectory, 3, true, (msg) => { spinner.text = `Final full verification — ${msg}`; });
|
|
333
|
+
}, (r, elapsed) => r.pass
|
|
334
|
+
? `Final full verification: passed (${elapsed.toFixed(1)}s)`
|
|
335
|
+
: `Final full verification: ${r.failedScenarios.length} failure(s) (${elapsed.toFixed(1)}s)`);
|
|
336
|
+
verificationResult = finalVerifyResult;
|
|
337
|
+
// Accumulate any new probes from final verification, filtering structural conflicts
|
|
338
|
+
const { valid: validFinalProbes } = filterAndLogStructuralConflicts(filterEngine, collectProbeScenarios(verificationResult), 'Discarded probe (structural conflict)');
|
|
339
|
+
accumulatedProbes.push(...validFinalProbes);
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Deduplicate accumulated probes by description
|
|
345
|
+
const seenDescriptions = new Set(scenarioResult.scenarios.map(s => s.description));
|
|
346
|
+
const uniqueProbes = accumulatedProbes.filter(s => {
|
|
347
|
+
if (seenDescriptions.has(s.description))
|
|
348
|
+
return false;
|
|
349
|
+
seenDescriptions.add(s.description);
|
|
350
|
+
return true;
|
|
351
|
+
});
|
|
352
|
+
const totalScenariosTested = filteredScenarios.length + uniqueProbes.length;
|
|
353
|
+
console.error('');
|
|
354
|
+
console.error(` Rules: ${compilationResult.rules.length}`);
|
|
355
|
+
console.error(` Scenarios tested: ${totalScenariosTested}`);
|
|
356
|
+
if (discardedScenarios.length > 0) {
|
|
357
|
+
console.error(` Scenarios discarded (structural conflicts): ${discardedScenarios.length}`);
|
|
358
|
+
}
|
|
359
|
+
if (uniqueProbes.length > 0) {
|
|
360
|
+
console.error(` Probe scenarios accumulated: ${uniqueProbes.length}`);
|
|
361
|
+
}
|
|
362
|
+
if (repairAttempts > 0) {
|
|
363
|
+
console.error(` Repair attempts: ${repairAttempts}`);
|
|
364
|
+
}
|
|
365
|
+
if (scenarioCorrectionsApplied > 0) {
|
|
366
|
+
console.error(` Scenario corrections: ${scenarioCorrectionsApplied}`);
|
|
367
|
+
}
|
|
368
|
+
console.error(` Artifacts written to: ${chalk.dim(config.generatedDir + '/')}`);
|
|
369
|
+
console.error(` LLM interaction log: ${chalk.dim(logPath)}`);
|
|
370
|
+
if (!verificationResult.pass) {
|
|
371
|
+
console.error('');
|
|
372
|
+
console.error(chalk.red.bold('Verification FAILED — artifacts written but policy may need review.'));
|
|
373
|
+
process.exit(1);
|
|
374
|
+
}
|
|
375
|
+
console.error('');
|
|
376
|
+
console.error(chalk.green.bold('Policy compilation successful!'));
|
|
377
|
+
}
|
|
378
|
+
// Only run when executed directly (not when imported by cli.ts or tests)
|
|
379
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
380
|
+
await import('dotenv/config');
|
|
381
|
+
main().catch((err) => {
|
|
382
|
+
console.error(chalk.red.bold('Policy compilation failed:'), err);
|
|
383
|
+
process.exit(1);
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/pipeline/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constitution Compiler -- LLM-driven compilation of English-language
|
|
3
|
+
* constitution principles into enforceable declarative policy rules.
|
|
4
|
+
*
|
|
5
|
+
* The compiler takes the constitution text, tool annotations, and system
|
|
6
|
+
* config (concrete directory paths) and produces an ordered rule chain
|
|
7
|
+
* that faithfully implements the non-structural principles.
|
|
8
|
+
*/
|
|
9
|
+
import type { LanguageModel } from 'ai';
|
|
10
|
+
import type { ToolAnnotation, CompiledRule, RepairContext } from './types.js';
|
|
11
|
+
export interface CompilerConfig {
|
|
12
|
+
protectedPaths: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function buildCompilerPrompt(constitutionText: string, annotations: ToolAnnotation[], config: CompilerConfig): string;
|
|
15
|
+
export declare function buildRepairPrompt(basePrompt: string, repairContext: RepairContext): string;
|
|
16
|
+
export declare function compileConstitution(constitutionText: string, annotations: ToolAnnotation[], config: CompilerConfig, llm: LanguageModel, repairContext?: RepairContext, onProgress?: (message: string) => void): Promise<CompiledRule[]>;
|
|
17
|
+
export interface RuleValidationResult {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
errors: string[];
|
|
20
|
+
warnings: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare function validateCompiledRules(rules: CompiledRule[]): RuleValidationResult;
|