Skip to content

Commit 7f2ab59

Browse files
committed
feat(a2a): implement secure acknowledgement and correct agent indexing
1 parent 7b226a1 commit 7f2ab59

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

packages/core/src/agents/acknowledgedAgents.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ export class AcknowledgedAgentsService {
6666
hash: string,
6767
): Promise<boolean> {
6868
await this.load();
69+
return this.isAcknowledgedSync(projectPath, agentName, hash);
70+
}
71+
72+
/**
73+
* Synchronous check for acknowledgment.
74+
* Note: Assumes load() has already been called and awaited (e.g. during registry init).
75+
*/
76+
isAcknowledgedSync(
77+
projectPath: string,
78+
agentName: string,
79+
hash: string,
80+
): boolean {
6981
const projectAgents = this.acknowledgedAgents[projectPath];
7082
if (!projectAgents) return false;
7183
return projectAgents[agentName] === hash;

packages/core/src/agents/registry_acknowledgement.test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { coreEvents } from '../utils/events.js';
1212
import * as tomlLoader from './agentLoader.js';
1313
import { type Config } from '../config/config.js';
1414
import { AcknowledgedAgentsService } from './acknowledgedAgents.js';
15+
import { PolicyDecision } from '../policy/types.js';
1516
import * as fs from 'node:fs/promises';
1617
import * as path from 'node:path';
1718
import * as os from 'node:os';
@@ -103,13 +104,22 @@ describe('AgentRegistry Acknowledgement', () => {
103104
await fs.rm(tempDir, { recursive: true, force: true });
104105
});
105106

106-
it('should not register unacknowledged project agents and emit event', async () => {
107+
it('should register unacknowledged project agents and emit event', async () => {
107108
const emitSpy = vi.spyOn(coreEvents, 'emitAgentsDiscovered');
108109

109110
await registry.initialize();
110111

111-
expect(registry.getDefinition('ProjectAgent')).toBeUndefined();
112+
// Now unacknowledged agents ARE registered (but with ASK_USER policy)
113+
expect(registry.getDefinition('ProjectAgent')).toBeDefined();
112114
expect(emitSpy).toHaveBeenCalledWith([MOCK_AGENT_WITH_HASH]);
115+
116+
// Verify policy
117+
const policyEngine = config.getPolicyEngine();
118+
expect(
119+
await policyEngine?.check({ name: 'ProjectAgent', args: {} }, undefined),
120+
).toMatchObject({
121+
decision: PolicyDecision.ASK_USER,
122+
});
113123
});
114124

115125
it('should register acknowledged project agents', async () => {
@@ -134,6 +144,14 @@ describe('AgentRegistry Acknowledgement', () => {
134144

135145
expect(registry.getDefinition('ProjectAgent')).toBeDefined();
136146
expect(emitSpy).not.toHaveBeenCalled();
147+
148+
// Verify policy is ALLOW for acknowledged agent
149+
const policyEngine = config.getPolicyEngine();
150+
expect(
151+
await policyEngine?.check({ name: 'ProjectAgent', args: {} }, undefined),
152+
).toMatchObject({
153+
decision: PolicyDecision.ALLOW,
154+
});
137155
});
138156

139157
it('should register agents without hash (legacy/safe?)', async () => {

0 commit comments

Comments
 (0)