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.
- package/README.md +441 -150
- package/dist/aims_governance.d.ts +238 -0
- package/dist/aims_governance.d.ts.map +1 -0
- package/dist/aims_governance.js +922 -0
- package/dist/alerts.d.ts +16 -0
- package/dist/alerts.d.ts.map +1 -1
- package/dist/alerts.js +16 -0
- package/dist/api.d.ts +6 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -0
- package/dist/assessment.d.ts +269 -0
- package/dist/assessment.d.ts.map +1 -0
- package/dist/assessment.js +1232 -0
- package/dist/attestation.js +23 -1
- package/dist/attribution.d.ts +349 -0
- package/dist/attribution.d.ts.map +1 -0
- package/dist/attribution.js +987 -0
- package/dist/autodetect.d.ts +69 -1
- package/dist/autodetect.d.ts.map +1 -1
- package/dist/autodetect.js +644 -1
- package/dist/bias.d.ts +130 -0
- package/dist/bias.d.ts.map +1 -0
- package/dist/bias.js +223 -0
- package/dist/circuit_breaker.js +3 -3
- package/dist/cli/diagnostics.d.ts +5 -1
- package/dist/cli/diagnostics.d.ts.map +1 -1
- package/dist/cli/diagnostics.js +31 -8
- package/dist/cli/doctor.d.ts +25 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +381 -0
- package/dist/cli/fix.d.ts +16 -0
- package/dist/cli/fix.d.ts.map +1 -0
- package/dist/cli/fix.js +284 -0
- package/dist/cli/init.d.ts +57 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +205 -0
- package/dist/cli.js +1611 -126
- package/dist/complianceTargets.d.ts +111 -0
- package/dist/complianceTargets.d.ts.map +1 -0
- package/dist/complianceTargets.js +521 -0
- package/dist/config.d.ts +301 -17
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +428 -36
- package/dist/config_migrations.d.ts +41 -0
- package/dist/config_migrations.d.ts.map +1 -1
- package/dist/config_migrations.js +205 -0
- package/dist/config_schema.d.ts +2900 -731
- package/dist/config_schema.d.ts.map +1 -1
- package/dist/config_schema.js +257 -55
- package/dist/context.d.ts +34 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +118 -7
- package/dist/control_backbone.d.ts +122 -0
- package/dist/control_backbone.d.ts.map +1 -0
- package/dist/control_backbone.js +698 -0
- package/dist/data-governance.d.ts +187 -0
- package/dist/data-governance.d.ts.map +1 -0
- package/dist/data-governance.js +424 -0
- package/dist/dataResidency.d.ts +44 -0
- package/dist/dataResidency.d.ts.map +1 -0
- package/dist/dataResidency.js +203 -0
- package/dist/dispatcher.d.ts +32 -0
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js +91 -4
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +38 -0
- package/dist/evidence_store.d.ts +103 -0
- package/dist/evidence_store.d.ts.map +1 -0
- package/dist/evidence_store.js +459 -0
- package/dist/executiveSummary.d.ts +65 -8
- package/dist/executiveSummary.d.ts.map +1 -1
- package/dist/executiveSummary.js +289 -26
- package/dist/identity.d.ts +143 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +231 -0
- package/dist/impact-assessment.d.ts +350 -0
- package/dist/impact-assessment.d.ts.map +1 -0
- package/dist/impact-assessment.js +580 -0
- package/dist/index.d.ts +25 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +300 -4
- package/dist/instrumentation.d.ts +1 -1
- package/dist/instrumentation.d.ts.map +1 -1
- package/dist/instrumentation.js +243 -27
- package/dist/integrations/anthropic.d.ts +3 -0
- package/dist/integrations/anthropic.d.ts.map +1 -1
- package/dist/integrations/anthropic.js +284 -79
- package/dist/integrations/governance.d.ts +33 -0
- package/dist/integrations/governance.d.ts.map +1 -0
- package/dist/integrations/governance.js +208 -0
- package/dist/integrations/langchain.d.ts +7 -0
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +387 -143
- package/dist/integrations/openai.d.ts +9 -0
- package/dist/integrations/openai.d.ts.map +1 -1
- package/dist/integrations/openai.js +673 -73
- package/dist/iso42001_consolidation.d.ts +16 -0
- package/dist/iso42001_consolidation.d.ts.map +1 -0
- package/dist/iso42001_consolidation.js +413 -0
- package/dist/iso42001_workflows.d.ts +263 -0
- package/dist/iso42001_workflows.d.ts.map +1 -0
- package/dist/iso42001_workflows.js +781 -0
- package/dist/lifecycle.d.ts +299 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +624 -0
- package/dist/lineage.d.ts +2 -2
- package/dist/lineage.d.ts.map +1 -1
- package/dist/lineage.js +12 -17
- package/dist/middleware/express.d.ts.map +1 -1
- package/dist/middleware/express.js +33 -3
- package/dist/middleware/nextjs.d.ts.map +1 -1
- package/dist/middleware/nextjs.js +42 -68
- package/dist/model.d.ts +143 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +371 -0
- package/dist/onboarding.d.ts +42 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +1022 -0
- package/dist/oversight.d.ts +264 -0
- package/dist/oversight.d.ts.map +1 -0
- package/dist/oversight.js +497 -0
- package/dist/pdf_report.d.ts.map +1 -1
- package/dist/pdf_report.js +42 -21
- package/dist/presets.d.ts +88 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +520 -0
- package/dist/propagation.d.ts.map +1 -1
- package/dist/propagation.js +34 -2
- package/dist/quotas.d.ts +171 -0
- package/dist/quotas.d.ts.map +1 -0
- package/dist/quotas.js +259 -0
- package/dist/register.d.ts +13 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +99 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -0
- package/dist/registryData.json +43 -6
- package/dist/report.d.ts +2 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +189 -2
- package/dist/reporting.d.ts +125 -0
- package/dist/reporting.d.ts.map +1 -1
- package/dist/reporting.js +196 -5
- package/dist/resources.d.ts +285 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +643 -0
- package/dist/risk.d.ts +120 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +220 -0
- package/dist/runtime.d.ts +74 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +598 -22
- package/dist/schemaInference.d.ts +92 -0
- package/dist/schemaInference.d.ts.map +1 -0
- package/dist/schemaInference.js +466 -0
- package/dist/schema_validation.js +2 -2
- package/dist/schemas/config.schema.json +169 -6
- package/dist/schemas/event.schema.json +4 -0
- package/dist/security_report.js +4 -4
- package/dist/signing.d.ts +1 -1
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +4 -0
- package/dist/sinks/file.d.ts +19 -1
- package/dist/sinks/file.d.ts.map +1 -1
- package/dist/sinks/file.js +82 -13
- package/dist/sinks/https.d.ts +10 -0
- package/dist/sinks/https.d.ts.map +1 -1
- package/dist/sinks/https.js +76 -16
- package/dist/sinks/stdout.d.ts +1 -0
- package/dist/sinks/stdout.d.ts.map +1 -1
- package/dist/sinks/stdout.js +12 -1
- package/dist/spec.d.ts +159 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +391 -0
- package/dist/stakeholders.d.ts +199 -0
- package/dist/stakeholders.d.ts.map +1 -0
- package/dist/stakeholders.js +398 -0
- package/dist/standards.d.ts.map +1 -1
- package/dist/standards.js +160 -2
- package/dist/standards_ingest.d.ts +2 -2
- package/dist/standards_ingest.d.ts.map +1 -1
- package/dist/standards_ingest.js +105 -23
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +7 -2
- package/dist/telemetry.d.ts +16 -2
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +79 -14
- package/dist/templates/controls/iso42001_control_catalog.json +1443 -0
- package/dist/traced_emitter.d.ts +3 -0
- package/dist/traced_emitter.d.ts.map +1 -1
- package/dist/traced_emitter.js +142 -25
- package/dist/trust_package.d.ts +21 -1
- package/dist/trust_package.d.ts.map +1 -1
- package/dist/trust_package.js +101 -4
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +9 -2
- package/dist/wal.d.ts.map +1 -1
- package/dist/wal.js +2 -1
- package/package.json +14 -1
- package/scripts/postinstall.js +119 -97
- package/templates/controls/iso42001_control_catalog.json +1443 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Stakeholder & Third-Party Management for ISO 42001 A.8/A.10 compliance.
|
|
4
|
+
*
|
|
5
|
+
* This module provides stakeholder and third-party management supporting ISO 42001:
|
|
6
|
+
* - A.8.2: System documentation for users
|
|
7
|
+
* - A.10.2: Allocating responsibilities
|
|
8
|
+
* - A.10.3: Suppliers
|
|
9
|
+
* - A.10.4: Customers
|
|
10
|
+
*
|
|
11
|
+
* Cross-SDK Parity:
|
|
12
|
+
* Both Python and Node.js SDKs provide identical stakeholder APIs:
|
|
13
|
+
* - registerStakeholder() / register_stakeholder()
|
|
14
|
+
* - registerSupplier() / register_supplier()
|
|
15
|
+
* - registerCustomer() / register_customer()
|
|
16
|
+
* - allocateResponsibility() / allocate_responsibility()
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.documentRefToDict = documentRefToDict;
|
|
20
|
+
exports.responsibilityToDict = responsibilityToDict;
|
|
21
|
+
exports.stakeholderRecordToDict = stakeholderRecordToDict;
|
|
22
|
+
exports.supplierRecordToDict = supplierRecordToDict;
|
|
23
|
+
exports.customerRecordToDict = customerRecordToDict;
|
|
24
|
+
exports.registerStakeholder = registerStakeholder;
|
|
25
|
+
exports.getStakeholder = getStakeholder;
|
|
26
|
+
exports.getAllStakeholders = getAllStakeholders;
|
|
27
|
+
exports.addStakeholderDocumentation = addStakeholderDocumentation;
|
|
28
|
+
exports.allocateResponsibility = allocateResponsibility;
|
|
29
|
+
exports.registerSupplier = registerSupplier;
|
|
30
|
+
exports.getSupplier = getSupplier;
|
|
31
|
+
exports.getAllSuppliers = getAllSuppliers;
|
|
32
|
+
exports.assessSupplier = assessSupplier;
|
|
33
|
+
exports.updateSupplierStatus = updateSupplierStatus;
|
|
34
|
+
exports.registerCustomer = registerCustomer;
|
|
35
|
+
exports.getCustomer = getCustomer;
|
|
36
|
+
exports.getAllCustomers = getAllCustomers;
|
|
37
|
+
exports.updateCustomerNeeds = updateCustomerNeeds;
|
|
38
|
+
exports.clearStakeholders = clearStakeholders;
|
|
39
|
+
exports.clearSuppliers = clearSuppliers;
|
|
40
|
+
exports.clearCustomers = clearCustomers;
|
|
41
|
+
exports.clearAll = clearAll;
|
|
42
|
+
exports.getSupplierRiskSummary = getSupplierRiskSummary;
|
|
43
|
+
exports.getStakeholderReport = getStakeholderReport;
|
|
44
|
+
const crypto_1 = require("crypto");
|
|
45
|
+
const logger_1 = require("./logger");
|
|
46
|
+
function generateId(prefix, ...parts) {
|
|
47
|
+
const combined = parts.join(':');
|
|
48
|
+
const hash = (0, crypto_1.createHash)('sha256').update(combined).digest('hex').slice(0, 12);
|
|
49
|
+
return `${prefix}_${hash}`;
|
|
50
|
+
}
|
|
51
|
+
function nowIso() {
|
|
52
|
+
return new Date().toISOString();
|
|
53
|
+
}
|
|
54
|
+
function documentRefToDict(doc) {
|
|
55
|
+
return {
|
|
56
|
+
doc_id: doc.docId,
|
|
57
|
+
title: doc.title,
|
|
58
|
+
doc_type: doc.docType,
|
|
59
|
+
path_or_url: doc.pathOrUrl,
|
|
60
|
+
version: doc.version,
|
|
61
|
+
last_updated: doc.lastUpdated,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function responsibilityToDict(resp) {
|
|
65
|
+
return {
|
|
66
|
+
responsibility_id: resp.responsibilityId,
|
|
67
|
+
description: resp.description,
|
|
68
|
+
category: resp.category,
|
|
69
|
+
assigned_to: resp.assignedTo,
|
|
70
|
+
agreed_at: resp.agreedAt,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function stakeholderRecordToDict(record) {
|
|
74
|
+
return {
|
|
75
|
+
party_id: record.partyId,
|
|
76
|
+
name: record.name,
|
|
77
|
+
type: record.type,
|
|
78
|
+
information_requirements: record.informationRequirements,
|
|
79
|
+
documentation_provided: record.documentationProvided.map(documentRefToDict),
|
|
80
|
+
responsibilities: record.responsibilities.map(responsibilityToDict),
|
|
81
|
+
contact: record.contact,
|
|
82
|
+
communication_channel: record.communicationChannel,
|
|
83
|
+
notification_preferences: record.notificationPreferences,
|
|
84
|
+
created_at: record.createdAt,
|
|
85
|
+
updated_at: record.updatedAt,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function supplierRecordToDict(record) {
|
|
89
|
+
const result = {
|
|
90
|
+
supplier_id: record.supplierId,
|
|
91
|
+
name: record.name,
|
|
92
|
+
services: record.services,
|
|
93
|
+
risk_level: record.riskLevel,
|
|
94
|
+
compliance_requirements: record.complianceRequirements,
|
|
95
|
+
certifications: record.certifications,
|
|
96
|
+
status: record.status,
|
|
97
|
+
contract_ref: record.contractRef,
|
|
98
|
+
sla_requirements: record.slaRequirements,
|
|
99
|
+
created_at: record.createdAt,
|
|
100
|
+
updated_at: record.updatedAt,
|
|
101
|
+
};
|
|
102
|
+
if (record.lastAssessmentDate) {
|
|
103
|
+
result.last_assessment_date = record.lastAssessmentDate;
|
|
104
|
+
}
|
|
105
|
+
if (Object.keys(record.assessmentResults).length > 0) {
|
|
106
|
+
result.assessment_results = record.assessmentResults;
|
|
107
|
+
}
|
|
108
|
+
if (record.contractExpiry) {
|
|
109
|
+
result.contract_expiry = record.contractExpiry;
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
function customerRecordToDict(record) {
|
|
114
|
+
return {
|
|
115
|
+
customer_id: record.customerId,
|
|
116
|
+
name: record.name,
|
|
117
|
+
stated_needs: record.statedNeeds,
|
|
118
|
+
expectations: record.expectations,
|
|
119
|
+
constraints: record.constraints,
|
|
120
|
+
support_level: record.supportLevel,
|
|
121
|
+
escalation_contact: record.escalationContact,
|
|
122
|
+
created_at: record.createdAt,
|
|
123
|
+
updated_at: record.updatedAt,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// Runtime registries
|
|
127
|
+
const stakeholders = new Map();
|
|
128
|
+
const suppliers = new Map();
|
|
129
|
+
const customers = new Map();
|
|
130
|
+
function registerStakeholder(options) {
|
|
131
|
+
const partyId = generateId('stk', options.name, options.stakeholderType);
|
|
132
|
+
const record = {
|
|
133
|
+
partyId,
|
|
134
|
+
name: options.name,
|
|
135
|
+
type: options.stakeholderType,
|
|
136
|
+
informationRequirements: options.informationRequirements || [],
|
|
137
|
+
documentationProvided: [],
|
|
138
|
+
responsibilities: [],
|
|
139
|
+
contact: options.contact || '',
|
|
140
|
+
communicationChannel: options.communicationChannel || 'email',
|
|
141
|
+
notificationPreferences: {},
|
|
142
|
+
createdAt: nowIso(),
|
|
143
|
+
updatedAt: nowIso(),
|
|
144
|
+
};
|
|
145
|
+
stakeholders.set(partyId, record);
|
|
146
|
+
return record;
|
|
147
|
+
}
|
|
148
|
+
function getStakeholder(partyId) {
|
|
149
|
+
return stakeholders.get(partyId);
|
|
150
|
+
}
|
|
151
|
+
function getAllStakeholders() {
|
|
152
|
+
return Array.from(stakeholders.values());
|
|
153
|
+
}
|
|
154
|
+
function addStakeholderDocumentation(options) {
|
|
155
|
+
const stakeholder = stakeholders.get(options.partyId);
|
|
156
|
+
if (!stakeholder) {
|
|
157
|
+
throw new Error(`Stakeholder ${options.partyId} not found`);
|
|
158
|
+
}
|
|
159
|
+
const docId = generateId('doc', options.partyId, options.title);
|
|
160
|
+
const doc = {
|
|
161
|
+
docId,
|
|
162
|
+
title: options.title,
|
|
163
|
+
docType: options.docType,
|
|
164
|
+
pathOrUrl: options.pathOrUrl,
|
|
165
|
+
version: options.version || '1.0',
|
|
166
|
+
lastUpdated: nowIso(),
|
|
167
|
+
};
|
|
168
|
+
stakeholder.documentationProvided.push(doc);
|
|
169
|
+
stakeholder.updatedAt = nowIso();
|
|
170
|
+
return doc;
|
|
171
|
+
}
|
|
172
|
+
function allocateResponsibility(options) {
|
|
173
|
+
const stakeholder = stakeholders.get(options.partyId);
|
|
174
|
+
if (!stakeholder) {
|
|
175
|
+
throw new Error(`Stakeholder ${options.partyId} not found`);
|
|
176
|
+
}
|
|
177
|
+
const respId = generateId('resp', options.partyId, options.description.slice(0, 20));
|
|
178
|
+
const responsibility = {
|
|
179
|
+
responsibilityId: respId,
|
|
180
|
+
description: options.description,
|
|
181
|
+
category: options.category,
|
|
182
|
+
assignedTo: options.partyId,
|
|
183
|
+
agreedAt: nowIso(),
|
|
184
|
+
};
|
|
185
|
+
stakeholder.responsibilities.push(responsibility);
|
|
186
|
+
stakeholder.updatedAt = nowIso();
|
|
187
|
+
return responsibility;
|
|
188
|
+
}
|
|
189
|
+
function registerSupplier(options) {
|
|
190
|
+
const supplierId = generateId('sup', options.name);
|
|
191
|
+
const record = {
|
|
192
|
+
supplierId,
|
|
193
|
+
name: options.name,
|
|
194
|
+
services: options.services || [],
|
|
195
|
+
riskLevel: options.riskLevel || 'medium',
|
|
196
|
+
complianceRequirements: options.complianceRequirements || [],
|
|
197
|
+
certifications: options.certifications || [],
|
|
198
|
+
assessmentResults: {},
|
|
199
|
+
status: 'under_review',
|
|
200
|
+
contractRef: options.contractRef || '',
|
|
201
|
+
slaRequirements: {},
|
|
202
|
+
createdAt: nowIso(),
|
|
203
|
+
updatedAt: nowIso(),
|
|
204
|
+
};
|
|
205
|
+
suppliers.set(supplierId, record);
|
|
206
|
+
return record;
|
|
207
|
+
}
|
|
208
|
+
function getSupplier(supplierId) {
|
|
209
|
+
return suppliers.get(supplierId);
|
|
210
|
+
}
|
|
211
|
+
function getAllSuppliers() {
|
|
212
|
+
return Array.from(suppliers.values());
|
|
213
|
+
}
|
|
214
|
+
function assessSupplier(options) {
|
|
215
|
+
const supplier = suppliers.get(options.supplierId);
|
|
216
|
+
if (!supplier) {
|
|
217
|
+
throw new Error(`Supplier ${options.supplierId} not found`);
|
|
218
|
+
}
|
|
219
|
+
supplier.lastAssessmentDate = new Date().toISOString().split('T')[0];
|
|
220
|
+
supplier.assessmentResults = {
|
|
221
|
+
...options.assessmentResults,
|
|
222
|
+
assessed_by: options.assessedBy || '',
|
|
223
|
+
};
|
|
224
|
+
supplier.updatedAt = nowIso();
|
|
225
|
+
return supplier;
|
|
226
|
+
}
|
|
227
|
+
function updateSupplierStatus(options) {
|
|
228
|
+
const supplier = suppliers.get(options.supplierId);
|
|
229
|
+
if (!supplier) {
|
|
230
|
+
throw new Error(`Supplier ${options.supplierId} not found`);
|
|
231
|
+
}
|
|
232
|
+
const stakeholderConfig = options.config?.stakeholders;
|
|
233
|
+
const riskThresholds = stakeholderConfig?.risk_thresholds;
|
|
234
|
+
if (options.status === 'approved') {
|
|
235
|
+
if (supplier.riskLevel === 'critical' && riskThresholds?.critical_requires_approval !== false) {
|
|
236
|
+
if (Object.keys(supplier.assessmentResults).length === 0) {
|
|
237
|
+
throw new Error('Critical suppliers require assessment before approval');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (supplier.riskLevel === 'high' && riskThresholds?.high_requires_review !== false) {
|
|
241
|
+
if (Object.keys(supplier.assessmentResults).length === 0) {
|
|
242
|
+
throw new Error('High risk suppliers require review before approval');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
supplier.status = options.status;
|
|
247
|
+
supplier.updatedAt = nowIso();
|
|
248
|
+
// Emit supplier event
|
|
249
|
+
emitStakeholderEvent(supplier, 'supplier_status_change', options.config);
|
|
250
|
+
return supplier;
|
|
251
|
+
}
|
|
252
|
+
function registerCustomer(options) {
|
|
253
|
+
const customerId = generateId('cust', options.name);
|
|
254
|
+
const record = {
|
|
255
|
+
customerId,
|
|
256
|
+
name: options.name,
|
|
257
|
+
statedNeeds: options.statedNeeds || [],
|
|
258
|
+
expectations: options.expectations || [],
|
|
259
|
+
constraints: options.constraints || [],
|
|
260
|
+
supportLevel: options.supportLevel || 'standard',
|
|
261
|
+
escalationContact: options.escalationContact || '',
|
|
262
|
+
createdAt: nowIso(),
|
|
263
|
+
updatedAt: nowIso(),
|
|
264
|
+
};
|
|
265
|
+
customers.set(customerId, record);
|
|
266
|
+
return record;
|
|
267
|
+
}
|
|
268
|
+
function getCustomer(customerId) {
|
|
269
|
+
return customers.get(customerId);
|
|
270
|
+
}
|
|
271
|
+
function getAllCustomers() {
|
|
272
|
+
return Array.from(customers.values());
|
|
273
|
+
}
|
|
274
|
+
function updateCustomerNeeds(options) {
|
|
275
|
+
const customer = customers.get(options.customerId);
|
|
276
|
+
if (!customer) {
|
|
277
|
+
throw new Error(`Customer ${options.customerId} not found`);
|
|
278
|
+
}
|
|
279
|
+
if (options.statedNeeds !== undefined) {
|
|
280
|
+
customer.statedNeeds = options.statedNeeds;
|
|
281
|
+
}
|
|
282
|
+
if (options.expectations !== undefined) {
|
|
283
|
+
customer.expectations = options.expectations;
|
|
284
|
+
}
|
|
285
|
+
if (options.constraints !== undefined) {
|
|
286
|
+
customer.constraints = options.constraints;
|
|
287
|
+
}
|
|
288
|
+
customer.updatedAt = nowIso();
|
|
289
|
+
return customer;
|
|
290
|
+
}
|
|
291
|
+
function clearStakeholders() {
|
|
292
|
+
stakeholders.clear();
|
|
293
|
+
}
|
|
294
|
+
function clearSuppliers() {
|
|
295
|
+
suppliers.clear();
|
|
296
|
+
}
|
|
297
|
+
function clearCustomers() {
|
|
298
|
+
customers.clear();
|
|
299
|
+
}
|
|
300
|
+
function clearAll() {
|
|
301
|
+
stakeholders.clear();
|
|
302
|
+
suppliers.clear();
|
|
303
|
+
customers.clear();
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Get summary of supplier risk levels.
|
|
307
|
+
*/
|
|
308
|
+
function getSupplierRiskSummary(config) {
|
|
309
|
+
if (suppliers.size === 0) {
|
|
310
|
+
return {
|
|
311
|
+
total_suppliers: 0,
|
|
312
|
+
by_risk_level: {},
|
|
313
|
+
by_status: {},
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const byRisk = {};
|
|
317
|
+
const byStatus = {};
|
|
318
|
+
suppliers.forEach(supplier => {
|
|
319
|
+
byRisk[supplier.riskLevel] = (byRisk[supplier.riskLevel] || 0) + 1;
|
|
320
|
+
byStatus[supplier.status] = (byStatus[supplier.status] || 0) + 1;
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
total_suppliers: suppliers.size,
|
|
324
|
+
by_risk_level: byRisk,
|
|
325
|
+
by_status: byStatus,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Get aggregate stakeholder report.
|
|
330
|
+
*/
|
|
331
|
+
function getStakeholderReport(config) {
|
|
332
|
+
const stakeholderSummary = [];
|
|
333
|
+
stakeholders.forEach(s => {
|
|
334
|
+
stakeholderSummary.push({
|
|
335
|
+
party_id: s.partyId,
|
|
336
|
+
name: s.name,
|
|
337
|
+
type: s.type,
|
|
338
|
+
responsibilities_count: s.responsibilities.length,
|
|
339
|
+
documentation_count: s.documentationProvided.length,
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
const supplierSummary = [];
|
|
343
|
+
suppliers.forEach(s => {
|
|
344
|
+
supplierSummary.push({
|
|
345
|
+
supplier_id: s.supplierId,
|
|
346
|
+
name: s.name,
|
|
347
|
+
risk_level: s.riskLevel,
|
|
348
|
+
status: s.status,
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
const customerSummary = [];
|
|
352
|
+
customers.forEach(c => {
|
|
353
|
+
customerSummary.push({
|
|
354
|
+
customer_id: c.customerId,
|
|
355
|
+
name: c.name,
|
|
356
|
+
support_level: c.supportLevel,
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
return {
|
|
360
|
+
total_stakeholders: stakeholders.size,
|
|
361
|
+
total_suppliers: suppliers.size,
|
|
362
|
+
total_customers: customers.size,
|
|
363
|
+
stakeholders: stakeholderSummary,
|
|
364
|
+
suppliers: supplierSummary,
|
|
365
|
+
customers: customerSummary,
|
|
366
|
+
supplier_risk_summary: getSupplierRiskSummary(config),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Emit a stakeholder event.
|
|
371
|
+
*/
|
|
372
|
+
function emitStakeholderEvent(record, eventType, config) {
|
|
373
|
+
try {
|
|
374
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
375
|
+
const { getState } = require('./runtime');
|
|
376
|
+
const state = getState();
|
|
377
|
+
if (state && typeof state.emitInternal === 'function') {
|
|
378
|
+
let body;
|
|
379
|
+
if ('supplierId' in record) {
|
|
380
|
+
body = supplierRecordToDict(record);
|
|
381
|
+
}
|
|
382
|
+
else if ('partyId' in record) {
|
|
383
|
+
body = stakeholderRecordToDict(record);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
body = customerRecordToDict(record);
|
|
387
|
+
}
|
|
388
|
+
state.emitInternal({
|
|
389
|
+
event_type: eventType,
|
|
390
|
+
timestamp: nowIso(),
|
|
391
|
+
body,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
logger_1.logger.warning('Failed to emit stakeholder event:', err);
|
|
397
|
+
}
|
|
398
|
+
}
|
package/dist/standards.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards.d.ts","sourceRoot":"","sources":["../src/standards.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"standards.d.ts","sourceRoot":"","sources":["../src/standards.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAkkCxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAwDtB"}
|
package/dist/standards.js
CHANGED
|
@@ -243,6 +243,150 @@ function buildCoverageSummary(claims) {
|
|
|
243
243
|
}
|
|
244
244
|
return summary;
|
|
245
245
|
}
|
|
246
|
+
function claimSeverity(options) {
|
|
247
|
+
const { status, checks, insufficientReasons } = options;
|
|
248
|
+
if (status === 'corroborated') {
|
|
249
|
+
return 'none';
|
|
250
|
+
}
|
|
251
|
+
const failedTypes = new Set(checks
|
|
252
|
+
.filter((check) => check && check.status === 'failed')
|
|
253
|
+
.map((check) => String(check.type)));
|
|
254
|
+
if (status === 'disproved') {
|
|
255
|
+
if (failedTypes.has('hash_chain_status') || failedTypes.has('signatures_status')) {
|
|
256
|
+
return 'critical';
|
|
257
|
+
}
|
|
258
|
+
if (failedTypes.has('policy_violations_max') ||
|
|
259
|
+
failedTypes.has('forbidden_models_max') ||
|
|
260
|
+
failedTypes.has('config_required')) {
|
|
261
|
+
return 'high';
|
|
262
|
+
}
|
|
263
|
+
return 'medium';
|
|
264
|
+
}
|
|
265
|
+
const reasonCodes = new Set(insufficientReasons
|
|
266
|
+
.filter((reason) => reason && typeof reason === 'object' && reason.code)
|
|
267
|
+
.map((reason) => String(reason.code)));
|
|
268
|
+
if (reasonCodes.has('missing_required_excerpts')) {
|
|
269
|
+
return 'high';
|
|
270
|
+
}
|
|
271
|
+
if (reasonCodes.has('unverified_excerpts') || reasonCodes.has('check_skipped')) {
|
|
272
|
+
return 'medium';
|
|
273
|
+
}
|
|
274
|
+
return 'low';
|
|
275
|
+
}
|
|
276
|
+
function claimRemediation(options) {
|
|
277
|
+
const { status, checks, insufficientReasons } = options;
|
|
278
|
+
if (status === 'corroborated') {
|
|
279
|
+
return { summary: 'No action required.', actions: [] };
|
|
280
|
+
}
|
|
281
|
+
const actions = [];
|
|
282
|
+
for (const check of checks) {
|
|
283
|
+
if (!check || check.status !== 'failed') {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
const checkType = String(check.type || '');
|
|
287
|
+
if (checkType === 'policy_violations_max') {
|
|
288
|
+
actions.push('Resolve policy violations and reduce violation count below threshold.');
|
|
289
|
+
}
|
|
290
|
+
else if (checkType === 'unknown_models_max') {
|
|
291
|
+
actions.push('Register unknown models in the registry or block their usage.');
|
|
292
|
+
}
|
|
293
|
+
else if (checkType === 'forbidden_models_max') {
|
|
294
|
+
actions.push('Remove blocked/forbidden models from runtime traffic.');
|
|
295
|
+
}
|
|
296
|
+
else if (checkType === 'hash_chain_status') {
|
|
297
|
+
actions.push('Fix hash-chain integrity issues and re-verify emitted events.');
|
|
298
|
+
}
|
|
299
|
+
else if (checkType === 'signatures_status') {
|
|
300
|
+
actions.push('Enable valid signing keys and verify event signatures.');
|
|
301
|
+
}
|
|
302
|
+
else if (checkType === 'sequence_gaps_max') {
|
|
303
|
+
actions.push('Investigate event sequence gaps and restore event continuity.');
|
|
304
|
+
}
|
|
305
|
+
else if (checkType === 'errors_max') {
|
|
306
|
+
actions.push('Reduce runtime errors and capture complete error diagnostics.');
|
|
307
|
+
}
|
|
308
|
+
else if (checkType === 'config_required') {
|
|
309
|
+
const pathLabel = check.details?.path;
|
|
310
|
+
const expected = check.details?.expected;
|
|
311
|
+
actions.push(`Set required config '${pathLabel}' to '${expected}' and redeploy.`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
for (const reason of insufficientReasons) {
|
|
315
|
+
const code = String(reason?.code || '');
|
|
316
|
+
if (code === 'missing_required_excerpts') {
|
|
317
|
+
actions.push('Attach required report excerpts for this claim.');
|
|
318
|
+
}
|
|
319
|
+
else if (code === 'unverified_excerpts') {
|
|
320
|
+
actions.push('Provide excerpt hashes/report linkage so evidence can be verified.');
|
|
321
|
+
}
|
|
322
|
+
else if (code === 'check_skipped') {
|
|
323
|
+
actions.push('Provide missing config/evidence inputs so skipped checks can execute.');
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const deduped = Array.from(new Set(actions));
|
|
327
|
+
const summary = deduped.length > 0
|
|
328
|
+
? deduped[0]
|
|
329
|
+
: 'Investigate missing or failing evidence and rerun standards evaluation.';
|
|
330
|
+
return { summary, actions: deduped.slice(0, 8) };
|
|
331
|
+
}
|
|
332
|
+
function buildFindingsSummary(claims) {
|
|
333
|
+
const severityLevels = ['critical', 'high', 'medium', 'low', 'none'];
|
|
334
|
+
const totals = Object.fromEntries(severityLevels.map((level) => [level, 0]));
|
|
335
|
+
const byStandard = {};
|
|
336
|
+
const statusBreakdown = {
|
|
337
|
+
corroborated: 0,
|
|
338
|
+
disproved: 0,
|
|
339
|
+
insufficient_evidence: 0,
|
|
340
|
+
};
|
|
341
|
+
const remediationRecommendations = [];
|
|
342
|
+
for (const claim of claims) {
|
|
343
|
+
const standard = String(claim.standard || 'unspecified');
|
|
344
|
+
let severity = String(claim.severity || 'none');
|
|
345
|
+
const status = String(claim.status || 'insufficient_evidence');
|
|
346
|
+
if (!(severity in totals)) {
|
|
347
|
+
severity = 'low';
|
|
348
|
+
}
|
|
349
|
+
totals[severity] += 1;
|
|
350
|
+
statusBreakdown[status] = (statusBreakdown[status] || 0) + 1;
|
|
351
|
+
if (!byStandard[standard]) {
|
|
352
|
+
byStandard[standard] = Object.fromEntries(severityLevels.map((level) => [level, 0]));
|
|
353
|
+
}
|
|
354
|
+
byStandard[standard][severity] = (byStandard[standard][severity] || 0) + 1;
|
|
355
|
+
const remediation = claim.remediation && typeof claim.remediation === 'object'
|
|
356
|
+
? claim.remediation
|
|
357
|
+
: {};
|
|
358
|
+
if (typeof remediation.summary === 'string' && remediation.summary.length > 0) {
|
|
359
|
+
remediationRecommendations.push({
|
|
360
|
+
claim_id: claim.id,
|
|
361
|
+
standard,
|
|
362
|
+
severity,
|
|
363
|
+
summary: remediation.summary,
|
|
364
|
+
actions: Array.isArray(remediation.actions) ? remediation.actions.slice(0, 3) : [],
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const severityRank = {
|
|
369
|
+
critical: 0,
|
|
370
|
+
high: 1,
|
|
371
|
+
medium: 2,
|
|
372
|
+
low: 3,
|
|
373
|
+
none: 4,
|
|
374
|
+
};
|
|
375
|
+
remediationRecommendations.sort((a, b) => {
|
|
376
|
+
const left = severityRank[String(a.severity)] ?? 5;
|
|
377
|
+
const right = severityRank[String(b.severity)] ?? 5;
|
|
378
|
+
if (left !== right) {
|
|
379
|
+
return left - right;
|
|
380
|
+
}
|
|
381
|
+
return String(a.claim_id || '').localeCompare(String(b.claim_id || ''));
|
|
382
|
+
});
|
|
383
|
+
return {
|
|
384
|
+
totals,
|
|
385
|
+
by_standard: byStandard,
|
|
386
|
+
status_breakdown: statusBreakdown,
|
|
387
|
+
remediation_recommendations: remediationRecommendations.slice(0, 20),
|
|
388
|
+
};
|
|
389
|
+
}
|
|
246
390
|
function checkHashChain(events, config) {
|
|
247
391
|
const immutability = (config || {}).immutability || {};
|
|
248
392
|
const scope = immutability.scope || 'per_trace';
|
|
@@ -383,7 +527,7 @@ function buildCallInventory(events, maxCalls) {
|
|
|
383
527
|
return { by_event_type: byType, llm_call_samples: calls };
|
|
384
528
|
}
|
|
385
529
|
function buildModelInventory(events, config) {
|
|
386
|
-
const report = (0, report_1.buildReport)(events, (config || {}).policies);
|
|
530
|
+
const report = (0, report_1.buildReport)(events, (config || {}).policies, (config || {}).registry);
|
|
387
531
|
const byModel = report.by_model || {};
|
|
388
532
|
const registry = new registry_1.ModelRegistry((config || {}).registry || {});
|
|
389
533
|
const inventory = [];
|
|
@@ -815,6 +959,16 @@ function evaluateClaims(claims, evidence, config, events, verifiedExcerpts, exce
|
|
|
815
959
|
else if (claimSkipped) {
|
|
816
960
|
overallStatus = 'insufficient_evidence';
|
|
817
961
|
}
|
|
962
|
+
const severity = claimSeverity({
|
|
963
|
+
status: overallStatus,
|
|
964
|
+
checks: checkResults,
|
|
965
|
+
insufficientReasons,
|
|
966
|
+
});
|
|
967
|
+
const remediation = claimRemediation({
|
|
968
|
+
status: overallStatus,
|
|
969
|
+
checks: checkResults,
|
|
970
|
+
insufficientReasons,
|
|
971
|
+
});
|
|
818
972
|
const evidenceIds = Array.from(new Set(checkResults.flatMap((check) => check.evidence_event_ids || [])));
|
|
819
973
|
const eventGraph = evidenceIds.length > 0 ? buildEventGraph(events, evidenceIds) : {
|
|
820
974
|
nodes: [],
|
|
@@ -830,6 +984,8 @@ function evaluateClaims(claims, evidence, config, events, verifiedExcerpts, exce
|
|
|
830
984
|
section: claim.section,
|
|
831
985
|
statement: claim.statement,
|
|
832
986
|
status: overallStatus,
|
|
987
|
+
severity,
|
|
988
|
+
remediation,
|
|
833
989
|
checks: checkResults,
|
|
834
990
|
evidence_event_ids: evidenceIds,
|
|
835
991
|
causal_paths: evidenceIds.length > 0 ? buildCausalPaths(events, evidenceIds) : {},
|
|
@@ -846,7 +1002,7 @@ function buildStandardsReport(options) {
|
|
|
846
1002
|
const { events, config, reportPath, claimsPath, maxCalls = 25 } = options;
|
|
847
1003
|
const { metadata, claims, excerpts, reportSource } = loadClaims(reportPath, claimsPath);
|
|
848
1004
|
validateClaims(claims);
|
|
849
|
-
const report = (0, report_1.buildReport)(events, (config || {}).policies);
|
|
1005
|
+
const report = (0, report_1.buildReport)(events, (config || {}).policies, (config || {}).registry);
|
|
850
1006
|
const evidence = report.evidence || {};
|
|
851
1007
|
evidence.unknown_models_used = report.model_compliance?.unknown_models_used || [];
|
|
852
1008
|
evidence.forbidden_models_blocked = report.model_compliance?.forbidden_models_blocked || [];
|
|
@@ -859,6 +1015,7 @@ function buildStandardsReport(options) {
|
|
|
859
1015
|
const { normalized: normalizedExcerpts, verified, issues } = normalizeExcerpts(excerpts, resolvedReportSource);
|
|
860
1016
|
const evaluatedClaims = evaluateClaims(claims, evidence, config, events, verified, issues);
|
|
861
1017
|
const coverageSummary = buildCoverageSummary(evaluatedClaims);
|
|
1018
|
+
const findingsSummary = buildFindingsSummary(evaluatedClaims);
|
|
862
1019
|
const excerptsSummary = {
|
|
863
1020
|
total: normalizedExcerpts.length,
|
|
864
1021
|
verified: Object.keys(verified).length,
|
|
@@ -882,5 +1039,6 @@ function buildStandardsReport(options) {
|
|
|
882
1039
|
evidence,
|
|
883
1040
|
claims: evaluatedClaims,
|
|
884
1041
|
coverage_summary: coverageSummary,
|
|
1042
|
+
findings_summary: findingsSummary,
|
|
885
1043
|
};
|
|
886
1044
|
}
|
|
@@ -14,10 +14,10 @@ export declare function applyExcerptSelections(options: {
|
|
|
14
14
|
ingestPath: string;
|
|
15
15
|
claimsPath: string;
|
|
16
16
|
selections: Array<Record<string, any>>;
|
|
17
|
-
}): Record<string, any
|
|
17
|
+
}): Promise<Record<string, any>>;
|
|
18
18
|
export declare function applyExcerpts(options: {
|
|
19
19
|
ingestPath: string;
|
|
20
20
|
claimsPath: string;
|
|
21
21
|
excerptsPath: string;
|
|
22
|
-
}): Record<string, any
|
|
22
|
+
}): Promise<Record<string, any>>;
|
|
23
23
|
//# sourceMappingURL=standards_ingest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standards_ingest.d.ts","sourceRoot":"","sources":["../src/standards_ingest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"standards_ingest.d.ts","sourceRoot":"","sources":["../src/standards_ingest.ts"],"names":[],"mappings":"AAkIA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAyB/B;AA6CD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD;AA4BD,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CA4D7B;AAoPD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;CACxC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAU/B;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAW/B"}
|