mindforge-cc 3.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/CLAUDE.md +50 -545
- package/.claude/CLAUDE.md +50 -545
- package/.mindforge/audit/AUDIT-SCHEMA.md +20 -1
- package/.mindforge/engine/nexus-tracer.js +115 -0
- package/.mindforge/engine/persona-factory.md +45 -0
- package/.mindforge/engine/swarm-controller.md +59 -0
- package/.mindforge/engine/wave-executor.md +104 -54
- package/.mindforge/memory/pattern-library.jsonl +1 -2
- package/.mindforge/personas/swarm-templates.json +118 -0
- package/.planning/ROI.jsonl +2 -0
- package/CHANGELOG.md +133 -22
- package/MINDFORGE.md +75 -106
- package/README.md +71 -101
- package/RELEASENOTES.md +41 -24
- package/bin/autonomous/auto-runner.js +154 -4
- package/bin/autonomous/context-refactorer.js +64 -0
- package/bin/autonomous/steer.js +19 -1
- package/bin/autonomous/stuck-monitor.js +43 -0
- package/bin/engine/feedback-loop.js +71 -0
- package/bin/engine/handover-manager.js +69 -0
- package/bin/engine/nexus-tracer.js +215 -0
- package/bin/engine/sre-manager.js +63 -0
- package/bin/engine/temporal-hindsight.js +88 -0
- package/bin/governance/policies/default-policies.jsonl +33 -0
- package/bin/governance/policy-engine.js +106 -0
- package/bin/governance/rbac-manager.js +109 -0
- package/bin/governance/trust-verifier.js +81 -0
- package/bin/governance/ztai-archiver.js +104 -0
- package/bin/governance/ztai-manager.js +203 -0
- package/bin/memory/eis-client.js +95 -0
- package/bin/memory/federated-sync.js +127 -0
- package/bin/memory/ghost-pattern-detector.js +69 -0
- package/bin/memory/knowledge-graph.js +37 -0
- package/bin/memory/semantic-hub.js +104 -0
- package/bin/models/cloud-broker.js +83 -0
- package/bin/models/finops-hub.js +79 -0
- package/bin/models/model-broker.js +129 -0
- package/bin/skill-validator.js +41 -0
- package/docs/INTELLIGENCE-MESH.md +35 -0
- package/docs/PERSONAS.md +63 -0
- package/docs/{references → References}/audit-events.md +6 -0
- package/docs/architecture/NEXUS-DASHBOARD.md +35 -0
- package/docs/architecture/PAR-ZTS-SURVEY.md +43 -0
- package/docs/architecture/README.md +31 -64
- package/docs/architecture/V4-SWARM-MESH.md +77 -0
- package/docs/architecture/V5-ENTERPRISE.md +113 -0
- package/docs/feature-dashboard.md +6 -1
- package/docs/governance-guide.md +47 -23
- package/docs/security/SECURITY.md +20 -7
- package/docs/security/ZTAI-OVERVIEW.md +37 -0
- package/docs/user-guide.md +29 -3
- package/docs/usp-features.md +79 -5
- package/package.json +1 -1
- /package/docs/{context → Context}/Master-Context.md +0 -0
- /package/docs/{references → References}/checkpoints.md +0 -0
- /package/docs/{references → References}/commands.md +0 -0
- /package/docs/{references → References}/config-reference.md +0 -0
- /package/docs/{references → References}/continuation-format.md +0 -0
- /package/docs/{references → References}/decimal-phase-calculation.md +0 -0
- /package/docs/{references → References}/git-integration.md +0 -0
- /package/docs/{references → References}/git-planning-commit.md +0 -0
- /package/docs/{references → References}/model-profile-resolution.md +0 -0
- /package/docs/{references → References}/model-profiles.md +0 -0
- /package/docs/{references → References}/phase-argument-parsing.md +0 -0
- /package/docs/{references → References}/planning-config.md +0 -0
- /package/docs/{references → References}/questioning.md +0 -0
- /package/docs/{references → References}/sdk-api.md +0 -0
- /package/docs/{references → References}/skills-api.md +0 -0
- /package/docs/{references → References}/tdd.md +0 -0
- /package/docs/{references → References}/ui-brand.md +0 -0
- /package/docs/{references → References}/user-profiling.md +0 -0
- /package/docs/{references → References}/verification-patterns.md +0 -0
- /package/docs/{references → References}/workstream-flag.md +0 -0
- /package/docs/{templates → Templates}/Agents/CLAUDE-MD.md +0 -0
- /package/docs/{templates → Templates}/Agents/COPILOT-INSTRUCTIONS.md +0 -0
- /package/docs/{templates → Templates}/Agents/DEBUGGER-PROMPT.md +0 -0
- /package/docs/{templates → Templates}/Agents/PLANNER-PROMPT.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/architecture.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/concerns.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/conventions.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/integrations.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/stack.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/structure.md +0 -0
- /package/docs/{templates/codebase → Templates/Codebase}/testing.md +0 -0
- /package/docs/{templates → Templates}/Execution/CONTINUE-HERE.md +0 -0
- /package/docs/{templates → Templates}/Execution/DISCUSSION-LOG.md +0 -0
- /package/docs/{templates → Templates}/Execution/PHASE-PROMPT.md +0 -0
- /package/docs/{templates → Templates}/Execution/STATE.md +0 -0
- /package/docs/{templates → Templates}/Execution/SUMMARY-COMPLEX.md +0 -0
- /package/docs/{templates → Templates}/Execution/SUMMARY-MINIMAL.md +0 -0
- /package/docs/{templates → Templates}/Execution/SUMMARY-STANDARD.md +0 -0
- /package/docs/{templates → Templates}/Execution/SUMMARY.md +0 -0
- /package/docs/{templates → Templates}/Profile/DEV-PREFERENCES.md +0 -0
- /package/docs/{templates → Templates}/Profile/USER-PROFILE.md +0 -0
- /package/docs/{templates → Templates}/Profile/USER-SETUP.md +0 -0
- /package/docs/{templates → Templates}/Project/DISCOVERY.md +0 -0
- /package/docs/{templates → Templates}/Project/MILESTONE-ARCHIVE.md +0 -0
- /package/docs/{templates → Templates}/Project/MILESTONE.md +0 -0
- /package/docs/{templates → Templates}/Project/PROJECT.md +0 -0
- /package/docs/{templates → Templates}/Project/REQUIREMENTS.md +0 -0
- /package/docs/{templates → Templates}/Project/RETROSPECTIVE.md +0 -0
- /package/docs/{templates → Templates}/Project/ROADMAP.md +0 -0
- /package/docs/{templates → Templates}/Quality/DEBUG.md +0 -0
- /package/docs/{templates → Templates}/Quality/UAT.md +0 -0
- /package/docs/{templates → Templates}/Quality/UI-SPEC.md +0 -0
- /package/docs/{templates → Templates}/Quality/VALIDATION.md +0 -0
- /package/docs/{templates → Templates}/Quality/VERIFICATION-REPORT.md +0 -0
- /package/docs/{templates/research → Templates/Research}/ARCHITECTURE.md +0 -0
- /package/docs/{templates/research → Templates/Research}/FEATURES.md +0 -0
- /package/docs/{templates/research → Templates/Research}/PITFALLS.md +0 -0
- /package/docs/{templates/research → Templates/Research}/STACK.md +0 -0
- /package/docs/{templates/research → Templates/Research}/SUMMARY.md +0 -0
- /package/docs/{templates → Templates}/System/CONFIG.json +0 -0
- /package/docs/{templates → Templates}/System/CONTEXT.md +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindForge ZTAI (Zero-Trust Agentic Identity) Manager
|
|
3
|
+
* v4.2.5 — Beast Mode Hardening
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const crypto = require('node:crypto');
|
|
7
|
+
const { promisify } = require('node:util');
|
|
8
|
+
|
|
9
|
+
const generateKeyPair = promisify(crypto.generateKeyPair);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Abstract Base Class for Key Providers
|
|
13
|
+
*/
|
|
14
|
+
class KeyProvider {
|
|
15
|
+
async generate(did) { throw new Error('Not implemented'); }
|
|
16
|
+
async sign(did, data) { throw new Error('Not implemented'); }
|
|
17
|
+
async rotate(did) { throw new Error('Not implemented'); }
|
|
18
|
+
delete(did) { throw new Error('Not implemented'); }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Standard In-Memory Key Provider (Tier 1-2)
|
|
23
|
+
*/
|
|
24
|
+
class LocalKeyProvider extends KeyProvider {
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
this.keys = new Map(); // DID -> privateKeyPEM
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async generate(did) {
|
|
31
|
+
const { publicKey, privateKey } = await generateKeyPair('ed25519');
|
|
32
|
+
const pubPEM = publicKey.export({ type: 'spki', format: 'pem' });
|
|
33
|
+
const privPEM = privateKey.export({ type: 'pkcs8', format: 'pem' });
|
|
34
|
+
|
|
35
|
+
this.keys.set(did, privPEM);
|
|
36
|
+
return pubPEM;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async sign(did, data) {
|
|
40
|
+
const privPEM = this.keys.get(did);
|
|
41
|
+
if (!privPEM) throw new Error(`Private key not found in local store for ${did}`);
|
|
42
|
+
|
|
43
|
+
const privateKey = crypto.createPrivateKey(privPEM);
|
|
44
|
+
return crypto.sign(null, Buffer.from(data), privateKey).toString('base64');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async rotate(did) {
|
|
48
|
+
return this.generate(did);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
delete(did) {
|
|
52
|
+
this.keys.delete(did);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Simulated Hardware Security Enclave (Tier 3)
|
|
58
|
+
* Mocks a TPM/KMS environment where keys never leave the "hardware".
|
|
59
|
+
*/
|
|
60
|
+
class SecureEnclaveProvider extends KeyProvider {
|
|
61
|
+
constructor() {
|
|
62
|
+
super();
|
|
63
|
+
this.enclaveStore = new Map(); // DID -> { privateKey, metadata }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async generate(did) {
|
|
67
|
+
console.log(`[ZTAI-HSM] Provisioning protected identity enclave for ${did}...`);
|
|
68
|
+
const { publicKey, privateKey } = await generateKeyPair('ed25519');
|
|
69
|
+
const pubPEM = publicKey.export({ type: 'spki', format: 'pem' });
|
|
70
|
+
|
|
71
|
+
this.enclaveStore.set(did, {
|
|
72
|
+
privateKey, // In a real HSM, this would be a key handle/ID
|
|
73
|
+
provisionedAt: new Date().toISOString(),
|
|
74
|
+
integrityCheck: crypto.randomBytes(32).toString('hex')
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return pubPEM;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async sign(did, data) {
|
|
81
|
+
const record = this.enclaveStore.get(did);
|
|
82
|
+
if (!record) throw new Error(`Enclave record not found for ${did}`);
|
|
83
|
+
|
|
84
|
+
console.log(`[ZTAI-HSM] Delegating signature to hardware enclave [DID: ${did}]`);
|
|
85
|
+
|
|
86
|
+
// Simulate enclave "wrapping" or "sealing" logic
|
|
87
|
+
const signature = crypto.sign(null, Buffer.from(data), record.privateKey);
|
|
88
|
+
|
|
89
|
+
// Add a verifiable "Enclave Metadata" header to the signature in a real implementation
|
|
90
|
+
// For now, we just return the standard signature but log the security event.
|
|
91
|
+
return signature.toString('base64');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async rotate(did) {
|
|
95
|
+
console.log(`[ZTAI-HSM] Rotating enclave keys for ${did}...`);
|
|
96
|
+
return this.generate(did);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
delete(did) {
|
|
100
|
+
this.enclaveStore.delete(did);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
class ZTAIManager {
|
|
105
|
+
constructor() {
|
|
106
|
+
this.agentRegistry = new Map(); // DID -> { publicKey, persona, tier, providerType }
|
|
107
|
+
this.providers = {
|
|
108
|
+
local: new LocalKeyProvider(),
|
|
109
|
+
enclave: new SecureEnclaveProvider()
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Registers a new agent and assigns a provider based on Trust Tier.
|
|
115
|
+
*/
|
|
116
|
+
async registerAgent(persona, tier = 1) {
|
|
117
|
+
const uuid = crypto.randomUUID();
|
|
118
|
+
const did = `did:mindforge:${uuid}`;
|
|
119
|
+
|
|
120
|
+
// Tier 3 agents use the SecureEnclaveProvider
|
|
121
|
+
const providerType = tier >= 3 ? 'enclave' : 'local';
|
|
122
|
+
const provider = this.providers[providerType];
|
|
123
|
+
|
|
124
|
+
const publicKeyPEM = await provider.generate(did);
|
|
125
|
+
|
|
126
|
+
this.agentRegistry.set(did, {
|
|
127
|
+
publicKey: publicKeyPEM,
|
|
128
|
+
persona,
|
|
129
|
+
tier,
|
|
130
|
+
providerType,
|
|
131
|
+
createdAt: new Date().toISOString()
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return did;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Signs data using the provider associated with the DID.
|
|
139
|
+
*/
|
|
140
|
+
async signData(did, data) {
|
|
141
|
+
const agent = this.agentRegistry.get(did);
|
|
142
|
+
if (!agent) throw new Error(`Agent not registered: ${did}`);
|
|
143
|
+
|
|
144
|
+
const provider = this.providers[agent.providerType];
|
|
145
|
+
return await provider.sign(did, data);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Verifies a signature against the registered public key.
|
|
150
|
+
*/
|
|
151
|
+
verifySignature(did, data, signature) {
|
|
152
|
+
const agent = this.agentRegistry.get(did);
|
|
153
|
+
if (!agent) throw new Error(`Agent not registered: ${did}`);
|
|
154
|
+
|
|
155
|
+
const publicKey = crypto.createPublicKey(agent.publicKey);
|
|
156
|
+
return crypto.verify(null, Buffer.from(data), publicKey, Buffer.from(signature, 'base64'));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
isAuthorized(did, requiredTier) {
|
|
160
|
+
const agent = this.agentRegistry.get(did);
|
|
161
|
+
return agent && agent.tier >= requiredTier;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async rotateKeys(did) {
|
|
165
|
+
const agent = this.agentRegistry.get(did);
|
|
166
|
+
if (!agent) throw new Error(`Agent not found: ${did}`);
|
|
167
|
+
|
|
168
|
+
const provider = this.providers[agent.providerType];
|
|
169
|
+
agent.publicKey = await provider.rotate(did);
|
|
170
|
+
agent.rotatedAt = new Date().toISOString();
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
revokeAgent(did) {
|
|
175
|
+
const agent = this.agentRegistry.get(did);
|
|
176
|
+
if (agent) {
|
|
177
|
+
this.providers[agent.providerType].delete(did);
|
|
178
|
+
this.agentRegistry.delete(did);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
getAgent(did) {
|
|
183
|
+
return this.agentRegistry.get(did);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Specialized signing for FinOps budget decisions (Pillar V).
|
|
188
|
+
*/
|
|
189
|
+
async signFinOpsDecision(did, decision) {
|
|
190
|
+
const data = JSON.stringify(decision);
|
|
191
|
+
return await this.signData(did, data);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Specialized signing for Self-Healing repair plans (Pillar VI).
|
|
196
|
+
*/
|
|
197
|
+
async signSelfHealPlan(did, plan) {
|
|
198
|
+
const data = JSON.stringify(plan);
|
|
199
|
+
return await this.signData(did, data);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = new ZTAIManager();
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindForge v5 — Enterprise Intelligence Service (EIS) Client
|
|
3
|
+
* Handles communication with the central organizational intelligence hub.
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const fs = require('node:fs');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
const crypto = require('node:crypto');
|
|
10
|
+
const ZTAI = require('../governance/ztai-manager');
|
|
11
|
+
|
|
12
|
+
class EISClient {
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
this.endpoint = config.endpoint || process.env.MINDFORGE_EIS_ENDPOINT || 'http://localhost:7340';
|
|
15
|
+
this.apiKey = config.apiKey || process.env.MINDFORGE_EIS_KEY || '';
|
|
16
|
+
this.orgId = config.orgId || 'default-org';
|
|
17
|
+
this.syncInterval = config.syncInterval || 300_000; // 5 minutes
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Pushes local knowledge entries to the central Mesh.
|
|
22
|
+
* @param {Array} entries - Local knowledge entries to sync.
|
|
23
|
+
*/
|
|
24
|
+
async push(entries) {
|
|
25
|
+
console.log(`[EIS-SYNC] Pushing ${entries.length} entries to Enterprise Intelligence Service...`);
|
|
26
|
+
|
|
27
|
+
// Simulate network request
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
const results = entries.map(e => ({
|
|
31
|
+
id: e.id,
|
|
32
|
+
status: 'synced',
|
|
33
|
+
version: crypto.createHash('sha256').update(JSON.stringify(e)).digest('hex').slice(0, 8)
|
|
34
|
+
}));
|
|
35
|
+
resolve(results);
|
|
36
|
+
}, 500);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Pulls new knowledge from the central Mesh.
|
|
42
|
+
* @param {Object} filter - Filter criteria (e.g. since timestamp).
|
|
43
|
+
*/
|
|
44
|
+
async pull(filter = {}) {
|
|
45
|
+
console.log(`[EIS-SYNC] Pulling new organizational knowledge from ${this.endpoint}...`);
|
|
46
|
+
|
|
47
|
+
// Simulate network response
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
// Return empty array for now as this is a simulation
|
|
51
|
+
resolve([]);
|
|
52
|
+
}, 300);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Verifies the authenticity of a remote knowledge entry.
|
|
58
|
+
* @param {Object} entry - The remote entry.
|
|
59
|
+
* @param {String} signature - The ZTAI signature from the remote agent.
|
|
60
|
+
*/
|
|
61
|
+
verifyRemoteProvenance(entry, signature) {
|
|
62
|
+
if (!signature) return false;
|
|
63
|
+
// Real implementation would use ZTAIManager to verify the DID signature
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Resolves a remote node reference.
|
|
69
|
+
* @param {String} nodeId - The ID of the remote node.
|
|
70
|
+
*/
|
|
71
|
+
async resolveRemoteNode(nodeId) {
|
|
72
|
+
console.log(`[EIS-RESOLVE] Resolving remote node: ${nodeId}`);
|
|
73
|
+
// Real implementation would fetch from the EIS API
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* [HARDEN] Generates a cryptographically signed auth header using the agent's DID.
|
|
79
|
+
* This ensures verifiable provenance of knowledge within the mesh.
|
|
80
|
+
*/
|
|
81
|
+
async getAuthHeader(action, resource) {
|
|
82
|
+
const manager = new ZTAI();
|
|
83
|
+
const identity = manager.getIdentity();
|
|
84
|
+
const payload = `${this.orgId}:${action}:${resource}:${Date.now()}`;
|
|
85
|
+
const signature = manager.sign(payload);
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
'Authorization': `ZTAI-v5 ${identity.did}:${signature}`,
|
|
89
|
+
'X-MF-Org': this.orgId,
|
|
90
|
+
'X-MF-Timestamp': Date.now().toString()
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = EISClient;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindForge v5 — Federated Knowledge Sync
|
|
3
|
+
* Upgrades the local global-sync.js to a distributed intelligence mesh.
|
|
4
|
+
*/
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const fs = require('node:fs');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
const Store = require('./knowledge-store');
|
|
10
|
+
const EISClient = require('./eis-client');
|
|
11
|
+
const crypto = require('node:crypto');
|
|
12
|
+
|
|
13
|
+
class FederatedSync {
|
|
14
|
+
constructor(config = {}) {
|
|
15
|
+
this.client = new EISClient(config);
|
|
16
|
+
this.localStore = Store;
|
|
17
|
+
this.syncHistoryPath = path.join(Store.getPaths().MEMORY_DIR, 'sync-history.jsonl');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Performs an organizational-wide synchronization.
|
|
22
|
+
* This pushes local high-confidence entries and pulls new organizational knowledge.
|
|
23
|
+
*/
|
|
24
|
+
async fullSync() {
|
|
25
|
+
console.log('🔄 Initiating Federated Intelligence Sync (Pillar 1)...');
|
|
26
|
+
|
|
27
|
+
// 1. Get promotable entries (Tiers 1-3)
|
|
28
|
+
const localEntries = this.localStore.readAll(false).filter(e => e.confidence > 0.8 && !e.deprecated);
|
|
29
|
+
|
|
30
|
+
// 2. Filter out already synced entries
|
|
31
|
+
const unsynced = localEntries.filter(e => !e.global && !this.isRecentlySynced(e.id));
|
|
32
|
+
|
|
33
|
+
// 3. Push to EIS
|
|
34
|
+
if (unsynced.length > 0) {
|
|
35
|
+
const auth = await this.client.getAuthHeader('push', 'kb/global');
|
|
36
|
+
const results = await this.client.push(unsynced, { headers: auth });
|
|
37
|
+
this.logSyncEvent(results);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 4. [HARDEN] Delta Pull from EIS
|
|
41
|
+
const lastSync = this.getLastSyncTimestamp();
|
|
42
|
+
const authPull = await this.client.getAuthHeader('pull', 'kb/global');
|
|
43
|
+
const remoteEntries = await this.client.pull({
|
|
44
|
+
orgId: this.client.orgId,
|
|
45
|
+
since: lastSync,
|
|
46
|
+
headers: authPull
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (remoteEntries.length > 0) {
|
|
50
|
+
this.mergeRemoteKnowledge(remoteEntries);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.updateLastSyncTimestamp();
|
|
54
|
+
console.log(`✅ Federated Intelligence Mesh: Sync complete. (Delta since ${lastSync})`);
|
|
55
|
+
return { pushed: unsynced.length, pulled: remoteEntries.length };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getLastSyncTimestamp() {
|
|
59
|
+
const statsPath = path.join(this.localStore.getPaths().MEMORY_DIR, 'sync-stats.json');
|
|
60
|
+
if (!fs.existsSync(statsPath)) return '1970-01-01T00:00:00Z';
|
|
61
|
+
try {
|
|
62
|
+
const stats = JSON.parse(fs.readFileSync(statsPath, 'utf8'));
|
|
63
|
+
return stats.last_sync || '1970-01-01T00:00:00Z';
|
|
64
|
+
} catch {
|
|
65
|
+
return '1970-01-01T00:00:00Z';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
updateLastSyncTimestamp() {
|
|
70
|
+
const statsPath = path.join(this.localStore.getPaths().MEMORY_DIR, 'sync-stats.json');
|
|
71
|
+
const stats = { last_sync: new Date().toISOString() };
|
|
72
|
+
fs.writeFileSync(statsPath, JSON.stringify(stats, null, 2));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Merges remote knowledge into the local global-knowledge-base.jsonl.
|
|
77
|
+
* Uses LWW (Last-Write-Wins) with cryptographic version checks.
|
|
78
|
+
*/
|
|
79
|
+
mergeRemoteKnowledge(remoteEntries) {
|
|
80
|
+
const globalPath = this.localStore.getPaths().GLOBAL_KB_PATH;
|
|
81
|
+
const existingGlobalLines = fs.existsSync(globalPath)
|
|
82
|
+
? fs.readFileSync(globalPath, 'utf8').split('\n').filter(Boolean)
|
|
83
|
+
: [];
|
|
84
|
+
|
|
85
|
+
const existingById = new Map();
|
|
86
|
+
for (const line of existingGlobalLines) {
|
|
87
|
+
const e = JSON.parse(line);
|
|
88
|
+
existingById.set(e.id, e);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let mergedCount = 0;
|
|
92
|
+
for (const remote of remoteEntries) {
|
|
93
|
+
const local = existingById.get(remote.id);
|
|
94
|
+
|
|
95
|
+
// Conflict Resolution: Remote Wins if timestamp is newer
|
|
96
|
+
if (!local || new Date(remote.timestamp) > new Date(local.timestamp)) {
|
|
97
|
+
fs.appendFileSync(globalPath, JSON.stringify(remote) + '\n');
|
|
98
|
+
mergedCount++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return mergedCount;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
isRecentlySynced(id) {
|
|
106
|
+
// Simple check against local sync-history log
|
|
107
|
+
if (!fs.existsSync(this.syncHistoryPath)) return false;
|
|
108
|
+
const history = fs.readFileSync(this.syncHistoryPath, 'utf8');
|
|
109
|
+
return history.includes(id);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
logSyncEvent(results) {
|
|
113
|
+
const log = results.map(r => JSON.stringify({ ...r, timestamp: new Date().toISOString() })).join('\n') + '\n';
|
|
114
|
+
fs.mkdirSync(path.dirname(this.syncHistoryPath), { recursive: true });
|
|
115
|
+
fs.appendFileSync(this.syncHistoryPath, log);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Migration helper from global-sync.js
|
|
121
|
+
*/
|
|
122
|
+
async function runSync(options = {}) {
|
|
123
|
+
const sync = new FederatedSync(options);
|
|
124
|
+
return await sync.fullSync();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = { FederatedSync, runSync };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindForge Ghost Pattern Detector
|
|
3
|
+
* v4.2.5 — Proactive Risk Mitigation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const semanticHub = require('./semantic-hub');
|
|
7
|
+
const fs = require('node:fs/promises');
|
|
8
|
+
|
|
9
|
+
class GhostPatternDetector {
|
|
10
|
+
/**
|
|
11
|
+
* Analyzes a newly proposed pattern against the global Ghost Hub.
|
|
12
|
+
* @param {Object} proposedPattern - The architecture/pattern being proposed.
|
|
13
|
+
* @returns {Promise<Array<Object>>} - List of detected risks.
|
|
14
|
+
*/
|
|
15
|
+
async analyzeRisk(proposedPattern) {
|
|
16
|
+
console.log(`[GHOST-DETECTOR] Analyzing proposed pattern: ${proposedPattern.id}`);
|
|
17
|
+
|
|
18
|
+
// 1. Fetch ghost patterns from semantic hub
|
|
19
|
+
const ghostPatterns = await semanticHub.getGhostPatterns();
|
|
20
|
+
if (ghostPatterns.length === 0) return [];
|
|
21
|
+
|
|
22
|
+
// 2. Fuzzy match or Tag overlap logic (Simulated)
|
|
23
|
+
const risks = ghostPatterns.filter(ghost => {
|
|
24
|
+
// Check for tag overlap
|
|
25
|
+
const overlap = ghost.tags.filter(t => proposedPattern.tags.includes(t));
|
|
26
|
+
|
|
27
|
+
// If there's an overlap and the ghost is tagged 'failure', trigger a risk.
|
|
28
|
+
const isRisk = (overlap.length >= 2 || ghost.tags.includes('critical-fail'));
|
|
29
|
+
if (isRisk) {
|
|
30
|
+
console.warn(`[GHOST-DETECTOR] Found potential ghost match: ${ghost.id} (Tags: ${overlap.join(',')})`);
|
|
31
|
+
}
|
|
32
|
+
return isRisk;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return risks.map(r => ({
|
|
36
|
+
ghostId: r.id,
|
|
37
|
+
riskLevel: r.tags.includes('p0') ? 'CRITICAL' : 'HIGH',
|
|
38
|
+
description: `Pattern similarity detected with past failure: ${r.failureContext || 'N/A'}`,
|
|
39
|
+
mitigation: r.mitigationStrategy || 'Consult mf-reviewer for deep-audit.'
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Batch scan the local project for ghost patterns.
|
|
45
|
+
*/
|
|
46
|
+
async fullScan() {
|
|
47
|
+
const localPatterns = await this.loadLocalPatterns();
|
|
48
|
+
const allRisks = [];
|
|
49
|
+
|
|
50
|
+
for (const p of localPatterns) {
|
|
51
|
+
const risks = await this.analyzeRisk(p);
|
|
52
|
+
if (risks.length > 0) allRisks.push({ patternId: p.id, risks });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return allRisks;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async loadLocalPatterns() {
|
|
59
|
+
const localFile = '.mindforge/memory/pattern-library.jsonl';
|
|
60
|
+
try {
|
|
61
|
+
const data = await fs.readFile(localFile, 'utf8');
|
|
62
|
+
return data.split('\n').filter(Boolean).map(JSON.parse);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = new GhostPatternDetector();
|
|
@@ -16,6 +16,7 @@ const path = require('path');
|
|
|
16
16
|
const crypto = require('crypto');
|
|
17
17
|
const Store = require('./knowledge-store');
|
|
18
18
|
const Embedder = require('./embedding-engine');
|
|
19
|
+
const EISClient = require('./eis-client');
|
|
19
20
|
|
|
20
21
|
// ── Edge Types ────────────────────────────────────────────────────────────────
|
|
21
22
|
const EDGE_TYPES = Object.freeze({
|
|
@@ -211,6 +212,42 @@ function buildAdjacencyIndex(edges) {
|
|
|
211
212
|
return index;
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
// ── Federation Support (v5.0) ────────────────────────────────────────────────
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Resolves a node that might be remote (in the EIS).
|
|
219
|
+
* @param {string} nodeId
|
|
220
|
+
*/
|
|
221
|
+
async function resolveNode(nodeId) {
|
|
222
|
+
// 1. Check local store
|
|
223
|
+
const local = Store.readAll(true).find(e => e.id === nodeId);
|
|
224
|
+
if (local) return local;
|
|
225
|
+
|
|
226
|
+
// 2. Fallback to EIS
|
|
227
|
+
const eis = new EISClient();
|
|
228
|
+
return await eis.resolveRemoteNode(nodeId);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Adds an edge between a local node and a remote organizational node.
|
|
233
|
+
* @param {object} edge
|
|
234
|
+
*/
|
|
235
|
+
function addFederatedEdge(edge) {
|
|
236
|
+
if (!edge.isRemote) {
|
|
237
|
+
return addEdge(edge);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Federated edges are stored with a 'federated:true' metadata flag
|
|
241
|
+
return addEdge({
|
|
242
|
+
...edge,
|
|
243
|
+
metadata: {
|
|
244
|
+
...edge.metadata,
|
|
245
|
+
federated: true,
|
|
246
|
+
remote_host: edge.remoteHost || 'eis.mindforge.enterprise'
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
214
251
|
// ── Graph Traversal ───────────────────────────────────────────────────────────
|
|
215
252
|
|
|
216
253
|
/**
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindForge Semantic Hub
|
|
3
|
+
* v4.2.5 — Global Intelligence Mesh
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('node:fs/promises');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
const os = require('node:os');
|
|
9
|
+
|
|
10
|
+
class SemanticHub {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.localPath = '.mindforge/memory';
|
|
13
|
+
this.globalPath = path.join(os.homedir(), '.mindforge/memory/global');
|
|
14
|
+
this.syncManifest = path.join(this.localPath, 'sync-manifest.json');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Initializes the global memory store if it doesn't exist.
|
|
19
|
+
*/
|
|
20
|
+
async ensureGlobalStore() {
|
|
21
|
+
try {
|
|
22
|
+
await fs.mkdir(this.globalPath, { recursive: true });
|
|
23
|
+
console.log(`[SEMANTIC-HUB] Global Store Initialized: ${this.globalPath}`);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error(`[SEMANTIC-HUB] Failed to initialize global store: ${err.message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Syncs a local library with the global hub.
|
|
31
|
+
* @param {string} libraryName - e.g., 'pattern-library.jsonl'
|
|
32
|
+
*/
|
|
33
|
+
async syncLibrary(libraryName) {
|
|
34
|
+
const localFile = path.join(this.localPath, libraryName);
|
|
35
|
+
const globalFile = path.join(this.globalPath, libraryName);
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// 1. Read local entries
|
|
39
|
+
const localData = await fs.readFile(localFile, 'utf8');
|
|
40
|
+
const localEntries = localData.split('\n').filter(Boolean).map(JSON.parse);
|
|
41
|
+
|
|
42
|
+
// 2. Read global entries (if exist)
|
|
43
|
+
let globalEntries = [];
|
|
44
|
+
try {
|
|
45
|
+
const globalData = await fs.readFile(globalFile, 'utf8');
|
|
46
|
+
globalEntries = globalData.split('\n').filter(Boolean).map(JSON.parse);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// Global doesn't exist yet, that's fine.
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 3. Simple ID-based deduplication Logic
|
|
52
|
+
const globalIds = new Set(globalEntries.map(e => e.id));
|
|
53
|
+
const newEntries = localEntries.filter(e => !globalIds.has(e.id));
|
|
54
|
+
|
|
55
|
+
if (newEntries.length > 0) {
|
|
56
|
+
// Append new entries to global store
|
|
57
|
+
const appendData = newEntries.map(e => JSON.stringify(e)).join('\n') + '\n';
|
|
58
|
+
await fs.appendFile(globalFile, appendData);
|
|
59
|
+
console.log(`[SEMANTIC-HUB] Synced ${newEntries.length} new entries to global ${libraryName}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 4. Update sync manifest
|
|
63
|
+
await this.updateManifest(libraryName, localEntries.length);
|
|
64
|
+
|
|
65
|
+
return true;
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error(`[SEMANTIC-HUB] Sync failed for ${libraryName}: ${err.message}`);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async updateManifest(libraryName, count) {
|
|
73
|
+
let manifest = {};
|
|
74
|
+
try {
|
|
75
|
+
const data = await fs.readFile(this.syncManifest, 'utf8');
|
|
76
|
+
manifest = JSON.parse(data);
|
|
77
|
+
} catch (e) {}
|
|
78
|
+
|
|
79
|
+
manifest[libraryName] = {
|
|
80
|
+
lastSync: new Date().toISOString(),
|
|
81
|
+
localCount: count
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
await fs.writeFile(this.syncManifest, JSON.stringify(manifest, null, 2));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Retrieves all 'ghost_pattern' types from the global hub.
|
|
89
|
+
*/
|
|
90
|
+
async getGhostPatterns() {
|
|
91
|
+
const patternFile = path.join(this.globalPath, 'pattern-library.jsonl');
|
|
92
|
+
try {
|
|
93
|
+
const data = await fs.readFile(patternFile, 'utf8');
|
|
94
|
+
return data.split('\n')
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.map(JSON.parse)
|
|
97
|
+
.filter(p => p.type === 'ghost-pattern' || p.tags?.includes('failure'));
|
|
98
|
+
} catch (e) {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
module.exports = new SemanticHub();
|