monora-ai 2.0.0 → 2.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 (202) hide show
  1. package/README.md +441 -150
  2. package/dist/aims_governance.d.ts +238 -0
  3. package/dist/aims_governance.d.ts.map +1 -0
  4. package/dist/aims_governance.js +922 -0
  5. package/dist/alerts.d.ts +16 -0
  6. package/dist/alerts.d.ts.map +1 -1
  7. package/dist/alerts.js +16 -0
  8. package/dist/api.d.ts +6 -0
  9. package/dist/api.d.ts.map +1 -1
  10. package/dist/api.js +6 -0
  11. package/dist/assessment.d.ts +269 -0
  12. package/dist/assessment.d.ts.map +1 -0
  13. package/dist/assessment.js +1232 -0
  14. package/dist/attestation.js +23 -1
  15. package/dist/attribution.d.ts +349 -0
  16. package/dist/attribution.d.ts.map +1 -0
  17. package/dist/attribution.js +987 -0
  18. package/dist/autodetect.d.ts +69 -1
  19. package/dist/autodetect.d.ts.map +1 -1
  20. package/dist/autodetect.js +644 -1
  21. package/dist/bias.d.ts +130 -0
  22. package/dist/bias.d.ts.map +1 -0
  23. package/dist/bias.js +223 -0
  24. package/dist/circuit_breaker.js +3 -3
  25. package/dist/cli/diagnostics.d.ts +5 -1
  26. package/dist/cli/diagnostics.d.ts.map +1 -1
  27. package/dist/cli/diagnostics.js +31 -8
  28. package/dist/cli/doctor.d.ts +25 -0
  29. package/dist/cli/doctor.d.ts.map +1 -0
  30. package/dist/cli/doctor.js +381 -0
  31. package/dist/cli/fix.d.ts +16 -0
  32. package/dist/cli/fix.d.ts.map +1 -0
  33. package/dist/cli/fix.js +284 -0
  34. package/dist/cli/init.d.ts +57 -0
  35. package/dist/cli/init.d.ts.map +1 -0
  36. package/dist/cli/init.js +205 -0
  37. package/dist/cli.js +1611 -126
  38. package/dist/complianceTargets.d.ts +111 -0
  39. package/dist/complianceTargets.d.ts.map +1 -0
  40. package/dist/complianceTargets.js +521 -0
  41. package/dist/config.d.ts +301 -17
  42. package/dist/config.d.ts.map +1 -1
  43. package/dist/config.js +428 -36
  44. package/dist/config_migrations.d.ts +41 -0
  45. package/dist/config_migrations.d.ts.map +1 -1
  46. package/dist/config_migrations.js +205 -0
  47. package/dist/config_schema.d.ts +2900 -731
  48. package/dist/config_schema.d.ts.map +1 -1
  49. package/dist/config_schema.js +257 -55
  50. package/dist/context.d.ts +34 -0
  51. package/dist/context.d.ts.map +1 -1
  52. package/dist/context.js +118 -7
  53. package/dist/control_backbone.d.ts +122 -0
  54. package/dist/control_backbone.d.ts.map +1 -0
  55. package/dist/control_backbone.js +698 -0
  56. package/dist/data-governance.d.ts +187 -0
  57. package/dist/data-governance.d.ts.map +1 -0
  58. package/dist/data-governance.js +424 -0
  59. package/dist/dataResidency.d.ts +44 -0
  60. package/dist/dataResidency.d.ts.map +1 -0
  61. package/dist/dataResidency.js +203 -0
  62. package/dist/dispatcher.d.ts +32 -0
  63. package/dist/dispatcher.d.ts.map +1 -1
  64. package/dist/dispatcher.js +91 -4
  65. package/dist/events.d.ts.map +1 -1
  66. package/dist/events.js +38 -0
  67. package/dist/evidence_store.d.ts +103 -0
  68. package/dist/evidence_store.d.ts.map +1 -0
  69. package/dist/evidence_store.js +459 -0
  70. package/dist/executiveSummary.d.ts +65 -8
  71. package/dist/executiveSummary.d.ts.map +1 -1
  72. package/dist/executiveSummary.js +289 -26
  73. package/dist/identity.d.ts +143 -0
  74. package/dist/identity.d.ts.map +1 -0
  75. package/dist/identity.js +231 -0
  76. package/dist/impact-assessment.d.ts +350 -0
  77. package/dist/impact-assessment.d.ts.map +1 -0
  78. package/dist/impact-assessment.js +580 -0
  79. package/dist/index.d.ts +25 -5
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +300 -4
  82. package/dist/instrumentation.d.ts +1 -1
  83. package/dist/instrumentation.d.ts.map +1 -1
  84. package/dist/instrumentation.js +243 -27
  85. package/dist/integrations/anthropic.d.ts +3 -0
  86. package/dist/integrations/anthropic.d.ts.map +1 -1
  87. package/dist/integrations/anthropic.js +284 -79
  88. package/dist/integrations/governance.d.ts +33 -0
  89. package/dist/integrations/governance.d.ts.map +1 -0
  90. package/dist/integrations/governance.js +208 -0
  91. package/dist/integrations/langchain.d.ts +7 -0
  92. package/dist/integrations/langchain.d.ts.map +1 -1
  93. package/dist/integrations/langchain.js +387 -143
  94. package/dist/integrations/openai.d.ts +9 -0
  95. package/dist/integrations/openai.d.ts.map +1 -1
  96. package/dist/integrations/openai.js +673 -73
  97. package/dist/iso42001_consolidation.d.ts +16 -0
  98. package/dist/iso42001_consolidation.d.ts.map +1 -0
  99. package/dist/iso42001_consolidation.js +413 -0
  100. package/dist/iso42001_workflows.d.ts +263 -0
  101. package/dist/iso42001_workflows.d.ts.map +1 -0
  102. package/dist/iso42001_workflows.js +781 -0
  103. package/dist/lifecycle.d.ts +299 -0
  104. package/dist/lifecycle.d.ts.map +1 -0
  105. package/dist/lifecycle.js +624 -0
  106. package/dist/lineage.d.ts +2 -2
  107. package/dist/lineage.d.ts.map +1 -1
  108. package/dist/lineage.js +12 -17
  109. package/dist/middleware/express.d.ts.map +1 -1
  110. package/dist/middleware/express.js +33 -3
  111. package/dist/middleware/nextjs.d.ts.map +1 -1
  112. package/dist/middleware/nextjs.js +42 -68
  113. package/dist/model.d.ts +143 -0
  114. package/dist/model.d.ts.map +1 -0
  115. package/dist/model.js +371 -0
  116. package/dist/onboarding.d.ts +42 -0
  117. package/dist/onboarding.d.ts.map +1 -0
  118. package/dist/onboarding.js +1022 -0
  119. package/dist/oversight.d.ts +264 -0
  120. package/dist/oversight.d.ts.map +1 -0
  121. package/dist/oversight.js +497 -0
  122. package/dist/pdf_report.d.ts.map +1 -1
  123. package/dist/pdf_report.js +42 -21
  124. package/dist/presets.d.ts +88 -0
  125. package/dist/presets.d.ts.map +1 -0
  126. package/dist/presets.js +520 -0
  127. package/dist/propagation.d.ts.map +1 -1
  128. package/dist/propagation.js +34 -2
  129. package/dist/quotas.d.ts +171 -0
  130. package/dist/quotas.d.ts.map +1 -0
  131. package/dist/quotas.js +259 -0
  132. package/dist/register.d.ts +13 -0
  133. package/dist/register.d.ts.map +1 -0
  134. package/dist/register.js +99 -0
  135. package/dist/registry.d.ts +1 -0
  136. package/dist/registry.d.ts.map +1 -1
  137. package/dist/registry.js +7 -0
  138. package/dist/registryData.json +43 -6
  139. package/dist/report.d.ts +2 -1
  140. package/dist/report.d.ts.map +1 -1
  141. package/dist/report.js +189 -2
  142. package/dist/reporting.d.ts +125 -0
  143. package/dist/reporting.d.ts.map +1 -1
  144. package/dist/reporting.js +196 -5
  145. package/dist/resources.d.ts +285 -0
  146. package/dist/resources.d.ts.map +1 -0
  147. package/dist/resources.js +643 -0
  148. package/dist/risk.d.ts +120 -0
  149. package/dist/risk.d.ts.map +1 -0
  150. package/dist/risk.js +220 -0
  151. package/dist/runtime.d.ts +74 -1
  152. package/dist/runtime.d.ts.map +1 -1
  153. package/dist/runtime.js +598 -22
  154. package/dist/schemaInference.d.ts +92 -0
  155. package/dist/schemaInference.d.ts.map +1 -0
  156. package/dist/schemaInference.js +466 -0
  157. package/dist/schema_validation.js +2 -2
  158. package/dist/schemas/config.schema.json +169 -6
  159. package/dist/schemas/event.schema.json +4 -0
  160. package/dist/security_report.js +4 -4
  161. package/dist/signing.d.ts +1 -1
  162. package/dist/signing.d.ts.map +1 -1
  163. package/dist/signing.js +4 -0
  164. package/dist/sinks/file.d.ts +19 -1
  165. package/dist/sinks/file.d.ts.map +1 -1
  166. package/dist/sinks/file.js +82 -13
  167. package/dist/sinks/https.d.ts +10 -0
  168. package/dist/sinks/https.d.ts.map +1 -1
  169. package/dist/sinks/https.js +76 -16
  170. package/dist/sinks/stdout.d.ts +1 -0
  171. package/dist/sinks/stdout.d.ts.map +1 -1
  172. package/dist/sinks/stdout.js +12 -1
  173. package/dist/spec.d.ts +159 -0
  174. package/dist/spec.d.ts.map +1 -0
  175. package/dist/spec.js +391 -0
  176. package/dist/stakeholders.d.ts +199 -0
  177. package/dist/stakeholders.d.ts.map +1 -0
  178. package/dist/stakeholders.js +398 -0
  179. package/dist/standards.d.ts.map +1 -1
  180. package/dist/standards.js +160 -2
  181. package/dist/standards_ingest.d.ts +2 -2
  182. package/dist/standards_ingest.d.ts.map +1 -1
  183. package/dist/standards_ingest.js +105 -23
  184. package/dist/streaming.d.ts.map +1 -1
  185. package/dist/streaming.js +7 -2
  186. package/dist/telemetry.d.ts +16 -2
  187. package/dist/telemetry.d.ts.map +1 -1
  188. package/dist/telemetry.js +79 -14
  189. package/dist/templates/controls/iso42001_control_catalog.json +1443 -0
  190. package/dist/traced_emitter.d.ts +3 -0
  191. package/dist/traced_emitter.d.ts.map +1 -1
  192. package/dist/traced_emitter.js +142 -25
  193. package/dist/trust_package.d.ts +21 -1
  194. package/dist/trust_package.d.ts.map +1 -1
  195. package/dist/trust_package.js +101 -4
  196. package/dist/verify.d.ts.map +1 -1
  197. package/dist/verify.js +9 -2
  198. package/dist/wal.d.ts.map +1 -1
  199. package/dist/wal.js +2 -1
  200. package/package.json +14 -1
  201. package/scripts/postinstall.js +119 -97
  202. package/templates/controls/iso42001_control_catalog.json +1443 -0
@@ -38,40 +38,181 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  };
39
39
  })();
40
40
  Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.FRAMEWORK_WEIGHTS = void 0;
42
+ exports.getFrameworkWeights = getFrameworkWeights;
41
43
  exports.calculateComplianceScore = calculateComplianceScore;
42
44
  exports.generateExecutiveSummary = generateExecutiveSummary;
45
+ exports.generateEvidenceMapping = generateEvidenceMapping;
43
46
  exports.writeExecutiveSummary = writeExecutiveSummary;
44
47
  const fs = __importStar(require("fs"));
48
+ /**
49
+ * Default framework weights (balanced governance).
50
+ */
51
+ const DEFAULT_WEIGHTS = {
52
+ policyViolation: 10,
53
+ maxPolicyPenalty: 50,
54
+ chainIntegrityFailed: 30,
55
+ chainIntegrityDisabled: 10,
56
+ signingEnabled: 10,
57
+ signingDisabled: 5,
58
+ walEnabled: 5,
59
+ walDisabled: 5,
60
+ unknownModel: 5,
61
+ maxUnknownPenalty: 15,
62
+ dataHandlingEnabled: 0,
63
+ dataHandlingDisabled: 0,
64
+ aiActEnabled: 0,
65
+ };
66
+ /**
67
+ * Framework-specific weight profiles.
68
+ */
69
+ exports.FRAMEWORK_WEIGHTS = {
70
+ default: DEFAULT_WEIGHTS,
71
+ // SOC 2 - Emphasizes audit trails, integrity, and security controls
72
+ soc2: {
73
+ policyViolation: 12,
74
+ maxPolicyPenalty: 60,
75
+ chainIntegrityFailed: 40,
76
+ chainIntegrityDisabled: 15,
77
+ signingEnabled: 15,
78
+ signingDisabled: 10,
79
+ walEnabled: 10,
80
+ walDisabled: 5,
81
+ unknownModel: 5,
82
+ maxUnknownPenalty: 15,
83
+ dataHandlingEnabled: 5,
84
+ dataHandlingDisabled: 0,
85
+ aiActEnabled: 0,
86
+ },
87
+ // GDPR - Emphasizes data handling, PII protection, and consent
88
+ gdpr: {
89
+ policyViolation: 8,
90
+ maxPolicyPenalty: 40,
91
+ chainIntegrityFailed: 25,
92
+ chainIntegrityDisabled: 10,
93
+ signingEnabled: 5,
94
+ signingDisabled: 3,
95
+ walEnabled: 5,
96
+ walDisabled: 3,
97
+ unknownModel: 3,
98
+ maxUnknownPenalty: 10,
99
+ dataHandlingEnabled: 20,
100
+ dataHandlingDisabled: 15,
101
+ aiActEnabled: 10,
102
+ },
103
+ // HIPAA - Emphasizes encryption, access controls, and audit trails
104
+ hipaa: {
105
+ policyViolation: 15,
106
+ maxPolicyPenalty: 60,
107
+ chainIntegrityFailed: 35,
108
+ chainIntegrityDisabled: 15,
109
+ signingEnabled: 20,
110
+ signingDisabled: 15,
111
+ walEnabled: 10,
112
+ walDisabled: 5,
113
+ unknownModel: 8,
114
+ maxUnknownPenalty: 25,
115
+ dataHandlingEnabled: 15,
116
+ dataHandlingDisabled: 10,
117
+ aiActEnabled: 0,
118
+ },
119
+ // AI Act (EU) - Emphasizes transparency, human oversight, and documentation
120
+ ai_act: {
121
+ policyViolation: 10,
122
+ maxPolicyPenalty: 50,
123
+ chainIntegrityFailed: 30,
124
+ chainIntegrityDisabled: 15,
125
+ signingEnabled: 10,
126
+ signingDisabled: 5,
127
+ walEnabled: 5,
128
+ walDisabled: 3,
129
+ unknownModel: 10,
130
+ maxUnknownPenalty: 30,
131
+ dataHandlingEnabled: 10,
132
+ dataHandlingDisabled: 5,
133
+ aiActEnabled: 15,
134
+ },
135
+ // ISO 27001 - Emphasizes information security management
136
+ iso27001: {
137
+ policyViolation: 12,
138
+ maxPolicyPenalty: 55,
139
+ chainIntegrityFailed: 35,
140
+ chainIntegrityDisabled: 15,
141
+ signingEnabled: 15,
142
+ signingDisabled: 10,
143
+ walEnabled: 10,
144
+ walDisabled: 5,
145
+ unknownModel: 5,
146
+ maxUnknownPenalty: 15,
147
+ dataHandlingEnabled: 10,
148
+ dataHandlingDisabled: 5,
149
+ aiActEnabled: 0,
150
+ },
151
+ // PCI-DSS - Emphasizes payment data protection
152
+ pci_dss: {
153
+ policyViolation: 15,
154
+ maxPolicyPenalty: 60,
155
+ chainIntegrityFailed: 40,
156
+ chainIntegrityDisabled: 20,
157
+ signingEnabled: 20,
158
+ signingDisabled: 15,
159
+ walEnabled: 10,
160
+ walDisabled: 5,
161
+ unknownModel: 5,
162
+ maxUnknownPenalty: 15,
163
+ dataHandlingEnabled: 20,
164
+ dataHandlingDisabled: 15,
165
+ aiActEnabled: 0,
166
+ },
167
+ };
168
+ /**
169
+ * Get weights for a specific compliance framework.
170
+ */
171
+ function getFrameworkWeights(framework) {
172
+ if (!framework) {
173
+ return DEFAULT_WEIGHTS;
174
+ }
175
+ const normalized = framework.toLowerCase().replace(/[- ]/g, '_');
176
+ return exports.FRAMEWORK_WEIGHTS[normalized] || DEFAULT_WEIGHTS;
177
+ }
45
178
  /**
46
179
  * Calculate compliance score (0-100) based on governance controls.
47
180
  *
48
- * Scoring breakdown:
49
- * - Base score: 100
50
- * - Policy violations: -10 per violation (max -50)
51
- * - Chain integrity: -30 if failed, -10 if disabled
52
- * - Signing enabled: +10 bonus (if disabled: -5)
53
- * - WAL enabled: +5 bonus (if disabled: -5)
54
- * - Unknown models used: -5 per model (max -15)
181
+ * Scoring uses framework-specific weights when a compliance framework is specified.
182
+ * Supported frameworks: soc2, gdpr, hipaa, ai_act, iso27001, pci_dss
183
+ *
184
+ * @param report - The compliance report data
185
+ * @param chainStatus - Status of hash chain ('verified', 'failed', 'disabled')
186
+ * @param config - Monora configuration
187
+ * @param framework - Optional compliance framework for weighted scoring
55
188
  */
56
- function calculateComplianceScore(report, chainStatus, config) {
189
+ function calculateComplianceScore(report, chainStatus, config, framework) {
190
+ const weights = getFrameworkWeights(framework);
57
191
  let score = 100;
58
192
  const breakdown = {};
193
+ const applyAdjustment = (key, intended) => {
194
+ if (intended === 0) {
195
+ return;
196
+ }
197
+ const headroom = 100 - score;
198
+ const floor = 0 - score;
199
+ const applied = intended > 0 ? Math.min(intended, headroom) : Math.max(intended, floor);
200
+ breakdown[key] = applied;
201
+ score += applied;
202
+ };
59
203
  // Policy violations
60
204
  const violations = report.violations || [];
61
205
  const violationCount = violations.length;
62
- const violationPenalty = Math.min(violationCount * 10, 50);
206
+ const violationPenalty = Math.min(violationCount * weights.policyViolation, weights.maxPolicyPenalty);
63
207
  if (violationPenalty > 0) {
64
- breakdown['policy_violations'] = -violationPenalty;
65
- score -= violationPenalty;
208
+ applyAdjustment('policy_violations', -violationPenalty);
66
209
  }
67
210
  // Chain integrity
68
211
  if (chainStatus === 'failed') {
69
- breakdown['chain_integrity_failed'] = -30;
70
- score -= 30;
212
+ applyAdjustment('chain_integrity_failed', -weights.chainIntegrityFailed);
71
213
  }
72
214
  else if (chainStatus === 'disabled') {
73
- breakdown['chain_integrity_disabled'] = -10;
74
- score -= 10;
215
+ applyAdjustment('chain_integrity_disabled', -weights.chainIntegrityDisabled);
75
216
  }
76
217
  else {
77
218
  breakdown['chain_integrity_verified'] = 0;
@@ -79,30 +220,38 @@ function calculateComplianceScore(report, chainStatus, config) {
79
220
  // Signing
80
221
  const signing = config.signing || {};
81
222
  if (signing.enabled) {
82
- breakdown['signing_enabled'] = 10;
83
- score += 10;
223
+ applyAdjustment('signing_enabled', weights.signingEnabled);
84
224
  }
85
225
  else {
86
- breakdown['signing_disabled'] = -5;
87
- score -= 5;
226
+ applyAdjustment('signing_disabled', -weights.signingDisabled);
88
227
  }
89
228
  // WAL (crash resilience)
90
229
  const wal = config.wal || {};
91
230
  if (wal.enabled) {
92
- breakdown['wal_enabled'] = 5;
93
- score += 5;
231
+ applyAdjustment('wal_enabled', weights.walEnabled);
94
232
  }
95
233
  else {
96
- breakdown['wal_disabled'] = -5;
97
- score -= 5;
234
+ applyAdjustment('wal_disabled', -weights.walDisabled);
98
235
  }
99
236
  // Unknown models used
100
237
  const compliance = report.model_compliance || {};
101
238
  const unknownModels = compliance.unknown_models_used || [];
102
- const unknownPenalty = Math.min(unknownModels.length * 5, 15);
239
+ const unknownPenalty = Math.min(unknownModels.length * weights.unknownModel, weights.maxUnknownPenalty);
103
240
  if (unknownPenalty > 0) {
104
- breakdown['unknown_models'] = -unknownPenalty;
105
- score -= unknownPenalty;
241
+ applyAdjustment('unknown_models', -unknownPenalty);
242
+ }
243
+ // Data handling (framework-specific bonus/penalty)
244
+ const dataHandling = config.data_handling || {};
245
+ if (dataHandling.enabled && weights.dataHandlingEnabled > 0) {
246
+ applyAdjustment('data_handling_enabled', weights.dataHandlingEnabled);
247
+ }
248
+ else if (!dataHandling.enabled && weights.dataHandlingDisabled > 0) {
249
+ applyAdjustment('data_handling_disabled', -weights.dataHandlingDisabled);
250
+ }
251
+ // AI Act compliance (framework-specific bonus)
252
+ const aiAct = config.ai_act || {};
253
+ if (aiAct.enabled && weights.aiActEnabled > 0) {
254
+ applyAdjustment('ai_act_enabled', weights.aiActEnabled);
106
255
  }
107
256
  // Clamp score to 0-100
108
257
  score = Math.max(0, Math.min(100, score));
@@ -128,6 +277,7 @@ function calculateComplianceScore(report, chainStatus, config) {
128
277
  grade,
129
278
  breakdown,
130
279
  max_score: 100,
280
+ framework: framework || 'default',
131
281
  };
132
282
  }
133
283
  /**
@@ -342,6 +492,9 @@ function generateExecutiveSummary(report, events, chainStatus, config, traceId)
342
492
  }
343
493
  }
344
494
  lines.push('');
495
+ // Evidence Mapping Section
496
+ const evidenceLines = generateEvidenceSection(events);
497
+ lines.push(...evidenceLines);
345
498
  // Footer
346
499
  lines.push('---');
347
500
  lines.push('');
@@ -349,6 +502,116 @@ function generateExecutiveSummary(report, events, chainStatus, config, traceId)
349
502
  lines.push('');
350
503
  return lines.join('\n');
351
504
  }
505
+ /**
506
+ * Evidence mapping for compliance frameworks.
507
+ */
508
+ const CONTROL_EVENT_MAPPING = {
509
+ soc2: [
510
+ { controlId: 'CC6.1', controlName: 'Logical Access Controls', eventTypes: ['llm_call', 'tool_call'] },
511
+ { controlId: 'CC7.2', controlName: 'System Monitoring', eventTypes: ['llm_call', 'tool_call', 'agent_step'] },
512
+ { controlId: 'CC8.1', controlName: 'Change Management', eventTypes: ['policy_violation'] },
513
+ ],
514
+ gdpr: [
515
+ { controlId: 'Art.5', controlName: 'Data Processing Principles', eventTypes: ['llm_call'] },
516
+ { controlId: 'Art.25', controlName: 'Data Protection by Design', eventTypes: ['llm_call', 'tool_call'] },
517
+ { controlId: 'Art.30', controlName: 'Records of Processing', eventTypes: ['llm_call', 'tool_call', 'agent_step'] },
518
+ ],
519
+ hipaa: [
520
+ { controlId: '164.312(b)', controlName: 'Audit Controls', eventTypes: ['llm_call', 'tool_call', 'agent_step'] },
521
+ { controlId: '164.312(c)', controlName: 'Integrity Controls', eventTypes: ['llm_call'] },
522
+ { controlId: '164.312(d)', controlName: 'Authentication', eventTypes: ['llm_call', 'tool_call'] },
523
+ ],
524
+ ai_act: [
525
+ { controlId: 'Art.13', controlName: 'Transparency & Disclosure', eventTypes: ['llm_call'] },
526
+ { controlId: 'Art.14', controlName: 'Human Oversight', eventTypes: ['agent_step', 'tool_call'] },
527
+ { controlId: 'Art.17', controlName: 'Quality Management', eventTypes: ['llm_call', 'policy_violation'] },
528
+ ],
529
+ iso27001: [
530
+ { controlId: 'A.12.4', controlName: 'Logging and Monitoring', eventTypes: ['llm_call', 'tool_call', 'agent_step'] },
531
+ { controlId: 'A.12.6', controlName: 'Technical Vulnerability Management', eventTypes: ['policy_violation'] },
532
+ { controlId: 'A.14.2', controlName: 'Security in Development', eventTypes: ['llm_call', 'tool_call'] },
533
+ ],
534
+ iso42001: [
535
+ { controlId: '6.1.2', controlName: 'AI Risk Assessment', eventTypes: ['llm_call', 'policy_violation'] },
536
+ { controlId: '8.4', controlName: 'AI System Development', eventTypes: ['llm_call', 'tool_call', 'agent_step'] },
537
+ { controlId: '9.1', controlName: 'Monitoring & Measurement', eventTypes: ['llm_call', 'tool_call'] },
538
+ ],
539
+ };
540
+ /**
541
+ * Generate evidence mapping for compliance controls.
542
+ */
543
+ function generateEvidenceMapping(events, framework) {
544
+ const evidence = [];
545
+ // Count events by type
546
+ const eventsByType = {};
547
+ for (const event of events) {
548
+ const eventType = event.event_type || 'unknown';
549
+ if (!eventsByType[eventType]) {
550
+ eventsByType[eventType] = [];
551
+ }
552
+ eventsByType[eventType].push(event);
553
+ }
554
+ // Get frameworks to process
555
+ const frameworksToProcess = framework
556
+ ? [framework.toLowerCase().replace(/[- ]/g, '_')]
557
+ : Object.keys(CONTROL_EVENT_MAPPING);
558
+ for (const fw of frameworksToProcess) {
559
+ const controls = CONTROL_EVENT_MAPPING[fw];
560
+ if (!controls)
561
+ continue;
562
+ for (const control of controls) {
563
+ let totalCount = 0;
564
+ const sampleIds = [];
565
+ for (const eventType of control.eventTypes) {
566
+ const matchingEvents = eventsByType[eventType] || [];
567
+ totalCount += matchingEvents.length;
568
+ // Collect sample event IDs (up to 3 per control)
569
+ for (const evt of matchingEvents.slice(0, 3 - sampleIds.length)) {
570
+ if (evt.event_id && sampleIds.length < 3) {
571
+ sampleIds.push(evt.event_id);
572
+ }
573
+ }
574
+ }
575
+ if (totalCount > 0) {
576
+ evidence.push({
577
+ controlId: control.controlId,
578
+ controlName: control.controlName,
579
+ framework: fw.toUpperCase().replace(/_/g, ' '),
580
+ eventTypes: control.eventTypes,
581
+ eventCount: totalCount,
582
+ sampleEventIds: sampleIds,
583
+ });
584
+ }
585
+ }
586
+ }
587
+ return evidence;
588
+ }
589
+ /**
590
+ * Generate evidence section for executive summary.
591
+ */
592
+ function generateEvidenceSection(events, framework) {
593
+ const lines = [];
594
+ const evidence = generateEvidenceMapping(events, framework);
595
+ if (evidence.length === 0) {
596
+ return lines;
597
+ }
598
+ lines.push('---');
599
+ lines.push('');
600
+ lines.push('## Compliance Evidence Mapping');
601
+ lines.push('');
602
+ lines.push('Events linked to specific compliance controls:');
603
+ lines.push('');
604
+ lines.push('| Framework | Control ID | Control Name | Events | Sample IDs |');
605
+ lines.push('|-----------|------------|--------------|--------|------------|');
606
+ for (const item of evidence) {
607
+ const sampleIds = item.sampleEventIds.length > 0
608
+ ? item.sampleEventIds.map(id => `\`${id.slice(0, 12)}...\``).join(', ')
609
+ : '-';
610
+ lines.push(`| ${item.framework} | ${item.controlId} | ${item.controlName} | ${item.eventCount} | ${sampleIds} |`);
611
+ }
612
+ lines.push('');
613
+ return lines;
614
+ }
352
615
  /**
353
616
  * Write executive summary to a file.
354
617
  */
@@ -0,0 +1,143 @@
1
+ /**
2
+ * User/identity tracking for SOC 2 CC6 access control compliance.
3
+ *
4
+ * This module provides identity context management for tracking who invoked
5
+ * each AI call, supporting SOC 2 access control audit trails.
6
+ *
7
+ * Cross-SDK Parity:
8
+ * Both Python and Node.js SDKs provide identical identity tracking APIs:
9
+ * - setIdentity() / set_identity()
10
+ * - getIdentity() / get_identity()
11
+ * - clearIdentity() / clear_identity()
12
+ * - withIdentity() / identity_context()
13
+ */
14
+ import { MonoraConfig } from './config';
15
+ /**
16
+ * Represents a user/system identity for audit tracking.
17
+ */
18
+ export interface Identity {
19
+ /** Unique identifier for the user (required if identity.require_user_id is True). */
20
+ userId: string;
21
+ /** Optional session identifier for grouping related calls. */
22
+ sessionId?: string;
23
+ /** Authentication method used (oauth2, api_key, jwt, etc.). */
24
+ authMethod?: string;
25
+ /** List of roles assigned to the user. */
26
+ roles?: string[];
27
+ /** Organization identifier for multi-tenant systems. */
28
+ orgId?: string;
29
+ /** Additional custom identity metadata. */
30
+ metadata?: Record<string, any>;
31
+ }
32
+ /**
33
+ * Options for converting identity to dict.
34
+ */
35
+ export interface IdentityToDictOptions {
36
+ /** Include roles array in output. */
37
+ includeRoles?: boolean;
38
+ /** Include org_id in output. */
39
+ includeOrg?: boolean;
40
+ /** Hash user_id for privacy (SHA-256). */
41
+ redactUserId?: boolean;
42
+ }
43
+ /**
44
+ * Convert identity to dictionary for event inclusion.
45
+ *
46
+ * @param identity - The identity object.
47
+ * @param options - Conversion options.
48
+ * @returns Dictionary representation of identity.
49
+ */
50
+ export declare function identityToDict(identity: Identity, options?: IdentityToDictOptions): Record<string, any>;
51
+ /**
52
+ * Set the current identity context.
53
+ *
54
+ * All subsequent events will include this identity information until
55
+ * clearIdentity() is called or the context exits.
56
+ *
57
+ * Note: This sets identity in the current async context. For scoped identity,
58
+ * use withIdentity() instead.
59
+ *
60
+ * @param identity - The identity to set.
61
+ * @returns The identity object.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * setIdentity({ userId: 'usr_123', sessionId: 'sess_456', roles: ['admin'] });
66
+ * // All subsequent AI calls will include identity
67
+ * await llmCall(...);
68
+ * ```
69
+ */
70
+ export declare function setIdentity(identity: Identity): Identity;
71
+ /**
72
+ * Get the current identity from context.
73
+ *
74
+ * @returns The current Identity object, or undefined if not set.
75
+ */
76
+ export declare function getIdentity(): Identity | undefined;
77
+ /**
78
+ * Clear the current identity context.
79
+ */
80
+ export declare function clearIdentity(): void;
81
+ /**
82
+ * Run a function within a specific identity context.
83
+ *
84
+ * The identity is automatically cleared when the function completes.
85
+ *
86
+ * @param identity - The identity to use.
87
+ * @param fn - The function to execute.
88
+ * @returns The result of the function.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * await withIdentity({ userId: 'usr_789', roles: ['analyst'] }, async () => {
93
+ * await llmCall(...); // Includes identity
94
+ * });
95
+ * // Identity cleared after function completes
96
+ * ```
97
+ */
98
+ export declare function withIdentity<T>(identity: Identity, fn: () => T): T;
99
+ /**
100
+ * Async version of withIdentity for async functions.
101
+ *
102
+ * @param identity - The identity to use.
103
+ * @param fn - The async function to execute.
104
+ * @returns Promise resolving to the result of the function.
105
+ */
106
+ export declare function withIdentityAsync<T>(identity: Identity, fn: () => Promise<T>): Promise<T>;
107
+ /**
108
+ * Bind a function to the current identity context.
109
+ *
110
+ * The returned function, when called, will execute with the captured
111
+ * identity context regardless of where it's called from.
112
+ *
113
+ * @param fn - The function to bind to the current identity.
114
+ * @returns A wrapped function that will execute with the captured identity.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * setIdentity({ userId: 'usr_123' });
119
+ * const boundCallback = bindIdentity(myCallback);
120
+ * // Call from anywhere - identity is preserved
121
+ * boundCallback();
122
+ * ```
123
+ */
124
+ export declare function bindIdentity<T extends (...args: any[]) => any>(fn: T): T;
125
+ /**
126
+ * Get identity dict for event inclusion based on config.
127
+ *
128
+ * This is called internally when building events to include identity
129
+ * information according to the configuration settings.
130
+ *
131
+ * @param config - The Monora configuration.
132
+ * @returns Identity dict for event inclusion, or undefined if identity not set
133
+ * or identity tracking is disabled.
134
+ */
135
+ export declare function getIdentityForEvent(config: MonoraConfig): Record<string, any> | undefined;
136
+ /**
137
+ * Validate that identity is set if required by config.
138
+ *
139
+ * @param config - The Monora configuration.
140
+ * @throws Error if require_user_id is true but no identity is set.
141
+ */
142
+ export declare function validateIdentityRequirement(config: MonoraConfig): void;
143
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qCAAqC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gCAAgC;IAChC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAgCrB;AAKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAIxD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAElD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAElE;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAQxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,GACnB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAgBjC;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAetE"}