mindforge-cc 5.4.0 → 5.6.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/CHANGELOG.md +32 -0
- package/bin/engine/nexus-tracer.js +67 -1
- package/bin/engine/temporal-hindsight.js +27 -0
- package/bin/skill-registry.js +66 -1
- package/bin/skill-validator.js +27 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.6.0] - 2026-03-28
|
|
4
|
+
### Added
|
|
5
|
+
- **Pillar IV: Supply Chain Trust (Binary Runtime Attestation)**.
|
|
6
|
+
- Cryptographic skill signing in `SkillRegistry` via ZTAIManager Tier 3 Enclaves.
|
|
7
|
+
- JIT Attestation in `SkillValidator` to verify skill integrity before agent execution.
|
|
8
|
+
- `SIGNATURES.json` tracking for all enterprise-grade skills.
|
|
9
|
+
|
|
10
|
+
## [5.5.0] - 2026-03-28
|
|
11
|
+
### Added
|
|
12
|
+
- **Pillar III: Predictive Agentic Reliability (Reasoning Entropy Monitoring)**.
|
|
13
|
+
- Reasoning Entropy Scoring (RES) in `NexusTracer` to detect semantic stagnation and loops.
|
|
14
|
+
- Proactive Self-Healing trigger for high-similarity thought sequences.
|
|
15
|
+
- Steering Vector generation in `TemporalHindsight` to break agentic deadlocks.
|
|
16
|
+
|
|
3
17
|
## [5.4.0] — Beast Mode Hardening — 2026-03-28
|
|
4
18
|
|
|
19
|
+
# Release Notes - MindForge v5.6.0 "Sentinel Execution"
|
|
20
|
+
|
|
21
|
+
MindForge v5.6.0 introduces the final pillars of the Hyper-Enterprise roadmap: Proactive Reliability and Zero-Trust Skill Execution.
|
|
22
|
+
|
|
23
|
+
## Highlights
|
|
24
|
+
- **Reasoning Entropy Monitoring (PAR)**: Proactively prevents token-burning reasoning loops.
|
|
25
|
+
- **Binary Runtime Attestation (ZTS)**: Cryptographically ensures that skills have not been tampered with before they are loaded by the agent.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## [5.6.0] - Sentinel Execution
|
|
30
|
+
- Implemented JIT Attestation for Skill Registry.
|
|
31
|
+
- Added Skill Signing utility in `mindforge-cc sign`.
|
|
32
|
+
|
|
33
|
+
## [5.5.0] - Predictive Reliability
|
|
34
|
+
- Implemented RES (Reasoning Entropy Scoring) in Nexus Tracer.
|
|
35
|
+
- Added Steering Vector injection for proactive loop breaking.
|
|
36
|
+
|
|
5
37
|
🚀 **MindForge v5.4.0 — Enterprise Resilience (Hardened Edition)**
|
|
6
38
|
|
|
7
39
|
This update elevates the v5.3.0 "Hyper-Enterprise" features to maximum robustness ("Beast Mode"), implementing critical safety systems and advanced observability.
|
|
@@ -21,6 +21,10 @@ class NexusTracer {
|
|
|
21
21
|
this.enableZtai = config.enableZtai !== false;
|
|
22
22
|
this.sreManager = new SREManager();
|
|
23
23
|
|
|
24
|
+
// v5 Pillar III: Reasoning Entropy Monitoring (RES)
|
|
25
|
+
this.RES_THRESHOLD = 0.8; // Similarity threshold for stagnation
|
|
26
|
+
this.entropyCache = new Map(); // spanId -> [thoughtHistories]
|
|
27
|
+
|
|
24
28
|
// v5 Pillar IV: Agentic SBOM
|
|
25
29
|
this.sbom = {
|
|
26
30
|
manifest_version: '1.0.0',
|
|
@@ -123,12 +127,74 @@ class NexusTracer {
|
|
|
123
127
|
sanitizedThought = this.sreManager.sanitizeThoughtChain(thought, span.attributes.enclave_id);
|
|
124
128
|
}
|
|
125
129
|
|
|
130
|
+
// v5 Pillar III: PES (Proactive Equilibrium Scoring)
|
|
131
|
+
const entropy = this.calculateEntropy(spanId, sanitizedThought);
|
|
132
|
+
const isStagnant = entropy > this.RES_THRESHOLD;
|
|
133
|
+
|
|
126
134
|
this._recordEvent('reasoning_trace', {
|
|
127
135
|
span_id: spanId,
|
|
128
136
|
agent,
|
|
129
137
|
thought: sanitizedThought,
|
|
130
|
-
resolution
|
|
138
|
+
resolution,
|
|
139
|
+
entropy: parseFloat(entropy.toFixed(4)),
|
|
140
|
+
is_stagnant: isStagnant
|
|
131
141
|
});
|
|
142
|
+
|
|
143
|
+
if (isStagnant) {
|
|
144
|
+
const history = this.entropyCache.get(spanId) || [];
|
|
145
|
+
const stagnationCount = history.filter(h => h.entropy > this.RES_THRESHOLD).length;
|
|
146
|
+
|
|
147
|
+
if (stagnationCount >= 3) {
|
|
148
|
+
this._recordEvent('vulnerability_detected', {
|
|
149
|
+
span_id: spanId,
|
|
150
|
+
type: 'REASONING_LOOP',
|
|
151
|
+
severity: 'HIGH',
|
|
152
|
+
description: 'Agent reasoning entropy dropped below threshold (stagnation detected). Triggering proactive RCA.',
|
|
153
|
+
entropy_score: entropy
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Signal proactive recovery
|
|
157
|
+
this.recordSelfHeal(spanId, {
|
|
158
|
+
type: 'PROACTIVE_RCA',
|
|
159
|
+
cause: 'REASONING_STAGNATION',
|
|
160
|
+
suggestion: 'Entropy threshold exceeded. Switch reasoning strategy.'
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Calculates "Reasoning Entropy" (Similarity to previous thoughts).
|
|
168
|
+
* Range 0.0 (High Entropy/New) to 1.0 (Low Entropy/Repetitive).
|
|
169
|
+
*/
|
|
170
|
+
calculateEntropy(spanId, currentThought) {
|
|
171
|
+
if (!this.entropyCache.has(spanId)) {
|
|
172
|
+
this.entropyCache.set(spanId, []);
|
|
173
|
+
}
|
|
174
|
+
const history = this.entropyCache.get(spanId);
|
|
175
|
+
|
|
176
|
+
if (history.length === 0) {
|
|
177
|
+
history.push({ thought: currentThought, entropy: 0 });
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Simple Jaccard Similarity approach for stagnation detection
|
|
182
|
+
const getTokens = (str) => new Set(str.toLowerCase().split(/\s+/).filter(t => t.length > 3));
|
|
183
|
+
const currentTokens = getTokens(currentThought);
|
|
184
|
+
|
|
185
|
+
let maxSimilarity = 0;
|
|
186
|
+
for (const prev of history) {
|
|
187
|
+
const prevTokens = getTokens(prev.thought);
|
|
188
|
+
const intersection = new Set([...currentTokens].filter(x => prevTokens.has(x)));
|
|
189
|
+
const union = new Set([...currentTokens, ...prevTokens]);
|
|
190
|
+
const similarity = union.size === 0 ? 0 : intersection.size / union.size;
|
|
191
|
+
if (similarity > maxSimilarity) maxSimilarity = similarity;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
history.push({ thought: currentThought, entropy: maxSimilarity });
|
|
195
|
+
if (history.length > 5) history.shift(); // Sliding window of 5 thoughts
|
|
196
|
+
|
|
197
|
+
return maxSimilarity;
|
|
132
198
|
}
|
|
133
199
|
|
|
134
200
|
/**
|
|
@@ -83,6 +83,33 @@ class TemporalHindsight {
|
|
|
83
83
|
autoApplyStatus: 'PENDING_SIGNATURE',
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* v5 Pillar III: Proactive Loop Recovery
|
|
89
|
+
* Generates a "Steering Vector" to break agentic Reasoning Stagnation.
|
|
90
|
+
*/
|
|
91
|
+
handleProactiveRecovery(traceId, entropyScore) {
|
|
92
|
+
console.log(`[TemporalHindsight] Proactive Recovery triggered for trace ${traceId} (Entropy: ${entropyScore})`);
|
|
93
|
+
|
|
94
|
+
const steeringVectors = [
|
|
95
|
+
"CRITICAL: Stagnation detected. You have repeated similar reasoning steps 3 times. STOP your current approach and decompose the problem into smaller, independent sub-tasks.",
|
|
96
|
+
"STATIONARY LOOP: Your recent thoughts show high similarity. Change your technical layer—if you were editing code, try running a diagnostic command instead.",
|
|
97
|
+
"REASONING DEADLOCK: Entropy too low. Request human intervention or switch to the 'Architect' persona to re-evaluate the plan.",
|
|
98
|
+
"DIVERGENCE ALERT: Proactive reset. Clear your context window of the last 3 reasoning steps and start fresh from the last successful checkpoint."
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
// Pick a vector based on entropy severity
|
|
102
|
+
const index = Math.min(Math.floor(entropyScore * steeringVectors.length), steeringVectors.length - 1);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
trace_id: traceId,
|
|
107
|
+
event: 'STEERING_VECTOR_GENERATED',
|
|
108
|
+
entropy: entropyScore,
|
|
109
|
+
instruction: steeringVectors[index],
|
|
110
|
+
action: 'INJECT_SYSTEM_PROMPT'
|
|
111
|
+
};
|
|
112
|
+
}
|
|
86
113
|
}
|
|
87
114
|
|
|
88
115
|
module.exports = TemporalHindsight;
|
package/bin/skill-registry.js
CHANGED
|
@@ -19,7 +19,7 @@ function main() {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
// Handle cases where the action might be missing if called incorrectly
|
|
22
|
-
const validActions = ['install', 'register', 'audit'];
|
|
22
|
+
const validActions = ['install', 'register', 'audit', 'sign'];
|
|
23
23
|
if (!validActions.includes(ACTION)) {
|
|
24
24
|
console.error(`❌ Invalid or missing action: ${ACTION}`);
|
|
25
25
|
console.error(` Expected one of: ${validActions.join(', ')}`);
|
|
@@ -36,12 +36,77 @@ function main() {
|
|
|
36
36
|
case 'audit':
|
|
37
37
|
handleAudit();
|
|
38
38
|
break;
|
|
39
|
+
case 'sign':
|
|
40
|
+
handleSign();
|
|
41
|
+
break;
|
|
39
42
|
default:
|
|
40
43
|
console.error(`❌ Unknown action: ${ACTION}`);
|
|
41
44
|
process.exit(1);
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
|
|
48
|
+
async function handleSign() {
|
|
49
|
+
const skillName = ARGS[1];
|
|
50
|
+
const ztai = require('./governance/ztai-manager');
|
|
51
|
+
const crypto = require('node:crypto');
|
|
52
|
+
|
|
53
|
+
if (!skillName) {
|
|
54
|
+
console.error('❌ Missing skill name to sign');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Find the skill file
|
|
59
|
+
const bases = [
|
|
60
|
+
'.mindforge/skills',
|
|
61
|
+
'.mindforge/org/skills',
|
|
62
|
+
'.mindforge/project-skills'
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
let targetPath = null;
|
|
66
|
+
for (const base of bases) {
|
|
67
|
+
const p = path.join(process.cwd(), base, skillName, 'SKILL.md');
|
|
68
|
+
if (fs.existsSync(p)) {
|
|
69
|
+
targetPath = p;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!targetPath) {
|
|
75
|
+
console.error(`❌ Skill ${skillName} not found in any registry path.`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`🛡️ Signing skill: ${skillName}...`);
|
|
80
|
+
const content = fs.readFileSync(targetPath, 'utf8');
|
|
81
|
+
const hash = crypto.createHash('sha256').update(content).digest('hex');
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// We use a dedicated System DID for skill signing (Tier 3)
|
|
85
|
+
const systemDid = await ztai.registerAgent('MindForge-System-Secretary', 3);
|
|
86
|
+
const signature = await ztai.signData(systemDid, hash);
|
|
87
|
+
|
|
88
|
+
const sigPath = path.join(process.cwd(), '.mindforge', 'org', 'skills', 'SIGNATURES.json');
|
|
89
|
+
let signatures = {};
|
|
90
|
+
if (fs.existsSync(sigPath)) {
|
|
91
|
+
signatures = JSON.parse(fs.readFileSync(sigPath, 'utf8'));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
signatures[skillName] = {
|
|
95
|
+
hash,
|
|
96
|
+
signature,
|
|
97
|
+
did: systemDid,
|
|
98
|
+
timestamp: new Date().toISOString()
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
fs.writeFileSync(sigPath, JSON.stringify(signatures, null, 2));
|
|
102
|
+
console.log(`✅ Skill ${skillName} signed and registered in SIGNATURES.json`);
|
|
103
|
+
process.exit(0);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error(`❌ Signing failed: ${err.message}`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
45
110
|
function handleInstall() {
|
|
46
111
|
const skillName = ARGS[1];
|
|
47
112
|
const tierFlag = ARGS.indexOf('--tier');
|
package/bin/skill-validator.js
CHANGED
|
@@ -38,7 +38,33 @@ function main() {
|
|
|
38
38
|
console.log('─'.repeat(60));
|
|
39
39
|
|
|
40
40
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
41
|
-
const results = { schema: [], content: [], quality: [], valid: true };
|
|
41
|
+
const results = { schema: [], content: [], quality: [], valid: true, attestation: { ok: true, msg: 'No signature found (optional)' } };
|
|
42
|
+
|
|
43
|
+
// ── Level 0: Binary Runtime Attestation (v5 Pillar IV) ──────────────────────
|
|
44
|
+
const sigPath = path.join(process.cwd(), '.mindforge', 'org', 'skills', 'SIGNATURES.json');
|
|
45
|
+
if (fs.existsSync(sigPath)) {
|
|
46
|
+
const crypto = require('node:crypto');
|
|
47
|
+
const ztai = require('./governance/ztai-manager');
|
|
48
|
+
const signatures = JSON.parse(fs.readFileSync(sigPath, 'utf8'));
|
|
49
|
+
const skillNameCandidate = path.basename(path.dirname(filePath));
|
|
50
|
+
const sigRecord = signatures[skillNameCandidate];
|
|
51
|
+
|
|
52
|
+
if (sigRecord) {
|
|
53
|
+
const currentHash = crypto.createHash('sha256').update(content).digest('hex');
|
|
54
|
+
const isHashValid = currentHash === sigRecord.hash;
|
|
55
|
+
const isSigValid = ztai.verifySignature(sigRecord.did, currentHash, sigRecord.signature);
|
|
56
|
+
|
|
57
|
+
if (!isHashValid || !isSigValid) {
|
|
58
|
+
results.attestation = { ok: false, msg: `INTEGRITY FAILURE: Signature mismatch [Hash: ${isHashValid}, Sig: ${isSigValid}]` };
|
|
59
|
+
results.valid = false;
|
|
60
|
+
} else {
|
|
61
|
+
results.attestation = { ok: true, msg: `VERIFIED: Signed by ${sigRecord.did}` };
|
|
62
|
+
}
|
|
63
|
+
} else if (ARGS.includes('--enterprise')) {
|
|
64
|
+
results.attestation = { ok: false, msg: 'REQUIRED: No signature found for this skill in Enterprise Mode' };
|
|
65
|
+
results.valid = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
42
68
|
|
|
43
69
|
// ── Level 1: Schema ─────────────────────────────────────────────────────────
|
|
44
70
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|