@ai-pip/core 0.2.0 → 0.3.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 (89) hide show
  1. package/CHANGELOG.md +66 -2
  2. package/README.md +107 -18
  3. package/dist/AAL/constants.d.ts +15 -0
  4. package/dist/AAL/constants.d.ts.map +1 -0
  5. package/dist/AAL/constants.js +20 -0
  6. package/dist/AAL/constants.js.map +1 -0
  7. package/dist/AAL/index.d.ts +2 -1
  8. package/dist/AAL/index.d.ts.map +1 -1
  9. package/dist/AAL/index.js +3 -1
  10. package/dist/AAL/index.js.map +1 -1
  11. package/dist/AAL/process/applyRemovalPlan.d.ts +21 -0
  12. package/dist/AAL/process/applyRemovalPlan.d.ts.map +1 -0
  13. package/dist/AAL/process/applyRemovalPlan.js +150 -0
  14. package/dist/AAL/process/applyRemovalPlan.js.map +1 -0
  15. package/dist/AAL/process/buildDecisionReason.d.ts.map +1 -1
  16. package/dist/AAL/process/buildDecisionReason.js +26 -4
  17. package/dist/AAL/process/buildDecisionReason.js.map +1 -1
  18. package/dist/AAL/process/buildRemovalPlan.d.ts +17 -10
  19. package/dist/AAL/process/buildRemovalPlan.d.ts.map +1 -1
  20. package/dist/AAL/process/buildRemovalPlan.js +84 -30
  21. package/dist/AAL/process/buildRemovalPlan.js.map +1 -1
  22. package/dist/AAL/process/index.d.ts +2 -1
  23. package/dist/AAL/process/index.d.ts.map +1 -1
  24. package/dist/AAL/process/index.js +2 -1
  25. package/dist/AAL/process/index.js.map +1 -1
  26. package/dist/AAL/process/resolveAgentAction.d.ts.map +1 -1
  27. package/dist/AAL/process/resolveAgentAction.js +24 -0
  28. package/dist/AAL/process/resolveAgentAction.js.map +1 -1
  29. package/dist/AAL/types.d.ts +11 -7
  30. package/dist/AAL/types.d.ts.map +1 -1
  31. package/dist/index.d.ts +5 -5
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/isl/detect/detect.d.ts +39 -0
  36. package/dist/isl/detect/detect.d.ts.map +1 -0
  37. package/dist/isl/detect/detect.js +369 -0
  38. package/dist/isl/detect/detect.js.map +1 -0
  39. package/dist/isl/detect/index.d.ts +6 -0
  40. package/dist/isl/detect/index.d.ts.map +1 -0
  41. package/dist/isl/detect/index.js +5 -0
  42. package/dist/isl/detect/index.js.map +1 -0
  43. package/dist/isl/index.d.ts +8 -1
  44. package/dist/isl/index.d.ts.map +1 -1
  45. package/dist/isl/index.js +5 -0
  46. package/dist/isl/index.js.map +1 -1
  47. package/dist/isl/process/emitSignal.d.ts +19 -10
  48. package/dist/isl/process/emitSignal.d.ts.map +1 -1
  49. package/dist/isl/process/emitSignal.js +25 -23
  50. package/dist/isl/process/emitSignal.js.map +1 -1
  51. package/dist/isl/process/index.d.ts +1 -0
  52. package/dist/isl/process/index.d.ts.map +1 -1
  53. package/dist/isl/riskScore/calculators.d.ts +19 -0
  54. package/dist/isl/riskScore/calculators.d.ts.map +1 -0
  55. package/dist/isl/riskScore/calculators.js +50 -0
  56. package/dist/isl/riskScore/calculators.js.map +1 -0
  57. package/dist/isl/riskScore/index.d.ts +14 -0
  58. package/dist/isl/riskScore/index.d.ts.map +1 -0
  59. package/dist/isl/riskScore/index.js +26 -0
  60. package/dist/isl/riskScore/index.js.map +1 -0
  61. package/dist/isl/riskScore/types.d.ts +20 -0
  62. package/dist/isl/riskScore/types.d.ts.map +1 -0
  63. package/dist/isl/riskScore/types.js +12 -0
  64. package/dist/isl/riskScore/types.js.map +1 -0
  65. package/dist/isl/sanitize.d.ts +8 -1
  66. package/dist/isl/sanitize.d.ts.map +1 -1
  67. package/dist/isl/sanitize.js +13 -5
  68. package/dist/isl/sanitize.js.map +1 -1
  69. package/dist/isl/signals.d.ts +16 -1
  70. package/dist/isl/signals.d.ts.map +1 -1
  71. package/dist/isl/signals.js +4 -2
  72. package/dist/isl/signals.js.map +1 -1
  73. package/dist/isl/value-objects/Pattern.d.ts +21 -0
  74. package/dist/isl/value-objects/Pattern.d.ts.map +1 -1
  75. package/dist/isl/value-objects/Pattern.js +36 -0
  76. package/dist/isl/value-objects/Pattern.js.map +1 -1
  77. package/dist/isl/value-objects/index.d.ts +2 -2
  78. package/dist/isl/value-objects/index.d.ts.map +1 -1
  79. package/dist/isl/value-objects/index.js +1 -1
  80. package/dist/isl/value-objects/index.js.map +1 -1
  81. package/dist/shared/audit.d.ts +116 -16
  82. package/dist/shared/audit.d.ts.map +1 -1
  83. package/dist/shared/audit.js +314 -32
  84. package/dist/shared/audit.js.map +1 -1
  85. package/dist/shared/index.d.ts +2 -2
  86. package/dist/shared/index.d.ts.map +1 -1
  87. package/dist/shared/index.js +1 -1
  88. package/dist/shared/index.js.map +1 -1
  89. package/package.json +6 -2
package/CHANGELOG.md CHANGED
@@ -7,6 +7,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.3.0] - (unreleased)
11
+
12
+ ### ✨ Added
13
+
14
+ - **ISL – Threat detection**
15
+ - `detectThreats(content, options?)`: pure, deterministic function returning `readonly PiDetection[]`.
16
+ - Default patterns for known attack surfaces (prompt-injection, jailbreak, role hijacking, script_like, hidden_text); expanded set (~287 patterns).
17
+ - Integration in `sanitize`: each segment may carry `piDetection` (`PiDetectionResult`).
18
+ - Option `SanitizeOptions.detectThreatsOptions` for custom patterns or limits (`patterns`, `maxTotal`, `maxPerPattern`).
19
+ - `getDefaultThreatPatterns()`: returns the default set (cached, frozen).
20
+ - `THREAT_TYPES` and type `ThreatType` for deterministic taxonomy.
21
+
22
+ - **ISL – Risk score strategies**
23
+ - Enum `RiskScoreStrategy`: `MAX_CONFIDENCE`, `SEVERITY_PLUS_VOLUME`, `WEIGHTED_BY_TYPE`.
24
+ - Pure calculators: `maxConfidenceCalculator`, `severityPlusVolumeCalculator`, `weightedByTypeCalculator`, `defaultWeightedByTypeCalculator`.
25
+ - `getCalculator(strategy, typeWeights?)`: returns the registered calculator for the strategy.
26
+ - Strategy fixed at `emitSignal`; reflected in `ISLSignal.metadata.strategy` for audit.
27
+
28
+ - **emitSignal – Risk score options**
29
+ - `EmitSignalOptions`: `timestamp?`, `riskScore?: { strategy, typeWeights? }`.
30
+ - Default: `RiskScoreStrategy.MAX_CONFIDENCE`.
31
+ - Backward compatibility: `emitSignal(islResult, timestamp)` still supported.
32
+
33
+ - **ISLSignal – Strategy metadata**
34
+ - `ISLSignal.metadata?: { strategy: RiskScoreStrategy }` for traceability.
35
+ - `createISLSignal(..., metadata?)` accepts optional fourth argument `metadata`.
36
+
37
+ - **AAL – Actionable removal plan**
38
+ - `buildRemovalPlanFromResult(islResult, policy)`: builds `RemovalPlan` from `ISLResult` with `segmentId` per instruction.
39
+ - `applyRemovalPlan(islResult, plan)`: pure function that removes malicious ranges from each segment's `sanitizedContent`; clamps ranges to content; merges overlapping and adjacent ranges (gap only punctuation/whitespace); returns new `ISLResult`.
40
+ - `RemovedInstruction.segmentId?`: optional, present when the plan is built from `ISLResult`.
41
+ - Guards in `resolveAgentAction`, `resolveAgentActionWithScore`, `buildDecisionReason`, `buildRemovalPlan`, and `buildRemovalPlanFromResult` for safe handling of detections and signals.
42
+
43
+ - **AAL – Resolve action with score**
44
+ - `resolveAgentActionWithScore(islSignal, policy)`: returns `{ action, anomalyScore }` for SDK/audit use.
45
+
46
+ - **AAL – Colors for UI/audit**
47
+ - `ACTION_DISPLAY_COLORS` and `getActionDisplayColor(action)` for ALLOW/WARN/BLOCK.
48
+
49
+ - **Shared – Audit improvements (run id, JSON, logs, full pipeline)**
50
+ - **Run identifier**: `createAuditRunId()` generates a unique run id; full-pipeline formatters accept `options.runId` and `options.generatedAt` for correlation across reports and logs.
51
+ - **Full pipeline audit**: `formatPipelineAuditFull(csl, isl, signal, aalReason, removalPlan?, cpe?, options?)` builds a single report (CSL → ISL → Signal → AAL → optional CPE) with run id and generated-at timestamp; lineage preserved in each section.
52
+ - **formatPipelineAudit** extended: `options.includeSignalAndAAL`, `options.signal`, `options.aalReason`, `options.removalPlan` to include ISL Signal and AAL sections in the pipeline report.
53
+ - **JSON variant**: `buildFullAuditPayload(csl, isl, signal, reason, options?)` returns a JSON-serializable object (runId, generatedAt, summary, sections with lineage). `formatPipelineAuditAsJson(...)` returns the JSON string; `options.compact: true` for one-line output (logs, SIEM).
54
+ - **Audit for logs**: `buildAuditLogEntry(signal, reason, options?)` returns a compact summary (runId, generatedAtIso, action, riskScore, hasThreats, detectionCount) for one-line logging.
55
+ - Types: `AuditRunInfo`, `AuditLogSummary`, `FullPipelineAuditOptions`, `PipelineAuditJsonOptions`.
56
+
57
+ ### 🔄 Changed
58
+
59
+ - **sanitize (ISL)**: optional second argument `SanitizeOptions`; uses `detectThreats` per segment and assigns `piDetection` when detections exist; option `detectThreatsOptions` for patterns or limits.
60
+ - **emitSignal (ISL)**: second argument may be `EmitSignalOptions` (object) or `number` (timestamp); computes risk score with configured strategy; includes `metadata.strategy` on the signal.
61
+ - **RemovedInstruction (AAL)**: `type` is now `string` (any `pattern_type`); added `segmentId?: string`.
62
+
63
+ ### 📚 Documentation
64
+
65
+ - **FEATURE.md**: per-version detail of new and modified features; table of methods/APIs changed in 0.3.0 with description of each change.
66
+ - **README.md**: audit section updated with run id, full pipeline (formatPipelineAuditFull), JSON variant (buildFullAuditPayload, formatPipelineAuditAsJson), and audit for logs (buildAuditLogEntry); examples for full report and compact log entry.
67
+
68
+ ### 📎 More information
69
+
70
+ For specific method signatures and API changes in 0.3.0, see **[FEATURE.md](./FEATURE.md)**.
71
+
72
+ ---
73
+
10
74
  ## [0.2.0] - 2026-01-26
11
75
 
12
76
  ### ♻️ Architectural Refactor - ISL / AAL Separation
@@ -161,7 +225,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
161
225
 
162
226
  **Problem**: When importing types from `@ai-pip/core` in SDK projects, TypeScript could not resolve nested type properties:
163
227
  - `this.data.trust.value` appeared as `any` instead of `TrustLevelType`
164
- - No autocompletado for nested properties
228
+ - No autocomplete for nested properties
165
229
  - Type inference failed for complex types
166
230
 
167
231
  **Root Cause**: Incompatibility between `moduleResolution: "bundler"` (used in `@ai-pip-core`) and `moduleResolution: "nodenext"` (used in SDK projects). TypeScript couldn't follow the chain of type imports correctly.
@@ -173,7 +237,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
173
237
 
174
238
  **Impact**:
175
239
  - ✅ Nested types now resolve correctly
176
- - ✅ Autocompletado works for all type properties
240
+ - ✅ Autocomplete works for all type properties
177
241
  - ✅ Type inference works correctly in consuming projects
178
242
  - ✅ Better compatibility with Node.js ESM module resolution
179
243
 
package/README.md CHANGED
@@ -44,7 +44,7 @@ This package contains the **core** implementation of the protocol, which include
44
44
  - [Import Strategies](#import-strategies)
45
45
  - [Official SDK](#official-sdk)
46
46
  - [CHANGELOG](#changelog)
47
-
47
+ - [FEATURES](#features)
48
48
  <a id="architecture"></a>
49
49
  ## 🏗️ Architecture
50
50
 
@@ -53,7 +53,7 @@ The AI-PIP protocol is composed of the following layers with clear separation of
53
53
  ### ✅ Implemented Layers
54
54
 
55
55
  - **CSL (Context Segmentation Layer)**: Segments and classifies content according to its origin
56
- - **ISL (Instruction Sanitization Layer)**: Detects malicious patterns, scores risk, and sanitizes content. Emits signals (ISLSignal) for other layers to consume.
56
+ - **ISL (Instruction Sanitization Layer)**: Detects malicious patterns (`detectThreats`, ~287 default patterns), scores risk (configurable strategies), and sanitizes content. Each segment may carry `piDetection` (`PiDetectionResult`). Optional `SanitizeOptions.detectThreatsOptions` for custom patterns or limits. Emits signals (ISLSignal) for other layers to consume.
57
57
  - **AAL (Agent Action Lock)**: Hybrid layer that consumes ISL signals and applies configurable policies (ALLOW/WARN/BLOCK). Core-defined contract, SDK-implemented.
58
58
  - **CPE (Cryptographic Prompt Envelope)**: Generates cryptographic envelope with HMAC-SHA256 signature
59
59
 
@@ -153,11 +153,11 @@ import { segment, classifySource, createTrustLevel } from '@ai-pip/core/csl'
153
153
  import type { CSLResult, CSLSegment, TrustLevel } from '@ai-pip/core/csl'
154
154
 
155
155
  // Import from ISL (Instruction Sanitization Layer)
156
- import { sanitize, createISLSignal } from '@ai-pip/core/isl'
157
- import type { ISLResult, ISLSegment, ISLSignal } from '@ai-pip/core/isl'
156
+ import { sanitize, createISLSignal, detectThreats, getDefaultThreatPatterns } from '@ai-pip/core/isl'
157
+ import type { ISLResult, ISLSegment, ISLSignal, DetectThreatsOptions } from '@ai-pip/core/isl'
158
158
 
159
159
  // Import from AAL (Agent Action Lock)
160
- import { createAnomalyScore, resolveAgentAction } from '@ai-pip/core/aal'
160
+ import { createAnomalyScore, resolveAgentAction, resolveAgentActionWithScore, buildRemovalPlanFromResult, applyRemovalPlan } from '@ai-pip/core/aal'
161
161
  import type { AnomalyScore, AgentPolicy } from '@ai-pip/core/aal'
162
162
 
163
163
  // Import from CPE (Cryptographic Prompt Envelope)
@@ -199,7 +199,7 @@ This example demonstrates the complete AI-PIP processing pipeline:
199
199
 
200
200
  1. **CSL (Context Segmentation Layer)**: The `segment()` function takes user input and segments it into semantic chunks. Each segment is classified by its origin (`source: 'UI'`), which determines its trust level. The result contains multiple segments, each with its own trust classification and lineage tracking.
201
201
 
202
- 2. **ISL (Instruction Sanitization Layer)**: The `sanitize()` function processes the segmented content and applies sanitization based on each segment's trust level. Trusted content (TC) receives minimal sanitization, semi-trusted (STC) gets moderate sanitization, and untrusted content (UC) receives aggressive sanitization to remove potential prompt injection attempts. ISL also detects malicious patterns and emits signals (ISLSignal) that can be consumed by AAL for policy-based decisions.
202
+ 2. **ISL (Instruction Sanitization Layer)**: The `sanitize()` function processes the segmented content and applies sanitization based on each segment's trust level. Trusted content (TC) receives minimal sanitization, semi-trusted (STC) gets moderate sanitization, and untrusted content (UC) receives aggressive sanitization to remove potential prompt injection attempts. ISL runs `detectThreats` per segment (default ~287 patterns; optional `SanitizeOptions.detectThreatsOptions` for custom patterns or limits) and attaches `piDetection` (`PiDetectionResult`) to segments with detections. It emits signals (ISLSignal) that can be consumed by AAL for policy-based decisions.
203
203
 
204
204
  3. **CPE (Cryptographic Prompt Envelope)**: The `envelope()` function creates a cryptographic wrapper around the sanitized content. It generates a unique nonce, timestamp, and HMAC-SHA256 signature to ensure the integrity and authenticity of the processed prompt. The resulting envelope can be safely sent to an AI model with cryptographic proof that the content hasn't been tampered with.
205
205
 
@@ -254,7 +254,7 @@ This example shows the same processing pipeline but using layer-specific imports
254
254
 
255
255
  2. **Content Segmentation**: The `segment()` function breaks down the input into semantic segments. Each segment inherits the trust classification from its source, allowing different parts of the content to be processed according to their trustworthiness.
256
256
 
257
- 3. **Content Sanitization**: The `sanitize()` function applies security measures based on each segment's trust level. This step removes or neutralizes potential prompt injection attempts, especially in untrusted content segments.
257
+ 3. **Content Sanitization**: The `sanitize()` function applies security measures based on each segment's trust level and runs threat detection per segment (each segment may have `piDetection`). This step removes or neutralizes potential prompt injection attempts, especially in untrusted content segments.
258
258
 
259
259
  4. **Nonce Generation**: `createNonce()` generates a unique random value that prevents replay attacks. This nonce is included in the cryptographic envelope to ensure each processed prompt is unique.
260
260
 
@@ -612,7 +612,9 @@ import {
612
612
  emitSignal,
613
613
  resolveAgentAction,
614
614
  buildDecisionReason,
615
- buildRemovalPlan
615
+ buildRemovalPlan,
616
+ buildRemovalPlanFromResult,
617
+ applyRemovalPlan
616
618
  } from '@ai-pip/core'
617
619
  import type { ISLSignal, AgentPolicy } from '@ai-pip/core'
618
620
 
@@ -623,7 +625,7 @@ const cslResult = segment({
623
625
  metadata: {}
624
626
  })
625
627
 
626
- // 2. Sanitize content (ISL) - produces internal result
628
+ // 2. Sanitize content (ISL) - produces internal result; segments may have piDetection
627
629
  const islResult = sanitize(cslResult)
628
630
 
629
631
  // 3. Emit signal from ISL result - external contract
@@ -649,10 +651,12 @@ console.log('Agent action:', action) // 'ALLOW', 'WARN', or 'BLOCK'
649
651
  const reason = buildDecisionReason(action, islSignal, policy)
650
652
  console.log('Decision reason:', reason.reason)
651
653
 
652
- // 7. Build removal plan if threats detected
654
+ // 7. Build removal plan from signal (descriptive) or from result (actionable)
653
655
  const removalPlan = buildRemovalPlan(islSignal, policy)
654
656
  if (removalPlan.shouldRemove) {
655
- console.log(`Removing ${removalPlan.instructionsToRemove.length} instruction(s)`)
657
+ const planFromResult = buildRemovalPlanFromResult(islResult, policy)
658
+ const cleanedResult = applyRemovalPlan(islResult, planFromResult)
659
+ console.log(`Removed ${planFromResult.instructionsToRemove.length} instruction(s); use cleanedResult for LLM`)
656
660
  }
657
661
  ```
658
662
 
@@ -675,6 +679,38 @@ if (removalPlan.shouldRemove) {
675
679
 
676
680
  **Key Principle**: A layer should never consume the internal "result" of another layer. It consumes a signal.
677
681
 
682
+ #### Risk score strategies (ISL)
683
+
684
+ The risk score on the signal is derived from aggregated detections using a **strategy** chosen at emit time. Only registered strategies are allowed (auditability and reproducibility).
685
+
686
+ | Strategy | Description | When to use |
687
+ |----------|-------------|-------------|
688
+ | **MAX_CONFIDENCE** (default) | Single highest confidence among detections. | Simple, conservative; good default. |
689
+ | **SEVERITY_PLUS_VOLUME** | Highest confidence plus a small bump per extra detection (volume). | When multiple detections should raise risk. |
690
+ | **WEIGHTED_BY_TYPE** | Weight by pattern type (e.g. jailbreak vs prompt-injection). | When some threat types should count more. |
691
+
692
+ ```typescript
693
+ import { emitSignal, RiskScoreStrategy } from '@ai-pip/core/isl'
694
+
695
+ // Default: MAX_CONFIDENCE
696
+ const signal = emitSignal(islResult)
697
+
698
+ // Explicit strategy
699
+ const signalSev = emitSignal(islResult, {
700
+ riskScore: { strategy: RiskScoreStrategy.SEVERITY_PLUS_VOLUME }
701
+ })
702
+
703
+ // WEIGHTED_BY_TYPE with custom weights
704
+ const signalWeighted = emitSignal(islResult, {
705
+ riskScore: {
706
+ strategy: RiskScoreStrategy.WEIGHTED_BY_TYPE,
707
+ typeWeights: { 'prompt-injection': 1.2, jailbreak: 1 }
708
+ }
709
+ })
710
+ ```
711
+
712
+ The strategy used is stored in **`signal.metadata.strategy`** for auditability. For full API and formulas, see the [ISL layer documentation](https://github.com/AI-PIP/ai-pip-docs/blob/main/docs/core/layers/ISL.md) in the protocol docs.
713
+
678
714
  ---
679
715
 
680
716
  <a id="example-audit-utilities"></a>
@@ -696,7 +732,12 @@ import {
696
732
  formatISLSignalForAudit,
697
733
  formatAALForAudit,
698
734
  formatCPEForAudit,
699
- formatPipelineAudit
735
+ formatPipelineAudit,
736
+ formatPipelineAuditFull,
737
+ formatPipelineAuditAsJson,
738
+ createAuditRunId,
739
+ buildAuditLogEntry,
740
+ buildFullAuditPayload
700
741
  } from '@ai-pip/core'
701
742
  import type { AgentPolicy } from '@ai-pip/core'
702
743
 
@@ -721,12 +762,32 @@ console.log(formatISLSignalForAudit(islSignal))
721
762
  console.log(formatAALForAudit(reason, removalPlan))
722
763
  console.log(formatCPEForAudit(cpeResult))
723
764
 
724
- // Full pipeline audit report
765
+ // Full pipeline audit report (CSL → ISL → CPE)
725
766
  const fullAudit = formatPipelineAudit(cslResult, islResult, cpeResult, {
726
767
  title: 'AI-PIP Pipeline Audit',
727
768
  sectionSeparator: '\n\n'
728
769
  })
729
770
  console.log(fullAudit)
771
+
772
+ // Full pipeline with run id and Signal + AAL (CSL → ISL → Signal → AAL → optional CPE)
773
+ const runId = createAuditRunId()
774
+ const generatedAt = Date.now()
775
+ const fullReport = formatPipelineAuditFull(cslResult, islResult, islSignal, reason, removalPlan, cpeResult, {
776
+ runId,
777
+ generatedAt,
778
+ includeCpe: true,
779
+ title: 'AI-PIP Pipeline Audit (full)'
780
+ })
781
+ console.log(fullReport)
782
+
783
+ // JSON for logs / SIEM / machine consumption
784
+ const payload = buildFullAuditPayload(cslResult, islResult, islSignal, reason, { runId, generatedAt, removalPlan, cpe: cpeResult })
785
+ const jsonReport = formatPipelineAuditAsJson(cslResult, islResult, islSignal, reason, { runId, generatedAt, removalPlan, compact: true })
786
+ logger.info(jsonReport)
787
+
788
+ // Compact log entry (one line per request)
789
+ const logEntry = buildAuditLogEntry(islSignal, reason, { runId, generatedAt })
790
+ logger.info(JSON.stringify(logEntry))
730
791
  ```
731
792
 
732
793
  **What this example demonstrates:**
@@ -736,9 +797,13 @@ console.log(fullAudit)
736
797
  - **`formatISLSignalForAudit(signal)`**: Formats ISL signal (risk score, threats, detections) for audit.
737
798
  - **`formatAALForAudit(reason, removalPlan?)`**: Formats AAL decision reason and optional removal plan.
738
799
  - **`formatCPEForAudit(result)`**: Formats CPE result (metadata, signature, lineage).
739
- - **`formatPipelineAudit(csl, isl, cpe, options?)`**: Builds a single full pipeline audit string.
800
+ - **`formatPipelineAudit(csl, isl, cpe, options?)`**: Builds a single full pipeline audit string (CSL → ISL → CPE). Use **`options.includeSignalAndAAL`** with **`options.signal`** and **`options.aalReason`** to include ISL Signal and AAL sections.
801
+ - **`formatPipelineAuditFull(csl, isl, signal, aalReason, removalPlan?, cpe?, options?)`**: Full pipeline report (CSL → ISL → Signal → AAL → optional CPE) with **run id** and **generated at** timestamp; lineage in each section.
802
+ - **Run identifier**: **`createAuditRunId()`** generates a unique run id; pass **`options.runId`** and **`options.generatedAt`** to formatters for correlation across reports and logs.
803
+ - **JSON variant**: **`buildFullAuditPayload(csl, isl, signal, reason, options?)`** returns a JSON-serializable object (runId, generatedAt, summary, sections with lineage). **`formatPipelineAuditAsJson(...)`** returns the JSON string; use **`options.compact: true`** for one-line output (logs, SIEM).
804
+ - **Audit for logs**: **`buildAuditLogEntry(signal, reason, options?)`** returns a compact summary (`runId`, `generatedAtIso`, `action`, `riskScore`, `hasThreats`, `detectionCount`) for one-line logging (e.g. `logger.info(JSON.stringify(entry))`).
740
805
 
741
- All formatters accept minimal shapes (layer-agnostic) so you can pass any compatible object. Output is ordered and consistent for compliance and debugging.
806
+ All formatters accept minimal shapes (layer-agnostic) so you can pass any compatible object. Output is ordered and consistent for compliance and debugging. Lineage is preserved in every section for traceability.
742
807
 
743
808
  <a id="use-cases"></a>
744
809
  ### Use cases
@@ -748,8 +813,8 @@ Typical scenarios where AI-PIP core is used:
748
813
  | Use case | Layers involved | Goal |
749
814
  |----------|-----------------|------|
750
815
  | **Secure user chat** | CSL → ISL → CPE | Segment UI input, sanitize, wrap in envelope before sending to the model. |
751
- | **Policy-based moderation** | CSL → ISL → emitSignal → AAL | Get risk signal from ISL, resolve ALLOW/WARN/BLOCK and removal plan from AAL. |
752
- | **Audit and compliance** | Shared audit formatters | Pretty-print CSL/ISL/AAL/CPE results and full pipeline for logs and reports. |
816
+ | **Policy-based moderation** | CSL → ISL → emitSignal → AAL | Get risk signal from ISL, resolve ALLOW/WARN/BLOCK; use `buildRemovalPlanFromResult` + `applyRemovalPlan` to get cleaned content for the LLM. |
817
+ | **Audit and compliance** | Shared audit formatters | Pretty-print CSL/ISL/AAL/CPE results; full pipeline with run id (`formatPipelineAuditFull`); JSON variant (`buildFullAuditPayload`, `formatPipelineAuditAsJson`) for SIEM; compact log entry (`buildAuditLogEntry`) for one-line logging. |
753
818
  | **DOM / scraped content** | CSL (source: DOM) → ISL → CPE | Treat web content as untrusted (UC), apply aggressive sanitization. |
754
819
  | **System instructions** | CSL (source: SYSTEM) → ISL → CPE | Trusted content (TC), minimal sanitization. |
755
820
  | **Lineage and forensics** | All layers | Use lineage from results and `filterLineageByStep` / `getLastLineageEntry` for tracing. |
@@ -763,17 +828,35 @@ const signal = emitSignal(islResult)
763
828
  const action = resolveAgentAction(signal, policy)
764
829
  const reason = buildDecisionReason(action, signal, policy)
765
830
  const plan = buildRemovalPlan(signal, policy)
766
- // Use action, reason, and plan in your SDK to enforce policy and optionally remove instructions.
831
+ const planFromResult = buildRemovalPlanFromResult(islResult, policy)
832
+ const cleanedResult = applyRemovalPlan(islResult, planFromResult)
833
+ // Use action, reason, plan; send cleanedResult.segments to the LLM when removal is enabled.
767
834
  ```
768
835
 
769
836
  **Example: audit report**
770
837
 
771
838
  ```typescript
839
+ // Text report (CSL → ISL → CPE)
772
840
  const report = formatPipelineAudit(cslResult, islResult, cpeResult, {
773
841
  title: 'Request Audit',
774
842
  sectionSeparator: '\n---\n'
775
843
  })
776
844
  logger.info(report)
845
+
846
+ // Full report with run id and Signal + AAL
847
+ const runId = createAuditRunId()
848
+ const fullReport = formatPipelineAuditFull(cslResult, islResult, signal, reason, removalPlan, cpeResult, {
849
+ runId, generatedAt: Date.now(), includeCpe: true
850
+ })
851
+ logger.info(fullReport)
852
+
853
+ // JSON for SIEM / machine consumption
854
+ const jsonReport = formatPipelineAuditAsJson(cslResult, islResult, signal, reason, { runId, generatedAt: Date.now(), removalPlan, compact: true })
855
+ logger.info(jsonReport)
856
+
857
+ // One-line log entry per request
858
+ const logEntry = buildAuditLogEntry(signal, reason, { runId, generatedAt: Date.now() })
859
+ logger.info(JSON.stringify(logEntry))
777
860
  ```
778
861
 
779
862
  <a id="documentation"></a>
@@ -804,6 +887,7 @@ All AI-PIP protocol documentation is centralized in the [documentation repositor
804
887
  ### Code-Specific Documentation
805
888
 
806
889
  - **[CHANGELOG](./CHANGELOG.md)** - Package version history
890
+ - **[FEATURE](./FEATURE.md)** - New and modified features by version
807
891
  - **[API Reference](#-basic-usage)** - Usage examples in this README
808
892
 
809
893
  <a id="testing"></a>
@@ -1000,6 +1084,11 @@ For SDK development updates and roadmap, see the [AI-PIP Documentation Repositor
1000
1084
 
1001
1085
  For complete details and all version history, see [CHANGELOG.md](./CHANGELOG.md).
1002
1086
 
1087
+ <a id="features"></a>
1088
+ ## 📋 Features
1089
+
1090
+ Summary of new and modified features per version (aligned with the changelog): **[FEATURE.md](./FEATURE.md)**.
1091
+
1003
1092
  ---
1004
1093
 
1005
1094
  **Current Version**: 0.2.0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * AAL display constants - semantic mapping for SDK/UI.
3
+ * Used for consistent display of AAL decisions (e.g. colors).
4
+ */
5
+ import type { AnomalyAction } from './types.js';
6
+ /**
7
+ * Display color for each AAL action.
8
+ * SDK/UI can use this for consistent styling (e.g. green = allow, yellow = warn, red = block).
9
+ */
10
+ export declare const ACTION_DISPLAY_COLORS: Record<AnomalyAction, string>;
11
+ /**
12
+ * Returns the display color for an AAL action.
13
+ */
14
+ export declare function getActionDisplayColor(action: AnomalyAction): string;
15
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/AAL/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAI9D,CAAA;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEnE"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * AAL display constants - semantic mapping for SDK/UI.
3
+ * Used for consistent display of AAL decisions (e.g. colors).
4
+ */
5
+ /**
6
+ * Display color for each AAL action.
7
+ * SDK/UI can use this for consistent styling (e.g. green = allow, yellow = warn, red = block).
8
+ */
9
+ export const ACTION_DISPLAY_COLORS = Object.freeze({
10
+ ALLOW: 'green',
11
+ WARN: 'yellow',
12
+ BLOCK: 'red'
13
+ });
14
+ /**
15
+ * Returns the display color for an AAL action.
16
+ */
17
+ export function getActionDisplayColor(action) {
18
+ return ACTION_DISPLAY_COLORS[action];
19
+ }
20
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/AAL/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAkC,MAAM,CAAC,MAAM,CAAC;IAChF,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,KAAK;CACb,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAqB;IACzD,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAA;AACtC,CAAC"}
@@ -21,8 +21,9 @@
21
21
  */
22
22
  export { createAnomalyScore, isHighRisk, isLowRisk, isWarnRisk, isRoleProtected, isContextLeakPreventionEnabled, isInstructionImmutable, isIntentBlocked, isScopeSensitive } from './value-objects/index.js';
23
23
  export type { AnomalyScore, PolicyRule } from './value-objects/index.js';
24
- export { resolveAgentAction, resolveAgentActionWithScore, buildDecisionReason, buildRemovalPlan } from './process/index.js';
24
+ export { resolveAgentAction, resolveAgentActionWithScore, buildDecisionReason, buildRemovalPlan, buildRemovalPlanFromResult, applyRemovalPlan } from './process/index.js';
25
25
  export type { DecisionReason, RemovalPlan } from './process/index.js';
26
26
  export { buildAALLineage } from './lineage/index.js';
27
+ export { ACTION_DISPLAY_COLORS, getActionDisplayColor } from './constants.js';
27
28
  export type { AnomalyAction, RemovedInstruction, BlockedIntent, SensitiveScope, ProtectedRole, ImmutableInstruction, AgentPolicy, } from './types.js';
28
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/AAL/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EACH,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,8BAA8B,EAC9B,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACnB,MAAM,0BAA0B,CAAA;AAEjC,YAAY,EACR,YAAY,EACZ,UAAU,EACb,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EACH,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,gBAAgB,EACnB,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACR,cAAc,EACd,WAAW,EACd,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGpD,YAAY,EACR,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,WAAW,GACd,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/AAL/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EACH,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,8BAA8B,EAC9B,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACnB,MAAM,0BAA0B,CAAA;AAEjC,YAAY,EACR,YAAY,EACZ,UAAU,EACb,MAAM,0BAA0B,CAAA;AAGjC,OAAO,EACH,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,gBAAgB,EACnB,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACR,cAAc,EACd,WAAW,EACd,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAGpD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAG7E,YAAY,EACR,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,WAAW,GACd,MAAM,YAAY,CAAA"}
package/dist/AAL/index.js CHANGED
@@ -22,7 +22,9 @@
22
22
  // Value objects
23
23
  export { createAnomalyScore, isHighRisk, isLowRisk, isWarnRisk, isRoleProtected, isContextLeakPreventionEnabled, isInstructionImmutable, isIntentBlocked, isScopeSensitive } from './value-objects/index.js';
24
24
  // Process functions
25
- export { resolveAgentAction, resolveAgentActionWithScore, buildDecisionReason, buildRemovalPlan } from './process/index.js';
25
+ export { resolveAgentAction, resolveAgentActionWithScore, buildDecisionReason, buildRemovalPlan, buildRemovalPlanFromResult, applyRemovalPlan } from './process/index.js';
26
26
  // Lineage
27
27
  export { buildAALLineage } from './lineage/index.js';
28
+ // Display constants (for SDK/UI)
29
+ export { ACTION_DISPLAY_COLORS, getActionDisplayColor } from './constants.js';
28
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/AAL/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,gBAAgB;AAChB,OAAO,EACH,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,8BAA8B,EAC9B,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACnB,MAAM,0BAA0B,CAAA;AAOjC,oBAAoB;AACpB,OAAO,EACH,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,gBAAgB,EACnB,MAAM,oBAAoB,CAAA;AAO3B,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/AAL/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,gBAAgB;AAChB,OAAO,EACH,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,8BAA8B,EAC9B,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EACnB,MAAM,0BAA0B,CAAA;AAOjC,oBAAoB;AACpB,OAAO,EACH,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,gBAAgB,EACnB,MAAM,oBAAoB,CAAA;AAO3B,UAAU;AACV,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEpD,iCAAiC;AACjC,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * applyRemovalPlan - Applies a removal plan to ISL result (pure, deterministic).
3
+ *
4
+ * @remarks
5
+ * Removes malicious ranges from each segment's sanitizedContent according to the plan.
6
+ * Only instructions with segmentId are applied; others are skipped.
7
+ * Overlapping ranges per segment are merged before removal.
8
+ */
9
+ import type { RemovalPlan } from './buildRemovalPlan.js';
10
+ import type { ISLResult } from '../../isl/types.js';
11
+ /**
12
+ * Applies a removal plan to an ISL result.
13
+ * Produces a new ISLResult with segment sanitizedContent updated (malicious ranges removed).
14
+ * Instructions without segmentId are ignored. Positions are clamped to [0, content.length] per segment; invalid or empty ranges are dropped. Lineage and metadata are preserved.
15
+ *
16
+ * @param islResult - ISL result (segments with sanitizedContent and optional piDetection)
17
+ * @param plan - Removal plan from buildRemovalPlanFromResult (must include segmentIds for removal)
18
+ * @returns New ISLResult with sanitizedContent updated per segment
19
+ */
20
+ export declare function applyRemovalPlan(islResult: ISLResult, plan: RemovalPlan): ISLResult;
21
+ //# sourceMappingURL=applyRemovalPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyRemovalPlan.d.ts","sourceRoot":"","sources":["../../../src/AAL/process/applyRemovalPlan.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,oBAAoB,CAAA;AAwG/D;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,CAmCnF"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * applyRemovalPlan - Applies a removal plan to ISL result (pure, deterministic).
3
+ *
4
+ * @remarks
5
+ * Removes malicious ranges from each segment's sanitizedContent according to the plan.
6
+ * Only instructions with segmentId are applied; others are skipped.
7
+ * Overlapping ranges per segment are merged before removal.
8
+ */
9
+ /**
10
+ * Clamps position ranges to valid [0, contentLength) and drops empty or invalid ranges.
11
+ * Ensures 0 <= start <= end <= contentLength and start < end.
12
+ */
13
+ function clampRangesToContent(ranges, contentLength) {
14
+ if (contentLength <= 0 || ranges.length === 0)
15
+ return [];
16
+ const result = [];
17
+ for (const r of ranges) {
18
+ const start = Math.max(0, Math.min(Number(r.start), contentLength));
19
+ const end = Math.max(0, Math.min(Number(r.end), contentLength));
20
+ if (start < end)
21
+ result.push({ start, end });
22
+ }
23
+ return result;
24
+ }
25
+ /**
26
+ * Merges overlapping ranges (start inclusive, end exclusive). Sorted by start.
27
+ */
28
+ function mergeRanges(ranges) {
29
+ if (ranges.length === 0)
30
+ return [];
31
+ const sorted = [...ranges].sort((a, b) => a.start - b.start);
32
+ const merged = [{ start: sorted[0].start, end: sorted[0].end }];
33
+ for (let i = 1; i < sorted.length; i++) {
34
+ const r = sorted[i];
35
+ const last = merged.at(-1);
36
+ if (r.start <= last.end) {
37
+ merged[merged.length - 1] = { start: last.start, end: Math.max(last.end, r.end) };
38
+ }
39
+ else {
40
+ merged.push({ start: r.start, end: r.end });
41
+ }
42
+ }
43
+ return merged;
44
+ }
45
+ /** Max gap (chars) between ranges to consider for merging when gap is only punctuation/whitespace */
46
+ const MAX_PUNCTUATION_GAP = 10;
47
+ /** True if the substring is only whitespace and/or common punctuation (no words). */
48
+ function isOnlyPunctuationOrWhitespace(s) {
49
+ return /^[\s.,;:!?'"-]*$/.test(s);
50
+ }
51
+ /**
52
+ * Merges consecutive ranges when the gap between them is only punctuation/whitespace,
53
+ * so we remove one contiguous block instead of leaving fragments like ", . ".
54
+ */
55
+ function mergeAdjacentByPunctuation(ranges, content) {
56
+ if (ranges.length <= 1)
57
+ return [...ranges];
58
+ const result = [{ ...ranges[0] }];
59
+ for (let i = 1; i < ranges.length; i++) {
60
+ const r = ranges[i];
61
+ const last = result.at(-1);
62
+ const gapStart = last.end;
63
+ const gapEnd = r.start;
64
+ if (gapEnd > gapStart && gapEnd - gapStart <= MAX_PUNCTUATION_GAP) {
65
+ const gap = content.slice(gapStart, gapEnd);
66
+ if (isOnlyPunctuationOrWhitespace(gap)) {
67
+ result[result.length - 1] = { start: last.start, end: r.end };
68
+ continue;
69
+ }
70
+ }
71
+ result.push({ ...r });
72
+ }
73
+ return result;
74
+ }
75
+ /**
76
+ * Removes given ranges from content. Ranges must be non-overlapping and sorted by start.
77
+ */
78
+ function removeRanges(content, ranges) {
79
+ if (ranges.length === 0)
80
+ return content;
81
+ let result = '';
82
+ let pos = 0;
83
+ for (const r of ranges) {
84
+ if (r.start > pos)
85
+ result += content.slice(pos, r.start);
86
+ pos = Math.max(pos, r.end);
87
+ }
88
+ if (pos < content.length)
89
+ result += content.slice(pos);
90
+ return result;
91
+ }
92
+ function assertApplyRemovalPlanArgs(islResult, plan) {
93
+ if (islResult == null || typeof islResult !== 'object') {
94
+ throw new TypeError('AAL applyRemovalPlan: islResult must be a non-null object');
95
+ }
96
+ if (!Array.isArray(islResult.segments)) {
97
+ throw new TypeError('AAL applyRemovalPlan: islResult.segments must be an array');
98
+ }
99
+ if (plan == null || typeof plan !== 'object') {
100
+ throw new TypeError('AAL applyRemovalPlan: plan must be a non-null object');
101
+ }
102
+ if (!Array.isArray(plan.instructionsToRemove)) {
103
+ throw new TypeError('AAL applyRemovalPlan: plan.instructionsToRemove must be an array');
104
+ }
105
+ }
106
+ /**
107
+ * Applies a removal plan to an ISL result.
108
+ * Produces a new ISLResult with segment sanitizedContent updated (malicious ranges removed).
109
+ * Instructions without segmentId are ignored. Positions are clamped to [0, content.length] per segment; invalid or empty ranges are dropped. Lineage and metadata are preserved.
110
+ *
111
+ * @param islResult - ISL result (segments with sanitizedContent and optional piDetection)
112
+ * @param plan - Removal plan from buildRemovalPlanFromResult (must include segmentIds for removal)
113
+ * @returns New ISLResult with sanitizedContent updated per segment
114
+ */
115
+ export function applyRemovalPlan(islResult, plan) {
116
+ assertApplyRemovalPlanArgs(islResult, plan);
117
+ if (!plan.shouldRemove || plan.instructionsToRemove.length === 0) {
118
+ return islResult;
119
+ }
120
+ const bySegmentId = new Map();
121
+ for (const inst of plan.instructionsToRemove) {
122
+ if (inst.segmentId == null)
123
+ continue;
124
+ const list = bySegmentId.get(inst.segmentId) ?? [];
125
+ list.push(inst.position);
126
+ bySegmentId.set(inst.segmentId, list);
127
+ }
128
+ if (bySegmentId.size === 0)
129
+ return islResult;
130
+ const newSegments = islResult.segments.map((seg) => {
131
+ const ranges = bySegmentId.get(seg.id);
132
+ if (ranges == null || ranges.length === 0)
133
+ return seg;
134
+ const content = seg.sanitizedContent ?? '';
135
+ const len = typeof content === 'string' ? content.length : 0;
136
+ const clamped = clampRangesToContent(ranges, len);
137
+ if (clamped.length === 0)
138
+ return seg;
139
+ const merged = mergeRanges(clamped);
140
+ const mergedAdjacent = mergeAdjacentByPunctuation(merged, content);
141
+ const newContent = removeRanges(content, mergedAdjacent);
142
+ return { ...seg, sanitizedContent: newContent };
143
+ });
144
+ return {
145
+ segments: Object.freeze(newSegments),
146
+ lineage: islResult.lineage,
147
+ metadata: islResult.metadata
148
+ };
149
+ }
150
+ //# sourceMappingURL=applyRemovalPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyRemovalPlan.js","sourceRoot":"","sources":["../../../src/AAL/process/applyRemovalPlan.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildDecisionReason.d.ts","sourceRoot":"","sources":["../../../src/AAL/process/buildDecisionReason.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,WAAW,GAClB,cAAc,CA2BhB"}
1
+ {"version":3,"file":"buildDecisionReason.d.ts","sourceRoot":"","sources":["../../../src/AAL/process/buildDecisionReason.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AA2BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,WAAW,GAClB,cAAc,CAgChB"}