monora-ai 2.1.0 → 2.1.4

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 (193) hide show
  1. package/README.md +339 -158
  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 +85 -0
  12. package/dist/assessment.d.ts.map +1 -1
  13. package/dist/assessment.js +525 -13
  14. package/dist/attribution.d.ts +44 -3
  15. package/dist/attribution.d.ts.map +1 -1
  16. package/dist/attribution.js +197 -10
  17. package/dist/autodetect.d.ts +68 -0
  18. package/dist/autodetect.d.ts.map +1 -1
  19. package/dist/autodetect.js +639 -0
  20. package/dist/bias.d.ts +130 -0
  21. package/dist/bias.d.ts.map +1 -0
  22. package/dist/bias.js +223 -0
  23. package/dist/cli/diagnostics.d.ts +5 -1
  24. package/dist/cli/diagnostics.d.ts.map +1 -1
  25. package/dist/cli/diagnostics.js +23 -6
  26. package/dist/cli/doctor.d.ts +25 -0
  27. package/dist/cli/doctor.d.ts.map +1 -0
  28. package/dist/cli/doctor.js +381 -0
  29. package/dist/cli/fix.d.ts +16 -0
  30. package/dist/cli/fix.d.ts.map +1 -0
  31. package/dist/cli/fix.js +284 -0
  32. package/dist/cli/init.d.ts +57 -0
  33. package/dist/cli/init.d.ts.map +1 -0
  34. package/dist/cli/init.js +205 -0
  35. package/dist/cli.js +1564 -177
  36. package/dist/complianceConsolidation.d.ts +17 -0
  37. package/dist/complianceConsolidation.d.ts.map +1 -0
  38. package/dist/complianceConsolidation.js +68 -0
  39. package/dist/complianceTargets.d.ts +111 -0
  40. package/dist/complianceTargets.d.ts.map +1 -0
  41. package/dist/complianceTargets.js +521 -0
  42. package/dist/config.d.ts +261 -16
  43. package/dist/config.d.ts.map +1 -1
  44. package/dist/config.js +381 -32
  45. package/dist/config_migrations.d.ts.map +1 -1
  46. package/dist/config_migrations.js +38 -1
  47. package/dist/config_schema.d.ts +2490 -1035
  48. package/dist/config_schema.d.ts.map +1 -1
  49. package/dist/config_schema.js +233 -64
  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 +128 -0
  54. package/dist/control_backbone.d.ts.map +1 -0
  55. package/dist/control_backbone.js +826 -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.map +1 -1
  63. package/dist/dispatcher.js +17 -5
  64. package/dist/evidence_store.d.ts +103 -0
  65. package/dist/evidence_store.d.ts.map +1 -0
  66. package/dist/evidence_store.js +459 -0
  67. package/dist/executiveSummary.d.ts +15 -0
  68. package/dist/executiveSummary.d.ts.map +1 -1
  69. package/dist/executiveSummary.js +135 -22
  70. package/dist/identity.d.ts +143 -0
  71. package/dist/identity.d.ts.map +1 -0
  72. package/dist/identity.js +231 -0
  73. package/dist/impact-assessment.d.ts +350 -0
  74. package/dist/impact-assessment.d.ts.map +1 -0
  75. package/dist/impact-assessment.js +580 -0
  76. package/dist/index.d.ts +21 -4
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +254 -5
  79. package/dist/instrumentation.d.ts +1 -1
  80. package/dist/instrumentation.d.ts.map +1 -1
  81. package/dist/instrumentation.js +123 -22
  82. package/dist/integrations/anthropic.d.ts +3 -0
  83. package/dist/integrations/anthropic.d.ts.map +1 -1
  84. package/dist/integrations/anthropic.js +282 -80
  85. package/dist/integrations/governance.d.ts +33 -0
  86. package/dist/integrations/governance.d.ts.map +1 -0
  87. package/dist/integrations/governance.js +208 -0
  88. package/dist/integrations/langchain.d.ts +4 -0
  89. package/dist/integrations/langchain.d.ts.map +1 -1
  90. package/dist/integrations/langchain.js +362 -142
  91. package/dist/integrations/openai.d.ts +9 -0
  92. package/dist/integrations/openai.d.ts.map +1 -1
  93. package/dist/integrations/openai.js +673 -73
  94. package/dist/iso42001_consolidation.d.ts +16 -0
  95. package/dist/iso42001_consolidation.d.ts.map +1 -0
  96. package/dist/iso42001_consolidation.js +413 -0
  97. package/dist/iso42001_workflows.d.ts +263 -0
  98. package/dist/iso42001_workflows.d.ts.map +1 -0
  99. package/dist/iso42001_workflows.js +781 -0
  100. package/dist/lifecycle.d.ts +299 -0
  101. package/dist/lifecycle.d.ts.map +1 -0
  102. package/dist/lifecycle.js +624 -0
  103. package/dist/lineage.d.ts +2 -2
  104. package/dist/lineage.d.ts.map +1 -1
  105. package/dist/lineage.js +9 -16
  106. package/dist/middleware/express.d.ts.map +1 -1
  107. package/dist/middleware/express.js +18 -3
  108. package/dist/middleware/nextjs.js +2 -2
  109. package/dist/model.d.ts +143 -0
  110. package/dist/model.d.ts.map +1 -0
  111. package/dist/model.js +371 -0
  112. package/dist/onboarding.d.ts +42 -0
  113. package/dist/onboarding.d.ts.map +1 -0
  114. package/dist/onboarding.js +1075 -0
  115. package/dist/oversight.d.ts +264 -0
  116. package/dist/oversight.d.ts.map +1 -0
  117. package/dist/oversight.js +497 -0
  118. package/dist/presets.js +7 -7
  119. package/dist/quotas.d.ts +171 -0
  120. package/dist/quotas.d.ts.map +1 -0
  121. package/dist/quotas.js +259 -0
  122. package/dist/register.d.ts +13 -0
  123. package/dist/register.d.ts.map +1 -0
  124. package/dist/register.js +99 -0
  125. package/dist/registry.d.ts +1 -0
  126. package/dist/registry.d.ts.map +1 -1
  127. package/dist/registry.js +7 -0
  128. package/dist/registryData.json +43 -6
  129. package/dist/report.d.ts +2 -1
  130. package/dist/report.d.ts.map +1 -1
  131. package/dist/report.js +189 -2
  132. package/dist/reporting.d.ts +125 -0
  133. package/dist/reporting.d.ts.map +1 -1
  134. package/dist/reporting.js +192 -2
  135. package/dist/resources.d.ts +285 -0
  136. package/dist/resources.d.ts.map +1 -0
  137. package/dist/resources.js +643 -0
  138. package/dist/risk.d.ts +120 -0
  139. package/dist/risk.d.ts.map +1 -0
  140. package/dist/risk.js +220 -0
  141. package/dist/runtime.d.ts +74 -0
  142. package/dist/runtime.d.ts.map +1 -1
  143. package/dist/runtime.js +416 -18
  144. package/dist/schemaInference.d.ts +92 -0
  145. package/dist/schemaInference.d.ts.map +1 -0
  146. package/dist/schemaInference.js +466 -0
  147. package/dist/schema_validation.js +2 -2
  148. package/dist/schemas/config.schema.json +118 -4
  149. package/dist/security_report.js +4 -4
  150. package/dist/signing.d.ts +1 -1
  151. package/dist/signing.d.ts.map +1 -1
  152. package/dist/signing.js +4 -0
  153. package/dist/sinks/file.d.ts +19 -1
  154. package/dist/sinks/file.d.ts.map +1 -1
  155. package/dist/sinks/file.js +82 -13
  156. package/dist/sinks/https.d.ts +10 -0
  157. package/dist/sinks/https.d.ts.map +1 -1
  158. package/dist/sinks/https.js +76 -16
  159. package/dist/sinks/stdout.d.ts +1 -0
  160. package/dist/sinks/stdout.d.ts.map +1 -1
  161. package/dist/sinks/stdout.js +12 -1
  162. package/dist/spec.d.ts +159 -0
  163. package/dist/spec.d.ts.map +1 -0
  164. package/dist/spec.js +391 -0
  165. package/dist/stakeholders.d.ts +199 -0
  166. package/dist/stakeholders.d.ts.map +1 -0
  167. package/dist/stakeholders.js +398 -0
  168. package/dist/standards.d.ts.map +1 -1
  169. package/dist/standards.js +160 -2
  170. package/dist/standards_ingest.d.ts.map +1 -1
  171. package/dist/standards_ingest.js +1 -4
  172. package/dist/telemetry.d.ts +16 -2
  173. package/dist/telemetry.d.ts.map +1 -1
  174. package/dist/telemetry.js +77 -14
  175. package/dist/templates/controls/gdpr_control_catalog.json +261 -0
  176. package/dist/templates/controls/iso42001_control_catalog.json +1443 -0
  177. package/dist/templates/controls/soc2_control_catalog.json +163 -0
  178. package/dist/templates/standards/iso42001_claims.json +72 -0
  179. package/dist/traced_emitter.d.ts.map +1 -1
  180. package/dist/traced_emitter.js +19 -9
  181. package/dist/trust_package.d.ts +20 -1
  182. package/dist/trust_package.d.ts.map +1 -1
  183. package/dist/trust_package.js +90 -2
  184. package/dist/verify.d.ts.map +1 -1
  185. package/dist/verify.js +9 -2
  186. package/dist/wal.d.ts.map +1 -1
  187. package/dist/wal.js +2 -1
  188. package/package.json +14 -1
  189. package/scripts/postinstall.js +105 -210
  190. package/templates/controls/gdpr_control_catalog.json +261 -0
  191. package/templates/controls/iso42001_control_catalog.json +1443 -0
  192. package/templates/controls/soc2_control_catalog.json +163 -0
  193. package/templates/standards/iso42001_claims.json +72 -0
@@ -0,0 +1,497 @@
1
+ "use strict";
2
+ /**
3
+ * Human oversight tracking for EU AI Act Art.14 and ISO 42001 8.3 compliance.
4
+ *
5
+ * This module provides human review and override tracking for AI decisions,
6
+ * supporting EU AI Act Article 14 human oversight requirements and ISO 42001
7
+ * control 8.3.
8
+ *
9
+ * Cross-SDK Parity:
10
+ * Both Python and Node.js SDKs provide identical human oversight APIs:
11
+ * - recordHumanReview() / record_human_review()
12
+ * - recordHumanOverride() / record_human_override()
13
+ * - getPendingReviews() / get_pending_reviews()
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.SqliteReviewStore = exports.MemoryReviewStore = void 0;
50
+ exports.reviewToEventBody = reviewToEventBody;
51
+ exports.overrideToEventBody = overrideToEventBody;
52
+ exports.setReviewStore = setReviewStore;
53
+ exports.recordHumanReview = recordHumanReview;
54
+ exports.recordHumanOverride = recordHumanOverride;
55
+ exports.requireReview = requireReview;
56
+ exports.getPendingReviews = getPendingReviews;
57
+ exports.getTimedOutReviews = getTimedOutReviews;
58
+ exports.checkReviewRequired = checkReviewRequired;
59
+ exports.getOversightSummary = getOversightSummary;
60
+ exports.clearOversightData = clearOversightData;
61
+ const crypto = __importStar(require("crypto"));
62
+ /**
63
+ * Convert HumanReview to event body dictionary.
64
+ */
65
+ function reviewToEventBody(review) {
66
+ const body = {
67
+ reviewed_event_id: review.reviewedEventId,
68
+ reviewer_id: review.reviewerId,
69
+ review_type: review.reviewType,
70
+ decision: review.decision,
71
+ timestamp: review.timestamp,
72
+ };
73
+ if (review.modifications) {
74
+ body.modifications = review.modifications;
75
+ }
76
+ if (review.reviewDurationMs !== undefined) {
77
+ body.review_duration_ms = review.reviewDurationMs;
78
+ }
79
+ if (review.reviewNotes) {
80
+ body.review_notes = review.reviewNotes;
81
+ }
82
+ if (review.complianceFlags.length > 0) {
83
+ body.compliance_flags = review.complianceFlags;
84
+ }
85
+ return body;
86
+ }
87
+ /**
88
+ * Convert HumanOverride to event body dictionary.
89
+ */
90
+ function overrideToEventBody(override) {
91
+ const body = {
92
+ overridden_event_id: override.overriddenEventId,
93
+ override_reason: override.overrideReason,
94
+ timestamp: override.timestamp,
95
+ };
96
+ if (override.originalOutputHash) {
97
+ body.original_output_hash = override.originalOutputHash;
98
+ }
99
+ if (override.correctedOutputHash) {
100
+ body.corrected_output_hash = override.correctedOutputHash;
101
+ }
102
+ if (override.overrideAuthority) {
103
+ body.override_authority = override.overrideAuthority;
104
+ }
105
+ return body;
106
+ }
107
+ const DEFAULT_COMPLETED_REVIEW_TTL_MS = 30 * 24 * 60 * 60 * 1000;
108
+ /**
109
+ * In-memory store for oversight reviews.
110
+ *
111
+ * Note: This is single-instance only. For production/distributed use, supply
112
+ * a persistent store via setReviewStore (e.g., SqliteReviewStore or Redis).
113
+ */
114
+ class MemoryReviewStore {
115
+ constructor(options) {
116
+ this.pendingReviews = new Map();
117
+ this.completedReviews = [];
118
+ this.overrides = [];
119
+ this.completedTtlMs = options?.completedTtlMs ?? DEFAULT_COMPLETED_REVIEW_TTL_MS;
120
+ }
121
+ addPendingReview(review) {
122
+ this.pendingReviews.set(review.eventId, review);
123
+ }
124
+ removePendingReview(eventId) {
125
+ this.pendingReviews.delete(eventId);
126
+ }
127
+ listPendingReviews() {
128
+ return Array.from(this.pendingReviews.values());
129
+ }
130
+ listTimedOutReviews(now) {
131
+ return this.listPendingReviews().filter((review) => review.timeoutAt < now);
132
+ }
133
+ addCompletedReview(review) {
134
+ this.pruneCompletedReviews(Date.now());
135
+ this.completedReviews.push(review);
136
+ }
137
+ listCompletedReviews() {
138
+ this.pruneCompletedReviews(Date.now());
139
+ return [...this.completedReviews];
140
+ }
141
+ addOverride(override) {
142
+ this.overrides.push(override);
143
+ }
144
+ listOverrides() {
145
+ return [...this.overrides];
146
+ }
147
+ clear() {
148
+ this.pendingReviews.clear();
149
+ this.completedReviews = [];
150
+ this.overrides = [];
151
+ }
152
+ pruneCompletedReviews(now) {
153
+ if (this.completedTtlMs <= 0) {
154
+ return;
155
+ }
156
+ const cutoff = now - this.completedTtlMs;
157
+ this.completedReviews = this.completedReviews.filter((review) => {
158
+ const timestampMs = Date.parse(review.timestamp);
159
+ if (Number.isNaN(timestampMs)) {
160
+ return true;
161
+ }
162
+ return timestampMs >= cutoff;
163
+ });
164
+ }
165
+ }
166
+ exports.MemoryReviewStore = MemoryReviewStore;
167
+ /**
168
+ * SQLite-backed persistent review store (requires better-sqlite3).
169
+ */
170
+ class SqliteReviewStore {
171
+ constructor(dbPath, options) {
172
+ let Database;
173
+ try {
174
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
175
+ Database = require('better-sqlite3');
176
+ }
177
+ catch (error) {
178
+ const message = error instanceof Error ? error.message : String(error);
179
+ throw new Error(`SqliteReviewStore requires better-sqlite3. ${message}`);
180
+ }
181
+ this.db = new Database(dbPath);
182
+ this.completedTtlMs = options?.completedTtlMs ?? DEFAULT_COMPLETED_REVIEW_TTL_MS;
183
+ this.db.exec(`
184
+ CREATE TABLE IF NOT EXISTS pending_reviews (
185
+ event_id TEXT PRIMARY KEY,
186
+ trace_id TEXT,
187
+ event_type TEXT,
188
+ model TEXT,
189
+ risk_level TEXT,
190
+ created_at INTEGER,
191
+ timeout_at INTEGER
192
+ );
193
+ CREATE TABLE IF NOT EXISTS completed_reviews (
194
+ reviewed_event_id TEXT,
195
+ reviewer_id TEXT,
196
+ review_type TEXT,
197
+ decision TEXT,
198
+ modifications TEXT,
199
+ review_duration_ms INTEGER,
200
+ review_notes TEXT,
201
+ compliance_flags TEXT,
202
+ timestamp TEXT,
203
+ timestamp_ms INTEGER
204
+ );
205
+ CREATE TABLE IF NOT EXISTS overrides (
206
+ overridden_event_id TEXT,
207
+ override_reason TEXT,
208
+ original_output_hash TEXT,
209
+ corrected_output_hash TEXT,
210
+ override_authority TEXT,
211
+ timestamp TEXT
212
+ );
213
+ `);
214
+ }
215
+ addPendingReview(review) {
216
+ this.db.prepare(`
217
+ INSERT OR REPLACE INTO pending_reviews
218
+ (event_id, trace_id, event_type, model, risk_level, created_at, timeout_at)
219
+ VALUES (?, ?, ?, ?, ?, ?, ?)
220
+ `).run(review.eventId, review.traceId ?? null, review.eventType, review.model ?? null, review.riskLevel ?? null, review.createdAt, review.timeoutAt);
221
+ }
222
+ removePendingReview(eventId) {
223
+ this.db.prepare('DELETE FROM pending_reviews WHERE event_id = ?').run(eventId);
224
+ }
225
+ listPendingReviews() {
226
+ const rows = this.db.prepare('SELECT * FROM pending_reviews').all();
227
+ return rows.map((row) => ({
228
+ eventId: row.event_id,
229
+ traceId: row.trace_id ?? undefined,
230
+ eventType: row.event_type,
231
+ model: row.model ?? undefined,
232
+ riskLevel: row.risk_level ?? undefined,
233
+ createdAt: row.created_at,
234
+ timeoutAt: row.timeout_at,
235
+ }));
236
+ }
237
+ listTimedOutReviews(now) {
238
+ const rows = this.db
239
+ .prepare('SELECT * FROM pending_reviews WHERE timeout_at < ?')
240
+ .all(now);
241
+ return rows.map((row) => ({
242
+ eventId: row.event_id,
243
+ traceId: row.trace_id ?? undefined,
244
+ eventType: row.event_type,
245
+ model: row.model ?? undefined,
246
+ riskLevel: row.risk_level ?? undefined,
247
+ createdAt: row.created_at,
248
+ timeoutAt: row.timeout_at,
249
+ }));
250
+ }
251
+ addCompletedReview(review) {
252
+ const timestampMs = Date.parse(review.timestamp);
253
+ this.db.prepare(`
254
+ INSERT INTO completed_reviews
255
+ (reviewed_event_id, reviewer_id, review_type, decision, modifications, review_duration_ms,
256
+ review_notes, compliance_flags, timestamp, timestamp_ms)
257
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
258
+ `).run(review.reviewedEventId, review.reviewerId, review.reviewType, review.decision, review.modifications ?? null, review.reviewDurationMs ?? null, review.reviewNotes ?? null, JSON.stringify(review.complianceFlags || []), review.timestamp, Number.isNaN(timestampMs) ? null : timestampMs);
259
+ this.pruneCompletedReviews(Date.now());
260
+ }
261
+ listCompletedReviews() {
262
+ this.pruneCompletedReviews(Date.now());
263
+ const rows = this.db.prepare('SELECT * FROM completed_reviews').all();
264
+ return rows.map((row) => ({
265
+ reviewedEventId: row.reviewed_event_id,
266
+ reviewerId: row.reviewer_id,
267
+ reviewType: row.review_type,
268
+ decision: row.decision,
269
+ modifications: row.modifications ?? undefined,
270
+ reviewDurationMs: row.review_duration_ms ?? undefined,
271
+ reviewNotes: row.review_notes ?? undefined,
272
+ complianceFlags: this.parseComplianceFlags(row.compliance_flags),
273
+ timestamp: row.timestamp,
274
+ }));
275
+ }
276
+ addOverride(override) {
277
+ this.db.prepare(`
278
+ INSERT INTO overrides
279
+ (overridden_event_id, override_reason, original_output_hash, corrected_output_hash,
280
+ override_authority, timestamp)
281
+ VALUES (?, ?, ?, ?, ?, ?)
282
+ `).run(override.overriddenEventId, override.overrideReason, override.originalOutputHash ?? null, override.correctedOutputHash ?? null, override.overrideAuthority ?? null, override.timestamp);
283
+ }
284
+ listOverrides() {
285
+ const rows = this.db.prepare('SELECT * FROM overrides').all();
286
+ return rows.map((row) => ({
287
+ overriddenEventId: row.overridden_event_id,
288
+ overrideReason: row.override_reason,
289
+ originalOutputHash: row.original_output_hash ?? undefined,
290
+ correctedOutputHash: row.corrected_output_hash ?? undefined,
291
+ overrideAuthority: row.override_authority ?? undefined,
292
+ timestamp: row.timestamp,
293
+ }));
294
+ }
295
+ clear() {
296
+ this.db.exec('DELETE FROM pending_reviews; DELETE FROM completed_reviews; DELETE FROM overrides;');
297
+ }
298
+ pruneCompletedReviews(now) {
299
+ if (this.completedTtlMs <= 0) {
300
+ return;
301
+ }
302
+ const cutoff = now - this.completedTtlMs;
303
+ this.db.prepare('DELETE FROM completed_reviews WHERE timestamp_ms IS NOT NULL AND timestamp_ms < ?')
304
+ .run(cutoff);
305
+ }
306
+ parseComplianceFlags(value) {
307
+ if (!value) {
308
+ return [];
309
+ }
310
+ try {
311
+ const parsed = JSON.parse(value);
312
+ return Array.isArray(parsed) ? parsed : [];
313
+ }
314
+ catch {
315
+ return [];
316
+ }
317
+ }
318
+ }
319
+ exports.SqliteReviewStore = SqliteReviewStore;
320
+ let reviewStore = new MemoryReviewStore();
321
+ function setReviewStore(store) {
322
+ reviewStore = store;
323
+ }
324
+ /**
325
+ * Record a human review of an AI decision.
326
+ *
327
+ * @param reviewedEventId - ID of the event being reviewed.
328
+ * @param reviewerId - ID of the human reviewer.
329
+ * @param reviewType - Type of review (approval, rejection, modification, escalation).
330
+ * @param decision - Review decision (approved, rejected, modified, escalated).
331
+ * @param options - Additional options.
332
+ * @returns The created HumanReview.
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * recordHumanReview(
337
+ * 'evt_123',
338
+ * 'usr_456',
339
+ * 'approval',
340
+ * 'approved',
341
+ * { notes: 'Verified output accuracy' }
342
+ * );
343
+ * ```
344
+ */
345
+ function recordHumanReview(reviewedEventId, reviewerId, reviewType, decision, options = {}) {
346
+ const review = {
347
+ reviewedEventId,
348
+ reviewerId,
349
+ reviewType,
350
+ decision,
351
+ modifications: options.modifications,
352
+ reviewDurationMs: options.reviewDurationMs,
353
+ reviewNotes: options.notes,
354
+ complianceFlags: options.complianceFlags || [],
355
+ timestamp: new Date().toISOString(),
356
+ };
357
+ reviewStore.addCompletedReview(review);
358
+ reviewStore.removePendingReview(reviewedEventId);
359
+ return review;
360
+ }
361
+ /**
362
+ * Record a human override of an AI output.
363
+ *
364
+ * @param overriddenEventId - ID of the event being overridden.
365
+ * @param overrideReason - Reason for the override.
366
+ * @param options - Additional options.
367
+ * @returns The created HumanOverride.
368
+ *
369
+ * @example
370
+ * ```typescript
371
+ * recordHumanOverride(
372
+ * 'evt_123',
373
+ * 'Incorrect recommendation',
374
+ * { overrideAuthority: 'supervisor' }
375
+ * );
376
+ * ```
377
+ */
378
+ function recordHumanOverride(overriddenEventId, overrideReason, options = {}) {
379
+ let originalHash;
380
+ let correctedHash;
381
+ if (options.originalOutput) {
382
+ const hash = crypto.createHash('sha256').update(options.originalOutput).digest('hex');
383
+ originalHash = `sha256:${hash}`;
384
+ }
385
+ if (options.correctedOutput) {
386
+ const hash = crypto.createHash('sha256').update(options.correctedOutput).digest('hex');
387
+ correctedHash = `sha256:${hash}`;
388
+ }
389
+ const override = {
390
+ overriddenEventId,
391
+ overrideReason,
392
+ originalOutputHash: originalHash,
393
+ correctedOutputHash: correctedHash,
394
+ overrideAuthority: options.overrideAuthority,
395
+ timestamp: new Date().toISOString(),
396
+ };
397
+ reviewStore.addOverride(override);
398
+ return override;
399
+ }
400
+ /**
401
+ * Mark an event as requiring human review.
402
+ *
403
+ * @param eventId - ID of the event requiring review.
404
+ * @param options - Additional options.
405
+ * @returns The created PendingReview.
406
+ */
407
+ function requireReview(eventId, options = {}) {
408
+ const config = options.config || {};
409
+ const oversightConfig = config.human_oversight || {};
410
+ const timeoutHours = oversightConfig.review_timeout_hours ?? 24;
411
+ const now = Date.now();
412
+ const pending = {
413
+ eventId,
414
+ traceId: options.traceId,
415
+ eventType: options.eventType || 'llm_call',
416
+ model: options.model,
417
+ riskLevel: options.riskLevel,
418
+ createdAt: now,
419
+ timeoutAt: now + timeoutHours * 3600 * 1000,
420
+ };
421
+ reviewStore.addPendingReview(pending);
422
+ return pending;
423
+ }
424
+ /**
425
+ * Get all events pending human review.
426
+ */
427
+ function getPendingReviews() {
428
+ return reviewStore.listPendingReviews();
429
+ }
430
+ /**
431
+ * Get reviews that have timed out.
432
+ */
433
+ function getTimedOutReviews() {
434
+ return reviewStore.listTimedOutReviews(Date.now());
435
+ }
436
+ /**
437
+ * Check if an event requires human review based on config.
438
+ *
439
+ * @param eventType - Type of event.
440
+ * @param model - Model used.
441
+ * @param riskLevel - Risk level of the event.
442
+ * @param config - Optional config.
443
+ * @returns True if review is required.
444
+ */
445
+ function checkReviewRequired(eventType, model, riskLevel, config) {
446
+ const oversightConfig = config?.human_oversight;
447
+ if (!oversightConfig?.enabled) {
448
+ return false;
449
+ }
450
+ const requireFor = oversightConfig.require_review_for || [];
451
+ if (requireFor.length === 0) {
452
+ return false;
453
+ }
454
+ for (const condition of requireFor) {
455
+ if (condition.risk_level && riskLevel !== condition.risk_level) {
456
+ continue;
457
+ }
458
+ if (condition.event_type && eventType !== condition.event_type) {
459
+ continue;
460
+ }
461
+ if (condition.tool_name && model !== condition.tool_name) {
462
+ continue;
463
+ }
464
+ return true;
465
+ }
466
+ return false;
467
+ }
468
+ /**
469
+ * Get summary of human oversight for reporting.
470
+ *
471
+ * @returns Summary dict for compliance reports.
472
+ */
473
+ function getOversightSummary() {
474
+ const completed = reviewStore.listCompletedReviews();
475
+ const pending = reviewStore.listPendingReviews();
476
+ const overrides = reviewStore.listOverrides();
477
+ const timedOut = reviewStore.listTimedOutReviews(Date.now());
478
+ const reviewTimes = completed
479
+ .filter((r) => r.reviewDurationMs !== undefined)
480
+ .map((r) => r.reviewDurationMs);
481
+ const avgReviewTime = reviewTimes.length > 0
482
+ ? reviewTimes.reduce((a, b) => a + b, 0) / reviewTimes.length
483
+ : null;
484
+ return {
485
+ reviews_completed: completed.length,
486
+ reviews_pending: pending.length,
487
+ overrides: overrides.length,
488
+ average_review_time_ms: avgReviewTime,
489
+ timed_out_reviews: timedOut.length,
490
+ };
491
+ }
492
+ /**
493
+ * Clear all oversight tracking data.
494
+ */
495
+ function clearOversightData() {
496
+ reviewStore.clear();
497
+ }
package/dist/presets.js CHANGED
@@ -63,7 +63,7 @@ exports.DEVELOPMENT = {
63
63
  telemetry: {
64
64
  enabled: false,
65
65
  send_data: false,
66
- data_residency: 'none',
66
+ data_residency: null,
67
67
  },
68
68
  },
69
69
  },
@@ -110,7 +110,7 @@ exports.POC = {
110
110
  telemetry: {
111
111
  enabled: false,
112
112
  send_data: false,
113
- data_residency: 'none',
113
+ data_residency: null,
114
114
  },
115
115
  },
116
116
  },
@@ -161,7 +161,7 @@ exports.PRODUCTION = {
161
161
  environment: 'production',
162
162
  data_classification: 'confidential',
163
163
  },
164
- sinks: [{ type: 'file', path: './monora_events.jsonl', rotation: 'daily' }],
164
+ sinks: [{ type: 'file', path: './monora_events.jsonl', rotation: 'daily', symlink: true }],
165
165
  immutability: {
166
166
  enabled: true,
167
167
  scope: 'per_trace',
@@ -202,7 +202,7 @@ exports.STRICT_ENTERPRISE = {
202
202
  environment: 'production',
203
203
  data_classification: 'restricted',
204
204
  },
205
- sinks: [{ type: 'file', path: './monora_events.jsonl', rotation: 'daily' }],
205
+ sinks: [{ type: 'file', path: './monora_events.jsonl', rotation: 'daily', symlink: true }],
206
206
  immutability: {
207
207
  enabled: true,
208
208
  scope: 'per_trace',
@@ -328,7 +328,7 @@ exports.AUDIT_FIRST = {
328
328
  environment: 'production',
329
329
  data_classification: 'restricted',
330
330
  },
331
- sinks: [{ type: 'file', path: './monora_events.jsonl', rotation: 'daily' }],
331
+ sinks: [{ type: 'file', path: './monora_events.jsonl', rotation: 'daily', symlink: true }],
332
332
  immutability: {
333
333
  enabled: true,
334
334
  scope: 'per_trace',
@@ -363,7 +363,7 @@ exports.AUDIT_FIRST = {
363
363
  telemetry: {
364
364
  enabled: false,
365
365
  send_data: false,
366
- data_residency: 'none',
366
+ data_residency: null,
367
367
  },
368
368
  },
369
369
  },
@@ -506,7 +506,7 @@ function deepMerge(base, updates) {
506
506
  deepMerge(base[key], updates[key]);
507
507
  }
508
508
  else {
509
- base[key] = updates[key];
509
+ base[key] = deepClone(updates[key]);
510
510
  }
511
511
  }
512
512
  }