tryassay 0.3.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 +142 -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 +69 -0
- package/dist/commands/runtime.js +673 -0
- package/dist/commands/runtime.js.map +1 -1
- package/dist/runtime/agent-loop.d.ts +6 -0
- package/dist/runtime/agent-loop.js +87 -5
- package/dist/runtime/agent-loop.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/code-agent.d.ts +11 -0
- package/dist/runtime/agents/code-agent.js +90 -0
- package/dist/runtime/agents/code-agent.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/review-agent.d.ts +11 -0
- package/dist/runtime/agents/review-agent.js +96 -0
- package/dist/runtime/agents/review-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/composition-verifier.d.ts +22 -0
- package/dist/runtime/composition-verifier.js +265 -0
- package/dist/runtime/composition-verifier.js.map +1 -0
- package/dist/runtime/confidence-calibrator.d.ts +10 -0
- package/dist/runtime/confidence-calibrator.js +95 -0
- package/dist/runtime/confidence-calibrator.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/enriched-prompt-builder.d.ts +25 -0
- package/dist/runtime/enriched-prompt-builder.js +173 -0
- package/dist/runtime/enriched-prompt-builder.js.map +1 -0
- package/dist/runtime/gap-detector.d.ts +6 -0
- package/dist/runtime/gap-detector.js +111 -0
- package/dist/runtime/gap-detector.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/message-bus.d.ts +57 -0
- package/dist/runtime/message-bus.js +115 -0
- package/dist/runtime/message-bus.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/pattern-extractor.d.ts +20 -0
- package/dist/runtime/pattern-extractor.js +257 -0
- package/dist/runtime/pattern-extractor.js.map +1 -0
- package/dist/runtime/planner.d.ts +2 -2
- package/dist/runtime/planner.js +10 -7
- package/dist/runtime/planner.js.map +1 -1
- 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/reasoner.d.ts +2 -2
- package/dist/runtime/reasoner.js +9 -5
- package/dist/runtime/reasoner.js.map +1 -1
- package/dist/runtime/reflector.d.ts +7 -1
- package/dist/runtime/reflector.js.map +1 -1
- 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/shadow-runner.d.ts +14 -0
- package/dist/runtime/shadow-runner.js +190 -0
- package/dist/runtime/shadow-runner.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 +72 -0
- package/dist/runtime/specialized-agent.js +123 -0
- package/dist/runtime/specialized-agent.js.map +1 -0
- 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/strategy-library.d.ts +11 -0
- package/dist/runtime/strategy-library.js +142 -0
- package/dist/runtime/strategy-library.js.map +1 -0
- package/dist/runtime/supabase-experience-store.d.ts +19 -0
- package/dist/runtime/supabase-experience-store.js +215 -0
- package/dist/runtime/supabase-experience-store.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 +63 -0
- package/dist/runtime/trust-manager.js +212 -0
- package/dist/runtime/trust-manager.js.map +1 -0
- package/dist/runtime/two-agent-loop.d.ts +35 -0
- package/dist/runtime/two-agent-loop.js +208 -0
- package/dist/runtime/two-agent-loop.js.map +1 -0
- package/dist/runtime/types.d.ts +939 -1
- 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,289 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Rule Canary Deployer
|
|
3
|
+
// Manages rule progression: shadow -> canary 5% -> canary 25% -> full.
|
|
4
|
+
// Automatic rollback on error rate spikes.
|
|
5
|
+
// ============================================================
|
|
6
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
7
|
+
import { dirname } from 'node:path';
|
|
8
|
+
// ── Default Exit Criteria ───────────────────────────────
|
|
9
|
+
const DEFAULT_EXIT_CRITERIA = {
|
|
10
|
+
shadow: {
|
|
11
|
+
min_evaluations: 50,
|
|
12
|
+
max_error_rate: 0.05,
|
|
13
|
+
max_disagreement_rate: 0.15,
|
|
14
|
+
min_duration_hours: 24,
|
|
15
|
+
},
|
|
16
|
+
canary_5: {
|
|
17
|
+
min_evaluations: 100,
|
|
18
|
+
max_error_rate: 0.03,
|
|
19
|
+
max_disagreement_rate: 0.10,
|
|
20
|
+
min_duration_hours: 48,
|
|
21
|
+
},
|
|
22
|
+
canary_25: {
|
|
23
|
+
min_evaluations: 250,
|
|
24
|
+
max_error_rate: 0.02,
|
|
25
|
+
max_disagreement_rate: 0.05,
|
|
26
|
+
min_duration_hours: 24,
|
|
27
|
+
},
|
|
28
|
+
full_rollout: {
|
|
29
|
+
min_evaluations: 0,
|
|
30
|
+
max_error_rate: 0,
|
|
31
|
+
max_disagreement_rate: 0,
|
|
32
|
+
min_duration_hours: 0,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const STAGE_PROGRESSION = [
|
|
36
|
+
'shadow',
|
|
37
|
+
'canary_5',
|
|
38
|
+
'canary_25',
|
|
39
|
+
'full_rollout',
|
|
40
|
+
];
|
|
41
|
+
// ── Rule Canary Deployer ────────────────────────────────
|
|
42
|
+
export class RuleCanaryDeployer {
|
|
43
|
+
deployments = new Map();
|
|
44
|
+
evaluations = new Map();
|
|
45
|
+
statePath;
|
|
46
|
+
constructor(statePath) {
|
|
47
|
+
this.statePath = statePath ?? '.assay/canary-state.json';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Start canary deployment for a rule.
|
|
51
|
+
* Formal rules skip shadow mode (they are deterministic).
|
|
52
|
+
*/
|
|
53
|
+
startDeployment(rule, customExitCriteria) {
|
|
54
|
+
// Formal rules skip shadow mode
|
|
55
|
+
const startStage = rule.substrate.startsWith('formal_')
|
|
56
|
+
? 'canary_5'
|
|
57
|
+
: 'shadow';
|
|
58
|
+
const exitCriteria = {
|
|
59
|
+
...DEFAULT_EXIT_CRITERIA[startStage],
|
|
60
|
+
...(customExitCriteria?.[startStage] ?? {}),
|
|
61
|
+
};
|
|
62
|
+
const deployment = {
|
|
63
|
+
rule_id: rule.id,
|
|
64
|
+
stage: startStage,
|
|
65
|
+
started_at: new Date().toISOString(),
|
|
66
|
+
stage_duration_hours: 0,
|
|
67
|
+
metrics: this.emptyMetrics(),
|
|
68
|
+
exit_criteria: exitCriteria,
|
|
69
|
+
};
|
|
70
|
+
this.deployments.set(rule.id, deployment);
|
|
71
|
+
this.evaluations.set(rule.id, []);
|
|
72
|
+
return deployment;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Record a canary evaluation (comparison of new rule against baseline).
|
|
76
|
+
*/
|
|
77
|
+
recordEvaluation(evaluation) {
|
|
78
|
+
const evals = this.evaluations.get(evaluation.rule_id) ?? [];
|
|
79
|
+
evals.push(evaluation);
|
|
80
|
+
this.evaluations.set(evaluation.rule_id, evals);
|
|
81
|
+
// Update deployment metrics
|
|
82
|
+
const deployment = this.deployments.get(evaluation.rule_id);
|
|
83
|
+
if (deployment) {
|
|
84
|
+
const updatedMetrics = this.computeMetrics(evaluation.rule_id);
|
|
85
|
+
const updatedDeployment = {
|
|
86
|
+
...deployment,
|
|
87
|
+
metrics: updatedMetrics,
|
|
88
|
+
stage_duration_hours: this.computeDurationHours(deployment.started_at),
|
|
89
|
+
};
|
|
90
|
+
this.deployments.set(evaluation.rule_id, updatedDeployment);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if a rule is ready to promote to the next canary stage.
|
|
95
|
+
* Returns the next stage if ready, null if not ready, 'rollback' if metrics are bad.
|
|
96
|
+
*/
|
|
97
|
+
checkPromotion(ruleId) {
|
|
98
|
+
const deployment = this.deployments.get(ruleId);
|
|
99
|
+
if (!deployment) {
|
|
100
|
+
return { action: 'wait', reason: 'No active deployment found' };
|
|
101
|
+
}
|
|
102
|
+
const metrics = deployment.metrics;
|
|
103
|
+
const criteria = deployment.exit_criteria;
|
|
104
|
+
// Check for rollback conditions
|
|
105
|
+
if (metrics.error_rate > criteria.max_error_rate * 2) {
|
|
106
|
+
return {
|
|
107
|
+
action: 'rollback',
|
|
108
|
+
reason: `Error rate ${(metrics.error_rate * 100).toFixed(1)}% exceeds 2x threshold (${(criteria.max_error_rate * 100).toFixed(1)}%)`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Check exit criteria
|
|
112
|
+
if (metrics.total_evaluations < criteria.min_evaluations) {
|
|
113
|
+
return {
|
|
114
|
+
action: 'wait',
|
|
115
|
+
reason: `Need ${criteria.min_evaluations - metrics.total_evaluations} more evaluations (${metrics.total_evaluations}/${criteria.min_evaluations})`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const durationHours = this.computeDurationHours(deployment.started_at);
|
|
119
|
+
if (durationHours < criteria.min_duration_hours) {
|
|
120
|
+
return {
|
|
121
|
+
action: 'wait',
|
|
122
|
+
reason: `Need ${(criteria.min_duration_hours - durationHours).toFixed(1)} more hours (${durationHours.toFixed(1)}/${criteria.min_duration_hours}h)`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (metrics.error_rate > criteria.max_error_rate) {
|
|
126
|
+
return {
|
|
127
|
+
action: 'rollback',
|
|
128
|
+
reason: `Error rate ${(metrics.error_rate * 100).toFixed(1)}% exceeds threshold (${(criteria.max_error_rate * 100).toFixed(1)}%)`,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const disagreementRate = metrics.total_evaluations > 0
|
|
132
|
+
? metrics.disagreements / metrics.total_evaluations
|
|
133
|
+
: 0;
|
|
134
|
+
if (disagreementRate > criteria.max_disagreement_rate) {
|
|
135
|
+
return {
|
|
136
|
+
action: 'rollback',
|
|
137
|
+
reason: `Disagreement rate ${(disagreementRate * 100).toFixed(1)}% exceeds threshold (${(criteria.max_disagreement_rate * 100).toFixed(1)}%)`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// All criteria met — promote
|
|
141
|
+
const currentIdx = STAGE_PROGRESSION.indexOf(deployment.stage);
|
|
142
|
+
if (currentIdx >= STAGE_PROGRESSION.length - 1) {
|
|
143
|
+
return {
|
|
144
|
+
action: 'wait',
|
|
145
|
+
reason: 'Already at full rollout',
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const nextStage = STAGE_PROGRESSION[currentIdx + 1];
|
|
149
|
+
return {
|
|
150
|
+
action: 'promote',
|
|
151
|
+
nextStage,
|
|
152
|
+
reason: `All exit criteria met for ${deployment.stage}. Ready for ${nextStage}.`,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Promote a rule to the next canary stage.
|
|
157
|
+
*/
|
|
158
|
+
promote(ruleId) {
|
|
159
|
+
const deployment = this.deployments.get(ruleId);
|
|
160
|
+
if (!deployment)
|
|
161
|
+
return null;
|
|
162
|
+
const currentIdx = STAGE_PROGRESSION.indexOf(deployment.stage);
|
|
163
|
+
if (currentIdx >= STAGE_PROGRESSION.length - 1)
|
|
164
|
+
return null;
|
|
165
|
+
const nextStage = STAGE_PROGRESSION[currentIdx + 1];
|
|
166
|
+
const exitCriteria = DEFAULT_EXIT_CRITERIA[nextStage];
|
|
167
|
+
const promoted = {
|
|
168
|
+
...deployment,
|
|
169
|
+
stage: nextStage,
|
|
170
|
+
promoted_at: new Date().toISOString(),
|
|
171
|
+
started_at: new Date().toISOString(), // Reset timer for new stage
|
|
172
|
+
stage_duration_hours: 0,
|
|
173
|
+
metrics: this.emptyMetrics(), // Reset metrics for new stage
|
|
174
|
+
exit_criteria: exitCriteria,
|
|
175
|
+
};
|
|
176
|
+
this.deployments.set(ruleId, promoted);
|
|
177
|
+
this.evaluations.set(ruleId, []); // Reset evaluations for new stage
|
|
178
|
+
return promoted;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Rollback a rule's canary deployment. Removes it from all stages.
|
|
182
|
+
*/
|
|
183
|
+
rollback(ruleId) {
|
|
184
|
+
const deployment = this.deployments.get(ruleId);
|
|
185
|
+
if (!deployment) {
|
|
186
|
+
return { success: false, reason: 'No active deployment found' };
|
|
187
|
+
}
|
|
188
|
+
this.deployments.delete(ruleId);
|
|
189
|
+
this.evaluations.delete(ruleId);
|
|
190
|
+
return {
|
|
191
|
+
success: true,
|
|
192
|
+
reason: `Rolled back from ${deployment.stage} after ${deployment.metrics.total_evaluations} evaluations`,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get the current deployment state for a rule.
|
|
197
|
+
*/
|
|
198
|
+
getDeployment(ruleId) {
|
|
199
|
+
return this.deployments.get(ruleId);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* List all active canary deployments.
|
|
203
|
+
*/
|
|
204
|
+
listDeployments() {
|
|
205
|
+
return Array.from(this.deployments.values());
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check if a rule should be evaluated for a given request.
|
|
209
|
+
* Based on the canary stage traffic percentage.
|
|
210
|
+
*/
|
|
211
|
+
shouldEvaluate(ruleId) {
|
|
212
|
+
const deployment = this.deployments.get(ruleId);
|
|
213
|
+
if (!deployment)
|
|
214
|
+
return false;
|
|
215
|
+
switch (deployment.stage) {
|
|
216
|
+
case 'shadow': return true; // Always evaluate in shadow (results not used)
|
|
217
|
+
case 'canary_5': return Math.random() < 0.05;
|
|
218
|
+
case 'canary_25': return Math.random() < 0.25;
|
|
219
|
+
case 'full_rollout': return true;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Save deployment state to disk.
|
|
224
|
+
*/
|
|
225
|
+
async saveState() {
|
|
226
|
+
const state = {
|
|
227
|
+
deployments: Object.fromEntries(this.deployments),
|
|
228
|
+
evaluationCounts: Object.fromEntries(Array.from(this.evaluations.entries()).map(([k, v]) => [k, v.length])),
|
|
229
|
+
};
|
|
230
|
+
await mkdir(dirname(this.statePath), { recursive: true });
|
|
231
|
+
await writeFile(this.statePath, JSON.stringify(state, null, 2), 'utf-8');
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Load deployment state from disk.
|
|
235
|
+
*/
|
|
236
|
+
async loadState() {
|
|
237
|
+
try {
|
|
238
|
+
const raw = await readFile(this.statePath, 'utf-8');
|
|
239
|
+
const state = JSON.parse(raw);
|
|
240
|
+
if (state.deployments) {
|
|
241
|
+
this.deployments = new Map(Object.entries(state.deployments));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// No state file — start fresh
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ── Private helpers ────────────────────────────────────
|
|
249
|
+
computeMetrics(ruleId) {
|
|
250
|
+
const evals = this.evaluations.get(ruleId) ?? [];
|
|
251
|
+
if (evals.length === 0)
|
|
252
|
+
return this.emptyMetrics();
|
|
253
|
+
const totalEvaluations = evals.length;
|
|
254
|
+
const agreements = evals.filter(e => e.agreed).length;
|
|
255
|
+
const disagreements = totalEvaluations - agreements;
|
|
256
|
+
const errors = evals.filter(e => e.error !== undefined).length;
|
|
257
|
+
const totalLatency = evals.reduce((sum, e) => sum + e.latency_ms, 0);
|
|
258
|
+
// False positive: canary says FAIL, baseline says PASS
|
|
259
|
+
const falsePositives = evals.filter(e => e.canary_verdict === 'FAIL' && e.baseline_verdict === 'PASS').length;
|
|
260
|
+
// False negative: canary says PASS, baseline says FAIL
|
|
261
|
+
const falseNegatives = evals.filter(e => e.canary_verdict === 'PASS' && e.baseline_verdict === 'FAIL').length;
|
|
262
|
+
return {
|
|
263
|
+
total_evaluations: totalEvaluations,
|
|
264
|
+
agreements_with_baseline: agreements,
|
|
265
|
+
disagreements,
|
|
266
|
+
error_rate: totalEvaluations > 0 ? errors / totalEvaluations : 0,
|
|
267
|
+
false_positive_rate: totalEvaluations > 0 ? falsePositives / totalEvaluations : 0,
|
|
268
|
+
false_negative_rate: totalEvaluations > 0 ? falseNegatives / totalEvaluations : 0,
|
|
269
|
+
avg_latency_ms: totalEvaluations > 0 ? totalLatency / totalEvaluations : 0,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
computeDurationHours(startedAt) {
|
|
273
|
+
const start = new Date(startedAt).getTime();
|
|
274
|
+
const now = Date.now();
|
|
275
|
+
return (now - start) / (1000 * 60 * 60);
|
|
276
|
+
}
|
|
277
|
+
emptyMetrics() {
|
|
278
|
+
return {
|
|
279
|
+
total_evaluations: 0,
|
|
280
|
+
agreements_with_baseline: 0,
|
|
281
|
+
disagreements: 0,
|
|
282
|
+
error_rate: 0,
|
|
283
|
+
false_positive_rate: 0,
|
|
284
|
+
false_negative_rate: 0,
|
|
285
|
+
avg_latency_ms: 0,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=rule-canary-deployer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-canary-deployer.js","sourceRoot":"","sources":["../../src/runtime/rule-canary-deployer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { VerificationRule } from './types.js';
|
|
2
|
+
export interface ConflictReport {
|
|
3
|
+
readonly direct_conflicts: readonly DirectConflict[];
|
|
4
|
+
readonly scope_overlaps: readonly ScopeOverlap[];
|
|
5
|
+
readonly transitive_chains: readonly TransitiveChain[];
|
|
6
|
+
readonly summary: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DirectConflict {
|
|
9
|
+
readonly rule_a: string;
|
|
10
|
+
readonly rule_b: string;
|
|
11
|
+
readonly test_case_id: string;
|
|
12
|
+
readonly rule_a_verdict: 'PASS' | 'FAIL';
|
|
13
|
+
readonly rule_b_verdict: 'PASS' | 'FAIL';
|
|
14
|
+
readonly description: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ScopeOverlap {
|
|
17
|
+
readonly rule_a: string;
|
|
18
|
+
readonly rule_b: string;
|
|
19
|
+
readonly overlapping_categories: readonly string[];
|
|
20
|
+
readonly overlapping_languages: readonly string[];
|
|
21
|
+
readonly risk: 'low' | 'medium' | 'high';
|
|
22
|
+
readonly description: string;
|
|
23
|
+
}
|
|
24
|
+
export interface TransitiveChain {
|
|
25
|
+
readonly chain: readonly string[];
|
|
26
|
+
readonly root_conflict: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class RuleConflictDetector {
|
|
29
|
+
/**
|
|
30
|
+
* Perform comprehensive conflict analysis on a set of rules.
|
|
31
|
+
* Detects direct conflicts (opposite verdicts on same input),
|
|
32
|
+
* scope overlaps (same claim categories + languages), and
|
|
33
|
+
* transitive conflict chains.
|
|
34
|
+
*/
|
|
35
|
+
analyze(rules: readonly VerificationRule[]): ConflictReport;
|
|
36
|
+
/**
|
|
37
|
+
* Check if adding a new rule would introduce conflicts.
|
|
38
|
+
*/
|
|
39
|
+
checkNewRule(newRule: VerificationRule, existingRules: readonly VerificationRule[]): ConflictReport;
|
|
40
|
+
private findDirectConflicts;
|
|
41
|
+
private compareRulePair;
|
|
42
|
+
private runFormalCheck;
|
|
43
|
+
private findScopeOverlaps;
|
|
44
|
+
private assessOverlapRisk;
|
|
45
|
+
private findTransitiveChains;
|
|
46
|
+
private hasOverlappingScope;
|
|
47
|
+
private generateSummary;
|
|
48
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Assay Verified Agent Runtime — Rule Conflict Detector
|
|
3
|
+
// Finds rules that contradict each other, detects scope overlaps,
|
|
4
|
+
// and identifies transitive conflict chains.
|
|
5
|
+
// ============================================================
|
|
6
|
+
// ── Rule Conflict Detector ──────────────────────────────
|
|
7
|
+
export class RuleConflictDetector {
|
|
8
|
+
/**
|
|
9
|
+
* Perform comprehensive conflict analysis on a set of rules.
|
|
10
|
+
* Detects direct conflicts (opposite verdicts on same input),
|
|
11
|
+
* scope overlaps (same claim categories + languages), and
|
|
12
|
+
* transitive conflict chains.
|
|
13
|
+
*/
|
|
14
|
+
analyze(rules) {
|
|
15
|
+
const directConflicts = this.findDirectConflicts(rules);
|
|
16
|
+
const scopeOverlaps = this.findScopeOverlaps(rules);
|
|
17
|
+
const transitiveChains = this.findTransitiveChains(directConflicts, rules);
|
|
18
|
+
const summary = this.generateSummary(directConflicts, scopeOverlaps, transitiveChains);
|
|
19
|
+
return {
|
|
20
|
+
direct_conflicts: directConflicts,
|
|
21
|
+
scope_overlaps: scopeOverlaps,
|
|
22
|
+
transitive_chains: transitiveChains,
|
|
23
|
+
summary,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if adding a new rule would introduce conflicts.
|
|
28
|
+
*/
|
|
29
|
+
checkNewRule(newRule, existingRules) {
|
|
30
|
+
const allRules = [...existingRules, newRule];
|
|
31
|
+
const fullReport = this.analyze(allRules);
|
|
32
|
+
// Filter to only conflicts involving the new rule
|
|
33
|
+
return {
|
|
34
|
+
direct_conflicts: fullReport.direct_conflicts.filter(c => c.rule_a === newRule.id || c.rule_b === newRule.id),
|
|
35
|
+
scope_overlaps: fullReport.scope_overlaps.filter(o => o.rule_a === newRule.id || o.rule_b === newRule.id),
|
|
36
|
+
transitive_chains: fullReport.transitive_chains.filter(t => t.chain.includes(newRule.id)),
|
|
37
|
+
summary: fullReport.summary,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// ── Private: Direct Conflict Detection ─────────────────
|
|
41
|
+
findDirectConflicts(rules) {
|
|
42
|
+
const conflicts = [];
|
|
43
|
+
// For each pair of rules that have formal checks, compare
|
|
44
|
+
// their pattern behavior on each other's test cases
|
|
45
|
+
for (let i = 0; i < rules.length; i++) {
|
|
46
|
+
for (let j = i + 1; j < rules.length; j++) {
|
|
47
|
+
const ruleA = rules[i];
|
|
48
|
+
const ruleB = rules[j];
|
|
49
|
+
// Only compare rules with overlapping scope
|
|
50
|
+
if (!this.hasOverlappingScope(ruleA, ruleB))
|
|
51
|
+
continue;
|
|
52
|
+
// Test rule B's test cases against rule A (and vice versa)
|
|
53
|
+
const abConflicts = this.compareRulePair(ruleA, ruleB);
|
|
54
|
+
conflicts.push(...abConflicts);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return conflicts;
|
|
58
|
+
}
|
|
59
|
+
compareRulePair(ruleA, ruleB) {
|
|
60
|
+
const conflicts = [];
|
|
61
|
+
// Run ruleA's formal check against ruleB's test cases
|
|
62
|
+
if (ruleA.check.type === 'formal' || ruleA.check.type === 'composite') {
|
|
63
|
+
const formalCheck = ruleA.check.type === 'formal'
|
|
64
|
+
? ruleA.check
|
|
65
|
+
: ruleA.check.formal_component;
|
|
66
|
+
for (const testCase of ruleB.test_cases) {
|
|
67
|
+
if (!ruleA.target.languages.includes(testCase.input_language))
|
|
68
|
+
continue;
|
|
69
|
+
const aVerdict = this.runFormalCheck(formalCheck, testCase.input_code);
|
|
70
|
+
// If ruleA says PASS but the test case expects FAIL (or vice versa),
|
|
71
|
+
// this is a potential conflict
|
|
72
|
+
if (aVerdict !== testCase.expected_verdict) {
|
|
73
|
+
conflicts.push({
|
|
74
|
+
rule_a: ruleA.id,
|
|
75
|
+
rule_b: ruleB.id,
|
|
76
|
+
test_case_id: testCase.id,
|
|
77
|
+
rule_a_verdict: aVerdict,
|
|
78
|
+
rule_b_verdict: testCase.expected_verdict,
|
|
79
|
+
description: `Rule "${ruleA.name}" produces ${aVerdict} on test case "${testCase.description}" from rule "${ruleB.name}" which expects ${testCase.expected_verdict}`,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return conflicts;
|
|
85
|
+
}
|
|
86
|
+
runFormalCheck(check, code) {
|
|
87
|
+
const results = [];
|
|
88
|
+
for (const pattern of check.patterns) {
|
|
89
|
+
if (pattern.pattern_type === 'regex') {
|
|
90
|
+
try {
|
|
91
|
+
const regex = new RegExp(pattern.pattern, 'gm');
|
|
92
|
+
results.push(regex.test(code));
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
results.push(false);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Non-regex patterns are skipped in conflict detection
|
|
100
|
+
results.push(true);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
switch (check.logic) {
|
|
104
|
+
case 'all_match': return results.every(r => r) ? 'PASS' : 'FAIL';
|
|
105
|
+
case 'any_match': return results.some(r => r) ? 'PASS' : 'FAIL';
|
|
106
|
+
case 'none_match': return results.every(r => !r) ? 'PASS' : 'FAIL';
|
|
107
|
+
case 'custom': return results.every(r => r) ? 'PASS' : 'FAIL';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ── Private: Scope Overlap Detection ───────────────────
|
|
111
|
+
findScopeOverlaps(rules) {
|
|
112
|
+
const overlaps = [];
|
|
113
|
+
for (let i = 0; i < rules.length; i++) {
|
|
114
|
+
for (let j = i + 1; j < rules.length; j++) {
|
|
115
|
+
const ruleA = rules[i];
|
|
116
|
+
const ruleB = rules[j];
|
|
117
|
+
const overlappingCategories = ruleA.target.claim_categories.filter(c => ruleB.target.claim_categories.includes(c));
|
|
118
|
+
const overlappingLanguages = ruleA.target.languages.filter(l => ruleB.target.languages.includes(l));
|
|
119
|
+
if (overlappingCategories.length > 0 && overlappingLanguages.length > 0) {
|
|
120
|
+
// Determine risk based on substrate compatibility
|
|
121
|
+
const risk = this.assessOverlapRisk(ruleA, ruleB, overlappingCategories);
|
|
122
|
+
overlaps.push({
|
|
123
|
+
rule_a: ruleA.id,
|
|
124
|
+
rule_b: ruleB.id,
|
|
125
|
+
overlapping_categories: overlappingCategories,
|
|
126
|
+
overlapping_languages: overlappingLanguages,
|
|
127
|
+
risk,
|
|
128
|
+
description: `Rules "${ruleA.name}" and "${ruleB.name}" both target ${overlappingCategories.join(', ')} in ${overlappingLanguages.join(', ')}`,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return overlaps;
|
|
134
|
+
}
|
|
135
|
+
assessOverlapRisk(ruleA, ruleB, overlappingCategories) {
|
|
136
|
+
// Two formal rules with overlapping scope = low risk (deterministic, can be reconciled)
|
|
137
|
+
if (ruleA.substrate.startsWith('formal_') && ruleB.substrate.startsWith('formal_')) {
|
|
138
|
+
return 'low';
|
|
139
|
+
}
|
|
140
|
+
// Formal + LLM = medium risk (formal override handles disagreement)
|
|
141
|
+
if (ruleA.substrate.startsWith('formal_') || ruleB.substrate.startsWith('formal_')) {
|
|
142
|
+
return 'medium';
|
|
143
|
+
}
|
|
144
|
+
// Two LLM rules with many overlapping categories = high risk
|
|
145
|
+
if (overlappingCategories.length >= 2) {
|
|
146
|
+
return 'high';
|
|
147
|
+
}
|
|
148
|
+
return 'medium';
|
|
149
|
+
}
|
|
150
|
+
// ── Private: Transitive Chain Detection ────────────────
|
|
151
|
+
findTransitiveChains(directConflicts, _rules) {
|
|
152
|
+
// Build an adjacency graph of conflicts
|
|
153
|
+
const conflictGraph = new Map();
|
|
154
|
+
for (const conflict of directConflicts) {
|
|
155
|
+
if (!conflictGraph.has(conflict.rule_a)) {
|
|
156
|
+
conflictGraph.set(conflict.rule_a, new Set());
|
|
157
|
+
}
|
|
158
|
+
if (!conflictGraph.has(conflict.rule_b)) {
|
|
159
|
+
conflictGraph.set(conflict.rule_b, new Set());
|
|
160
|
+
}
|
|
161
|
+
conflictGraph.get(conflict.rule_a).add(conflict.rule_b);
|
|
162
|
+
conflictGraph.get(conflict.rule_b).add(conflict.rule_a);
|
|
163
|
+
}
|
|
164
|
+
// Find connected components of size > 2 (transitive chains)
|
|
165
|
+
const visited = new Set();
|
|
166
|
+
const chains = [];
|
|
167
|
+
for (const [ruleId] of conflictGraph) {
|
|
168
|
+
if (visited.has(ruleId))
|
|
169
|
+
continue;
|
|
170
|
+
const component = [];
|
|
171
|
+
const queue = [ruleId];
|
|
172
|
+
while (queue.length > 0) {
|
|
173
|
+
const current = queue.shift();
|
|
174
|
+
if (visited.has(current))
|
|
175
|
+
continue;
|
|
176
|
+
visited.add(current);
|
|
177
|
+
component.push(current);
|
|
178
|
+
const neighbors = conflictGraph.get(current) ?? new Set();
|
|
179
|
+
for (const neighbor of neighbors) {
|
|
180
|
+
if (!visited.has(neighbor)) {
|
|
181
|
+
queue.push(neighbor);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (component.length > 2) {
|
|
186
|
+
chains.push({
|
|
187
|
+
chain: component,
|
|
188
|
+
root_conflict: `${component.length} rules form a transitive conflict chain: ${component.join(' <-> ')}`,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return chains;
|
|
193
|
+
}
|
|
194
|
+
// ── Private: Helpers ───────────────────────────────────
|
|
195
|
+
hasOverlappingScope(a, b) {
|
|
196
|
+
const categoryOverlap = a.target.claim_categories.some(c => b.target.claim_categories.includes(c));
|
|
197
|
+
const languageOverlap = a.target.languages.some(l => b.target.languages.includes(l));
|
|
198
|
+
return categoryOverlap && languageOverlap;
|
|
199
|
+
}
|
|
200
|
+
generateSummary(conflicts, overlaps, chains) {
|
|
201
|
+
const parts = [];
|
|
202
|
+
parts.push(`Direct conflicts: ${conflicts.length}`);
|
|
203
|
+
parts.push(`Scope overlaps: ${overlaps.length} (${overlaps.filter(o => o.risk === 'high').length} high-risk)`);
|
|
204
|
+
parts.push(`Transitive chains: ${chains.length}`);
|
|
205
|
+
if (conflicts.length === 0 && chains.length === 0) {
|
|
206
|
+
parts.push('No conflicts detected. Safe to proceed.');
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
parts.push('Manual review recommended before activation.');
|
|
210
|
+
}
|
|
211
|
+
return parts.join('. ');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=rule-conflict-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-conflict-detector.js","sourceRoot":"","sources":["../../src/runtime/rule-conflict-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { VerificationRule, RuleMetaVerification } from './types.js';
|
|
2
|
+
export declare class RuleMetaVerifier {
|
|
3
|
+
private consistencyRuns;
|
|
4
|
+
constructor(opts?: {
|
|
5
|
+
consistencyRuns?: number;
|
|
6
|
+
});
|
|
7
|
+
/**
|
|
8
|
+
* Meta-verify a proposed rule:
|
|
9
|
+
* 1. Run all test cases through the rule's check logic
|
|
10
|
+
* 2. Check consistency (run multiple times for LLM-based rules)
|
|
11
|
+
* 3. Check for conflicts with existing rules
|
|
12
|
+
* Returns a RuleMetaVerification report.
|
|
13
|
+
*/
|
|
14
|
+
verify(proposedRule: VerificationRule, existingRules: readonly VerificationRule[]): Promise<RuleMetaVerification>;
|
|
15
|
+
private runTestCases;
|
|
16
|
+
private checkConsistency;
|
|
17
|
+
private checkConflicts;
|
|
18
|
+
}
|