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,643 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ISO 42001 Resource Inventory Management Module (A.4.2, A.4.4, A.4.5, A.2.4)
|
|
4
|
+
*
|
|
5
|
+
* Provides comprehensive resource tracking for AI systems including:
|
|
6
|
+
* - A.4.2: Resource determination
|
|
7
|
+
* - A.4.4: Tooling resources (algorithms, frameworks, libraries, models, tools)
|
|
8
|
+
* - A.4.5: Computing resources (cloud, on-premise, edge, hybrid)
|
|
9
|
+
* - A.4.6: Human resources (roles, competencies, certifications)
|
|
10
|
+
* - A.2.4: AI policy review scheduling and tracking
|
|
11
|
+
*
|
|
12
|
+
* This module enables organizations to maintain complete visibility
|
|
13
|
+
* into the resources supporting their AI systems.
|
|
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.ResourceRegistry = void 0;
|
|
50
|
+
exports.getRegistry = getRegistry;
|
|
51
|
+
exports.createResourceInventory = createResourceInventory;
|
|
52
|
+
exports.getResourceInventory = getResourceInventory;
|
|
53
|
+
exports.getInventoryForSystem = getInventoryForSystem;
|
|
54
|
+
exports.addToolingResource = addToolingResource;
|
|
55
|
+
exports.addComputeResource = addComputeResource;
|
|
56
|
+
exports.addHumanResource = addHumanResource;
|
|
57
|
+
exports.addDataResource = addDataResource;
|
|
58
|
+
exports.approveToolingResource = approveToolingResource;
|
|
59
|
+
exports.getInventorySummary = getInventorySummary;
|
|
60
|
+
exports.schedulePolicyReview = schedulePolicyReview;
|
|
61
|
+
exports.startPolicyReview = startPolicyReview;
|
|
62
|
+
exports.completePolicyReview = completePolicyReview;
|
|
63
|
+
exports.cancelPolicyReview = cancelPolicyReview;
|
|
64
|
+
exports.checkOverdueReviews = checkOverdueReviews;
|
|
65
|
+
exports.getPolicyReviewSummary = getPolicyReviewSummary;
|
|
66
|
+
exports.emitCustomResourceEvent = emitCustomResourceEvent;
|
|
67
|
+
exports.inventoryToDict = inventoryToDict;
|
|
68
|
+
exports.policyReviewToDict = policyReviewToDict;
|
|
69
|
+
exports.toolingResourceToDict = toolingResourceToDict;
|
|
70
|
+
exports.computeResourceToDict = computeResourceToDict;
|
|
71
|
+
exports.humanResourceToDict = humanResourceToDict;
|
|
72
|
+
const crypto = __importStar(require("crypto"));
|
|
73
|
+
// -----------------------------------------------------------------------------
|
|
74
|
+
// Conversion helpers
|
|
75
|
+
// -----------------------------------------------------------------------------
|
|
76
|
+
function toolingResourceToDict(resource) {
|
|
77
|
+
return {
|
|
78
|
+
resource_id: resource.resourceId,
|
|
79
|
+
type: resource.type,
|
|
80
|
+
name: resource.name,
|
|
81
|
+
version: resource.version,
|
|
82
|
+
purpose: resource.purpose,
|
|
83
|
+
license: resource.license,
|
|
84
|
+
risk_assessment: resource.riskAssessment,
|
|
85
|
+
approved: resource.approved,
|
|
86
|
+
approved_by: resource.approvedBy,
|
|
87
|
+
approved_at: resource.approvedAt,
|
|
88
|
+
added_at: resource.addedAt,
|
|
89
|
+
metadata: resource.metadata,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function computeResourceToDict(resource) {
|
|
93
|
+
return {
|
|
94
|
+
resource_id: resource.resourceId,
|
|
95
|
+
type: resource.type,
|
|
96
|
+
provider: resource.provider,
|
|
97
|
+
description: resource.description,
|
|
98
|
+
capacity: resource.capacity,
|
|
99
|
+
purpose: resource.purpose,
|
|
100
|
+
cost_tier: resource.costTier,
|
|
101
|
+
location: resource.location,
|
|
102
|
+
compliance_certifications: resource.complianceCertifications,
|
|
103
|
+
added_at: resource.addedAt,
|
|
104
|
+
metadata: resource.metadata,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function humanResourceToDict(resource) {
|
|
108
|
+
return {
|
|
109
|
+
resource_id: resource.resourceId,
|
|
110
|
+
role: resource.role,
|
|
111
|
+
name: resource.name,
|
|
112
|
+
competencies: resource.competencies,
|
|
113
|
+
certifications: resource.certifications,
|
|
114
|
+
training_completed: resource.trainingCompleted,
|
|
115
|
+
training_required: resource.trainingRequired,
|
|
116
|
+
assigned_systems: resource.assignedSystems,
|
|
117
|
+
department: resource.department,
|
|
118
|
+
added_at: resource.addedAt,
|
|
119
|
+
updated_at: resource.updatedAt,
|
|
120
|
+
metadata: resource.metadata,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function inventoryToDict(inventory) {
|
|
124
|
+
return {
|
|
125
|
+
inventory_id: inventory.inventoryId,
|
|
126
|
+
system_id: inventory.systemId,
|
|
127
|
+
name: inventory.name,
|
|
128
|
+
description: inventory.description,
|
|
129
|
+
data_resources: inventory.dataResources,
|
|
130
|
+
tooling_resources: inventory.toolingResources.map(toolingResourceToDict),
|
|
131
|
+
compute_resources: inventory.computeResources.map(computeResourceToDict),
|
|
132
|
+
human_resources: inventory.humanResources.map(humanResourceToDict),
|
|
133
|
+
created_at: inventory.createdAt,
|
|
134
|
+
updated_at: inventory.updatedAt,
|
|
135
|
+
metadata: inventory.metadata,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function policyReviewToDict(review) {
|
|
139
|
+
return {
|
|
140
|
+
review_id: review.reviewId,
|
|
141
|
+
policy_id: review.policyId,
|
|
142
|
+
policy_name: review.policyName,
|
|
143
|
+
policy_type: review.policyType,
|
|
144
|
+
policy_version: review.policyVersion,
|
|
145
|
+
scheduled_date: review.scheduledDate,
|
|
146
|
+
status: review.status,
|
|
147
|
+
reviewer: review.reviewer,
|
|
148
|
+
review_date: review.reviewDate,
|
|
149
|
+
findings: review.findings,
|
|
150
|
+
recommendations: review.recommendations,
|
|
151
|
+
action_items: review.actionItems,
|
|
152
|
+
policy_status: review.policyStatus,
|
|
153
|
+
next_review_date: review.nextReviewDate,
|
|
154
|
+
created_at: review.createdAt,
|
|
155
|
+
updated_at: review.updatedAt,
|
|
156
|
+
metadata: review.metadata,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// -----------------------------------------------------------------------------
|
|
160
|
+
// Registry
|
|
161
|
+
// -----------------------------------------------------------------------------
|
|
162
|
+
class ResourceRegistry {
|
|
163
|
+
constructor() {
|
|
164
|
+
this.inventories = new Map();
|
|
165
|
+
this.policyReviews = new Map();
|
|
166
|
+
}
|
|
167
|
+
addInventory(inventory) {
|
|
168
|
+
this.inventories.set(inventory.inventoryId, inventory);
|
|
169
|
+
}
|
|
170
|
+
getInventory(inventoryId) {
|
|
171
|
+
return this.inventories.get(inventoryId);
|
|
172
|
+
}
|
|
173
|
+
getInventoryBySystem(systemId) {
|
|
174
|
+
for (const inv of this.inventories.values()) {
|
|
175
|
+
if (inv.systemId === systemId) {
|
|
176
|
+
return inv;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
listInventories() {
|
|
182
|
+
return Array.from(this.inventories.values());
|
|
183
|
+
}
|
|
184
|
+
addPolicyReview(review) {
|
|
185
|
+
this.policyReviews.set(review.reviewId, review);
|
|
186
|
+
}
|
|
187
|
+
getPolicyReview(reviewId) {
|
|
188
|
+
return this.policyReviews.get(reviewId);
|
|
189
|
+
}
|
|
190
|
+
listPolicyReviews(status, policyType) {
|
|
191
|
+
let reviews = Array.from(this.policyReviews.values());
|
|
192
|
+
if (status) {
|
|
193
|
+
reviews = reviews.filter((r) => r.status === status);
|
|
194
|
+
}
|
|
195
|
+
if (policyType) {
|
|
196
|
+
reviews = reviews.filter((r) => r.policyType === policyType);
|
|
197
|
+
}
|
|
198
|
+
return reviews;
|
|
199
|
+
}
|
|
200
|
+
clear() {
|
|
201
|
+
this.inventories.clear();
|
|
202
|
+
this.policyReviews.clear();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.ResourceRegistry = ResourceRegistry;
|
|
206
|
+
// Global registry
|
|
207
|
+
const registry = new ResourceRegistry();
|
|
208
|
+
function getRegistry() {
|
|
209
|
+
return registry;
|
|
210
|
+
}
|
|
211
|
+
// -----------------------------------------------------------------------------
|
|
212
|
+
// ID Generation
|
|
213
|
+
// -----------------------------------------------------------------------------
|
|
214
|
+
function generateInventoryId(systemId) {
|
|
215
|
+
const timestamp = new Date().toISOString();
|
|
216
|
+
const content = `inventory:${systemId}:${timestamp}`;
|
|
217
|
+
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
218
|
+
return `inv_${hash}`;
|
|
219
|
+
}
|
|
220
|
+
function generateResourceId(resourceType, name) {
|
|
221
|
+
const timestamp = new Date().toISOString();
|
|
222
|
+
const content = `resource:${resourceType}:${name}:${timestamp}`;
|
|
223
|
+
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
224
|
+
return `res_${hash}`;
|
|
225
|
+
}
|
|
226
|
+
function generateReviewId(policyId) {
|
|
227
|
+
const timestamp = new Date().toISOString();
|
|
228
|
+
const content = `review:${policyId}:${timestamp}`;
|
|
229
|
+
const hash = crypto.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
230
|
+
return `prv_${hash}`;
|
|
231
|
+
}
|
|
232
|
+
// -----------------------------------------------------------------------------
|
|
233
|
+
// Event Emission
|
|
234
|
+
// -----------------------------------------------------------------------------
|
|
235
|
+
function emitResourceEvent(eventType, data) {
|
|
236
|
+
try {
|
|
237
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
238
|
+
const { getState, emitEvent } = require('./runtime');
|
|
239
|
+
const state = getState();
|
|
240
|
+
if (!state)
|
|
241
|
+
return;
|
|
242
|
+
const config = state.config.resources || {};
|
|
243
|
+
if (config.enabled === false)
|
|
244
|
+
return;
|
|
245
|
+
emitEvent({
|
|
246
|
+
event_type: `resource.${eventType}`,
|
|
247
|
+
timestamp: new Date().toISOString(),
|
|
248
|
+
body: data,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// Silently ignore emission errors
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Create a new resource inventory for an AI system.
|
|
257
|
+
*/
|
|
258
|
+
function createResourceInventory(options) {
|
|
259
|
+
const now = new Date().toISOString();
|
|
260
|
+
const inventory = {
|
|
261
|
+
inventoryId: generateInventoryId(options.systemId),
|
|
262
|
+
systemId: options.systemId,
|
|
263
|
+
name: options.name || `Inventory for ${options.systemId}`,
|
|
264
|
+
description: options.description || "",
|
|
265
|
+
dataResources: [],
|
|
266
|
+
toolingResources: [],
|
|
267
|
+
computeResources: [],
|
|
268
|
+
humanResources: [],
|
|
269
|
+
createdAt: now,
|
|
270
|
+
updatedAt: now,
|
|
271
|
+
metadata: options.metadata || {},
|
|
272
|
+
};
|
|
273
|
+
registry.addInventory(inventory);
|
|
274
|
+
return inventory;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Get a resource inventory by ID.
|
|
278
|
+
*/
|
|
279
|
+
function getResourceInventory(inventoryId) {
|
|
280
|
+
return registry.getInventory(inventoryId);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Get the resource inventory for a system.
|
|
284
|
+
*/
|
|
285
|
+
function getInventoryForSystem(systemId) {
|
|
286
|
+
return registry.getInventoryBySystem(systemId);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Add a tooling resource to an inventory.
|
|
290
|
+
*/
|
|
291
|
+
function addToolingResource(options) {
|
|
292
|
+
const inventory = registry.getInventory(options.inventoryId);
|
|
293
|
+
if (!inventory)
|
|
294
|
+
return undefined;
|
|
295
|
+
const now = new Date().toISOString();
|
|
296
|
+
const resource = {
|
|
297
|
+
resourceId: generateResourceId("tooling", options.name),
|
|
298
|
+
type: options.type,
|
|
299
|
+
name: options.name,
|
|
300
|
+
version: options.version,
|
|
301
|
+
purpose: options.purpose,
|
|
302
|
+
license: options.license,
|
|
303
|
+
riskAssessment: options.riskAssessment,
|
|
304
|
+
approved: options.approved || false,
|
|
305
|
+
approvedBy: options.approvedBy,
|
|
306
|
+
approvedAt: options.approved ? now : undefined,
|
|
307
|
+
addedAt: now,
|
|
308
|
+
metadata: options.metadata || {},
|
|
309
|
+
};
|
|
310
|
+
inventory.toolingResources.push(resource);
|
|
311
|
+
inventory.updatedAt = now;
|
|
312
|
+
emitResourceEvent("tooling_resource_added", {
|
|
313
|
+
inventory_id: options.inventoryId,
|
|
314
|
+
resource: toolingResourceToDict(resource),
|
|
315
|
+
});
|
|
316
|
+
return resource;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Add a computing resource to an inventory.
|
|
320
|
+
*/
|
|
321
|
+
function addComputeResource(options) {
|
|
322
|
+
const inventory = registry.getInventory(options.inventoryId);
|
|
323
|
+
if (!inventory)
|
|
324
|
+
return undefined;
|
|
325
|
+
const now = new Date().toISOString();
|
|
326
|
+
const resource = {
|
|
327
|
+
resourceId: generateResourceId("compute", options.provider),
|
|
328
|
+
type: options.type,
|
|
329
|
+
provider: options.provider,
|
|
330
|
+
description: options.description,
|
|
331
|
+
capacity: options.capacity || {},
|
|
332
|
+
purpose: options.purpose || "",
|
|
333
|
+
costTier: options.costTier || "",
|
|
334
|
+
location: options.location,
|
|
335
|
+
complianceCertifications: options.complianceCertifications || [],
|
|
336
|
+
addedAt: now,
|
|
337
|
+
metadata: options.metadata || {},
|
|
338
|
+
};
|
|
339
|
+
inventory.computeResources.push(resource);
|
|
340
|
+
inventory.updatedAt = now;
|
|
341
|
+
emitResourceEvent("compute_resource_added", {
|
|
342
|
+
inventory_id: options.inventoryId,
|
|
343
|
+
resource: computeResourceToDict(resource),
|
|
344
|
+
});
|
|
345
|
+
return resource;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Add a human resource to an inventory.
|
|
349
|
+
*/
|
|
350
|
+
function addHumanResource(options) {
|
|
351
|
+
const inventory = registry.getInventory(options.inventoryId);
|
|
352
|
+
if (!inventory)
|
|
353
|
+
return undefined;
|
|
354
|
+
// Check config for competency tracking
|
|
355
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
356
|
+
const { getState } = require('./runtime');
|
|
357
|
+
const state = getState();
|
|
358
|
+
const config = state?.config?.resources || {};
|
|
359
|
+
const trackCompetencies = config.trackCompetencies !== false;
|
|
360
|
+
const now = new Date().toISOString();
|
|
361
|
+
const resource = {
|
|
362
|
+
resourceId: generateResourceId("human", options.role),
|
|
363
|
+
role: options.role,
|
|
364
|
+
name: options.name,
|
|
365
|
+
competencies: trackCompetencies ? options.competencies || [] : [],
|
|
366
|
+
certifications: options.certifications || [],
|
|
367
|
+
trainingCompleted: options.trainingCompleted || [],
|
|
368
|
+
trainingRequired: options.trainingRequired || [],
|
|
369
|
+
assignedSystems: options.assignedSystems || [],
|
|
370
|
+
department: options.department,
|
|
371
|
+
addedAt: now,
|
|
372
|
+
updatedAt: now,
|
|
373
|
+
metadata: options.metadata || {},
|
|
374
|
+
};
|
|
375
|
+
inventory.humanResources.push(resource);
|
|
376
|
+
inventory.updatedAt = now;
|
|
377
|
+
emitResourceEvent("human_resource_added", {
|
|
378
|
+
inventory_id: options.inventoryId,
|
|
379
|
+
resource: humanResourceToDict(resource),
|
|
380
|
+
});
|
|
381
|
+
return resource;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Add a data resource reference to an inventory.
|
|
385
|
+
*/
|
|
386
|
+
function addDataResource(inventoryId, datasetId) {
|
|
387
|
+
const inventory = registry.getInventory(inventoryId);
|
|
388
|
+
if (!inventory)
|
|
389
|
+
return false;
|
|
390
|
+
if (!inventory.dataResources.includes(datasetId)) {
|
|
391
|
+
inventory.dataResources.push(datasetId);
|
|
392
|
+
inventory.updatedAt = new Date().toISOString();
|
|
393
|
+
emitResourceEvent("data_resource_added", {
|
|
394
|
+
inventory_id: inventoryId,
|
|
395
|
+
dataset_id: datasetId,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Approve a tooling resource for use.
|
|
402
|
+
*/
|
|
403
|
+
function approveToolingResource(inventoryId, resourceId, approver, riskAssessment) {
|
|
404
|
+
const inventory = registry.getInventory(inventoryId);
|
|
405
|
+
if (!inventory)
|
|
406
|
+
return false;
|
|
407
|
+
const resource = inventory.toolingResources.find((r) => r.resourceId === resourceId);
|
|
408
|
+
if (!resource)
|
|
409
|
+
return false;
|
|
410
|
+
const now = new Date().toISOString();
|
|
411
|
+
resource.approved = true;
|
|
412
|
+
resource.approvedBy = approver;
|
|
413
|
+
resource.approvedAt = now;
|
|
414
|
+
if (riskAssessment) {
|
|
415
|
+
resource.riskAssessment = riskAssessment;
|
|
416
|
+
}
|
|
417
|
+
inventory.updatedAt = now;
|
|
418
|
+
emitResourceEvent("tooling_resource_approved", {
|
|
419
|
+
inventory_id: inventoryId,
|
|
420
|
+
resource_id: resourceId,
|
|
421
|
+
approver,
|
|
422
|
+
});
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Generate a summary of a resource inventory.
|
|
427
|
+
*/
|
|
428
|
+
function getInventorySummary(inventoryId) {
|
|
429
|
+
const inventory = registry.getInventory(inventoryId);
|
|
430
|
+
if (!inventory)
|
|
431
|
+
return undefined;
|
|
432
|
+
// Count approved vs total tooling
|
|
433
|
+
const approvedTooling = inventory.toolingResources.filter((t) => t.approved).length;
|
|
434
|
+
const totalTooling = inventory.toolingResources.length;
|
|
435
|
+
// Count by type
|
|
436
|
+
const toolingByType = {};
|
|
437
|
+
for (const t of inventory.toolingResources) {
|
|
438
|
+
toolingByType[t.type] = (toolingByType[t.type] || 0) + 1;
|
|
439
|
+
}
|
|
440
|
+
const computeByType = {};
|
|
441
|
+
for (const c of inventory.computeResources) {
|
|
442
|
+
computeByType[c.type] = (computeByType[c.type] || 0) + 1;
|
|
443
|
+
}
|
|
444
|
+
// Count training gaps
|
|
445
|
+
let trainingGaps = 0;
|
|
446
|
+
for (const h of inventory.humanResources) {
|
|
447
|
+
const completed = new Set(h.trainingCompleted);
|
|
448
|
+
const remaining = h.trainingRequired.filter((t) => !completed.has(t));
|
|
449
|
+
trainingGaps += remaining.length;
|
|
450
|
+
}
|
|
451
|
+
return {
|
|
452
|
+
inventoryId: inventory.inventoryId,
|
|
453
|
+
systemId: inventory.systemId,
|
|
454
|
+
name: inventory.name,
|
|
455
|
+
summary: {
|
|
456
|
+
dataResources: inventory.dataResources.length,
|
|
457
|
+
toolingResources: {
|
|
458
|
+
total: totalTooling,
|
|
459
|
+
approved: approvedTooling,
|
|
460
|
+
byType: toolingByType,
|
|
461
|
+
},
|
|
462
|
+
computeResources: {
|
|
463
|
+
total: inventory.computeResources.length,
|
|
464
|
+
byType: computeByType,
|
|
465
|
+
},
|
|
466
|
+
humanResources: {
|
|
467
|
+
total: inventory.humanResources.length,
|
|
468
|
+
trainingGaps,
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
updatedAt: inventory.updatedAt,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Schedule a policy review.
|
|
476
|
+
*/
|
|
477
|
+
function schedulePolicyReview(options) {
|
|
478
|
+
const now = new Date().toISOString();
|
|
479
|
+
const review = {
|
|
480
|
+
reviewId: generateReviewId(options.policyId),
|
|
481
|
+
policyId: options.policyId,
|
|
482
|
+
policyName: options.policyName,
|
|
483
|
+
policyType: options.policyType,
|
|
484
|
+
policyVersion: options.policyVersion,
|
|
485
|
+
scheduledDate: options.scheduledDate,
|
|
486
|
+
status: "scheduled",
|
|
487
|
+
findings: [],
|
|
488
|
+
recommendations: [],
|
|
489
|
+
actionItems: [],
|
|
490
|
+
policyStatus: "current",
|
|
491
|
+
createdAt: now,
|
|
492
|
+
updatedAt: now,
|
|
493
|
+
metadata: options.metadata || {},
|
|
494
|
+
};
|
|
495
|
+
registry.addPolicyReview(review);
|
|
496
|
+
emitResourceEvent("policy_review_scheduled", {
|
|
497
|
+
review: policyReviewToDict(review),
|
|
498
|
+
});
|
|
499
|
+
return review;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Start a policy review.
|
|
503
|
+
*/
|
|
504
|
+
function startPolicyReview(reviewId, reviewer) {
|
|
505
|
+
const review = registry.getPolicyReview(reviewId);
|
|
506
|
+
if (!review)
|
|
507
|
+
return undefined;
|
|
508
|
+
if (review.status !== "scheduled" && review.status !== "overdue") {
|
|
509
|
+
return review; // Can't start if already in progress or completed
|
|
510
|
+
}
|
|
511
|
+
const now = new Date().toISOString();
|
|
512
|
+
review.status = "in_progress";
|
|
513
|
+
review.reviewer = reviewer;
|
|
514
|
+
review.reviewDate = now;
|
|
515
|
+
review.updatedAt = now;
|
|
516
|
+
emitResourceEvent("policy_review_started", {
|
|
517
|
+
review_id: reviewId,
|
|
518
|
+
reviewer,
|
|
519
|
+
});
|
|
520
|
+
return review;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Complete a policy review with findings.
|
|
524
|
+
*/
|
|
525
|
+
function completePolicyReview(options) {
|
|
526
|
+
const review = registry.getPolicyReview(options.reviewId);
|
|
527
|
+
if (!review)
|
|
528
|
+
return undefined;
|
|
529
|
+
if (review.status !== "in_progress") {
|
|
530
|
+
return review; // Must be in progress to complete
|
|
531
|
+
}
|
|
532
|
+
// Get config for default review interval
|
|
533
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
534
|
+
const { getState } = require('./runtime');
|
|
535
|
+
const state = getState();
|
|
536
|
+
const config = state?.config?.resources || {};
|
|
537
|
+
const defaultInterval = config.policyReviewIntervalDays || 365;
|
|
538
|
+
// Calculate next review date if not provided
|
|
539
|
+
let nextReviewDate = options.nextReviewDate;
|
|
540
|
+
if (!nextReviewDate) {
|
|
541
|
+
const nextDate = new Date();
|
|
542
|
+
nextDate.setDate(nextDate.getDate() + defaultInterval);
|
|
543
|
+
nextReviewDate = nextDate.toISOString().split("T")[0];
|
|
544
|
+
}
|
|
545
|
+
const now = new Date().toISOString();
|
|
546
|
+
review.status = "completed";
|
|
547
|
+
review.findings = options.findings;
|
|
548
|
+
review.recommendations = options.recommendations;
|
|
549
|
+
review.actionItems = options.actionItems || [];
|
|
550
|
+
review.policyStatus = options.policyStatus || "current";
|
|
551
|
+
review.nextReviewDate = nextReviewDate;
|
|
552
|
+
review.updatedAt = now;
|
|
553
|
+
emitResourceEvent("policy_review_completed", {
|
|
554
|
+
review: policyReviewToDict(review),
|
|
555
|
+
});
|
|
556
|
+
return review;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Cancel a scheduled policy review.
|
|
560
|
+
*/
|
|
561
|
+
function cancelPolicyReview(reviewId, reason) {
|
|
562
|
+
const review = registry.getPolicyReview(reviewId);
|
|
563
|
+
if (!review)
|
|
564
|
+
return undefined;
|
|
565
|
+
if (review.status !== "scheduled" && review.status !== "overdue") {
|
|
566
|
+
return review; // Can only cancel scheduled or overdue reviews
|
|
567
|
+
}
|
|
568
|
+
review.status = "cancelled";
|
|
569
|
+
review.metadata.cancellationReason = reason;
|
|
570
|
+
review.updatedAt = new Date().toISOString();
|
|
571
|
+
emitResourceEvent("policy_review_cancelled", {
|
|
572
|
+
review_id: reviewId,
|
|
573
|
+
reason,
|
|
574
|
+
});
|
|
575
|
+
return review;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Find and mark overdue policy reviews.
|
|
579
|
+
*/
|
|
580
|
+
function checkOverdueReviews() {
|
|
581
|
+
const now = new Date().toISOString().split("T")[0];
|
|
582
|
+
const overdue = [];
|
|
583
|
+
for (const review of registry.listPolicyReviews("scheduled")) {
|
|
584
|
+
if (review.scheduledDate < now) {
|
|
585
|
+
review.status = "overdue";
|
|
586
|
+
review.updatedAt = new Date().toISOString();
|
|
587
|
+
overdue.push(review);
|
|
588
|
+
emitResourceEvent("policy_review_overdue", {
|
|
589
|
+
review_id: review.reviewId,
|
|
590
|
+
policy_id: review.policyId,
|
|
591
|
+
scheduled_date: review.scheduledDate,
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return overdue;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Generate a summary of all policy reviews.
|
|
599
|
+
*/
|
|
600
|
+
function getPolicyReviewSummary() {
|
|
601
|
+
const reviews = registry.listPolicyReviews();
|
|
602
|
+
// Count by status
|
|
603
|
+
const byStatus = {};
|
|
604
|
+
for (const r of reviews) {
|
|
605
|
+
byStatus[r.status] = (byStatus[r.status] || 0) + 1;
|
|
606
|
+
}
|
|
607
|
+
// Count by type
|
|
608
|
+
const byType = {};
|
|
609
|
+
for (const r of reviews) {
|
|
610
|
+
byType[r.policyType] = (byType[r.policyType] || 0) + 1;
|
|
611
|
+
}
|
|
612
|
+
// Find upcoming reviews
|
|
613
|
+
const upcoming = reviews
|
|
614
|
+
.filter((r) => r.status === "scheduled")
|
|
615
|
+
.map((r) => ({
|
|
616
|
+
reviewId: r.reviewId,
|
|
617
|
+
policyName: r.policyName,
|
|
618
|
+
scheduledDate: r.scheduledDate,
|
|
619
|
+
}))
|
|
620
|
+
.sort((a, b) => a.scheduledDate.localeCompare(b.scheduledDate))
|
|
621
|
+
.slice(0, 5);
|
|
622
|
+
// Find overdue reviews
|
|
623
|
+
const overdue = reviews
|
|
624
|
+
.filter((r) => r.status === "overdue")
|
|
625
|
+
.map(policyReviewToDict);
|
|
626
|
+
return {
|
|
627
|
+
totalReviews: reviews.length,
|
|
628
|
+
byStatus,
|
|
629
|
+
byType,
|
|
630
|
+
upcoming,
|
|
631
|
+
overdue,
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Emit a custom resource event.
|
|
636
|
+
*/
|
|
637
|
+
function emitCustomResourceEvent(eventType, inventoryId, data) {
|
|
638
|
+
const eventData = data || {};
|
|
639
|
+
if (inventoryId) {
|
|
640
|
+
eventData.inventory_id = inventoryId;
|
|
641
|
+
}
|
|
642
|
+
emitResourceEvent(eventType, eventData);
|
|
643
|
+
}
|