@backendkit-labs/agent-enterprise 0.3.2 → 0.4.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 (144) hide show
  1. package/README.md +2 -0
  2. package/dist/__tests__/integration/EventPublisher.integration.test.d.ts +2 -0
  3. package/dist/__tests__/integration/EventPublisher.integration.test.d.ts.map +1 -0
  4. package/dist/__tests__/integration/EventPublisher.integration.test.js +122 -0
  5. package/dist/__tests__/integration/EventPublisher.integration.test.js.map +1 -0
  6. package/dist/__tests__/unit/ComplianceGate.test.d.ts +2 -0
  7. package/dist/__tests__/unit/ComplianceGate.test.d.ts.map +1 -0
  8. package/dist/__tests__/unit/ComplianceGate.test.js +271 -0
  9. package/dist/__tests__/unit/ComplianceGate.test.js.map +1 -0
  10. package/dist/__tests__/unit/EventPublisher.test.d.ts +2 -0
  11. package/dist/__tests__/unit/EventPublisher.test.d.ts.map +1 -0
  12. package/dist/__tests__/unit/EventPublisher.test.js +160 -0
  13. package/dist/__tests__/unit/EventPublisher.test.js.map +1 -0
  14. package/dist/__tests__/unit/FlowLoader.test.d.ts +2 -0
  15. package/dist/__tests__/unit/FlowLoader.test.d.ts.map +1 -0
  16. package/dist/__tests__/unit/FlowLoader.test.js +283 -0
  17. package/dist/__tests__/unit/FlowLoader.test.js.map +1 -0
  18. package/dist/__tests__/unit/FlowRunner.test.d.ts +2 -0
  19. package/dist/__tests__/unit/FlowRunner.test.d.ts.map +1 -0
  20. package/dist/__tests__/unit/FlowRunner.test.js +386 -0
  21. package/dist/__tests__/unit/FlowRunner.test.js.map +1 -0
  22. package/dist/__tests__/unit/PolicySeeder.test.d.ts +2 -0
  23. package/dist/__tests__/unit/PolicySeeder.test.d.ts.map +1 -0
  24. package/dist/__tests__/unit/PolicySeeder.test.js +146 -0
  25. package/dist/__tests__/unit/PolicySeeder.test.js.map +1 -0
  26. package/dist/__tests__/unit/ProfilePolicies.test.d.ts +2 -0
  27. package/dist/__tests__/unit/ProfilePolicies.test.d.ts.map +1 -0
  28. package/dist/__tests__/unit/ProfilePolicies.test.js +70 -0
  29. package/dist/__tests__/unit/ProfilePolicies.test.js.map +1 -0
  30. package/dist/__tests__/unit/ReconciliationSweeper.test.d.ts +2 -0
  31. package/dist/__tests__/unit/ReconciliationSweeper.test.d.ts.map +1 -0
  32. package/dist/__tests__/unit/ReconciliationSweeper.test.js +235 -0
  33. package/dist/__tests__/unit/ReconciliationSweeper.test.js.map +1 -0
  34. package/dist/__tests__/unit/n8nTriggerTool.test.d.ts +2 -0
  35. package/dist/__tests__/unit/n8nTriggerTool.test.d.ts.map +1 -0
  36. package/dist/__tests__/unit/n8nTriggerTool.test.js +103 -0
  37. package/dist/__tests__/unit/n8nTriggerTool.test.js.map +1 -0
  38. package/dist/events/EventPublisher.d.ts +47 -0
  39. package/dist/events/EventPublisher.d.ts.map +1 -0
  40. package/dist/events/EventPublisher.js +75 -0
  41. package/dist/events/EventPublisher.js.map +1 -0
  42. package/dist/events/ReconciliationSweeper.d.ts +37 -0
  43. package/dist/events/ReconciliationSweeper.d.ts.map +1 -0
  44. package/dist/events/ReconciliationSweeper.js +151 -0
  45. package/dist/events/ReconciliationSweeper.js.map +1 -0
  46. package/dist/events/index.d.ts +6 -0
  47. package/dist/events/index.d.ts.map +1 -0
  48. package/dist/events/index.js +8 -0
  49. package/dist/events/index.js.map +1 -0
  50. package/dist/events/types.d.ts +48 -0
  51. package/dist/events/types.d.ts.map +1 -0
  52. package/dist/events/types.js +3 -0
  53. package/dist/events/types.js.map +1 -0
  54. package/dist/factory.d.ts +6 -0
  55. package/dist/factory.d.ts.map +1 -1
  56. package/dist/factory.js +11 -5
  57. package/dist/factory.js.map +1 -1
  58. package/dist/flow/ComplianceGate.d.ts +90 -0
  59. package/dist/flow/ComplianceGate.d.ts.map +1 -0
  60. package/dist/flow/ComplianceGate.js +214 -0
  61. package/dist/flow/ComplianceGate.js.map +1 -0
  62. package/dist/flow/FlowLoader.d.ts +22 -0
  63. package/dist/flow/FlowLoader.d.ts.map +1 -0
  64. package/dist/flow/FlowLoader.js +170 -0
  65. package/dist/flow/FlowLoader.js.map +1 -0
  66. package/dist/flow/FlowRunner.d.ts +73 -0
  67. package/dist/flow/FlowRunner.d.ts.map +1 -0
  68. package/dist/flow/FlowRunner.js +162 -0
  69. package/dist/flow/FlowRunner.js.map +1 -0
  70. package/dist/flow/index.d.ts +8 -0
  71. package/dist/flow/index.d.ts.map +1 -0
  72. package/dist/flow/index.js +21 -0
  73. package/dist/flow/index.js.map +1 -0
  74. package/dist/flow/types.d.ts +306 -0
  75. package/dist/flow/types.d.ts.map +1 -0
  76. package/dist/flow/types.js +63 -0
  77. package/dist/flow/types.js.map +1 -0
  78. package/dist/index.d.ts +10 -0
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +32 -1
  81. package/dist/index.js.map +1 -1
  82. package/dist/integrations/index.d.ts +3 -0
  83. package/dist/integrations/index.d.ts.map +1 -0
  84. package/dist/integrations/index.js +6 -0
  85. package/dist/integrations/index.js.map +1 -0
  86. package/dist/integrations/n8nTriggerTool.d.ts +12 -0
  87. package/dist/integrations/n8nTriggerTool.d.ts.map +1 -0
  88. package/dist/integrations/n8nTriggerTool.js +45 -0
  89. package/dist/integrations/n8nTriggerTool.js.map +1 -0
  90. package/dist/policies/PolicySeeder.d.ts +31 -0
  91. package/dist/policies/PolicySeeder.d.ts.map +1 -0
  92. package/dist/policies/PolicySeeder.js +270 -0
  93. package/dist/policies/PolicySeeder.js.map +1 -0
  94. package/dist/policies/index.d.ts +3 -0
  95. package/dist/policies/index.d.ts.map +1 -0
  96. package/dist/policies/index.js +6 -0
  97. package/dist/policies/index.js.map +1 -0
  98. package/dist/profiles/constants.d.ts +4 -0
  99. package/dist/profiles/constants.d.ts.map +1 -1
  100. package/dist/profiles/constants.js +4 -0
  101. package/dist/profiles/constants.js.map +1 -1
  102. package/dist/profiles/finance.d.ts.map +1 -1
  103. package/dist/profiles/finance.js +7 -8
  104. package/dist/profiles/finance.js.map +1 -1
  105. package/dist/profiles/general.d.ts.map +1 -1
  106. package/dist/profiles/general.js +1 -0
  107. package/dist/profiles/general.js.map +1 -1
  108. package/dist/profiles/hr.d.ts.map +1 -1
  109. package/dist/profiles/hr.js +6 -8
  110. package/dist/profiles/hr.js.map +1 -1
  111. package/dist/profiles/ops.d.ts.map +1 -1
  112. package/dist/profiles/ops.js +6 -10
  113. package/dist/profiles/ops.js.map +1 -1
  114. package/dist/profiles/sales.d.ts.map +1 -1
  115. package/dist/profiles/sales.js +3 -1
  116. package/dist/profiles/sales.js.map +1 -1
  117. package/dist/profiles/support.d.ts.map +1 -1
  118. package/dist/profiles/support.js +2 -4
  119. package/dist/profiles/support.js.map +1 -1
  120. package/dist/rag/OllamaEmbedder.d.ts +6 -0
  121. package/dist/rag/OllamaEmbedder.d.ts.map +1 -1
  122. package/dist/rag/OllamaEmbedder.js +75 -16
  123. package/dist/rag/OllamaEmbedder.js.map +1 -1
  124. package/dist/rag/VaultWriter.d.ts +3 -0
  125. package/dist/rag/VaultWriter.d.ts.map +1 -1
  126. package/dist/rag/VaultWriter.js +63 -17
  127. package/dist/rag/VaultWriter.js.map +1 -1
  128. package/dist/reflection/EnterpriseReflection.d.ts +108 -0
  129. package/dist/reflection/EnterpriseReflection.d.ts.map +1 -0
  130. package/dist/reflection/EnterpriseReflection.js +296 -0
  131. package/dist/reflection/EnterpriseReflection.js.map +1 -0
  132. package/dist/reflection/GateReflectionBridge.d.ts +21 -0
  133. package/dist/reflection/GateReflectionBridge.d.ts.map +1 -0
  134. package/dist/reflection/GateReflectionBridge.js +120 -0
  135. package/dist/reflection/GateReflectionBridge.js.map +1 -0
  136. package/dist/reflection/domains.d.ts +6 -0
  137. package/dist/reflection/domains.d.ts.map +1 -0
  138. package/dist/reflection/domains.js +176 -0
  139. package/dist/reflection/domains.js.map +1 -0
  140. package/dist/reflection/index.d.ts +6 -0
  141. package/dist/reflection/index.d.ts.map +1 -0
  142. package/dist/reflection/index.js +11 -0
  143. package/dist/reflection/index.js.map +1 -0
  144. package/package.json +6 -2
package/README.md CHANGED
@@ -4,6 +4,8 @@ Enterprise-grade AI agent setup with RAG (Retrieval-Augmented Generation) over a
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@backendkit-labs/agent-enterprise)](https://www.npmjs.com/package/@backendkit-labs/agent-enterprise)
6
6
 
7
+ > **Status: `core`** — Required by the enterprise use case. Breaking changes go through full review before merging.
8
+
7
9
  ## Table of contents
8
10
 
9
11
  - [Installation](#installation)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=EventPublisher.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventPublisher.integration.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/EventPublisher.integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * Integration test: EventPublisher against a real BullMQ / Redis instance.
38
+ * Skipped automatically if Redis is not reachable on localhost:6379.
39
+ */
40
+ const fs = __importStar(require("fs/promises"));
41
+ const net = __importStar(require("net"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const agent_core_1 = require("@backendkit-labs/agent-core");
45
+ const EventPublisher_1 = require("../../events/EventPublisher");
46
+ const REDIS_HOST = process.env.REDIS_HOST ?? 'localhost';
47
+ const REDIS_PORT = parseInt(process.env.REDIS_PORT ?? '6379', 10);
48
+ const TestEventSchema = {
49
+ type: 'test-integracion',
50
+ version: 1,
51
+ schema: agent_core_1.z.object({ nombre: agent_core_1.z.string() }),
52
+ };
53
+ /** Fast TCP check — no BullMQ reconnection loop. */
54
+ async function checkRedis(host, port) {
55
+ return new Promise(resolve => {
56
+ const socket = new net.Socket();
57
+ socket.setTimeout(1000);
58
+ socket.connect(port, host, () => { socket.destroy(); resolve(true); });
59
+ socket.on('error', () => resolve(false));
60
+ socket.on('timeout', () => { socket.destroy(); resolve(false); });
61
+ });
62
+ }
63
+ let redisAvailable = false;
64
+ beforeAll(async () => {
65
+ redisAvailable = await checkRedis(REDIS_HOST, REDIS_PORT);
66
+ if (!redisAvailable) {
67
+ console.warn('\n⚠ EventPublisher integration tests skipped — ' +
68
+ `Redis not available at ${REDIS_HOST}:${REDIS_PORT}.\n` +
69
+ ' To run: start Redis on localhost:6379');
70
+ }
71
+ });
72
+ describe('EventPublisher integration — BullMQ / Redis', () => {
73
+ let tmpDir;
74
+ let queue;
75
+ beforeEach(async () => {
76
+ if (!redisAvailable)
77
+ return;
78
+ tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ep-int-'));
79
+ });
80
+ afterEach(async () => {
81
+ if (tmpDir) {
82
+ await fs.rm(tmpDir, { recursive: true, force: true });
83
+ tmpDir = undefined;
84
+ }
85
+ if (queue) {
86
+ try {
87
+ await queue.obliterate({ force: true });
88
+ }
89
+ catch { /* ignore */ }
90
+ await queue.close();
91
+ queue = undefined;
92
+ }
93
+ });
94
+ it('publishes a job to Redis and writes the vault note', async () => {
95
+ if (!redisAvailable)
96
+ return;
97
+ const BullMQ = require('bullmq');
98
+ queue = new BullMQ.Queue('eventos.test-integracion', {
99
+ connection: { host: REDIS_HOST, port: REDIS_PORT },
100
+ });
101
+ const publisher = new EventPublisher_1.EventPublisher({
102
+ queue,
103
+ vaultPath: tmpDir,
104
+ source: 'integration-test',
105
+ });
106
+ const envelope = await publisher.publish(TestEventSchema, { nombre: 'Juan' });
107
+ // Job was added to Redis
108
+ const job = await queue.getJob(envelope.id);
109
+ expect(job).not.toBeNull();
110
+ const data = job.data;
111
+ expect(data.id).toBe(envelope.id);
112
+ expect(data.type).toBe('test-integracion');
113
+ // Vault note was written
114
+ const eventsDir = path.join(tmpDir, 'eventos');
115
+ const files = await fs.readdir(eventsDir);
116
+ expect(files.filter(f => f.endsWith('.md'))).toHaveLength(1);
117
+ const content = await fs.readFile(path.join(eventsDir, files[0]), 'utf-8');
118
+ expect(content).toContain(envelope.id);
119
+ expect(content).toContain('test-integracion');
120
+ });
121
+ });
122
+ //# sourceMappingURL=EventPublisher.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventPublisher.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/EventPublisher.integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ComplianceGate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplianceGate.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/ComplianceGate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs/promises"));
37
+ const path = __importStar(require("path"));
38
+ const os = __importStar(require("os"));
39
+ const ComplianceGate_1 = require("../../flow/ComplianceGate");
40
+ // ── Helpers ───────────────────────────────────────────────────────────────────
41
+ function makeGate(overrides = {}) {
42
+ return new ComplianceGate_1.ComplianceGate({
43
+ stepId: 'preparar-ficha',
44
+ flowId: 'onboarding-empleado',
45
+ runId: 'run-test',
46
+ executor: 'rrhh',
47
+ criteria: ['Ficha creada en Odoo', 'Nota canónica escrita en /eventos', 'Legajo asignado'],
48
+ evidenceMode: 'required',
49
+ ...overrides,
50
+ });
51
+ }
52
+ // ── Initial state ─────────────────────────────────────────────────────────────
53
+ describe('ComplianceGate — initial state', () => {
54
+ it('starts with verdict pending', () => {
55
+ const gate = makeGate();
56
+ expect(gate.verdict).toBe('pending');
57
+ });
58
+ it('indexes criteria with auto-generated ids (c0, c1, c2)', () => {
59
+ const gate = makeGate();
60
+ const record = gate.getRecord();
61
+ expect(record.criteria.map(c => c.id)).toEqual(['c0', 'c1', 'c2']);
62
+ expect(record.criteria[0].description).toBe('Ficha creada en Odoo');
63
+ expect(record.log).toEqual([]);
64
+ });
65
+ });
66
+ // ── evaluateCriterion — happy path ────────────────────────────────────────────
67
+ describe('ComplianceGate — evaluateCriterion happy path', () => {
68
+ it('marks all 3 criteria passed → verdict becomes passed', () => {
69
+ const gate = makeGate();
70
+ gate.evaluateCriterion(0, 'auditor', true, 'odoo://employees/42');
71
+ gate.evaluateCriterion(1, 'auditor', true, 'vault://eventos/2026-01.md');
72
+ gate.evaluateCriterion(2, 'auditor', true, 'odoo://employees/42#legajo');
73
+ expect(gate.verdict).toBe('passed');
74
+ });
75
+ it('passes without evidence when evidenceMode is optional', () => {
76
+ const gate = makeGate({ evidenceMode: 'optional' });
77
+ gate.evaluateCriterion(0, 'auditor', true);
78
+ gate.evaluateCriterion(1, 'auditor', true);
79
+ gate.evaluateCriterion(2, 'auditor', true);
80
+ expect(gate.verdict).toBe('passed');
81
+ });
82
+ it('appends a criterion_evaluated entry to the log for each pass', () => {
83
+ const gate = makeGate();
84
+ gate.evaluateCriterion(0, 'auditor', true, 'odoo://employees/42');
85
+ const record = gate.getRecord();
86
+ expect(record.log).toHaveLength(1);
87
+ expect(record.log[0].event).toBe('criterion_evaluated');
88
+ expect(record.log[0].criterionId).toBe('c0');
89
+ expect(record.log[0].evaluatorId).toBe('auditor');
90
+ expect(record.log[0].at).toMatch(/^\d{4}-\d{2}-\d{2}T/);
91
+ });
92
+ it('appends a criterion_rejected entry when passed is false', () => {
93
+ const gate = makeGate();
94
+ gate.evaluateCriterion(0, 'auditor', false);
95
+ const record = gate.getRecord();
96
+ expect(record.log[0].event).toBe('criterion_rejected');
97
+ expect(gate.verdict).toBe('failed');
98
+ });
99
+ it('records evaluatedBy and evaluatedAt on the criterion', () => {
100
+ const gate = makeGate();
101
+ gate.evaluateCriterion(0, 'auditor', true, 'evidence-ref');
102
+ const record = gate.getRecord();
103
+ expect(record.criteria[0].evaluatedBy).toBe('auditor');
104
+ expect(record.criteria[0].evaluatedAt).toMatch(/^\d{4}-/);
105
+ expect(record.criteria[0].evidence).toBe('evidence-ref');
106
+ });
107
+ });
108
+ // ── evaluateCriterion — enforcement ───────────────────────────────────────────
109
+ describe('ComplianceGate — evaluateCriterion enforcement', () => {
110
+ it('throws ComplianceGateError when evaluator equals executor', () => {
111
+ const gate = makeGate();
112
+ expect(() => gate.evaluateCriterion(0, 'rrhh', true, 'evidence'))
113
+ .toThrow(ComplianceGate_1.ComplianceGateError);
114
+ expect(() => gate.evaluateCriterion(0, 'rrhh', true, 'evidence'))
115
+ .toThrow('self-evaluation is not allowed');
116
+ });
117
+ it('logs the self_evaluation_attempt BEFORE throwing', () => {
118
+ const gate = makeGate();
119
+ try {
120
+ gate.evaluateCriterion(0, 'rrhh', true, 'evidence');
121
+ }
122
+ catch { /* expected */ }
123
+ const record = gate.getRecord();
124
+ expect(record.log).toHaveLength(1);
125
+ expect(record.log[0].event).toBe('self_evaluation_attempt');
126
+ expect(gate.verdict).toBe('pending');
127
+ });
128
+ it('throws ComplianceGateError when evidence is missing and evidenceMode is required', () => {
129
+ const gate = makeGate({ evidenceMode: 'required' });
130
+ expect(() => gate.evaluateCriterion(0, 'auditor', true))
131
+ .toThrow(ComplianceGate_1.ComplianceGateError);
132
+ expect(() => gate.evaluateCriterion(0, 'auditor', true))
133
+ .toThrow('requires evidence');
134
+ });
135
+ it('logs the missing_evidence_attempt BEFORE throwing', () => {
136
+ const gate = makeGate({ evidenceMode: 'required' });
137
+ try {
138
+ gate.evaluateCriterion(0, 'auditor', true);
139
+ }
140
+ catch { /* expected */ }
141
+ const record = gate.getRecord();
142
+ expect(record.log).toHaveLength(1);
143
+ expect(record.log[0].event).toBe('missing_evidence_attempt');
144
+ expect(gate.verdict).toBe('pending');
145
+ });
146
+ it('throws ComplianceGateError for an out-of-range index', () => {
147
+ const gate = makeGate();
148
+ expect(() => gate.evaluateCriterion(99, 'auditor', true, 'e'))
149
+ .toThrow(ComplianceGate_1.ComplianceGateError);
150
+ });
151
+ });
152
+ // ── Verdict progression ───────────────────────────────────────────────────────
153
+ describe('ComplianceGate — verdict progression', () => {
154
+ it('stays pending when only some criteria are evaluated', () => {
155
+ const gate = makeGate();
156
+ gate.evaluateCriterion(0, 'auditor', true, 'ev');
157
+ gate.evaluateCriterion(1, 'auditor', true, 'ev');
158
+ expect(gate.verdict).toBe('pending');
159
+ });
160
+ it('becomes failed immediately when any criterion fails', () => {
161
+ const gate = makeGate();
162
+ gate.evaluateCriterion(0, 'auditor', false);
163
+ expect(gate.verdict).toBe('failed');
164
+ gate.evaluateCriterion(1, 'auditor', true, 'ev');
165
+ gate.evaluateCriterion(2, 'auditor', true, 'ev');
166
+ expect(gate.verdict).toBe('failed');
167
+ });
168
+ it('recovers to passed when a previously-failed criterion is re-evaluated as passed', () => {
169
+ const gate = makeGate({ evidenceMode: 'optional' });
170
+ gate.evaluateCriterion(0, 'auditor', false);
171
+ expect(gate.verdict).toBe('failed');
172
+ gate.evaluateCriterion(0, 'auditor', true);
173
+ gate.evaluateCriterion(1, 'auditor', true);
174
+ gate.evaluateCriterion(2, 'auditor', true);
175
+ expect(gate.verdict).toBe('passed');
176
+ });
177
+ });
178
+ // ── reject ────────────────────────────────────────────────────────────────────
179
+ describe('ComplianceGate — reject', () => {
180
+ it('immediately sets verdict to failed', () => {
181
+ const gate = makeGate();
182
+ gate.reject('auditor', 'datos inconsistentes');
183
+ expect(gate.verdict).toBe('failed');
184
+ const record = gate.getRecord();
185
+ expect(record.log[0].event).toBe('gate_rejected');
186
+ expect(record.log[0].detail).toBe('datos inconsistentes');
187
+ });
188
+ it('throws ComplianceGateError when the executor tries to self-reject', () => {
189
+ const gate = makeGate();
190
+ expect(() => gate.reject('rrhh')).toThrow(ComplianceGate_1.ComplianceGateError);
191
+ const record = gate.getRecord();
192
+ expect(record.log[0].event).toBe('self_evaluation_attempt');
193
+ expect(gate.verdict).toBe('pending');
194
+ });
195
+ });
196
+ // ── getRecord (immutability) ──────────────────────────────────────────────────
197
+ describe('ComplianceGate — getRecord', () => {
198
+ it('returns a snapshot — mutating the returned object does not affect internal state', () => {
199
+ const gate = makeGate();
200
+ const snap1 = gate.getRecord();
201
+ snap1.verdict = 'passed';
202
+ snap1.criteria[0].passed = true;
203
+ snap1.log.push({ at: 'x', event: 'gate_rejected' });
204
+ expect(gate.verdict).toBe('pending');
205
+ const snap2 = gate.getRecord();
206
+ expect(snap2.criteria[0].passed).toBeUndefined();
207
+ expect(snap2.log).toHaveLength(0);
208
+ });
209
+ });
210
+ // ── persist ───────────────────────────────────────────────────────────────────
211
+ describe('ComplianceGate — persist', () => {
212
+ let tmpDir;
213
+ beforeEach(async () => {
214
+ tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gate-persist-'));
215
+ });
216
+ afterEach(async () => {
217
+ await fs.rm(tmpDir, { recursive: true, force: true });
218
+ });
219
+ it('writes a Markdown file to the audit folder', async () => {
220
+ const gate = makeGate();
221
+ gate.evaluateCriterion(0, 'auditor', true, 'odoo://42');
222
+ gate.evaluateCriterion(1, 'auditor', true, 'vault://ev');
223
+ gate.evaluateCriterion(2, 'auditor', true, 'odoo://42#leg');
224
+ const filePath = await gate.persist(tmpDir);
225
+ const content = await fs.readFile(filePath, 'utf-8');
226
+ expect(content).toContain('## Gate — preparar-ficha');
227
+ expect(content).toContain('**passed**');
228
+ expect(content).toContain('Ficha creada en Odoo');
229
+ expect(content).toContain('auditor');
230
+ expect(content).toContain('criterion_evaluated');
231
+ });
232
+ it('file is created under auditoria/{flowId}/{runId}/', async () => {
233
+ const gate = makeGate();
234
+ gate.reject('auditor', 'incomplete');
235
+ const filePath = await gate.persist(tmpDir);
236
+ expect(filePath).toContain(path.join('auditoria', 'onboarding-empleado', 'run-test'));
237
+ });
238
+ });
239
+ // ── Criterio de salida fase 2 ─────────────────────────────────────────────────
240
+ describe('Fase 2 — criterio de salida', () => {
241
+ it('gate with 3 criteria passes only when a different agent marks each one with evidence; self-eval attempt is logged; full record persisted', async () => {
242
+ const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'fase2-'));
243
+ try {
244
+ const gate = makeGate({ evidenceMode: 'required' });
245
+ // Attempt self-evaluation — must fail and be logged
246
+ expect(() => gate.evaluateCriterion(0, 'rrhh', true, 'ev'))
247
+ .toThrow(ComplianceGate_1.ComplianceGateError);
248
+ expect(gate.verdict).toBe('pending');
249
+ // Legitimate evaluator marks all 3 criteria with evidence
250
+ gate.evaluateCriterion(0, 'auditor', true, 'odoo://employees/42');
251
+ gate.evaluateCriterion(1, 'auditor', true, 'vault://eventos/nota.md');
252
+ gate.evaluateCriterion(2, 'auditor', true, 'odoo://employees/42#legajo');
253
+ expect(gate.verdict).toBe('passed');
254
+ // Persist — full record must be in the vault
255
+ const filePath = await gate.persist(tmpDir);
256
+ const content = await fs.readFile(filePath, 'utf-8');
257
+ // All 3 criteria present
258
+ expect(content).toContain('Ficha creada en Odoo');
259
+ expect(content).toContain('Nota canónica escrita en /eventos');
260
+ expect(content).toContain('Legajo asignado');
261
+ // Self-eval attempt is in the audit log
262
+ expect(content).toContain('self_evaluation_attempt');
263
+ // Verdict is passed
264
+ expect(content).toContain('**passed**');
265
+ }
266
+ finally {
267
+ await fs.rm(tmpDir, { recursive: true, force: true });
268
+ }
269
+ });
270
+ });
271
+ //# sourceMappingURL=ComplianceGate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplianceGate.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/ComplianceGate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=EventPublisher.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventPublisher.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/EventPublisher.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs/promises"));
37
+ const path = __importStar(require("path"));
38
+ const os = __importStar(require("os"));
39
+ const agent_core_1 = require("@backendkit-labs/agent-core");
40
+ const EventPublisher_1 = require("../../events/EventPublisher");
41
+ // ── Helpers ───────────────────────────────────────────────────────────────────
42
+ const ContratacionSchema = {
43
+ type: 'contratacion',
44
+ version: 1,
45
+ schema: agent_core_1.z.object({ nombre: agent_core_1.z.string(), legajo: agent_core_1.z.string() }),
46
+ };
47
+ function makeQueue() {
48
+ const mock = jest.fn().mockResolvedValue({ id: 'job-test-123' });
49
+ return {
50
+ mock,
51
+ queue: { name: 'eventos.contratacion', add: mock },
52
+ };
53
+ }
54
+ async function makePublisher(tmpDir, source = 'hr-system') {
55
+ const { mock, queue } = makeQueue();
56
+ const publisher = new EventPublisher_1.EventPublisher({ queue, vaultPath: tmpDir, source });
57
+ return { publisher, queueAdd: mock };
58
+ }
59
+ // ── Validation ────────────────────────────────────────────────────────────────
60
+ describe('EventPublisher — validation', () => {
61
+ let tmpDir;
62
+ beforeEach(async () => { tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ep-')); });
63
+ afterEach(async () => { await fs.rm(tmpDir, { recursive: true, force: true }); });
64
+ it('publishes successfully when payload matches the schema', async () => {
65
+ const { publisher } = await makePublisher(tmpDir);
66
+ const envelope = await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
67
+ expect(envelope.type).toBe('contratacion');
68
+ expect(envelope.payload).toEqual({ nombre: 'Juan', legajo: 'L-001' });
69
+ });
70
+ it('throws ZodError when payload does not match the schema', async () => {
71
+ const { publisher } = await makePublisher(tmpDir);
72
+ await expect(publisher.publish(ContratacionSchema, { nombre: 'Juan' })).rejects.toThrow();
73
+ });
74
+ it('does NOT call queue.add when payload is invalid', async () => {
75
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
76
+ try {
77
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan' });
78
+ }
79
+ catch { /* expected */ }
80
+ expect(queueAdd).not.toHaveBeenCalled();
81
+ });
82
+ });
83
+ // ── Envelope ──────────────────────────────────────────────────────────────────
84
+ describe('EventPublisher — envelope', () => {
85
+ let tmpDir;
86
+ beforeEach(async () => { tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ep-')); });
87
+ afterEach(async () => { await fs.rm(tmpDir, { recursive: true, force: true }); });
88
+ it('returns an envelope with correct type, source, version, and ISO timestamp', async () => {
89
+ const { publisher } = await makePublisher(tmpDir, 'hr-system');
90
+ const envelope = await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
91
+ expect(envelope.type).toBe('contratacion');
92
+ expect(envelope.source).toBe('hr-system');
93
+ expect(envelope.version).toBe(1);
94
+ expect(envelope.occurredAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
95
+ expect(typeof envelope.id).toBe('string');
96
+ expect(envelope.id.length).toBeGreaterThan(10);
97
+ });
98
+ it('uses envelope.id as the BullMQ jobId by default', async () => {
99
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
100
+ const envelope = await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
101
+ expect(queueAdd).toHaveBeenCalledWith('contratacion', expect.objectContaining({ id: envelope.id }), expect.objectContaining({ jobId: envelope.id }));
102
+ });
103
+ it('uses the provided custom jobId', async () => {
104
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
105
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' }, { jobId: 'custom-123' });
106
+ expect(queueAdd).toHaveBeenCalledWith(expect.any(String), expect.any(Object), expect.objectContaining({ jobId: 'custom-123' }));
107
+ });
108
+ });
109
+ // ── BullMQ queue call ─────────────────────────────────────────────────────────
110
+ describe('EventPublisher — queue.add call', () => {
111
+ let tmpDir;
112
+ beforeEach(async () => { tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ep-')); });
113
+ afterEach(async () => { await fs.rm(tmpDir, { recursive: true, force: true }); });
114
+ it('calls queue.add with the event type as the job name', async () => {
115
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
116
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
117
+ expect(queueAdd).toHaveBeenCalledWith('contratacion', expect.any(Object), expect.any(Object));
118
+ });
119
+ it('sets removeOnComplete and removeOnFail to false for reconciliation', async () => {
120
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
121
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
122
+ const opts = queueAdd.mock.calls[0][2];
123
+ expect(opts.removeOnComplete).toBe(false);
124
+ expect(opts.removeOnFail).toBe(false);
125
+ });
126
+ it('uses custom attempts when provided', async () => {
127
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
128
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' }, { attempts: 5 });
129
+ expect(queueAdd.mock.calls[0][2].attempts).toBe(5);
130
+ });
131
+ it('defaults to 3 attempts', async () => {
132
+ const { publisher, queueAdd } = await makePublisher(tmpDir);
133
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
134
+ expect(queueAdd.mock.calls[0][2].attempts).toBe(3);
135
+ });
136
+ });
137
+ // ── Vault note ────────────────────────────────────────────────────────────────
138
+ describe('EventPublisher — vault note', () => {
139
+ let tmpDir;
140
+ beforeEach(async () => { tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ep-')); });
141
+ afterEach(async () => { await fs.rm(tmpDir, { recursive: true, force: true }); });
142
+ it('writes a Markdown file under {vaultPath}/eventos/', async () => {
143
+ const { publisher } = await makePublisher(tmpDir);
144
+ await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
145
+ const eventsDir = path.join(tmpDir, 'eventos');
146
+ const files = await fs.readdir(eventsDir);
147
+ expect(files.filter(f => f.endsWith('.md'))).toHaveLength(1);
148
+ });
149
+ it('vault note contains the event ID in a table row', async () => {
150
+ const { publisher } = await makePublisher(tmpDir);
151
+ const envelope = await publisher.publish(ContratacionSchema, { nombre: 'Juan', legajo: 'L-001' });
152
+ const eventsDir = path.join(tmpDir, 'eventos');
153
+ const [file] = await fs.readdir(eventsDir);
154
+ const content = await fs.readFile(path.join(eventsDir, file), 'utf-8');
155
+ expect(content).toContain(envelope.id);
156
+ expect(content).toContain('contratacion');
157
+ expect(content).toContain('Juan');
158
+ });
159
+ });
160
+ //# sourceMappingURL=EventPublisher.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EventPublisher.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/EventPublisher.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=FlowLoader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlowLoader.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/FlowLoader.test.ts"],"names":[],"mappings":""}