tryassay 0.6.0 → 0.11.1

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.
Files changed (109) hide show
  1. package/dist/api/pricing-enforcer.d.ts +45 -0
  2. package/dist/api/pricing-enforcer.js +144 -0
  3. package/dist/api/pricing-enforcer.js.map +1 -0
  4. package/dist/api/server.d.ts +28 -0
  5. package/dist/api/server.js +265 -0
  6. package/dist/api/server.js.map +1 -0
  7. package/dist/api/team-session.d.ts +59 -0
  8. package/dist/api/team-session.js +240 -0
  9. package/dist/api/team-session.js.map +1 -0
  10. package/dist/cli.js +123 -2
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/api.d.ts +4 -0
  13. package/dist/commands/api.js +50 -0
  14. package/dist/commands/api.js.map +1 -0
  15. package/dist/commands/runtime.d.ts +61 -0
  16. package/dist/commands/runtime.js +554 -0
  17. package/dist/commands/runtime.js.map +1 -1
  18. package/dist/runtime/agent-spawner.d.ts +56 -0
  19. package/dist/runtime/agent-spawner.js +217 -0
  20. package/dist/runtime/agent-spawner.js.map +1 -0
  21. package/dist/runtime/agents/coordinator-agent.d.ts +20 -0
  22. package/dist/runtime/agents/coordinator-agent.js +182 -0
  23. package/dist/runtime/agents/coordinator-agent.js.map +1 -0
  24. package/dist/runtime/agents/ops-agent.d.ts +11 -0
  25. package/dist/runtime/agents/ops-agent.js +113 -0
  26. package/dist/runtime/agents/ops-agent.js.map +1 -0
  27. package/dist/runtime/agents/research-agent.d.ts +11 -0
  28. package/dist/runtime/agents/research-agent.js +114 -0
  29. package/dist/runtime/agents/research-agent.js.map +1 -0
  30. package/dist/runtime/agents/test-agent.d.ts +11 -0
  31. package/dist/runtime/agents/test-agent.js +114 -0
  32. package/dist/runtime/agents/test-agent.js.map +1 -0
  33. package/dist/runtime/audit-log.js +2 -2
  34. package/dist/runtime/audit-log.js.map +1 -1
  35. package/dist/runtime/capability-registry.d.ts +62 -0
  36. package/dist/runtime/capability-registry.js +191 -0
  37. package/dist/runtime/capability-registry.js.map +1 -0
  38. package/dist/runtime/collusion-detector.d.ts +35 -0
  39. package/dist/runtime/collusion-detector.js +97 -0
  40. package/dist/runtime/collusion-detector.js.map +1 -0
  41. package/dist/runtime/control-server.js +8 -4
  42. package/dist/runtime/control-server.js.map +1 -1
  43. package/dist/runtime/domain-coverage-analyzer.d.ts +24 -0
  44. package/dist/runtime/domain-coverage-analyzer.js +178 -0
  45. package/dist/runtime/domain-coverage-analyzer.js.map +1 -0
  46. package/dist/runtime/executor.js +27 -12
  47. package/dist/runtime/executor.js.map +1 -1
  48. package/dist/runtime/human-escalation.d.ts +41 -0
  49. package/dist/runtime/human-escalation.js +122 -0
  50. package/dist/runtime/human-escalation.js.map +1 -0
  51. package/dist/runtime/kill-switch.d.ts +51 -0
  52. package/dist/runtime/kill-switch.js +185 -0
  53. package/dist/runtime/kill-switch.js.map +1 -0
  54. package/dist/runtime/layer2-guardian.d.ts +81 -0
  55. package/dist/runtime/layer2-guardian.js +263 -0
  56. package/dist/runtime/layer2-guardian.js.map +1 -0
  57. package/dist/runtime/multi-agent-loop.d.ts +37 -0
  58. package/dist/runtime/multi-agent-loop.js +411 -0
  59. package/dist/runtime/multi-agent-loop.js.map +1 -0
  60. package/dist/runtime/prompt-safety-analyzer.d.ts +17 -0
  61. package/dist/runtime/prompt-safety-analyzer.js +230 -0
  62. package/dist/runtime/prompt-safety-analyzer.js.map +1 -0
  63. package/dist/runtime/rollback-manager.d.ts +50 -0
  64. package/dist/runtime/rollback-manager.js +157 -0
  65. package/dist/runtime/rollback-manager.js.map +1 -0
  66. package/dist/runtime/rule-canary-deployer.d.ts +69 -0
  67. package/dist/runtime/rule-canary-deployer.js +289 -0
  68. package/dist/runtime/rule-canary-deployer.js.map +1 -0
  69. package/dist/runtime/rule-conflict-detector.d.ts +48 -0
  70. package/dist/runtime/rule-conflict-detector.js +214 -0
  71. package/dist/runtime/rule-conflict-detector.js.map +1 -0
  72. package/dist/runtime/rule-meta-verifier.d.ts +18 -0
  73. package/dist/runtime/rule-meta-verifier.js +275 -0
  74. package/dist/runtime/rule-meta-verifier.js.map +1 -0
  75. package/dist/runtime/rule-proposal-manager.d.ts +95 -0
  76. package/dist/runtime/rule-proposal-manager.js +190 -0
  77. package/dist/runtime/rule-proposal-manager.js.map +1 -0
  78. package/dist/runtime/safety-enforcer.d.ts +35 -0
  79. package/dist/runtime/safety-enforcer.js +165 -0
  80. package/dist/runtime/safety-enforcer.js.map +1 -0
  81. package/dist/runtime/safety-status.d.ts +48 -0
  82. package/dist/runtime/safety-status.js +119 -0
  83. package/dist/runtime/safety-status.js.map +1 -0
  84. package/dist/runtime/shared-memory.d.ts +47 -0
  85. package/dist/runtime/shared-memory.js +151 -0
  86. package/dist/runtime/shared-memory.js.map +1 -0
  87. package/dist/runtime/specialized-agent.d.ts +5 -0
  88. package/dist/runtime/specialized-agent.js +37 -0
  89. package/dist/runtime/specialized-agent.js.map +1 -1
  90. package/dist/runtime/stall-detector.d.ts +13 -0
  91. package/dist/runtime/stall-detector.js +121 -0
  92. package/dist/runtime/stall-detector.js.map +1 -0
  93. package/dist/runtime/tool-approval.d.ts +51 -0
  94. package/dist/runtime/tool-approval.js +148 -0
  95. package/dist/runtime/tool-approval.js.map +1 -0
  96. package/dist/runtime/tool-sandbox.d.ts +43 -0
  97. package/dist/runtime/tool-sandbox.js +394 -0
  98. package/dist/runtime/tool-sandbox.js.map +1 -0
  99. package/dist/runtime/tool-verifier.d.ts +18 -0
  100. package/dist/runtime/tool-verifier.js +323 -0
  101. package/dist/runtime/tool-verifier.js.map +1 -0
  102. package/dist/runtime/trust-manager.d.ts +33 -3
  103. package/dist/runtime/trust-manager.js +128 -26
  104. package/dist/runtime/trust-manager.js.map +1 -1
  105. package/dist/runtime/types.d.ts +652 -0
  106. package/dist/runtime/verification-intensity.d.ts +34 -0
  107. package/dist/runtime/verification-intensity.js +104 -0
  108. package/dist/runtime/verification-intensity.js.map +1 -0
  109. 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
+ }