@ai-pip/csl 0.1.0 → 0.1.3

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 (59) hide show
  1. package/README.md +607 -56
  2. package/package.json +10 -28
  3. package/src/index.test.ts +429 -0
  4. package/{index.ts → src/index.ts} +100 -65
  5. package/src/test-external.js +547 -0
  6. package/layers/csl/adapters/index.ts +0 -9
  7. package/layers/csl/adapters/input/DOMAdapter.ts +0 -236
  8. package/layers/csl/adapters/input/UIAdapter.ts +0 -0
  9. package/layers/csl/adapters/output/ConsoleLogger.ts +0 -34
  10. package/layers/csl/adapters/output/CryptoHashGenerator.ts +0 -29
  11. package/layers/csl/adapters/output/FilePolicyRepository.ts +0 -0
  12. package/layers/csl/adapters/output/InMemoryPolicyRepository.ts +0 -135
  13. package/layers/csl/adapters/output/SystemTimestampProvider.ts +0 -9
  14. package/layers/csl/domain/entities/CSLResult.ts +0 -309
  15. package/layers/csl/domain/entities/Segment.ts +0 -338
  16. package/layers/csl/domain/entities/index.ts +0 -2
  17. package/layers/csl/domain/exceptions/ClassificationError.ts +0 -26
  18. package/layers/csl/domain/exceptions/SegmentationError.ts +0 -30
  19. package/layers/csl/domain/exceptions/index.ts +0 -2
  20. package/layers/csl/domain/index.ts +0 -4
  21. package/layers/csl/domain/services/AnomalyService.ts +0 -255
  22. package/layers/csl/domain/services/LineageService.ts +0 -224
  23. package/layers/csl/domain/services/NormalizationService.ts +0 -392
  24. package/layers/csl/domain/services/OriginClassificationService.ts +0 -69
  25. package/layers/csl/domain/services/PiDetectionService.ts +0 -475
  26. package/layers/csl/domain/services/PolicyService.ts +0 -296
  27. package/layers/csl/domain/services/SegmentClassificationService.ts +0 -105
  28. package/layers/csl/domain/services/SerializationService.ts +0 -229
  29. package/layers/csl/domain/services/index.ts +0 -7
  30. package/layers/csl/domain/value-objects/AnomalyScore.ts +0 -23
  31. package/layers/csl/domain/value-objects/ContentHash.ts +0 -54
  32. package/layers/csl/domain/value-objects/LineageEntry.ts +0 -42
  33. package/layers/csl/domain/value-objects/Origin-map.ts +0 -67
  34. package/layers/csl/domain/value-objects/Origin.ts +0 -99
  35. package/layers/csl/domain/value-objects/Pattern.ts +0 -221
  36. package/layers/csl/domain/value-objects/PiDetection.ts +0 -140
  37. package/layers/csl/domain/value-objects/PiDetectionResult.ts +0 -275
  38. package/layers/csl/domain/value-objects/PolicyRule.ts +0 -151
  39. package/layers/csl/domain/value-objects/TrustLevel.ts +0 -34
  40. package/layers/csl/domain/value-objects/index.ts +0 -10
  41. package/layers/csl/index.ts +0 -3
  42. package/layers/csl/ports/index.ts +0 -10
  43. package/layers/csl/ports/input/ClassificationPort.ts +0 -76
  44. package/layers/csl/ports/input/SegmentationPort.ts +0 -81
  45. package/layers/csl/ports/output/DOMAdapter.ts +0 -14
  46. package/layers/csl/ports/output/HashGenerator.ts +0 -18
  47. package/layers/csl/ports/output/Logger.ts +0 -17
  48. package/layers/csl/ports/output/PolicyRepository.ts +0 -29
  49. package/layers/csl/ports/output/SegmentClassified.ts +0 -8
  50. package/layers/csl/ports/output/TimeStampProvider.ts +0 -5
  51. package/layers/csl/services/CSLService.ts +0 -393
  52. package/layers/csl/services/index.ts +0 -1
  53. package/layers/csl/types/entities-types.ts +0 -37
  54. package/layers/csl/types/index.ts +0 -4
  55. package/layers/csl/types/pi-types.ts +0 -111
  56. package/layers/csl/types/port-output-types.ts +0 -17
  57. package/layers/csl/types/value-objects-types.ts +0 -213
  58. package/layers/csl/utils/colors.ts +0 -25
  59. package/layers/csl/utils/pattern-helpers.ts +0 -174
package/package.json CHANGED
@@ -1,38 +1,25 @@
1
1
  {
2
2
  "name": "@ai-pip/csl",
3
- "version": "0.1.0",
4
- "description": "SDK oficial para la capa de segmentación de contexto (CSL) del protocolo AI-PIP. Proporciona herramientas para clasificar, etiquetar y aislar contenido según origen, confiabilidad y riesgo operacional, protegiendo aplicaciones contra prompt injection y otros ataques de seguridad en LLM.",
3
+ "version": "0.1.3",
4
+ "description": "SDK oficial de la capa Context Segmentation Layer (CSL) del protocolo AI-PIP.",
5
5
  "type": "module",
6
- "types": "./index.ts",
7
6
  "exports": {
8
7
  ".": {
9
- "types": "./index.ts",
10
- "import": "./index.ts"
8
+ "types": "./src/index.ts",
9
+ "import": "./src/index.ts"
11
10
  }
12
11
  },
13
12
  "files": [
14
- "index.ts",
13
+ "src",
15
14
  "README.md",
16
- "layers"
15
+ "package.json"
17
16
  ],
17
+ "dependencies": {
18
+ "@ai-pip/csl-layer": "0.0.0"
19
+ },
18
20
  "engines": {
19
21
  "node": ">=22.6.0"
20
22
  },
21
- "keywords": [
22
- "ai-pip",
23
- "csl",
24
- "context-segmentation",
25
- "prompt-security",
26
- "llm-security",
27
- "prompt-injection",
28
- "ai-safety",
29
- "content-classification",
30
- "trust-levels",
31
- "anomaly-detection",
32
- "typescript",
33
- "browser-extension",
34
- "ai-protocol"
35
- ],
36
23
  "license": "MIT",
37
24
  "publishConfig": {
38
25
  "access": "public"
@@ -41,10 +28,5 @@
41
28
  "type": "git",
42
29
  "url": "https://github.com/MasliahDev99/AI-PIP.git",
43
30
  "directory": "src/sdk/csl"
44
- },
45
- "homepage": "https://github.com/MasliahDev99/AI-PIP",
46
- "bugs": {
47
- "url": "https://github.com/MasliahDev99/AI-PIP/issues"
48
- },
49
- "scripts": {}
31
+ }
50
32
  }
@@ -0,0 +1,429 @@
1
+ import { describe, it, expect, beforeEach, vi } from 'vitest'
2
+ import {
3
+ createCSLService,
4
+ CSLService,
5
+ type CreateCSLServiceOptions,
6
+ type LoggerPort,
7
+ type HashGeneratorPort,
8
+ type TimeStampProviderPort,
9
+ InMemoryPolicyRepository,
10
+ PolicyRule,
11
+ SegmentationError,
12
+ } from './index'
13
+
14
+ describe('@ai-pip/csl SDK', () => {
15
+ beforeEach(() => {
16
+ // Limpiar el body antes de cada test
17
+ document.body.innerHTML = ''
18
+ })
19
+
20
+ describe('createCSLService', () => {
21
+ it('debe crear un servicio con configuración por defecto', () => {
22
+ const service = createCSLService()
23
+
24
+ expect(service).toBeInstanceOf(CSLService)
25
+ })
26
+
27
+ it('debe crear un servicio con configuración personalizada', () => {
28
+ const options: CreateCSLServiceOptions = {
29
+ enablePolicyValidation: false,
30
+ enableLineageTracking: false,
31
+ hashAlgorithm: 'sha512',
32
+ }
33
+
34
+ const service = createCSLService(options)
35
+
36
+ expect(service).toBeInstanceOf(CSLService)
37
+ })
38
+
39
+ it('debe aceptar dependencias personalizadas', () => {
40
+ const customLogger: LoggerPort = {
41
+ debug: vi.fn(),
42
+ info: vi.fn(),
43
+ warn: vi.fn(),
44
+ error: vi.fn(),
45
+ }
46
+
47
+ const customHashGenerator: HashGeneratorPort = {
48
+ generate: vi.fn().mockResolvedValue('mock-hash'),
49
+ compare: vi.fn().mockResolvedValue(true),
50
+ generateHMAC: vi.fn().mockResolvedValue('mock-hmac'),
51
+ compareHMAC: vi.fn().mockResolvedValue(true),
52
+ }
53
+
54
+ const customTimestampProvider: TimeStampProviderPort = {
55
+ now: vi.fn().mockReturnValue(1234567890),
56
+ }
57
+
58
+ const customPolicyRepository = new InMemoryPolicyRepository()
59
+
60
+ const service = createCSLService({
61
+ logger: customLogger,
62
+ hashGenerator: customHashGenerator,
63
+ timestampProvider: customTimestampProvider,
64
+ policyRepository: customPolicyRepository,
65
+ })
66
+
67
+ expect(service).toBeInstanceOf(CSLService)
68
+ })
69
+
70
+ it('debe usar implementaciones por defecto cuando no se proporcionan', () => {
71
+ const service = createCSLService()
72
+
73
+ expect(service).toBeInstanceOf(CSLService)
74
+ // El servicio debe estar creado correctamente con todas las dependencias
75
+ })
76
+ })
77
+
78
+ describe('CSLService.segment', () => {
79
+ it('debe procesar un elemento DOM simple', async () => {
80
+ const body = document.body
81
+
82
+ // Crear contenido simple
83
+ const div = document.createElement('div')
84
+ div.textContent = 'Hello, world!'
85
+ body.appendChild(div)
86
+
87
+ const service = createCSLService({
88
+ enablePolicyValidation: false,
89
+ enableLineageTracking: false,
90
+ })
91
+
92
+ const result = await service.segment(body)
93
+
94
+ expect(result).toBeDefined()
95
+ expect(result.segments).toBeDefined()
96
+ expect(Array.isArray(result.segments)).toBe(true)
97
+ expect(result.metadata).toBeDefined()
98
+ expect(result.metadata.total_segments).toBeGreaterThanOrEqual(0)
99
+ })
100
+
101
+ it('debe procesar múltiples segmentos', async () => {
102
+ const body = document.body
103
+
104
+ // Crear múltiples elementos
105
+ const div1 = document.createElement('div')
106
+ div1.textContent = 'Primer segmento'
107
+ body.appendChild(div1)
108
+
109
+ const div2 = document.createElement('div')
110
+ div2.textContent = 'Segundo segmento'
111
+ body.appendChild(div2)
112
+
113
+ const service = createCSLService({
114
+ enablePolicyValidation: false,
115
+ enableLineageTracking: false,
116
+ })
117
+
118
+ const result = await service.segment(body)
119
+
120
+ expect(result.segments.length).toBeGreaterThanOrEqual(2)
121
+ })
122
+
123
+ it('debe retornar metadatos correctos', async () => {
124
+ const body = document.body
125
+
126
+ const div = document.createElement('div')
127
+ div.textContent = 'Test content'
128
+ body.appendChild(div)
129
+
130
+ const service = createCSLService({
131
+ enablePolicyValidation: false,
132
+ enableLineageTracking: false,
133
+ })
134
+
135
+ const result = await service.segment(body)
136
+
137
+ expect(result.metadata).toHaveProperty('total_segments')
138
+ expect(result.metadata).toHaveProperty('trust_distribution')
139
+ expect(result.metadata).toHaveProperty('anomaly_score')
140
+ expect(result.metadata).toHaveProperty('blocked_segments')
141
+ expect(result.metadata).toHaveProperty('processing_time_ms')
142
+ expect(typeof result.metadata.processing_time_ms).toBe('number')
143
+ })
144
+
145
+ it('debe calcular la distribución de confianza correctamente', async () => {
146
+ const body = document.body
147
+
148
+ const div = document.createElement('div')
149
+ div.textContent = 'Content for testing'
150
+ body.appendChild(div)
151
+
152
+ const service = createCSLService({
153
+ enablePolicyValidation: false,
154
+ enableLineageTracking: false,
155
+ })
156
+
157
+ const result = await service.segment(body)
158
+
159
+ expect(result.metadata.trust_distribution).toHaveProperty('TC')
160
+ expect(result.metadata.trust_distribution).toHaveProperty('STC')
161
+ expect(result.metadata.trust_distribution).toHaveProperty('UC')
162
+ expect(
163
+ result.metadata.trust_distribution.TC +
164
+ result.metadata.trust_distribution.STC +
165
+ result.metadata.trust_distribution.UC
166
+ ).toBe(result.metadata.total_segments)
167
+ })
168
+
169
+ it('debe manejar elementos vacíos', async () => {
170
+ const body = document.body
171
+
172
+ // Body vacío
173
+
174
+ const service = createCSLService({
175
+ enablePolicyValidation: false,
176
+ enableLineageTracking: false,
177
+ })
178
+
179
+ const result = await service.segment(body)
180
+
181
+ expect(result.segments).toEqual([])
182
+ expect(result.metadata.total_segments).toBe(0)
183
+ })
184
+
185
+ it('debe procesar el documento completo', async () => {
186
+ const div = document.createElement('div')
187
+ div.textContent = 'Document content'
188
+ document.body.appendChild(div)
189
+
190
+ const service = createCSLService({
191
+ enablePolicyValidation: false,
192
+ enableLineageTracking: false,
193
+ })
194
+
195
+ const result = await service.segment(document)
196
+
197
+ expect(result).toBeDefined()
198
+ expect(result.segments.length).toBeGreaterThanOrEqual(0)
199
+ })
200
+ })
201
+
202
+ describe('CSLService con políticas', () => {
203
+ it('debe validar políticas cuando está habilitado', async () => {
204
+ const body = document.body
205
+
206
+ const div = document.createElement('div')
207
+ div.textContent = 'Test content'
208
+ body.appendChild(div)
209
+
210
+ const policyRepository = new InMemoryPolicyRepository()
211
+ const policy = new PolicyRule(
212
+ '1.0',
213
+ [],
214
+ [],
215
+ { protectedRoles: [], immutableInstructions: [] },
216
+ { enabled: false, blockMetadataExposure: false, sanitizeInternalReferences: false }
217
+ )
218
+ await policyRepository.savePolicy(policy)
219
+
220
+ const service = createCSLService({
221
+ policyRepository,
222
+ enablePolicyValidation: true,
223
+ enableLineageTracking: false,
224
+ })
225
+
226
+ const result = await service.segment(body)
227
+
228
+ expect(result).toBeDefined()
229
+ expect(result.segments).toBeDefined()
230
+ })
231
+ })
232
+
233
+ describe('CSLService con linaje', () => {
234
+ it('debe trackear linaje cuando está habilitado', async () => {
235
+ const body = document.body
236
+
237
+ const div = document.createElement('div')
238
+ div.textContent = 'Test content for lineage'
239
+ body.appendChild(div)
240
+
241
+ const service = createCSLService({
242
+ enablePolicyValidation: false,
243
+ enableLineageTracking: true,
244
+ })
245
+
246
+ const result = await service.segment(body)
247
+
248
+ expect(result.lineage).toBeDefined()
249
+ expect(Array.isArray(result.lineage)).toBe(true)
250
+ })
251
+
252
+ it('no debe trackear linaje cuando está deshabilitado', async () => {
253
+ const body = document.body
254
+
255
+ const div = document.createElement('div')
256
+ div.textContent = 'Test content'
257
+ body.appendChild(div)
258
+
259
+ const service = createCSLService({
260
+ enablePolicyValidation: false,
261
+ enableLineageTracking: false,
262
+ })
263
+
264
+ const result = await service.segment(body)
265
+
266
+ // El linaje puede estar vacío pero debe existir
267
+ expect(result.lineage).toBeDefined()
268
+ })
269
+ })
270
+
271
+ describe('Manejo de errores', () => {
272
+ it('debe lanzar SegmentationError en caso de error', async () => {
273
+ const service = createCSLService({
274
+ enablePolicyValidation: false,
275
+ enableLineageTracking: false,
276
+ })
277
+
278
+ // Intentar procesar un elemento inválido debería causar error
279
+ await expect(async () => {
280
+ await service.segment(null as any)
281
+ }).rejects.toThrow(SegmentationError)
282
+ })
283
+ })
284
+
285
+ describe('CSLResult', () => {
286
+ it('debe tener método getBlockedCount', async () => {
287
+ const body = document.body
288
+
289
+ const div = document.createElement('div')
290
+ div.textContent = 'Test content'
291
+ body.appendChild(div)
292
+
293
+ const service = createCSLService({
294
+ enablePolicyValidation: false,
295
+ enableLineageTracking: false,
296
+ })
297
+
298
+ const result = await service.segment(body)
299
+
300
+ expect(typeof result.getBlockedCount).toBe('function')
301
+ const blockedCount = result.getBlockedCount()
302
+ expect(typeof blockedCount).toBe('number')
303
+ expect(blockedCount).toBeGreaterThanOrEqual(0)
304
+ })
305
+
306
+ it('debe tener método getTrustDistribution', async () => {
307
+ const body = document.body
308
+
309
+ const div = document.createElement('div')
310
+ div.textContent = 'Test content'
311
+ body.appendChild(div)
312
+
313
+ const service = createCSLService({
314
+ enablePolicyValidation: false,
315
+ enableLineageTracking: false,
316
+ })
317
+
318
+ const result = await service.segment(body)
319
+
320
+ expect(result.metadata.trust_distribution).toHaveProperty('TC')
321
+ expect(result.metadata.trust_distribution).toHaveProperty('STC')
322
+ expect(result.metadata.trust_distribution).toHaveProperty('UC')
323
+ })
324
+ })
325
+
326
+ describe('Segmentos', () => {
327
+ it('debe crear segmentos con propiedades correctas', async () => {
328
+ const body = document.body
329
+
330
+ const div = document.createElement('div')
331
+ div.textContent = 'Test segment content'
332
+ body.appendChild(div)
333
+
334
+ const service = createCSLService({
335
+ enablePolicyValidation: false,
336
+ enableLineageTracking: false,
337
+ })
338
+
339
+ const result = await service.segment(body)
340
+
341
+ if (result.segments.length > 0) {
342
+ const segment = result.segments[0]
343
+
344
+ expect(segment).toHaveProperty('id')
345
+ expect(segment).toHaveProperty('content')
346
+ expect(segment).toHaveProperty('origin')
347
+ expect(segment).toHaveProperty('mime')
348
+ expect(segment).toHaveProperty('timestamp')
349
+ expect(segment).toHaveProperty('source')
350
+ expect(typeof segment?.id).toBe('string')
351
+ expect(typeof segment?.content).toBe('string')
352
+ expect(typeof segment?.shouldBlock).toBe('function')
353
+ }
354
+ })
355
+
356
+ it('debe detectar si un segmento debe ser bloqueado', async () => {
357
+ const body = document.body
358
+
359
+ const div = document.createElement('div')
360
+ div.textContent = 'Normal content'
361
+ body.appendChild(div)
362
+
363
+ const service = createCSLService({
364
+ enablePolicyValidation: false,
365
+ enableLineageTracking: false,
366
+ })
367
+
368
+ const result = await service.segment(body)
369
+
370
+ expect(result.segments.length).toBeGreaterThan(0)
371
+ const segment = result.segments[0]
372
+ expect(segment).toBeDefined()
373
+ if (!segment) return // Type guard
374
+ const shouldBlock = segment.shouldBlock()
375
+ expect(typeof shouldBlock).toBe('boolean')
376
+ })
377
+ })
378
+
379
+ describe('Configuración de hash algorithm', () => {
380
+ it('debe usar sha256 por defecto', async () => {
381
+ const body = document.body
382
+
383
+ const div = document.createElement('div')
384
+ div.textContent = 'Test content'
385
+ body.appendChild(div)
386
+
387
+ const service = createCSLService({
388
+ enablePolicyValidation: false,
389
+ enableLineageTracking: false,
390
+ })
391
+
392
+ const result = await service.segment(body)
393
+
394
+ // Verificar que los segmentos tienen hash
395
+ expect(result.segments.length).toBeGreaterThan(0)
396
+ const segment = result.segments[0]
397
+ expect(segment).toBeDefined()
398
+ if (!segment) return // Type guard
399
+ if (segment.hash) {
400
+ expect(segment.hash.algorithm).toBe('sha256')
401
+ }
402
+ })
403
+
404
+ it('debe usar sha512 cuando se configura', async () => {
405
+ const body = document.body
406
+
407
+ const div = document.createElement('div')
408
+ div.textContent = 'Test content'
409
+ body.appendChild(div)
410
+
411
+ const service = createCSLService({
412
+ hashAlgorithm: 'sha512',
413
+ enablePolicyValidation: false,
414
+ enableLineageTracking: false,
415
+ })
416
+
417
+ const result = await service.segment(body)
418
+
419
+ // Verificar que los segmentos tienen hash con sha512
420
+ expect(result.segments.length).toBeGreaterThan(0)
421
+ const segment = result.segments[0]
422
+ expect(segment).toBeDefined()
423
+ if (!segment) return // Type guard
424
+ if (segment.hash) {
425
+ expect(segment.hash.algorithm).toBe('sha512')
426
+ }
427
+ })
428
+ })
429
+ })