tryassay 0.6.0 → 0.11.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/dist/api/pricing-enforcer.d.ts +45 -0
- package/dist/api/pricing-enforcer.js +144 -0
- package/dist/api/pricing-enforcer.js.map +1 -0
- package/dist/api/server.d.ts +28 -0
- package/dist/api/server.js +265 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/team-session.d.ts +59 -0
- package/dist/api/team-session.js +240 -0
- package/dist/api/team-session.js.map +1 -0
- package/dist/cli.js +123 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/api.d.ts +4 -0
- package/dist/commands/api.js +50 -0
- package/dist/commands/api.js.map +1 -0
- package/dist/commands/runtime.d.ts +61 -0
- package/dist/commands/runtime.js +554 -0
- package/dist/commands/runtime.js.map +1 -1
- package/dist/runtime/agent-spawner.d.ts +56 -0
- package/dist/runtime/agent-spawner.js +217 -0
- package/dist/runtime/agent-spawner.js.map +1 -0
- package/dist/runtime/agents/coordinator-agent.d.ts +20 -0
- package/dist/runtime/agents/coordinator-agent.js +182 -0
- package/dist/runtime/agents/coordinator-agent.js.map +1 -0
- package/dist/runtime/agents/ops-agent.d.ts +11 -0
- package/dist/runtime/agents/ops-agent.js +113 -0
- package/dist/runtime/agents/ops-agent.js.map +1 -0
- package/dist/runtime/agents/research-agent.d.ts +11 -0
- package/dist/runtime/agents/research-agent.js +114 -0
- package/dist/runtime/agents/research-agent.js.map +1 -0
- package/dist/runtime/agents/test-agent.d.ts +11 -0
- package/dist/runtime/agents/test-agent.js +114 -0
- package/dist/runtime/agents/test-agent.js.map +1 -0
- package/dist/runtime/capability-registry.d.ts +62 -0
- package/dist/runtime/capability-registry.js +191 -0
- package/dist/runtime/capability-registry.js.map +1 -0
- package/dist/runtime/collusion-detector.d.ts +35 -0
- package/dist/runtime/collusion-detector.js +97 -0
- package/dist/runtime/collusion-detector.js.map +1 -0
- package/dist/runtime/domain-coverage-analyzer.d.ts +24 -0
- package/dist/runtime/domain-coverage-analyzer.js +178 -0
- package/dist/runtime/domain-coverage-analyzer.js.map +1 -0
- package/dist/runtime/human-escalation.d.ts +41 -0
- package/dist/runtime/human-escalation.js +122 -0
- package/dist/runtime/human-escalation.js.map +1 -0
- package/dist/runtime/kill-switch.d.ts +51 -0
- package/dist/runtime/kill-switch.js +185 -0
- package/dist/runtime/kill-switch.js.map +1 -0
- package/dist/runtime/layer2-guardian.d.ts +81 -0
- package/dist/runtime/layer2-guardian.js +263 -0
- package/dist/runtime/layer2-guardian.js.map +1 -0
- package/dist/runtime/multi-agent-loop.d.ts +37 -0
- package/dist/runtime/multi-agent-loop.js +411 -0
- package/dist/runtime/multi-agent-loop.js.map +1 -0
- package/dist/runtime/prompt-safety-analyzer.d.ts +17 -0
- package/dist/runtime/prompt-safety-analyzer.js +230 -0
- package/dist/runtime/prompt-safety-analyzer.js.map +1 -0
- package/dist/runtime/rollback-manager.d.ts +50 -0
- package/dist/runtime/rollback-manager.js +157 -0
- package/dist/runtime/rollback-manager.js.map +1 -0
- package/dist/runtime/rule-canary-deployer.d.ts +69 -0
- package/dist/runtime/rule-canary-deployer.js +289 -0
- package/dist/runtime/rule-canary-deployer.js.map +1 -0
- package/dist/runtime/rule-conflict-detector.d.ts +48 -0
- package/dist/runtime/rule-conflict-detector.js +214 -0
- package/dist/runtime/rule-conflict-detector.js.map +1 -0
- package/dist/runtime/rule-meta-verifier.d.ts +18 -0
- package/dist/runtime/rule-meta-verifier.js +275 -0
- package/dist/runtime/rule-meta-verifier.js.map +1 -0
- package/dist/runtime/rule-proposal-manager.d.ts +95 -0
- package/dist/runtime/rule-proposal-manager.js +190 -0
- package/dist/runtime/rule-proposal-manager.js.map +1 -0
- package/dist/runtime/safety-enforcer.d.ts +35 -0
- package/dist/runtime/safety-enforcer.js +165 -0
- package/dist/runtime/safety-enforcer.js.map +1 -0
- package/dist/runtime/safety-status.d.ts +48 -0
- package/dist/runtime/safety-status.js +119 -0
- package/dist/runtime/safety-status.js.map +1 -0
- package/dist/runtime/shared-memory.d.ts +47 -0
- package/dist/runtime/shared-memory.js +151 -0
- package/dist/runtime/shared-memory.js.map +1 -0
- package/dist/runtime/specialized-agent.d.ts +5 -0
- package/dist/runtime/specialized-agent.js +37 -0
- package/dist/runtime/specialized-agent.js.map +1 -1
- package/dist/runtime/stall-detector.d.ts +13 -0
- package/dist/runtime/stall-detector.js +121 -0
- package/dist/runtime/stall-detector.js.map +1 -0
- package/dist/runtime/tool-approval.d.ts +51 -0
- package/dist/runtime/tool-approval.js +148 -0
- package/dist/runtime/tool-approval.js.map +1 -0
- package/dist/runtime/tool-sandbox.d.ts +43 -0
- package/dist/runtime/tool-sandbox.js +394 -0
- package/dist/runtime/tool-sandbox.js.map +1 -0
- package/dist/runtime/tool-verifier.d.ts +18 -0
- package/dist/runtime/tool-verifier.js +323 -0
- package/dist/runtime/tool-verifier.js.map +1 -0
- package/dist/runtime/trust-manager.d.ts +33 -3
- package/dist/runtime/trust-manager.js +128 -26
- package/dist/runtime/trust-manager.js.map +1 -1
- package/dist/runtime/types.d.ts +652 -0
- package/dist/runtime/verification-intensity.d.ts +34 -0
- package/dist/runtime/verification-intensity.js +104 -0
- package/dist/runtime/verification-intensity.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Rule Meta-Verification Pipeline
|
|
3
|
+
// Existing rules verify new rules (monotonic induction):
|
|
4
|
+
// Rule N is verified by rules 1..N-1.
|
|
5
|
+
// ============================================================
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { getClient, MODEL } from '../lib/anthropic.js';
|
|
8
|
+
// ── Rule Executor ──────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Execute a rule's check against a code snippet.
|
|
11
|
+
* Returns a verdict: 'PASS' or 'FAIL'.
|
|
12
|
+
*/
|
|
13
|
+
async function executeRuleCheck(check, code, language) {
|
|
14
|
+
switch (check.type) {
|
|
15
|
+
case 'formal':
|
|
16
|
+
return executeFormalCheck(check, code);
|
|
17
|
+
case 'llm':
|
|
18
|
+
return executeLLMCheck(check, code, language);
|
|
19
|
+
case 'composite':
|
|
20
|
+
return executeCompositeCheck(check, code, language);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function executeFormalCheck(check, code) {
|
|
24
|
+
const results = [];
|
|
25
|
+
const evidenceParts = [];
|
|
26
|
+
for (const pattern of check.patterns) {
|
|
27
|
+
if (pattern.pattern_type === 'regex') {
|
|
28
|
+
try {
|
|
29
|
+
const regex = new RegExp(pattern.pattern, 'gm');
|
|
30
|
+
const matches = code.match(regex);
|
|
31
|
+
const matched = matches !== null && matches.length > 0;
|
|
32
|
+
results.push(matched);
|
|
33
|
+
evidenceParts.push(matched
|
|
34
|
+
? `Pattern "${pattern.description}" matched ${matches.length} time(s)`
|
|
35
|
+
: `Pattern "${pattern.description}" did not match`);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
results.push(false);
|
|
39
|
+
evidenceParts.push(`Pattern "${pattern.description}" failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (pattern.pattern_type === 'tree_sitter' || pattern.pattern_type === 'semgrep') {
|
|
43
|
+
// tree-sitter and semgrep require external tools — stub for now
|
|
44
|
+
// In production, these would shell out to the respective tools
|
|
45
|
+
evidenceParts.push(`Pattern "${pattern.description}" (${pattern.pattern_type}): skipped — requires external tooling`);
|
|
46
|
+
results.push(true); // optimistic pass for non-regex patterns
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let verdict;
|
|
50
|
+
switch (check.logic) {
|
|
51
|
+
case 'all_match':
|
|
52
|
+
verdict = results.every(r => r) ? 'PASS' : 'FAIL';
|
|
53
|
+
break;
|
|
54
|
+
case 'any_match':
|
|
55
|
+
verdict = results.some(r => r) ? 'PASS' : 'FAIL';
|
|
56
|
+
break;
|
|
57
|
+
case 'none_match':
|
|
58
|
+
verdict = results.every(r => !r) ? 'PASS' : 'FAIL';
|
|
59
|
+
break;
|
|
60
|
+
case 'custom':
|
|
61
|
+
// Custom logic is not executed dynamically for safety
|
|
62
|
+
verdict = results.every(r => r) ? 'PASS' : 'FAIL';
|
|
63
|
+
evidenceParts.push('Custom logic evaluated as all_match');
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
return { verdict, evidence: evidenceParts.join('. ') };
|
|
67
|
+
}
|
|
68
|
+
async function executeLLMCheck(check, code, language) {
|
|
69
|
+
try {
|
|
70
|
+
const client = getClient();
|
|
71
|
+
const prompt = check.prompt_template
|
|
72
|
+
.replace('{{code}}', code)
|
|
73
|
+
.replace('{{language}}', language)
|
|
74
|
+
.replace('{{claim}}', 'Verify the code against the rule');
|
|
75
|
+
const response = await client.messages.create({
|
|
76
|
+
model: MODEL,
|
|
77
|
+
max_tokens: check.max_tokens,
|
|
78
|
+
temperature: check.temperature,
|
|
79
|
+
messages: [{ role: 'user', content: prompt }],
|
|
80
|
+
});
|
|
81
|
+
const content = response.content[0];
|
|
82
|
+
if (content.type !== 'text') {
|
|
83
|
+
return { verdict: 'FAIL', evidence: 'LLM returned non-text response' };
|
|
84
|
+
}
|
|
85
|
+
const text = content.text.toLowerCase();
|
|
86
|
+
const verdict = text.includes('pass') && !text.includes('fail') ? 'PASS' : 'FAIL';
|
|
87
|
+
return { verdict, evidence: content.text.slice(0, 500) };
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
return {
|
|
91
|
+
verdict: 'FAIL',
|
|
92
|
+
evidence: `LLM check failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function executeCompositeCheck(check, code, language) {
|
|
97
|
+
const formalResult = executeFormalCheck(check.formal_component, code);
|
|
98
|
+
switch (check.merge_strategy) {
|
|
99
|
+
case 'formal_gate': {
|
|
100
|
+
// LLM only runs if formal passes
|
|
101
|
+
if (formalResult.verdict === 'FAIL') {
|
|
102
|
+
return { verdict: 'FAIL', evidence: `Formal gate: ${formalResult.evidence}` };
|
|
103
|
+
}
|
|
104
|
+
const llmResult = await executeLLMCheck(check.llm_component, code, language);
|
|
105
|
+
return {
|
|
106
|
+
verdict: llmResult.verdict,
|
|
107
|
+
evidence: `Formal gate passed. LLM: ${llmResult.evidence}`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
case 'formal_override': {
|
|
111
|
+
// Both run, formal overrides on disagreement
|
|
112
|
+
const llmResult = await executeLLMCheck(check.llm_component, code, language);
|
|
113
|
+
if (formalResult.verdict !== llmResult.verdict) {
|
|
114
|
+
return {
|
|
115
|
+
verdict: formalResult.verdict,
|
|
116
|
+
evidence: `Formal override: formal=${formalResult.verdict}, llm=${llmResult.verdict}. ${formalResult.evidence}`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
verdict: formalResult.verdict,
|
|
121
|
+
evidence: `Agreement: formal=${formalResult.verdict}, llm=${llmResult.verdict}. ${formalResult.evidence}`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
case 'weighted': {
|
|
125
|
+
// Both run, use combined signal
|
|
126
|
+
const llmResult = await executeLLMCheck(check.llm_component, code, language);
|
|
127
|
+
// Weight formal higher (0.7 formal, 0.3 LLM)
|
|
128
|
+
const formalScore = formalResult.verdict === 'PASS' ? 0.7 : 0;
|
|
129
|
+
const llmScore = llmResult.verdict === 'PASS' ? 0.3 : 0;
|
|
130
|
+
const verdict = formalScore + llmScore >= 0.5 ? 'PASS' : 'FAIL';
|
|
131
|
+
return {
|
|
132
|
+
verdict,
|
|
133
|
+
evidence: `Weighted: formal=${formalResult.verdict}(0.7), llm=${llmResult.verdict}(0.3), combined=${(formalScore + llmScore).toFixed(2)}`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// ── Meta-Verification Pipeline ────────────────────────────
|
|
139
|
+
export class RuleMetaVerifier {
|
|
140
|
+
consistencyRuns;
|
|
141
|
+
constructor(opts) {
|
|
142
|
+
this.consistencyRuns = opts?.consistencyRuns ?? 3;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Meta-verify a proposed rule:
|
|
146
|
+
* 1. Run all test cases through the rule's check logic
|
|
147
|
+
* 2. Check consistency (run multiple times for LLM-based rules)
|
|
148
|
+
* 3. Check for conflicts with existing rules
|
|
149
|
+
* Returns a RuleMetaVerification report.
|
|
150
|
+
*/
|
|
151
|
+
async verify(proposedRule, existingRules) {
|
|
152
|
+
const verificationId = randomUUID();
|
|
153
|
+
// Step 1: Run test cases
|
|
154
|
+
const testResults = await this.runTestCases(proposedRule);
|
|
155
|
+
// Step 2: Consistency check
|
|
156
|
+
const consistency = await this.checkConsistency(proposedRule);
|
|
157
|
+
// Step 3: Conflict check
|
|
158
|
+
const conflictCheck = await this.checkConflicts(proposedRule, existingRules);
|
|
159
|
+
// Determine verdict
|
|
160
|
+
const blockers = [];
|
|
161
|
+
const failedTests = testResults.filter(r => !r.match);
|
|
162
|
+
if (failedTests.length > 0) {
|
|
163
|
+
blockers.push(`${failedTests.length} test case(s) produced incorrect verdicts`);
|
|
164
|
+
}
|
|
165
|
+
if (!consistency.consistent) {
|
|
166
|
+
blockers.push(`Rule is not deterministic: variance ${consistency.variance.toFixed(3)} over ${consistency.runs} runs`);
|
|
167
|
+
}
|
|
168
|
+
// Formal rules must have zero variance
|
|
169
|
+
if (proposedRule.substrate.startsWith('formal_') && consistency.variance > 0) {
|
|
170
|
+
blockers.push('Formal rules must produce identical results on every run');
|
|
171
|
+
}
|
|
172
|
+
if (conflictCheck.conflicting_rules.length > 0) {
|
|
173
|
+
blockers.push(`Conflicts with ${conflictCheck.conflicting_rules.length} existing rule(s): ${conflictCheck.conflicting_rules.join(', ')}`);
|
|
174
|
+
}
|
|
175
|
+
const verdict = blockers.length > 0 ? 'reject'
|
|
176
|
+
: consistency.variance > 0 && consistency.variance <= 0.1 ? 'needs_review'
|
|
177
|
+
: 'approve';
|
|
178
|
+
return {
|
|
179
|
+
rule_id: proposedRule.id,
|
|
180
|
+
verification_id: verificationId,
|
|
181
|
+
timestamp: new Date().toISOString(),
|
|
182
|
+
test_results: testResults,
|
|
183
|
+
consistency,
|
|
184
|
+
conflict_check: conflictCheck,
|
|
185
|
+
verdict,
|
|
186
|
+
blockers,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// ── Private: Test Case Execution ────────────────────────
|
|
190
|
+
async runTestCases(rule) {
|
|
191
|
+
const results = [];
|
|
192
|
+
for (const testCase of rule.test_cases) {
|
|
193
|
+
const { verdict, evidence } = await executeRuleCheck(rule.check, testCase.input_code, testCase.input_language);
|
|
194
|
+
results.push({
|
|
195
|
+
case_id: testCase.id,
|
|
196
|
+
actual_verdict: verdict,
|
|
197
|
+
expected_verdict: testCase.expected_verdict,
|
|
198
|
+
match: verdict === testCase.expected_verdict,
|
|
199
|
+
evidence,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return results;
|
|
203
|
+
}
|
|
204
|
+
// ── Private: Consistency Check ──────────────────────────
|
|
205
|
+
async checkConsistency(rule) {
|
|
206
|
+
// For formal-only rules, consistency is guaranteed (single run)
|
|
207
|
+
if (rule.substrate.startsWith('formal_')) {
|
|
208
|
+
return {
|
|
209
|
+
runs: 1,
|
|
210
|
+
consistent: true,
|
|
211
|
+
variance: 0.0,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
// For LLM-based rules, run multiple times and check variance
|
|
215
|
+
const runs = this.consistencyRuns;
|
|
216
|
+
const verdictsByCase = new Map();
|
|
217
|
+
for (let i = 0; i < runs; i++) {
|
|
218
|
+
for (const testCase of rule.test_cases) {
|
|
219
|
+
const { verdict } = await executeRuleCheck(rule.check, testCase.input_code, testCase.input_language);
|
|
220
|
+
const existing = verdictsByCase.get(testCase.id) ?? [];
|
|
221
|
+
existing.push(verdict);
|
|
222
|
+
verdictsByCase.set(testCase.id, existing);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Calculate variance: what fraction of cases had inconsistent verdicts?
|
|
226
|
+
let inconsistentCases = 0;
|
|
227
|
+
for (const [, verdicts] of verdictsByCase) {
|
|
228
|
+
const unique = new Set(verdicts);
|
|
229
|
+
if (unique.size > 1)
|
|
230
|
+
inconsistentCases++;
|
|
231
|
+
}
|
|
232
|
+
const variance = verdictsByCase.size > 0
|
|
233
|
+
? inconsistentCases / verdictsByCase.size
|
|
234
|
+
: 0;
|
|
235
|
+
return {
|
|
236
|
+
runs,
|
|
237
|
+
consistent: variance === 0,
|
|
238
|
+
variance,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
// ── Private: Conflict Check ─────────────────────────────
|
|
242
|
+
async checkConflicts(proposedRule, existingRules) {
|
|
243
|
+
const conflicting = [];
|
|
244
|
+
// Only check rules that target overlapping claim categories and languages
|
|
245
|
+
const overlappingRules = existingRules.filter(existing => {
|
|
246
|
+
const categoryOverlap = existing.target.claim_categories.some(c => proposedRule.target.claim_categories.includes(c));
|
|
247
|
+
const languageOverlap = existing.target.languages.some(l => proposedRule.target.languages.includes(l));
|
|
248
|
+
return categoryOverlap && languageOverlap;
|
|
249
|
+
});
|
|
250
|
+
// For each overlapping rule, run the proposed rule's test cases
|
|
251
|
+
// through the existing rule and check for contradictions
|
|
252
|
+
for (const existing of overlappingRules) {
|
|
253
|
+
for (const testCase of proposedRule.test_cases) {
|
|
254
|
+
// Check if the existing rule applies to this test case's language
|
|
255
|
+
if (!existing.target.languages.includes(testCase.input_language))
|
|
256
|
+
continue;
|
|
257
|
+
const existingResult = await executeRuleCheck(existing.check, testCase.input_code, testCase.input_language);
|
|
258
|
+
const proposedResult = await executeRuleCheck(proposedRule.check, testCase.input_code, testCase.input_language);
|
|
259
|
+
// Conflict: same input, opposite verdicts
|
|
260
|
+
if (existingResult.verdict !== proposedResult.verdict) {
|
|
261
|
+
conflicting.push(existing.id);
|
|
262
|
+
break; // One conflict per rule is enough
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const resolution = conflicting.length > 0
|
|
267
|
+
? `${conflicting.length} conflict(s) detected. Manual review required. Consider: (1) the new rule is more specific (override), (2) the existing rule is wrong (deprecate), or (3) both are correct for different contexts (scope refinement).`
|
|
268
|
+
: 'No conflicts with existing rules.';
|
|
269
|
+
return {
|
|
270
|
+
conflicting_rules: conflicting,
|
|
271
|
+
resolution,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=rule-meta-verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-meta-verifier.js","sourceRoot":"","sources":["../../src/runtime/rule-meta-verifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { RuleMetaVerifier } from './rule-meta-verifier.js';
|
|
2
|
+
import { RuleConflictDetector, type ConflictReport } from './rule-conflict-detector.js';
|
|
3
|
+
import { RuleCanaryDeployer } from './rule-canary-deployer.js';
|
|
4
|
+
import type { VerificationRule, RuleMetaVerification, ModificationProposal, ModificationApproval, ProposalStatus } from './types.js';
|
|
5
|
+
export interface PendingRuleApproval {
|
|
6
|
+
readonly proposal: ModificationProposal;
|
|
7
|
+
readonly metaVerification: RuleMetaVerification;
|
|
8
|
+
readonly conflictReport: ConflictReport;
|
|
9
|
+
readonly ruleDefinition: VerificationRule;
|
|
10
|
+
}
|
|
11
|
+
export declare class RuleProposalManager {
|
|
12
|
+
private metaVerifier;
|
|
13
|
+
private conflictDetector;
|
|
14
|
+
private canaryDeployer;
|
|
15
|
+
private pendingApprovals;
|
|
16
|
+
private activeRules;
|
|
17
|
+
constructor(opts?: {
|
|
18
|
+
metaVerifier?: RuleMetaVerifier;
|
|
19
|
+
conflictDetector?: RuleConflictDetector;
|
|
20
|
+
canaryDeployer?: RuleCanaryDeployer;
|
|
21
|
+
existingRules?: VerificationRule[];
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Propose a new verification rule.
|
|
25
|
+
* Runs meta-verification and conflict detection, then queues for approval.
|
|
26
|
+
*/
|
|
27
|
+
propose(rule: VerificationRule, justification: {
|
|
28
|
+
capability_gap: string;
|
|
29
|
+
evidence: string[];
|
|
30
|
+
expected_impact: string;
|
|
31
|
+
risk_assessment: string;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
proposalId: string;
|
|
34
|
+
metaVerification: RuleMetaVerification;
|
|
35
|
+
conflictReport: ConflictReport;
|
|
36
|
+
status: ProposalStatus;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* List all pending rule approvals.
|
|
40
|
+
*/
|
|
41
|
+
listPending(): PendingRuleApproval[];
|
|
42
|
+
/**
|
|
43
|
+
* Get a specific pending approval.
|
|
44
|
+
*/
|
|
45
|
+
getPending(proposalId: string): PendingRuleApproval | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Approve a pending rule proposal.
|
|
48
|
+
* Starts the canary deployment pipeline.
|
|
49
|
+
*/
|
|
50
|
+
approve(proposalId: string, approvedBy: string, reasoning: string): {
|
|
51
|
+
approval: ModificationApproval;
|
|
52
|
+
rule: VerificationRule;
|
|
53
|
+
canaryStage: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Reject a pending rule proposal.
|
|
57
|
+
*/
|
|
58
|
+
reject(proposalId: string, rejectedBy: string, reasoning: string): ModificationApproval;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a canary rule is ready to promote.
|
|
61
|
+
*/
|
|
62
|
+
checkCanaryPromotion(ruleId: string): {
|
|
63
|
+
action: 'promote' | 'wait' | 'rollback';
|
|
64
|
+
nextStage?: string;
|
|
65
|
+
reason: string;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Promote a canary rule to the next stage.
|
|
69
|
+
* When promoted to full_rollout, adds to active rules.
|
|
70
|
+
*/
|
|
71
|
+
promoteCanary(ruleId: string): {
|
|
72
|
+
promoted: boolean;
|
|
73
|
+
stage: string;
|
|
74
|
+
isActive: boolean;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Rollback a canary deployment.
|
|
78
|
+
*/
|
|
79
|
+
rollbackCanary(ruleId: string): {
|
|
80
|
+
success: boolean;
|
|
81
|
+
reason: string;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Get the canary deployer (for recording evaluations externally).
|
|
85
|
+
*/
|
|
86
|
+
getCanaryDeployer(): RuleCanaryDeployer;
|
|
87
|
+
/**
|
|
88
|
+
* Get all active rules.
|
|
89
|
+
*/
|
|
90
|
+
getActiveRules(): readonly VerificationRule[];
|
|
91
|
+
/**
|
|
92
|
+
* Add a rule to the active set (used when loading from registry).
|
|
93
|
+
*/
|
|
94
|
+
addActiveRule(rule: VerificationRule): void;
|
|
95
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Rule Proposal Manager
|
|
3
|
+
// Orchestrates: propose → meta-verify → conflict-check →
|
|
4
|
+
// approve → canary deploy → promote to production.
|
|
5
|
+
// ============================================================
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { RuleMetaVerifier } from './rule-meta-verifier.js';
|
|
8
|
+
import { RuleConflictDetector } from './rule-conflict-detector.js';
|
|
9
|
+
import { RuleCanaryDeployer } from './rule-canary-deployer.js';
|
|
10
|
+
// ── Rule Proposal Manager ──────────────────────────────
|
|
11
|
+
export class RuleProposalManager {
|
|
12
|
+
metaVerifier;
|
|
13
|
+
conflictDetector;
|
|
14
|
+
canaryDeployer;
|
|
15
|
+
pendingApprovals = new Map();
|
|
16
|
+
activeRules = [];
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
this.metaVerifier = opts?.metaVerifier ?? new RuleMetaVerifier();
|
|
19
|
+
this.conflictDetector = opts?.conflictDetector ?? new RuleConflictDetector();
|
|
20
|
+
this.canaryDeployer = opts?.canaryDeployer ?? new RuleCanaryDeployer();
|
|
21
|
+
this.activeRules = opts?.existingRules ? [...opts.existingRules] : [];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Propose a new verification rule.
|
|
25
|
+
* Runs meta-verification and conflict detection, then queues for approval.
|
|
26
|
+
*/
|
|
27
|
+
async propose(rule, justification) {
|
|
28
|
+
const proposalId = `mod_rule_${Date.now()}_${randomUUID().slice(0, 8)}`;
|
|
29
|
+
// Step 1: Meta-verification
|
|
30
|
+
const metaVerification = await this.metaVerifier.verify(rule, this.activeRules);
|
|
31
|
+
// Step 2: Conflict detection
|
|
32
|
+
const conflictReport = this.conflictDetector.checkNewRule(rule, this.activeRules);
|
|
33
|
+
// Determine status
|
|
34
|
+
const blockers = [...metaVerification.blockers];
|
|
35
|
+
if (conflictReport.direct_conflicts.length > 0) {
|
|
36
|
+
blockers.push(`${conflictReport.direct_conflicts.length} direct conflict(s) with existing rules`);
|
|
37
|
+
}
|
|
38
|
+
if (conflictReport.transitive_chains.length > 0) {
|
|
39
|
+
blockers.push(`${conflictReport.transitive_chains.length} transitive conflict chain(s) detected`);
|
|
40
|
+
}
|
|
41
|
+
const status = blockers.length > 0 ? 'rejected' : 'pending_approval';
|
|
42
|
+
// Create proposal
|
|
43
|
+
const proposal = {
|
|
44
|
+
id: proposalId,
|
|
45
|
+
type: 'rule',
|
|
46
|
+
timestamp: new Date().toISOString(),
|
|
47
|
+
title: `New rule: ${rule.name}`,
|
|
48
|
+
description: `${rule.substrate} rule targeting ${rule.target.claim_categories.join(', ')} in ${rule.target.languages.join(', ')}`,
|
|
49
|
+
payload: rule,
|
|
50
|
+
justification,
|
|
51
|
+
safety: {
|
|
52
|
+
modifies_layer2: false,
|
|
53
|
+
modifies_approval_framework: false,
|
|
54
|
+
trust_level_required: 'elevated',
|
|
55
|
+
rollback_plan: `Deprecate rule ${rule.id} and rollback canary deployment`,
|
|
56
|
+
},
|
|
57
|
+
proposed_by: rule.created_by,
|
|
58
|
+
status,
|
|
59
|
+
verification_id: metaVerification.verification_id,
|
|
60
|
+
};
|
|
61
|
+
if (status !== 'rejected') {
|
|
62
|
+
this.pendingApprovals.set(proposalId, {
|
|
63
|
+
proposal,
|
|
64
|
+
metaVerification,
|
|
65
|
+
conflictReport,
|
|
66
|
+
ruleDefinition: rule,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
proposalId,
|
|
71
|
+
metaVerification,
|
|
72
|
+
conflictReport,
|
|
73
|
+
status,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* List all pending rule approvals.
|
|
78
|
+
*/
|
|
79
|
+
listPending() {
|
|
80
|
+
return Array.from(this.pendingApprovals.values());
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get a specific pending approval.
|
|
84
|
+
*/
|
|
85
|
+
getPending(proposalId) {
|
|
86
|
+
return this.pendingApprovals.get(proposalId);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Approve a pending rule proposal.
|
|
90
|
+
* Starts the canary deployment pipeline.
|
|
91
|
+
*/
|
|
92
|
+
approve(proposalId, approvedBy, reasoning) {
|
|
93
|
+
const pending = this.pendingApprovals.get(proposalId);
|
|
94
|
+
if (!pending) {
|
|
95
|
+
throw new Error(`No pending approval found for "${proposalId}"`);
|
|
96
|
+
}
|
|
97
|
+
const approval = {
|
|
98
|
+
proposal_id: proposalId,
|
|
99
|
+
decision: 'approved',
|
|
100
|
+
decided_by: approvedBy,
|
|
101
|
+
decided_at: new Date().toISOString(),
|
|
102
|
+
reasoning,
|
|
103
|
+
};
|
|
104
|
+
// Update rule status
|
|
105
|
+
const approvedRule = {
|
|
106
|
+
...pending.ruleDefinition,
|
|
107
|
+
approved_by: approvedBy,
|
|
108
|
+
approved_at: new Date().toISOString(),
|
|
109
|
+
status: 'shadow',
|
|
110
|
+
};
|
|
111
|
+
// Start canary deployment
|
|
112
|
+
const deployment = this.canaryDeployer.startDeployment(approvedRule);
|
|
113
|
+
// Remove from pending
|
|
114
|
+
this.pendingApprovals.delete(proposalId);
|
|
115
|
+
return {
|
|
116
|
+
approval,
|
|
117
|
+
rule: approvedRule,
|
|
118
|
+
canaryStage: deployment.stage,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Reject a pending rule proposal.
|
|
123
|
+
*/
|
|
124
|
+
reject(proposalId, rejectedBy, reasoning) {
|
|
125
|
+
const pending = this.pendingApprovals.get(proposalId);
|
|
126
|
+
if (!pending) {
|
|
127
|
+
throw new Error(`No pending approval found for "${proposalId}"`);
|
|
128
|
+
}
|
|
129
|
+
this.pendingApprovals.delete(proposalId);
|
|
130
|
+
return {
|
|
131
|
+
proposal_id: proposalId,
|
|
132
|
+
decision: 'rejected',
|
|
133
|
+
decided_by: rejectedBy,
|
|
134
|
+
decided_at: new Date().toISOString(),
|
|
135
|
+
reasoning,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Check if a canary rule is ready to promote.
|
|
140
|
+
*/
|
|
141
|
+
checkCanaryPromotion(ruleId) {
|
|
142
|
+
return this.canaryDeployer.checkPromotion(ruleId);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Promote a canary rule to the next stage.
|
|
146
|
+
* When promoted to full_rollout, adds to active rules.
|
|
147
|
+
*/
|
|
148
|
+
promoteCanary(ruleId) {
|
|
149
|
+
const deployment = this.canaryDeployer.promote(ruleId);
|
|
150
|
+
if (!deployment) {
|
|
151
|
+
return { promoted: false, stage: 'unknown', isActive: false };
|
|
152
|
+
}
|
|
153
|
+
const isActive = deployment.stage === 'full_rollout';
|
|
154
|
+
// If fully rolled out, add to active rules
|
|
155
|
+
if (isActive) {
|
|
156
|
+
// Find the rule in canary state and mark as active
|
|
157
|
+
// (The actual rule data would be stored in the capability registry in production)
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
promoted: true,
|
|
161
|
+
stage: deployment.stage,
|
|
162
|
+
isActive,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Rollback a canary deployment.
|
|
167
|
+
*/
|
|
168
|
+
rollbackCanary(ruleId) {
|
|
169
|
+
return this.canaryDeployer.rollback(ruleId);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get the canary deployer (for recording evaluations externally).
|
|
173
|
+
*/
|
|
174
|
+
getCanaryDeployer() {
|
|
175
|
+
return this.canaryDeployer;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get all active rules.
|
|
179
|
+
*/
|
|
180
|
+
getActiveRules() {
|
|
181
|
+
return this.activeRules;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Add a rule to the active set (used when loading from registry).
|
|
185
|
+
*/
|
|
186
|
+
addActiveRule(rule) {
|
|
187
|
+
this.activeRules.push(rule);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=rule-proposal-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-proposal-manager.js","sourceRoot":"","sources":["../../src/runtime/rule-proposal-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { SafetyPolicy, SafetyCircuitBreaker } from './types.js';
|
|
2
|
+
import type { TrustManager } from './trust-manager.js';
|
|
3
|
+
import type { CollusionDetector } from './collusion-detector.js';
|
|
4
|
+
import type { HumanEscalationManager, EscalationContext } from './human-escalation.js';
|
|
5
|
+
export declare class SafetyEnforcer {
|
|
6
|
+
private policy;
|
|
7
|
+
private trustManager;
|
|
8
|
+
private collusionDetector;
|
|
9
|
+
private escalationManager;
|
|
10
|
+
private breakers;
|
|
11
|
+
private halted;
|
|
12
|
+
private haltReason;
|
|
13
|
+
constructor(policy: SafetyPolicy, trustManager: TrustManager, collusionDetector: CollusionDetector, escalationManager: HumanEscalationManager);
|
|
14
|
+
/**
|
|
15
|
+
* Check all safety signals and trip breakers if thresholds exceeded.
|
|
16
|
+
* Returns whether the system should halt.
|
|
17
|
+
*/
|
|
18
|
+
evaluate(context: EscalationContext): {
|
|
19
|
+
shouldHalt: boolean;
|
|
20
|
+
trippedBreakers: SafetyCircuitBreaker[];
|
|
21
|
+
reason: string | null;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Check if a specific task has exceeded reject cycles.
|
|
25
|
+
*/
|
|
26
|
+
checkTaskRejectCycles(taskId: string, attempts: number, context: EscalationContext): boolean;
|
|
27
|
+
/** Get all circuit breakers and their states. */
|
|
28
|
+
getBreakers(): readonly SafetyCircuitBreaker[];
|
|
29
|
+
/** Check if the system is halted. */
|
|
30
|
+
isHalted(): boolean;
|
|
31
|
+
/** Get the halt reason if halted. */
|
|
32
|
+
getHaltReason(): string | null;
|
|
33
|
+
/** Reset all circuit breakers (e.g., after human intervention). */
|
|
34
|
+
reset(): void;
|
|
35
|
+
}
|