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.
Files changed (150) 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 +142 -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 +69 -0
  16. package/dist/commands/runtime.js +673 -0
  17. package/dist/commands/runtime.js.map +1 -1
  18. package/dist/runtime/agent-loop.d.ts +6 -0
  19. package/dist/runtime/agent-loop.js +87 -5
  20. package/dist/runtime/agent-loop.js.map +1 -1
  21. package/dist/runtime/agent-spawner.d.ts +56 -0
  22. package/dist/runtime/agent-spawner.js +217 -0
  23. package/dist/runtime/agent-spawner.js.map +1 -0
  24. package/dist/runtime/agents/code-agent.d.ts +11 -0
  25. package/dist/runtime/agents/code-agent.js +90 -0
  26. package/dist/runtime/agents/code-agent.js.map +1 -0
  27. package/dist/runtime/agents/coordinator-agent.d.ts +20 -0
  28. package/dist/runtime/agents/coordinator-agent.js +182 -0
  29. package/dist/runtime/agents/coordinator-agent.js.map +1 -0
  30. package/dist/runtime/agents/ops-agent.d.ts +11 -0
  31. package/dist/runtime/agents/ops-agent.js +113 -0
  32. package/dist/runtime/agents/ops-agent.js.map +1 -0
  33. package/dist/runtime/agents/research-agent.d.ts +11 -0
  34. package/dist/runtime/agents/research-agent.js +114 -0
  35. package/dist/runtime/agents/research-agent.js.map +1 -0
  36. package/dist/runtime/agents/review-agent.d.ts +11 -0
  37. package/dist/runtime/agents/review-agent.js +96 -0
  38. package/dist/runtime/agents/review-agent.js.map +1 -0
  39. package/dist/runtime/agents/test-agent.d.ts +11 -0
  40. package/dist/runtime/agents/test-agent.js +114 -0
  41. package/dist/runtime/agents/test-agent.js.map +1 -0
  42. package/dist/runtime/capability-registry.d.ts +62 -0
  43. package/dist/runtime/capability-registry.js +191 -0
  44. package/dist/runtime/capability-registry.js.map +1 -0
  45. package/dist/runtime/collusion-detector.d.ts +35 -0
  46. package/dist/runtime/collusion-detector.js +97 -0
  47. package/dist/runtime/collusion-detector.js.map +1 -0
  48. package/dist/runtime/composition-verifier.d.ts +22 -0
  49. package/dist/runtime/composition-verifier.js +265 -0
  50. package/dist/runtime/composition-verifier.js.map +1 -0
  51. package/dist/runtime/confidence-calibrator.d.ts +10 -0
  52. package/dist/runtime/confidence-calibrator.js +95 -0
  53. package/dist/runtime/confidence-calibrator.js.map +1 -0
  54. package/dist/runtime/domain-coverage-analyzer.d.ts +24 -0
  55. package/dist/runtime/domain-coverage-analyzer.js +178 -0
  56. package/dist/runtime/domain-coverage-analyzer.js.map +1 -0
  57. package/dist/runtime/enriched-prompt-builder.d.ts +25 -0
  58. package/dist/runtime/enriched-prompt-builder.js +173 -0
  59. package/dist/runtime/enriched-prompt-builder.js.map +1 -0
  60. package/dist/runtime/gap-detector.d.ts +6 -0
  61. package/dist/runtime/gap-detector.js +111 -0
  62. package/dist/runtime/gap-detector.js.map +1 -0
  63. package/dist/runtime/human-escalation.d.ts +41 -0
  64. package/dist/runtime/human-escalation.js +122 -0
  65. package/dist/runtime/human-escalation.js.map +1 -0
  66. package/dist/runtime/kill-switch.d.ts +51 -0
  67. package/dist/runtime/kill-switch.js +185 -0
  68. package/dist/runtime/kill-switch.js.map +1 -0
  69. package/dist/runtime/layer2-guardian.d.ts +81 -0
  70. package/dist/runtime/layer2-guardian.js +263 -0
  71. package/dist/runtime/layer2-guardian.js.map +1 -0
  72. package/dist/runtime/message-bus.d.ts +57 -0
  73. package/dist/runtime/message-bus.js +115 -0
  74. package/dist/runtime/message-bus.js.map +1 -0
  75. package/dist/runtime/multi-agent-loop.d.ts +37 -0
  76. package/dist/runtime/multi-agent-loop.js +411 -0
  77. package/dist/runtime/multi-agent-loop.js.map +1 -0
  78. package/dist/runtime/pattern-extractor.d.ts +20 -0
  79. package/dist/runtime/pattern-extractor.js +257 -0
  80. package/dist/runtime/pattern-extractor.js.map +1 -0
  81. package/dist/runtime/planner.d.ts +2 -2
  82. package/dist/runtime/planner.js +10 -7
  83. package/dist/runtime/planner.js.map +1 -1
  84. package/dist/runtime/prompt-safety-analyzer.d.ts +17 -0
  85. package/dist/runtime/prompt-safety-analyzer.js +230 -0
  86. package/dist/runtime/prompt-safety-analyzer.js.map +1 -0
  87. package/dist/runtime/reasoner.d.ts +2 -2
  88. package/dist/runtime/reasoner.js +9 -5
  89. package/dist/runtime/reasoner.js.map +1 -1
  90. package/dist/runtime/reflector.d.ts +7 -1
  91. package/dist/runtime/reflector.js.map +1 -1
  92. package/dist/runtime/rollback-manager.d.ts +50 -0
  93. package/dist/runtime/rollback-manager.js +157 -0
  94. package/dist/runtime/rollback-manager.js.map +1 -0
  95. package/dist/runtime/rule-canary-deployer.d.ts +69 -0
  96. package/dist/runtime/rule-canary-deployer.js +289 -0
  97. package/dist/runtime/rule-canary-deployer.js.map +1 -0
  98. package/dist/runtime/rule-conflict-detector.d.ts +48 -0
  99. package/dist/runtime/rule-conflict-detector.js +214 -0
  100. package/dist/runtime/rule-conflict-detector.js.map +1 -0
  101. package/dist/runtime/rule-meta-verifier.d.ts +18 -0
  102. package/dist/runtime/rule-meta-verifier.js +275 -0
  103. package/dist/runtime/rule-meta-verifier.js.map +1 -0
  104. package/dist/runtime/rule-proposal-manager.d.ts +95 -0
  105. package/dist/runtime/rule-proposal-manager.js +190 -0
  106. package/dist/runtime/rule-proposal-manager.js.map +1 -0
  107. package/dist/runtime/safety-enforcer.d.ts +35 -0
  108. package/dist/runtime/safety-enforcer.js +165 -0
  109. package/dist/runtime/safety-enforcer.js.map +1 -0
  110. package/dist/runtime/safety-status.d.ts +48 -0
  111. package/dist/runtime/safety-status.js +119 -0
  112. package/dist/runtime/safety-status.js.map +1 -0
  113. package/dist/runtime/shadow-runner.d.ts +14 -0
  114. package/dist/runtime/shadow-runner.js +190 -0
  115. package/dist/runtime/shadow-runner.js.map +1 -0
  116. package/dist/runtime/shared-memory.d.ts +47 -0
  117. package/dist/runtime/shared-memory.js +151 -0
  118. package/dist/runtime/shared-memory.js.map +1 -0
  119. package/dist/runtime/specialized-agent.d.ts +72 -0
  120. package/dist/runtime/specialized-agent.js +123 -0
  121. package/dist/runtime/specialized-agent.js.map +1 -0
  122. package/dist/runtime/stall-detector.d.ts +13 -0
  123. package/dist/runtime/stall-detector.js +121 -0
  124. package/dist/runtime/stall-detector.js.map +1 -0
  125. package/dist/runtime/strategy-library.d.ts +11 -0
  126. package/dist/runtime/strategy-library.js +142 -0
  127. package/dist/runtime/strategy-library.js.map +1 -0
  128. package/dist/runtime/supabase-experience-store.d.ts +19 -0
  129. package/dist/runtime/supabase-experience-store.js +215 -0
  130. package/dist/runtime/supabase-experience-store.js.map +1 -0
  131. package/dist/runtime/tool-approval.d.ts +51 -0
  132. package/dist/runtime/tool-approval.js +148 -0
  133. package/dist/runtime/tool-approval.js.map +1 -0
  134. package/dist/runtime/tool-sandbox.d.ts +43 -0
  135. package/dist/runtime/tool-sandbox.js +394 -0
  136. package/dist/runtime/tool-sandbox.js.map +1 -0
  137. package/dist/runtime/tool-verifier.d.ts +18 -0
  138. package/dist/runtime/tool-verifier.js +323 -0
  139. package/dist/runtime/tool-verifier.js.map +1 -0
  140. package/dist/runtime/trust-manager.d.ts +63 -0
  141. package/dist/runtime/trust-manager.js +212 -0
  142. package/dist/runtime/trust-manager.js.map +1 -0
  143. package/dist/runtime/two-agent-loop.d.ts +35 -0
  144. package/dist/runtime/two-agent-loop.js +208 -0
  145. package/dist/runtime/two-agent-loop.js.map +1 -0
  146. package/dist/runtime/types.d.ts +939 -1
  147. package/dist/runtime/verification-intensity.d.ts +34 -0
  148. package/dist/runtime/verification-intensity.js +104 -0
  149. package/dist/runtime/verification-intensity.js.map +1 -0
  150. package/package.json +1 -1
@@ -0,0 +1,165 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Safety Policy Enforcer
3
+ // Circuit breakers that halt the system when safety thresholds
4
+ // are exceeded. Integrates trust, collusion, and stall signals.
5
+ // ============================================================
6
+ import { randomUUID } from 'node:crypto';
7
+ // ── Safety Enforcer ────────────────────────────────────────
8
+ export class SafetyEnforcer {
9
+ policy;
10
+ trustManager;
11
+ collusionDetector;
12
+ escalationManager;
13
+ breakers = [];
14
+ halted = false;
15
+ haltReason = null;
16
+ constructor(policy, trustManager, collusionDetector, escalationManager) {
17
+ this.policy = policy;
18
+ this.trustManager = trustManager;
19
+ this.collusionDetector = collusionDetector;
20
+ this.escalationManager = escalationManager;
21
+ // Initialize circuit breakers
22
+ this.breakers = [
23
+ {
24
+ id: randomUUID(),
25
+ rule: 'max_formal_overrides_per_session',
26
+ currentValue: 0,
27
+ threshold: policy.escalationRules.maxFormalOverridesBeforeHalt,
28
+ tripped: false,
29
+ action: 'halt',
30
+ },
31
+ {
32
+ id: randomUUID(),
33
+ rule: 'max_trust_demotions_per_agent',
34
+ currentValue: 0,
35
+ threshold: policy.escalationRules.maxTrustDemotions,
36
+ tripped: false,
37
+ action: 'escalate',
38
+ },
39
+ {
40
+ id: randomUUID(),
41
+ rule: 'max_reject_cycles_per_task',
42
+ currentValue: 0,
43
+ threshold: policy.escalationRules.maxRejectCyclesPerTask,
44
+ tripped: false,
45
+ action: 'escalate',
46
+ },
47
+ {
48
+ id: randomUUID(),
49
+ rule: 'critical_collusion_detected',
50
+ currentValue: 0,
51
+ threshold: 1,
52
+ tripped: false,
53
+ action: 'halt',
54
+ },
55
+ ];
56
+ }
57
+ /**
58
+ * Check all safety signals and trip breakers if thresholds exceeded.
59
+ * Returns whether the system should halt.
60
+ */
61
+ evaluate(context) {
62
+ if (this.halted) {
63
+ return { shouldHalt: true, trippedBreakers: [], reason: this.haltReason };
64
+ }
65
+ const tripped = [];
66
+ // Check formal override count across all agents
67
+ const allAgents = this.trustManager.getAllAgents();
68
+ let totalOverrides = 0;
69
+ let maxDemotions = 0;
70
+ for (const agent of allAgents) {
71
+ const stats = this.trustManager.getSessionStats(agent.id);
72
+ totalOverrides += stats.overrides;
73
+ if (stats.demotions > maxDemotions) {
74
+ maxDemotions = stats.demotions;
75
+ }
76
+ }
77
+ // Formal override breaker
78
+ const overrideBreaker = this.breakers.find(b => b.rule === 'max_formal_overrides_per_session');
79
+ overrideBreaker.currentValue = totalOverrides;
80
+ if (totalOverrides >= overrideBreaker.threshold && !overrideBreaker.tripped) {
81
+ overrideBreaker.tripped = true;
82
+ overrideBreaker.trippedAt = new Date().toISOString();
83
+ tripped.push(overrideBreaker);
84
+ }
85
+ // Trust demotion breaker
86
+ const demotionBreaker = this.breakers.find(b => b.rule === 'max_trust_demotions_per_agent');
87
+ demotionBreaker.currentValue = maxDemotions;
88
+ if (maxDemotions >= demotionBreaker.threshold && !demotionBreaker.tripped) {
89
+ demotionBreaker.tripped = true;
90
+ demotionBreaker.trippedAt = new Date().toISOString();
91
+ tripped.push(demotionBreaker);
92
+ // Find which agent triggered this
93
+ const collapsedAgent = allAgents.find(a => {
94
+ const stats = this.trustManager.getSessionStats(a.id);
95
+ return stats.demotions >= demotionBreaker.threshold;
96
+ });
97
+ if (collapsedAgent) {
98
+ this.escalationManager.escalateTrustCollapse(collapsedAgent.id, maxDemotions, context);
99
+ }
100
+ }
101
+ // Critical collusion breaker
102
+ const collusionBreaker = this.breakers.find(b => b.rule === 'critical_collusion_detected');
103
+ const criticalCollusions = this.collusionDetector.getCriticalEvents();
104
+ collusionBreaker.currentValue = criticalCollusions.length;
105
+ if (criticalCollusions.length >= collusionBreaker.threshold && !collusionBreaker.tripped) {
106
+ collusionBreaker.tripped = true;
107
+ collusionBreaker.trippedAt = new Date().toISOString();
108
+ tripped.push(collusionBreaker);
109
+ // Escalate each critical collusion event
110
+ for (const event of criticalCollusions) {
111
+ this.escalationManager.escalateCollusion(event, context);
112
+ }
113
+ }
114
+ // Determine if we should halt
115
+ const haltBreakers = tripped.filter(b => b.action === 'halt');
116
+ if (haltBreakers.length > 0) {
117
+ this.halted = true;
118
+ this.haltReason = `Safety halt: ${haltBreakers.map(b => b.rule).join(', ')}`;
119
+ }
120
+ return {
121
+ shouldHalt: this.halted,
122
+ trippedBreakers: tripped,
123
+ reason: this.haltReason,
124
+ };
125
+ }
126
+ /**
127
+ * Check if a specific task has exceeded reject cycles.
128
+ */
129
+ checkTaskRejectCycles(taskId, attempts, context) {
130
+ const rejectBreaker = this.breakers.find(b => b.rule === 'max_reject_cycles_per_task');
131
+ if (attempts >= rejectBreaker.threshold) {
132
+ rejectBreaker.currentValue = attempts;
133
+ if (!rejectBreaker.tripped) {
134
+ rejectBreaker.tripped = true;
135
+ rejectBreaker.trippedAt = new Date().toISOString();
136
+ }
137
+ this.escalationManager.escalateStall([{ taskId, type: 'reject_loop', duration: 0, attempts, suggestedAction: 'escalate' }], context);
138
+ return true;
139
+ }
140
+ return false;
141
+ }
142
+ /** Get all circuit breakers and their states. */
143
+ getBreakers() {
144
+ return this.breakers;
145
+ }
146
+ /** Check if the system is halted. */
147
+ isHalted() {
148
+ return this.halted;
149
+ }
150
+ /** Get the halt reason if halted. */
151
+ getHaltReason() {
152
+ return this.haltReason;
153
+ }
154
+ /** Reset all circuit breakers (e.g., after human intervention). */
155
+ reset() {
156
+ this.halted = false;
157
+ this.haltReason = null;
158
+ for (const breaker of this.breakers) {
159
+ breaker.tripped = false;
160
+ breaker.currentValue = 0;
161
+ delete breaker.trippedAt;
162
+ }
163
+ }
164
+ }
165
+ //# sourceMappingURL=safety-enforcer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety-enforcer.js","sourceRoot":"","sources":["../../src/runtime/safety-enforcer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { Layer2Guardian } from './layer2-guardian.js';
2
+ import { KillSwitch } from './kill-switch.js';
3
+ import { RollbackManager } from './rollback-manager.js';
4
+ import type { IntegrityCheckResult, KillSwitchEvent, RollbackEvent } from './types.js';
5
+ export interface SafetyReport {
6
+ readonly timestamp: string;
7
+ readonly overall_status: 'safe' | 'degraded' | 'critical' | 'halted';
8
+ readonly layer2: {
9
+ readonly integrity: IntegrityCheckResult | null;
10
+ readonly manifest_present: boolean;
11
+ readonly permissions_valid: boolean;
12
+ readonly permission_findings: readonly {
13
+ path: string;
14
+ issue: string;
15
+ }[];
16
+ };
17
+ readonly kill_switch: {
18
+ readonly system_halted: boolean;
19
+ readonly suspended_count: number;
20
+ readonly suspended_entities: readonly {
21
+ target: string;
22
+ level: string;
23
+ reason: string;
24
+ since: string;
25
+ }[];
26
+ readonly recent_events: readonly KillSwitchEvent[];
27
+ };
28
+ readonly rollback: {
29
+ readonly total_rollbacks: number;
30
+ readonly recent_rollbacks: readonly RollbackEvent[];
31
+ readonly auto_rollbacks: number;
32
+ readonly human_rollbacks: number;
33
+ readonly layer2_rollbacks: number;
34
+ };
35
+ readonly recommendations: readonly string[];
36
+ }
37
+ export declare class SafetyStatusReporter {
38
+ private guardian;
39
+ private killSwitch;
40
+ private rollbackManager;
41
+ constructor(guardian: Layer2Guardian, killSwitch: KillSwitch, rollbackManager: RollbackManager);
42
+ /**
43
+ * Generate a comprehensive safety status report.
44
+ */
45
+ generateReport(): Promise<SafetyReport>;
46
+ private determineOverallStatus;
47
+ private generateRecommendations;
48
+ }
@@ -0,0 +1,119 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Safety Status Reporter
3
+ // Aggregates all safety subsystems into a single report:
4
+ // - Layer 2 integrity
5
+ // - Kill switch state
6
+ // - Rollback history
7
+ // - Suspended entities
8
+ // - Overall safety posture
9
+ // ============================================================
10
+ // ── Safety Status Reporter ─────────────────────────────
11
+ export class SafetyStatusReporter {
12
+ guardian;
13
+ killSwitch;
14
+ rollbackManager;
15
+ constructor(guardian, killSwitch, rollbackManager) {
16
+ this.guardian = guardian;
17
+ this.killSwitch = killSwitch;
18
+ this.rollbackManager = rollbackManager;
19
+ }
20
+ /**
21
+ * Generate a comprehensive safety status report.
22
+ */
23
+ async generateReport() {
24
+ // Layer 2 status
25
+ const audit = await this.guardian.fullAudit();
26
+ // Kill switch status
27
+ const suspended = this.killSwitch.getSuspended();
28
+ const suspendedEntries = Array.from(suspended.entries()).map(([target, event]) => ({
29
+ target,
30
+ level: event.level,
31
+ reason: event.reason,
32
+ since: event.timestamp,
33
+ }));
34
+ const ksEvents = this.killSwitch.getEventLog();
35
+ const recentKsEvents = ksEvents.slice(-10); // Last 10 events
36
+ // Rollback status
37
+ const rollbackHistory = this.rollbackManager.getHistory();
38
+ const recentRollbacks = rollbackHistory.slice(-10);
39
+ const autoRollbacks = rollbackHistory.filter(r => r.trigger === 'automatic').length;
40
+ const humanRollbacks = rollbackHistory.filter(r => r.trigger === 'human').length;
41
+ const layer2Rollbacks = rollbackHistory.filter(r => r.trigger === 'layer2').length;
42
+ // Recommendations
43
+ const recommendations = this.generateRecommendations(audit, suspended.size, rollbackHistory);
44
+ // Overall status
45
+ const overallStatus = this.determineOverallStatus(audit, this.killSwitch.isSystemHalted(), suspended.size, rollbackHistory);
46
+ return {
47
+ timestamp: new Date().toISOString(),
48
+ overall_status: overallStatus,
49
+ layer2: {
50
+ integrity: audit.integrity,
51
+ manifest_present: audit.manifestPresent,
52
+ permissions_valid: audit.permissions.valid,
53
+ permission_findings: audit.permissions.findings,
54
+ },
55
+ kill_switch: {
56
+ system_halted: this.killSwitch.isSystemHalted(),
57
+ suspended_count: suspended.size,
58
+ suspended_entities: suspendedEntries,
59
+ recent_events: recentKsEvents,
60
+ },
61
+ rollback: {
62
+ total_rollbacks: rollbackHistory.length,
63
+ recent_rollbacks: recentRollbacks,
64
+ auto_rollbacks: autoRollbacks,
65
+ human_rollbacks: humanRollbacks,
66
+ layer2_rollbacks: layer2Rollbacks,
67
+ },
68
+ recommendations,
69
+ };
70
+ }
71
+ // ── Private helpers ────────────────────────────────────
72
+ determineOverallStatus(audit, systemHalted, suspendedCount, rollbackHistory) {
73
+ if (systemHalted)
74
+ return 'halted';
75
+ if (audit.integrity.overall === 'violation')
76
+ return 'critical';
77
+ if (!audit.manifestPresent)
78
+ return 'degraded';
79
+ if (!audit.permissions.valid)
80
+ return 'degraded';
81
+ // Recent rollbacks indicate instability
82
+ const recentRollbacks = rollbackHistory.filter(r => {
83
+ const age = Date.now() - new Date(r.timestamp).getTime();
84
+ return age < 60 * 60 * 1000; // Last hour
85
+ });
86
+ if (recentRollbacks.length >= 3)
87
+ return 'degraded';
88
+ if (suspendedCount > 0)
89
+ return 'degraded';
90
+ return 'safe';
91
+ }
92
+ generateRecommendations(audit, suspendedCount, rollbackHistory) {
93
+ const recommendations = [];
94
+ if (!audit.manifestPresent) {
95
+ recommendations.push('No Layer 2 manifest found. Run "tryassay runtime safety sign" to generate one.');
96
+ }
97
+ if (audit.integrity.overall === 'violation') {
98
+ recommendations.push('CRITICAL: Layer 2 integrity violation detected. Redeploy verified Layer 2 artifacts immediately.');
99
+ }
100
+ if (!audit.permissions.valid) {
101
+ for (const finding of audit.permissions.findings) {
102
+ recommendations.push(`Fix permissions: ${finding.path} — ${finding.issue}`);
103
+ }
104
+ }
105
+ if (suspendedCount > 0) {
106
+ recommendations.push(`${suspendedCount} entity(ies) currently suspended. Review and release or replace.`);
107
+ }
108
+ // Check for repeated auto-rollbacks (indicates systemic issue)
109
+ const autoRollbacks = rollbackHistory.filter(r => r.trigger === 'automatic');
110
+ if (autoRollbacks.length >= 5) {
111
+ recommendations.push(`${autoRollbacks.length} automatic rollbacks recorded. Review tool/rule quality before deploying new capabilities.`);
112
+ }
113
+ if (recommendations.length === 0) {
114
+ recommendations.push('All safety systems operating normally.');
115
+ }
116
+ return recommendations;
117
+ }
118
+ }
119
+ //# sourceMappingURL=safety-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safety-status.js","sourceRoot":"","sources":["../../src/runtime/safety-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { RuleCandidate, ShadowResult, ShadowStats, PromotionDecision, VerificationClaim } from './types.js';
2
+ export declare class ShadowRunner {
3
+ private candidates;
4
+ private results;
5
+ deploy(candidate: RuleCandidate): Promise<void>;
6
+ evaluate(claim: VerificationClaim, code: string, language: string): ShadowResult | null;
7
+ getStats(candidateId: string): ShadowStats | null;
8
+ checkPromotions(): PromotionDecision[];
9
+ applyDecisions(decisions: PromotionDecision[]): void;
10
+ getActiveCandidates(): RuleCandidate[];
11
+ getAllCandidates(): RuleCandidate[];
12
+ load(candidates: RuleCandidate[], results?: Map<string, ShadowResult[]>): void;
13
+ private inferCategory;
14
+ }
@@ -0,0 +1,190 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Shadow Runner
3
+ // Deploys rule candidates alongside real verification traffic.
4
+ // Evaluates without blocking. Auto-promotes after accuracy threshold.
5
+ // ============================================================
6
+ import { randomUUID } from 'node:crypto';
7
+ export class ShadowRunner {
8
+ candidates = new Map();
9
+ results = new Map();
10
+ async deploy(candidate) {
11
+ candidate.status = 'shadow';
12
+ this.candidates.set(candidate.id, candidate);
13
+ this.results.set(candidate.id, []);
14
+ }
15
+ evaluate(claim, code, language) {
16
+ // Find applicable shadow candidates
17
+ for (const [id, candidate] of this.candidates) {
18
+ if (candidate.status !== 'shadow')
19
+ continue;
20
+ if (candidate.language !== language)
21
+ continue;
22
+ // Check if this candidate's claim category matches
23
+ const claimCategory = this.inferCategory(claim.text);
24
+ if (claimCategory !== candidate.claimCategory)
25
+ continue;
26
+ // Run the shadow rule
27
+ let formalVerdict;
28
+ if (candidate.substrate === 'regex') {
29
+ try {
30
+ const regex = new RegExp(candidate.pattern, 'gm');
31
+ const matches = regex.test(code);
32
+ regex.lastIndex = 0;
33
+ formalVerdict = matches ? 'FAIL' : 'PASS';
34
+ }
35
+ catch {
36
+ continue; // invalid regex, skip
37
+ }
38
+ }
39
+ else {
40
+ continue; // AST rules not supported yet
41
+ }
42
+ const llmVerdict = claim.verdict === 'PASS' ? 'PASS'
43
+ : claim.verdict === 'FAIL' ? 'FAIL'
44
+ : 'PARTIAL';
45
+ const result = {
46
+ id: randomUUID(),
47
+ candidateId: id,
48
+ formalVerdict,
49
+ llmVerdict,
50
+ agreed: formalVerdict === llmVerdict || (formalVerdict === 'PASS' && llmVerdict === 'PARTIAL'),
51
+ codeSnippet: code.slice(0, 500),
52
+ timestamp: new Date().toISOString(),
53
+ };
54
+ const existing = this.results.get(id) ?? [];
55
+ existing.push(result);
56
+ this.results.set(id, existing);
57
+ return result;
58
+ }
59
+ return null;
60
+ }
61
+ getStats(candidateId) {
62
+ const results = this.results.get(candidateId);
63
+ if (!results || results.length === 0)
64
+ return null;
65
+ const candidate = this.candidates.get(candidateId);
66
+ if (!candidate)
67
+ return null;
68
+ const agreements = results.filter(r => r.agreed).length;
69
+ const disagreements = results.length - agreements;
70
+ const formalCaughtLlmMiss = results.filter(r => r.formalVerdict === 'FAIL' && (r.llmVerdict === 'PASS' || r.llmVerdict === 'PARTIAL')).length;
71
+ const falsePositives = results.filter(r => r.formalVerdict === 'FAIL' && r.llmVerdict === 'PASS' && !r.agreed).length;
72
+ const firstResult = results[0];
73
+ const lastResult = results[results.length - 1];
74
+ const shadowDays = (new Date(lastResult.timestamp).getTime() - new Date(firstResult.timestamp).getTime())
75
+ / (1000 * 60 * 60 * 24);
76
+ return {
77
+ candidateId,
78
+ totalEvaluations: results.length,
79
+ agreements,
80
+ disagreements,
81
+ formalCaughtLlmMiss,
82
+ falsePositives,
83
+ accuracy: results.length > 0 ? agreements / results.length : 0,
84
+ shadowDays,
85
+ };
86
+ }
87
+ checkPromotions() {
88
+ const decisions = [];
89
+ for (const [id, candidate] of this.candidates) {
90
+ if (candidate.status !== 'shadow')
91
+ continue;
92
+ const stats = this.getStats(id);
93
+ if (!stats)
94
+ continue;
95
+ // Check promotion criteria
96
+ if (stats.totalEvaluations >= 50 &&
97
+ stats.shadowDays >= 7 &&
98
+ stats.accuracy >= 0.9 &&
99
+ stats.formalCaughtLlmMiss >= 1 &&
100
+ (stats.falsePositives / stats.totalEvaluations) < 0.05) {
101
+ decisions.push({
102
+ candidateId: id,
103
+ decision: 'promote',
104
+ reason: `Meets all criteria: ${stats.totalEvaluations} evals, ${stats.shadowDays.toFixed(1)} days, ${(stats.accuracy * 100).toFixed(0)}% accuracy, ${stats.formalCaughtLlmMiss} LLM misses caught`,
105
+ stats,
106
+ });
107
+ continue;
108
+ }
109
+ // Check rejection criteria
110
+ if (stats.totalEvaluations >= 50 &&
111
+ (stats.falsePositives / stats.totalEvaluations) > 0.2) {
112
+ decisions.push({
113
+ candidateId: id,
114
+ decision: 'reject',
115
+ reason: `False positive rate ${((stats.falsePositives / stats.totalEvaluations) * 100).toFixed(0)}% exceeds 20% threshold`,
116
+ stats,
117
+ });
118
+ continue;
119
+ }
120
+ if (stats.totalEvaluations >= 100 &&
121
+ stats.formalCaughtLlmMiss === 0) {
122
+ decisions.push({
123
+ candidateId: id,
124
+ decision: 'reject',
125
+ reason: `No LLM misses caught after ${stats.totalEvaluations} evaluations — rule adds no value`,
126
+ stats,
127
+ });
128
+ continue;
129
+ }
130
+ // Keep shadowing
131
+ decisions.push({
132
+ candidateId: id,
133
+ decision: 'keep_shadowing',
134
+ reason: `${stats.totalEvaluations}/50 evals, ${stats.shadowDays.toFixed(1)}/7 days`,
135
+ stats,
136
+ });
137
+ }
138
+ return decisions;
139
+ }
140
+ applyDecisions(decisions) {
141
+ for (const d of decisions) {
142
+ const candidate = this.candidates.get(d.candidateId);
143
+ if (!candidate)
144
+ continue;
145
+ if (d.decision === 'promote') {
146
+ candidate.status = 'promoted';
147
+ candidate.promotedAt = new Date().toISOString();
148
+ }
149
+ else if (d.decision === 'reject') {
150
+ candidate.status = 'rejected';
151
+ candidate.rejectedAt = new Date().toISOString();
152
+ }
153
+ }
154
+ }
155
+ getActiveCandidates() {
156
+ return Array.from(this.candidates.values()).filter(c => c.status === 'shadow');
157
+ }
158
+ getAllCandidates() {
159
+ return Array.from(this.candidates.values());
160
+ }
161
+ load(candidates, results) {
162
+ for (const c of candidates) {
163
+ this.candidates.set(c.id, c);
164
+ }
165
+ if (results) {
166
+ for (const [id, rs] of results) {
167
+ this.results.set(id, rs);
168
+ }
169
+ }
170
+ }
171
+ inferCategory(claimText) {
172
+ const lower = claimText.toLowerCase();
173
+ if (lower.includes('error') || lower.includes('exception') || lower.includes('throw'))
174
+ return 'error-handling';
175
+ if (lower.includes('null') || lower.includes('undefined') || lower.includes('optional'))
176
+ return 'null-safety';
177
+ if (lower.includes('sql') || lower.includes('inject') || lower.includes('xss') || lower.includes('auth'))
178
+ return 'security';
179
+ if (lower.includes('type') || lower.includes('cast'))
180
+ return 'type-safety';
181
+ if (lower.includes('valid') || lower.includes('input') || lower.includes('sanitiz'))
182
+ return 'input-validation';
183
+ if (lower.includes('return') || lower.includes('correct'))
184
+ return 'correctness';
185
+ if (lower.includes('edge') || lower.includes('boundar'))
186
+ return 'edge-cases';
187
+ return 'general';
188
+ }
189
+ }
190
+ //# sourceMappingURL=shadow-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shadow-runner.js","sourceRoot":"","sources":["../../src/runtime/shadow-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { MemoryEntry, MemoryEntryType, MemoryFilter, MemoryConflict, ConflictResolution, BoundaryVerificationStatus, BoundaryClaim } from './types.js';
2
+ export declare class SharedMemoryStore {
3
+ private entries;
4
+ private conflicts;
5
+ /**
6
+ * Add a new entry to shared memory.
7
+ * Checks for conflicts with existing entries by the same tags.
8
+ * Returns the entry ID and any detected conflicts.
9
+ */
10
+ add(type: MemoryEntryType, content: string, author: string, opts?: {
11
+ tags?: string[];
12
+ verificationStatus?: BoundaryVerificationStatus;
13
+ claims?: readonly BoundaryClaim[];
14
+ confidence?: number;
15
+ supersedes?: string;
16
+ }): {
17
+ entryId: string;
18
+ conflicts: MemoryConflict[];
19
+ };
20
+ /**
21
+ * Query entries by filter criteria.
22
+ */
23
+ query(filter: MemoryFilter): readonly MemoryEntry[];
24
+ /** Get entries by tag. */
25
+ getByTag(tag: string): readonly MemoryEntry[];
26
+ /** Get entries by author agent ID. */
27
+ getByAgent(agentId: string): readonly MemoryEntry[];
28
+ /** Get only entries where all claims passed verification. */
29
+ getVerified(): readonly MemoryEntry[];
30
+ /** Get all detected conflicts. */
31
+ getConflicts(): readonly MemoryConflict[];
32
+ /** Get only open (unresolved) conflicts. */
33
+ getOpenConflicts(): readonly MemoryConflict[];
34
+ /** Resolve a conflict. */
35
+ resolveConflict(conflictId: string, resolution: ConflictResolution): boolean;
36
+ /** Escalate a conflict for human resolution. */
37
+ escalateConflict(conflictId: string): boolean;
38
+ /** Get all entries (for snapshots and audit). */
39
+ getAllEntries(): readonly MemoryEntry[];
40
+ /** Get entry by ID. */
41
+ getEntry(entryId: string): MemoryEntry | undefined;
42
+ /** Get the entry that superseded a given entry. */
43
+ getSuperseding(entryId: string): MemoryEntry | undefined;
44
+ /** Update verification status of an entry after boundary verification. */
45
+ updateVerification(entryId: string, status: BoundaryVerificationStatus, claims?: readonly BoundaryClaim[], confidence?: number): void;
46
+ private detectConflicts;
47
+ }