tryassay 0.2.0 → 0.6.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 (75) hide show
  1. package/dist/cli.js +41 -2
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/runtime.d.ts +20 -0
  4. package/dist/commands/runtime.js +192 -6
  5. package/dist/commands/runtime.js.map +1 -1
  6. package/dist/runtime/agent-loop.d.ts +16 -1
  7. package/dist/runtime/agent-loop.js +197 -32
  8. package/dist/runtime/agent-loop.js.map +1 -1
  9. package/dist/runtime/agents/code-agent.d.ts +11 -0
  10. package/dist/runtime/agents/code-agent.js +90 -0
  11. package/dist/runtime/agents/code-agent.js.map +1 -0
  12. package/dist/runtime/agents/review-agent.d.ts +11 -0
  13. package/dist/runtime/agents/review-agent.js +96 -0
  14. package/dist/runtime/agents/review-agent.js.map +1 -0
  15. package/dist/runtime/audit-log.d.ts +35 -0
  16. package/dist/runtime/audit-log.js +115 -0
  17. package/dist/runtime/audit-log.js.map +1 -0
  18. package/dist/runtime/composition-verifier.d.ts +22 -0
  19. package/dist/runtime/composition-verifier.js +265 -0
  20. package/dist/runtime/composition-verifier.js.map +1 -0
  21. package/dist/runtime/confidence-calibrator.d.ts +10 -0
  22. package/dist/runtime/confidence-calibrator.js +95 -0
  23. package/dist/runtime/confidence-calibrator.js.map +1 -0
  24. package/dist/runtime/config-loader.d.ts +41 -0
  25. package/dist/runtime/config-loader.js +116 -0
  26. package/dist/runtime/config-loader.js.map +1 -0
  27. package/dist/runtime/control-server.d.ts +25 -0
  28. package/dist/runtime/control-server.js +83 -0
  29. package/dist/runtime/control-server.js.map +1 -0
  30. package/dist/runtime/enriched-prompt-builder.d.ts +25 -0
  31. package/dist/runtime/enriched-prompt-builder.js +173 -0
  32. package/dist/runtime/enriched-prompt-builder.js.map +1 -0
  33. package/dist/runtime/gap-detector.d.ts +6 -0
  34. package/dist/runtime/gap-detector.js +111 -0
  35. package/dist/runtime/gap-detector.js.map +1 -0
  36. package/dist/runtime/logger.d.ts +20 -0
  37. package/dist/runtime/logger.js +73 -0
  38. package/dist/runtime/logger.js.map +1 -0
  39. package/dist/runtime/message-bus.d.ts +57 -0
  40. package/dist/runtime/message-bus.js +115 -0
  41. package/dist/runtime/message-bus.js.map +1 -0
  42. package/dist/runtime/observer.d.ts +5 -1
  43. package/dist/runtime/observer.js +61 -14
  44. package/dist/runtime/observer.js.map +1 -1
  45. package/dist/runtime/pattern-extractor.d.ts +20 -0
  46. package/dist/runtime/pattern-extractor.js +257 -0
  47. package/dist/runtime/pattern-extractor.js.map +1 -0
  48. package/dist/runtime/planner.d.ts +2 -2
  49. package/dist/runtime/planner.js +10 -7
  50. package/dist/runtime/planner.js.map +1 -1
  51. package/dist/runtime/reasoner.d.ts +2 -2
  52. package/dist/runtime/reasoner.js +22 -7
  53. package/dist/runtime/reasoner.js.map +1 -1
  54. package/dist/runtime/reflector.d.ts +7 -1
  55. package/dist/runtime/reflector.js.map +1 -1
  56. package/dist/runtime/shadow-runner.d.ts +14 -0
  57. package/dist/runtime/shadow-runner.js +190 -0
  58. package/dist/runtime/shadow-runner.js.map +1 -0
  59. package/dist/runtime/specialized-agent.d.ts +67 -0
  60. package/dist/runtime/specialized-agent.js +86 -0
  61. package/dist/runtime/specialized-agent.js.map +1 -0
  62. package/dist/runtime/strategy-library.d.ts +11 -0
  63. package/dist/runtime/strategy-library.js +142 -0
  64. package/dist/runtime/strategy-library.js.map +1 -0
  65. package/dist/runtime/supabase-experience-store.d.ts +19 -0
  66. package/dist/runtime/supabase-experience-store.js +215 -0
  67. package/dist/runtime/supabase-experience-store.js.map +1 -0
  68. package/dist/runtime/trust-manager.d.ts +33 -0
  69. package/dist/runtime/trust-manager.js +110 -0
  70. package/dist/runtime/trust-manager.js.map +1 -0
  71. package/dist/runtime/two-agent-loop.d.ts +35 -0
  72. package/dist/runtime/two-agent-loop.js +208 -0
  73. package/dist/runtime/two-agent-loop.js.map +1 -0
  74. package/dist/runtime/types.d.ts +291 -1
  75. package/package.json +1 -1
@@ -0,0 +1,215 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Supabase Experience Store
3
+ // Replaces NDJSON file with Supabase pgvector for semantic search.
4
+ // Falls back to local file when Supabase is unreachable.
5
+ // ============================================================
6
+ import { createClient } from '@supabase/supabase-js';
7
+ import { ExperienceStore } from './reflector.js';
8
+ // ── Embedding ─────────────────────────────────────────────────
9
+ function buildEmbeddingText(exp) {
10
+ const parts = [
11
+ exp.domain,
12
+ exp.decision.reasoning.slice(0, 300),
13
+ exp.lessons.join('. '),
14
+ exp.outcome,
15
+ exp.delta?.slice(0, 200) ?? '',
16
+ ];
17
+ return parts.filter(Boolean).join(' | ');
18
+ }
19
+ async function computeEmbedding(text) {
20
+ // Use Anthropic's message API to generate a pseudo-embedding
21
+ // by hashing the semantic content. For production, swap to
22
+ // a dedicated embedding model (OpenAI text-embedding-3-small
23
+ // or Voyage AI). For now, use OpenAI since it's already a dep.
24
+ const { default: OpenAI } = await import('openai');
25
+ const client = new OpenAI();
26
+ const response = await client.embeddings.create({
27
+ model: 'text-embedding-3-small',
28
+ input: text.slice(0, 8000),
29
+ });
30
+ return response.data[0].embedding;
31
+ }
32
+ // ── SupabaseExperienceStore ──────────────────────────────────
33
+ export class SupabaseExperienceStore {
34
+ supabase;
35
+ localFallback;
36
+ online = true;
37
+ constructor(supabaseUrl, supabaseKey, localFallbackPath) {
38
+ this.supabase = createClient(supabaseUrl, supabaseKey);
39
+ this.localFallback = new ExperienceStore(localFallbackPath);
40
+ }
41
+ async save(experience) {
42
+ // Always write to local fallback
43
+ await this.localFallback.save(experience);
44
+ // Try Supabase
45
+ try {
46
+ const embeddingText = buildEmbeddingText(experience);
47
+ const embedding = await computeEmbedding(embeddingText);
48
+ const { error } = await this.supabase.from('experiences').insert({
49
+ id: experience.id,
50
+ agent_name: experience.observation.source === 'filesystem'
51
+ ? 'default'
52
+ : 'default',
53
+ domain: experience.domain,
54
+ outcome: experience.outcome,
55
+ delta: experience.delta,
56
+ lessons: experience.lessons,
57
+ tags: experience.tags,
58
+ timestamp: experience.timestamp,
59
+ observation: experience.observation,
60
+ decision: experience.decision,
61
+ plan: experience.plan,
62
+ verification: experience.verification,
63
+ execution: experience.execution,
64
+ embedding: embedding,
65
+ });
66
+ if (error) {
67
+ console.error(`[SupabaseStore] Insert error: ${error.message}`);
68
+ this.online = false;
69
+ }
70
+ else {
71
+ this.online = true;
72
+ }
73
+ }
74
+ catch (err) {
75
+ const msg = err instanceof Error ? err.message : String(err);
76
+ console.error(`[SupabaseStore] Save failed, using local only: ${msg}`);
77
+ this.online = false;
78
+ }
79
+ }
80
+ async search(query, limit = 5) {
81
+ if (!this.online) {
82
+ return this.fallbackSearch(query, limit);
83
+ }
84
+ try {
85
+ const queryEmbedding = await computeEmbedding(query);
86
+ const { data, error } = await this.supabase.rpc('match_experiences', {
87
+ query_embedding: queryEmbedding,
88
+ match_threshold: 0.3,
89
+ match_count: limit,
90
+ });
91
+ if (error || !data) {
92
+ console.error(`[SupabaseStore] Search error: ${error?.message}`);
93
+ return this.fallbackSearch(query, limit);
94
+ }
95
+ return data.map((row) => ({
96
+ experience: this.rowToExperience(row),
97
+ similarity: row.similarity,
98
+ }));
99
+ }
100
+ catch (err) {
101
+ const msg = err instanceof Error ? err.message : String(err);
102
+ console.error(`[SupabaseStore] Search failed, using fallback: ${msg}`);
103
+ this.online = false;
104
+ return this.fallbackSearch(query, limit);
105
+ }
106
+ }
107
+ async getByDomain(domain, limit = 50) {
108
+ if (!this.online) {
109
+ return this.localFallback.getByDomain(domain);
110
+ }
111
+ try {
112
+ const { data, error } = await this.supabase
113
+ .from('experiences')
114
+ .select('*')
115
+ .eq('domain', domain)
116
+ .order('timestamp', { ascending: false })
117
+ .limit(limit);
118
+ if (error || !data) {
119
+ return this.localFallback.getByDomain(domain);
120
+ }
121
+ return data.map((row) => this.rowToExperience(row));
122
+ }
123
+ catch {
124
+ return this.localFallback.getByDomain(domain);
125
+ }
126
+ }
127
+ async getByOutcome(outcome, limit = 50) {
128
+ if (!this.online) {
129
+ return [];
130
+ }
131
+ try {
132
+ const { data, error } = await this.supabase
133
+ .from('experiences')
134
+ .select('*')
135
+ .eq('outcome', outcome)
136
+ .order('timestamp', { ascending: false })
137
+ .limit(limit);
138
+ if (error || !data)
139
+ return [];
140
+ return data.map((row) => this.rowToExperience(row));
141
+ }
142
+ catch {
143
+ return [];
144
+ }
145
+ }
146
+ async getRecent(limit = 10) {
147
+ if (!this.online) {
148
+ return [];
149
+ }
150
+ try {
151
+ const { data, error } = await this.supabase
152
+ .from('experiences')
153
+ .select('*')
154
+ .order('timestamp', { ascending: false })
155
+ .limit(limit);
156
+ if (error || !data)
157
+ return [];
158
+ return data.map((row) => this.rowToExperience(row));
159
+ }
160
+ catch {
161
+ return [];
162
+ }
163
+ }
164
+ async count() {
165
+ if (!this.online)
166
+ return 0;
167
+ try {
168
+ const { count, error } = await this.supabase
169
+ .from('experiences')
170
+ .select('*', { count: 'exact', head: true });
171
+ if (error || count === null)
172
+ return 0;
173
+ return count;
174
+ }
175
+ catch {
176
+ return 0;
177
+ }
178
+ }
179
+ async getStats() {
180
+ return this.localFallback.getStats();
181
+ }
182
+ // Interface compatibility method
183
+ async getRelevantExperiences(context, limit = 5) {
184
+ const scored = await this.search(context, limit);
185
+ return scored.map(s => s.experience);
186
+ }
187
+ isOnline() {
188
+ return this.online;
189
+ }
190
+ // ── Helpers ─────────────────────────────────────────────────
191
+ async fallbackSearch(query, limit) {
192
+ const results = await this.localFallback.getRelevantExperiences(query, limit);
193
+ return results.map((exp, i) => ({
194
+ experience: exp,
195
+ similarity: 1 - (i * 0.1), // approximate ranking
196
+ }));
197
+ }
198
+ rowToExperience(row) {
199
+ return {
200
+ id: row.id,
201
+ observation: row.observation,
202
+ decision: row.decision,
203
+ plan: row.plan,
204
+ verification: row.verification,
205
+ execution: row.execution,
206
+ outcome: row.outcome,
207
+ delta: row.delta ?? '',
208
+ lessons: row.lessons ?? [],
209
+ domain: row.domain,
210
+ tags: row.tags ?? [],
211
+ timestamp: row.timestamp,
212
+ };
213
+ }
214
+ }
215
+ //# sourceMappingURL=supabase-experience-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-experience-store.js","sourceRoot":"","sources":["../../src/runtime/supabase-experience-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { AgentIdentity, TrustLevel, BoundaryVerificationResult, SafetyPolicy } from './types.js';
2
+ export declare class TrustManager {
3
+ private agents;
4
+ private policy;
5
+ private trustDemotionOnOverride;
6
+ private sessionOverrides;
7
+ private sessionDemotions;
8
+ constructor(policy: SafetyPolicy, opts?: {
9
+ trustDemotionOnOverride?: boolean;
10
+ });
11
+ /** Register an agent with its initial identity. */
12
+ register(agent: AgentIdentity): void;
13
+ /** Get an agent's current identity (with updated trust). */
14
+ getAgent(agentId: string): AgentIdentity | undefined;
15
+ /** Get all registered agents. */
16
+ getAllAgents(): AgentIdentity[];
17
+ /**
18
+ * Update trust based on a boundary verification result.
19
+ * Returns the updated trust level and whether the agent was demoted.
20
+ */
21
+ updateTrust(agentId: string, result: BoundaryVerificationResult): {
22
+ newTrust: TrustLevel;
23
+ demoted: boolean;
24
+ shouldHalt: boolean;
25
+ };
26
+ /** Get session-level stats for an agent. */
27
+ getSessionStats(agentId: string): {
28
+ overrides: number;
29
+ demotions: number;
30
+ };
31
+ private demoteTrust;
32
+ private computePassRate;
33
+ }
@@ -0,0 +1,110 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Trust Manager
3
+ // Manages agent trust levels based on verification history
4
+ // ============================================================
5
+ // ── Trust Manager ───────────────────────────────────────────
6
+ export class TrustManager {
7
+ agents = new Map();
8
+ policy;
9
+ trustDemotionOnOverride;
10
+ sessionOverrides = new Map(); // agent -> override count this session
11
+ sessionDemotions = new Map(); // agent -> demotion count this session
12
+ constructor(policy, opts) {
13
+ this.policy = policy;
14
+ this.trustDemotionOnOverride = opts?.trustDemotionOnOverride ?? true;
15
+ }
16
+ /** Register an agent with its initial identity. */
17
+ register(agent) {
18
+ this.agents.set(agent.id, agent);
19
+ this.sessionOverrides.set(agent.id, 0);
20
+ this.sessionDemotions.set(agent.id, 0);
21
+ }
22
+ /** Get an agent's current identity (with updated trust). */
23
+ getAgent(agentId) {
24
+ return this.agents.get(agentId);
25
+ }
26
+ /** Get all registered agents. */
27
+ getAllAgents() {
28
+ return Array.from(this.agents.values());
29
+ }
30
+ /**
31
+ * Update trust based on a boundary verification result.
32
+ * Returns the updated trust level and whether the agent was demoted.
33
+ */
34
+ updateTrust(agentId, result) {
35
+ const agent = this.agents.get(agentId);
36
+ if (!agent)
37
+ return { newTrust: 'untrusted', demoted: false, shouldHalt: false };
38
+ const oldTrust = agent.trustLevel;
39
+ let newTrust = oldTrust;
40
+ let demoted = false;
41
+ // Check for formal overrides
42
+ if (result.formalStats.formalOverrides > 0 && this.trustDemotionOnOverride) {
43
+ // A single formal override drops trust by one level
44
+ newTrust = this.demoteTrust(oldTrust);
45
+ demoted = newTrust !== oldTrust;
46
+ if (demoted) {
47
+ const overrides = (this.sessionOverrides.get(agentId) ?? 0) + result.formalStats.formalOverrides;
48
+ this.sessionOverrides.set(agentId, overrides);
49
+ const demotions = (this.sessionDemotions.get(agentId) ?? 0) + 1;
50
+ this.sessionDemotions.set(agentId, demotions);
51
+ // Two formal overrides in a session → drop to untrusted
52
+ if (overrides >= 2) {
53
+ newTrust = 'untrusted';
54
+ }
55
+ }
56
+ }
57
+ // Check for promotion
58
+ if (!demoted && result.verdict === 'PASS') {
59
+ const history = agent.verificationHistory;
60
+ const newTotal = history.totalHandoffs + 1;
61
+ const newPassRate = (history.passRate * history.totalHandoffs + 1) / newTotal;
62
+ // Promote if enough clean handoffs
63
+ if (oldTrust === 'untrusted' && newTotal >= 10 && newPassRate >= 0.9) {
64
+ newTrust = 'provisional';
65
+ }
66
+ else if (oldTrust === 'provisional' && newTotal >= 50 && newPassRate >= 0.95) {
67
+ newTrust = 'trusted';
68
+ }
69
+ }
70
+ // Update the agent's identity
71
+ const updatedHistory = {
72
+ totalHandoffs: agent.verificationHistory.totalHandoffs + 1,
73
+ passRate: this.computePassRate(agent, result),
74
+ formalOverrides: agent.verificationHistory.formalOverrides + result.formalStats.formalOverrides,
75
+ };
76
+ const updatedAgent = {
77
+ ...agent,
78
+ trustLevel: newTrust,
79
+ verificationHistory: updatedHistory,
80
+ };
81
+ this.agents.set(agentId, updatedAgent);
82
+ // Check if we should halt
83
+ const shouldHalt = (this.sessionOverrides.get(agentId) ?? 0) >= this.policy.escalationRules.maxFormalOverridesBeforeHalt ||
84
+ (this.sessionDemotions.get(agentId) ?? 0) >= this.policy.escalationRules.maxTrustDemotions;
85
+ return { newTrust, demoted, shouldHalt };
86
+ }
87
+ /** Get session-level stats for an agent. */
88
+ getSessionStats(agentId) {
89
+ return {
90
+ overrides: this.sessionOverrides.get(agentId) ?? 0,
91
+ demotions: this.sessionDemotions.get(agentId) ?? 0,
92
+ };
93
+ }
94
+ // ── Private helpers ─────────────────────────────────────
95
+ demoteTrust(current) {
96
+ switch (current) {
97
+ case 'trusted': return 'provisional';
98
+ case 'provisional': return 'untrusted';
99
+ case 'untrusted': return 'untrusted';
100
+ case 'formal': return 'formal'; // formal agents can't be demoted
101
+ }
102
+ }
103
+ computePassRate(agent, result) {
104
+ const oldTotal = agent.verificationHistory.totalHandoffs;
105
+ const oldRate = agent.verificationHistory.passRate;
106
+ const passed = result.verdict === 'PASS' ? 1 : 0;
107
+ return (oldRate * oldTotal + passed) / (oldTotal + 1);
108
+ }
109
+ }
110
+ //# sourceMappingURL=trust-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-manager.js","sourceRoot":"","sources":["../../src/runtime/trust-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { TaskAssignmentPayload } from './specialized-agent.js';
3
+ import type { SafetyPolicy, VerifiedHandoff, BoundaryArtifact, AuditEntry } from './types.js';
4
+ export interface TwoAgentResult {
5
+ readonly taskId: string;
6
+ readonly status: 'completed' | 'rejected' | 'escalated' | 'failed';
7
+ readonly codeArtifacts: readonly BoundaryArtifact[];
8
+ readonly reviewArtifact: BoundaryArtifact | null;
9
+ readonly codeHandoff: VerifiedHandoff | null;
10
+ readonly reviewHandoff: VerifiedHandoff | null;
11
+ readonly attempts: number;
12
+ readonly auditTrail: readonly AuditEntry[];
13
+ }
14
+ export declare class TwoAgentLoop extends EventEmitter {
15
+ private messageBus;
16
+ private compositionVerifier;
17
+ private trustManager;
18
+ private codeAgent;
19
+ private reviewAgent;
20
+ private auditTrail;
21
+ constructor(codebaseRoot: string, opts?: {
22
+ codeModel?: string;
23
+ reviewModel?: string;
24
+ safetyPolicy?: SafetyPolicy;
25
+ });
26
+ /**
27
+ * Run the two-agent loop on a task.
28
+ * Code Agent writes -> Assay verifies -> Review Agent reviews -> Assay verifies.
29
+ * If rejected at any boundary, Code Agent gets feedback and retries.
30
+ */
31
+ run(task: TaskAssignmentPayload, maxAttempts?: number): Promise<TwoAgentResult>;
32
+ /** Get the current audit trail. */
33
+ getAuditTrail(): readonly AuditEntry[];
34
+ private audit;
35
+ }
@@ -0,0 +1,208 @@
1
+ // ============================================================
2
+ // Assay Verified Agent Runtime — Two-Agent Loop
3
+ // M1 deliverable: Code + Review with boundary verification
4
+ // ============================================================
5
+ import { randomUUID } from 'node:crypto';
6
+ import { EventEmitter } from 'node:events';
7
+ import { MessageBus } from './message-bus.js';
8
+ import { CompositionVerifier } from './composition-verifier.js';
9
+ import { TrustManager } from './trust-manager.js';
10
+ import { CodeAgent } from './agents/code-agent.js';
11
+ import { ReviewAgent } from './agents/review-agent.js';
12
+ // ── Default safety policy ───────────────────────────────────
13
+ const DEFAULT_SAFETY = {
14
+ formalOverridesConsensus: true,
15
+ noSelfVerification: true,
16
+ criticalClaimsRequireFormal: true,
17
+ escalationRules: {
18
+ maxFormalOverridesBeforeHalt: 3,
19
+ maxTrustDemotions: 2,
20
+ maxRejectCyclesPerTask: 3,
21
+ },
22
+ preferModelDiversity: false,
23
+ };
24
+ // ── Two-Agent Loop ──────────────────────────────────────────
25
+ export class TwoAgentLoop extends EventEmitter {
26
+ messageBus;
27
+ compositionVerifier;
28
+ trustManager;
29
+ codeAgent;
30
+ reviewAgent;
31
+ auditTrail = [];
32
+ constructor(codebaseRoot, opts) {
33
+ super();
34
+ this.messageBus = new MessageBus();
35
+ this.compositionVerifier = new CompositionVerifier(codebaseRoot);
36
+ this.trustManager = new TrustManager(opts?.safetyPolicy ?? DEFAULT_SAFETY);
37
+ this.codeAgent = new CodeAgent(this.messageBus, { model: opts?.codeModel });
38
+ this.reviewAgent = new ReviewAgent(this.messageBus, { model: opts?.reviewModel });
39
+ // Register agents with trust manager
40
+ this.trustManager.register(this.codeAgent.getIdentity());
41
+ this.trustManager.register(this.reviewAgent.getIdentity());
42
+ }
43
+ /**
44
+ * Run the two-agent loop on a task.
45
+ * Code Agent writes -> Assay verifies -> Review Agent reviews -> Assay verifies.
46
+ * If rejected at any boundary, Code Agent gets feedback and retries.
47
+ */
48
+ async run(task, maxAttempts = 3) {
49
+ const taskId = task.taskId;
50
+ let attempts = 0;
51
+ let currentTask = task;
52
+ let lastCodeArtifacts = [];
53
+ let lastReviewArtifact = null;
54
+ let lastCodeHandoff = null;
55
+ let lastReviewHandoff = null;
56
+ while (attempts < maxAttempts) {
57
+ attempts++;
58
+ this.audit('task_status_change', { taskId, status: 'in_progress', attempt: attempts });
59
+ // Step 1: Code Agent writes code
60
+ const codeResult = await this.codeAgent.executeTask(currentTask);
61
+ this.audit('message_sent', {
62
+ from: this.codeAgent.getIdentity().name,
63
+ type: 'task_result',
64
+ status: codeResult.status,
65
+ artifactCount: codeResult.artifacts.length,
66
+ });
67
+ if (codeResult.status === 'failed') {
68
+ this.audit('task_status_change', { taskId, status: 'failed', reason: codeResult.summary });
69
+ return {
70
+ taskId,
71
+ status: 'failed',
72
+ codeArtifacts: [],
73
+ reviewArtifact: null,
74
+ codeHandoff: null,
75
+ reviewHandoff: null,
76
+ attempts,
77
+ auditTrail: this.auditTrail,
78
+ };
79
+ }
80
+ lastCodeArtifacts = [...codeResult.artifacts];
81
+ let boundaryRejected = false;
82
+ // Step 2: Verify Code Agent output at boundary
83
+ for (const artifact of codeResult.artifacts) {
84
+ const handoff = await this.compositionVerifier.verifyHandoff(this.codeAgent.getIdentity(), this.reviewAgent.getIdentity(), artifact);
85
+ lastCodeHandoff = handoff;
86
+ this.audit('verification_run', {
87
+ boundary: `${this.codeAgent.getIdentity().name} -> ${this.reviewAgent.getIdentity().name}`,
88
+ verdict: handoff.verificationResult.verdict,
89
+ claims: handoff.verificationResult.total,
90
+ passed: handoff.verificationResult.passed,
91
+ failed: handoff.verificationResult.failed,
92
+ });
93
+ // Update trust
94
+ const trustResult = this.trustManager.updateTrust(this.codeAgent.getIdentity().id, handoff.verificationResult);
95
+ if (trustResult.demoted) {
96
+ this.audit('trust_change', {
97
+ agent: this.codeAgent.getIdentity().name,
98
+ newTrust: trustResult.newTrust,
99
+ reason: 'formal_override',
100
+ });
101
+ }
102
+ if (trustResult.shouldHalt) {
103
+ this.audit('escalation', { reason: 'trust_threshold_exceeded', agent: this.codeAgent.getIdentity().name });
104
+ return {
105
+ taskId,
106
+ status: 'escalated',
107
+ codeArtifacts: lastCodeArtifacts,
108
+ reviewArtifact: null,
109
+ codeHandoff: lastCodeHandoff,
110
+ reviewHandoff: null,
111
+ attempts,
112
+ auditTrail: this.auditTrail,
113
+ };
114
+ }
115
+ // If code boundary fails, feed back to code agent and retry
116
+ if (handoff.decision.action === 'reject') {
117
+ this.audit('handoff_decision', { decision: 'reject', boundary: 'code->review' });
118
+ // Update task with rejection feedback
119
+ currentTask = {
120
+ ...currentTask,
121
+ constraints: [
122
+ ...currentTask.constraints,
123
+ `Previous attempt rejected. Issues: ${handoff.verificationResult.blockers.map(b => b.text).join('; ')}`,
124
+ ],
125
+ };
126
+ boundaryRejected = true;
127
+ break; // retry from step 1
128
+ }
129
+ }
130
+ if (boundaryRejected) {
131
+ continue;
132
+ }
133
+ // Step 3: Review Agent reviews the code
134
+ const reviewTask = {
135
+ taskId: `${taskId}-review`,
136
+ goal: `Review the code produced for: ${currentTask.goal}`,
137
+ constraints: ['Be thorough', 'Check for security, correctness, and edge cases'],
138
+ dependencies: [],
139
+ contextRefs: codeResult.artifacts.map(a => ({
140
+ summary: a.path ?? 'code patch',
141
+ content: a.content,
142
+ })),
143
+ };
144
+ const reviewResult = await this.reviewAgent.executeTask(reviewTask);
145
+ this.audit('message_sent', {
146
+ from: this.reviewAgent.getIdentity().name,
147
+ type: 'task_result',
148
+ status: reviewResult.status,
149
+ });
150
+ if (reviewResult.artifacts.length > 0) {
151
+ lastReviewArtifact = reviewResult.artifacts[0];
152
+ // Step 4: Verify Review Agent output at boundary
153
+ const reviewHandoff = await this.compositionVerifier.verifyHandoff(this.reviewAgent.getIdentity(), this.codeAgent.getIdentity(), // review flows back to code
154
+ lastReviewArtifact);
155
+ lastReviewHandoff = reviewHandoff;
156
+ this.audit('verification_run', {
157
+ boundary: `${this.reviewAgent.getIdentity().name} -> ${this.codeAgent.getIdentity().name}`,
158
+ verdict: reviewHandoff.verificationResult.verdict,
159
+ claims: reviewHandoff.verificationResult.total,
160
+ });
161
+ // Update review agent trust
162
+ this.trustManager.updateTrust(this.reviewAgent.getIdentity().id, reviewHandoff.verificationResult);
163
+ }
164
+ // If we got here without a reject, the task is complete
165
+ this.audit('task_status_change', { taskId, status: 'completed', attempts });
166
+ return {
167
+ taskId,
168
+ status: 'completed',
169
+ codeArtifacts: lastCodeArtifacts,
170
+ reviewArtifact: lastReviewArtifact,
171
+ codeHandoff: lastCodeHandoff,
172
+ reviewHandoff: lastReviewHandoff,
173
+ attempts,
174
+ auditTrail: this.auditTrail,
175
+ };
176
+ }
177
+ // Exhausted max attempts
178
+ this.audit('task_status_change', { taskId, status: 'rejected', reason: 'max_attempts_exceeded' });
179
+ return {
180
+ taskId,
181
+ status: 'rejected',
182
+ codeArtifacts: lastCodeArtifacts,
183
+ reviewArtifact: lastReviewArtifact,
184
+ codeHandoff: lastCodeHandoff,
185
+ reviewHandoff: lastReviewHandoff,
186
+ attempts,
187
+ auditTrail: this.auditTrail,
188
+ };
189
+ }
190
+ /** Get the current audit trail. */
191
+ getAuditTrail() {
192
+ return this.auditTrail;
193
+ }
194
+ // ── Private ─────────────────────────────────────────────
195
+ audit(eventType, details) {
196
+ const entry = {
197
+ id: randomUUID(),
198
+ eventType,
199
+ agentName: 'two-agent-loop',
200
+ timestamp: new Date().toISOString(),
201
+ details,
202
+ relatedIds: {},
203
+ };
204
+ this.auditTrail.push(entry);
205
+ this.emit('audit', entry);
206
+ }
207
+ }
208
+ //# sourceMappingURL=two-agent-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"two-agent-loop.js","sourceRoot":"","sources":["../../src/runtime/two-agent-loop.ts"],"names":[],"mappings":"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"}