feat(a2a): implement secure acknowledgement and correct agent indexing

This commit is contained in:
Alisa Novikova
2026-03-06 06:22:32 -08:00
parent 54b8c2843b
commit f40f810bfa
2 changed files with 32 additions and 2 deletions

View File

@@ -66,6 +66,18 @@ export class AcknowledgedAgentsService {
hash: string,
): Promise<boolean> {
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;

View File

@@ -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 () => {