From f40f810bfa23c1e82e7d6b539a549bc741a0ae34 Mon Sep 17 00:00:00 2001 From: Alisa Novikova <62909685+alisa-alisa@users.noreply.github.com> Date: Fri, 6 Mar 2026 06:22:32 -0800 Subject: [PATCH] feat(a2a): implement secure acknowledgement and correct agent indexing --- .../core/src/agents/acknowledgedAgents.ts | 12 ++++++++++ .../agents/registry_acknowledgement.test.ts | 22 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/core/src/agents/acknowledgedAgents.ts b/packages/core/src/agents/acknowledgedAgents.ts index 98c90afb96..4d90b68022 100644 --- a/packages/core/src/agents/acknowledgedAgents.ts +++ b/packages/core/src/agents/acknowledgedAgents.ts @@ -66,6 +66,18 @@ export class AcknowledgedAgentsService { hash: string, ): Promise { await this.load(); + return this.isAcknowledgedSync(projectPath, agentName, hash); + } + + /** + * Synchronous check for acknowledgment. + * Note: Assumes load() has already been called and awaited (e.g. during registry init). + */ + isAcknowledgedSync( + projectPath: string, + agentName: string, + hash: string, + ): boolean { const projectAgents = this.acknowledgedAgents[projectPath]; if (!projectAgents) return false; return projectAgents[agentName] === hash; diff --git a/packages/core/src/agents/registry_acknowledgement.test.ts b/packages/core/src/agents/registry_acknowledgement.test.ts index 5ac563091d..283767ae78 100644 --- a/packages/core/src/agents/registry_acknowledgement.test.ts +++ b/packages/core/src/agents/registry_acknowledgement.test.ts @@ -12,6 +12,7 @@ import { coreEvents } from '../utils/events.js'; import * as tomlLoader from './agentLoader.js'; import { type Config } from '../config/config.js'; import { AcknowledgedAgentsService } from './acknowledgedAgents.js'; +import { PolicyDecision } from '../policy/types.js'; import * as fs from 'node:fs/promises'; import * as path from 'node:path'; import * as os from 'node:os'; @@ -103,13 +104,22 @@ describe('AgentRegistry Acknowledgement', () => { await fs.rm(tempDir, { recursive: true, force: true }); }); - it('should not register unacknowledged project agents and emit event', async () => { + it('should register unacknowledged project agents and emit event', async () => { const emitSpy = vi.spyOn(coreEvents, 'emitAgentsDiscovered'); await registry.initialize(); - expect(registry.getDefinition('ProjectAgent')).toBeUndefined(); + // Now unacknowledged agents ARE registered (but with ASK_USER policy) + expect(registry.getDefinition('ProjectAgent')).toBeDefined(); expect(emitSpy).toHaveBeenCalledWith([MOCK_AGENT_WITH_HASH]); + + // Verify policy + const policyEngine = config.getPolicyEngine(); + expect( + await policyEngine?.check({ name: 'ProjectAgent', args: {} }, undefined), + ).toMatchObject({ + decision: PolicyDecision.ASK_USER, + }); }); it('should register acknowledged project agents', async () => { @@ -134,6 +144,14 @@ describe('AgentRegistry Acknowledgement', () => { expect(registry.getDefinition('ProjectAgent')).toBeDefined(); expect(emitSpy).not.toHaveBeenCalled(); + + // Verify policy is ALLOW for acknowledged agent + const policyEngine = config.getPolicyEngine(); + expect( + await policyEngine?.check({ name: 'ProjectAgent', args: {} }, undefined), + ).toMatchObject({ + decision: PolicyDecision.ALLOW, + }); }); it('should register agents without hash (legacy/safe?)', async () => {