mindforge-cc 5.10.0 → 6.1.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.agent/mindforge/health.md +6 -0
  2. package/.agent/mindforge/help.md +6 -0
  3. package/.agent/mindforge/security-scan.md +6 -1
  4. package/.agent/mindforge/status.md +10 -5
  5. package/.claude/CLAUDE.md +14 -12
  6. package/.mindforge/engine/integrity.json +12 -0
  7. package/.mindforge/governance/policies/sovereign-default.json +16 -0
  8. package/.mindforge/org/skills/MANIFEST.md +10 -34
  9. package/.planning/RISK-AUDIT.jsonl +48 -0
  10. package/CHANGELOG.md +126 -19
  11. package/MINDFORGE.md +8 -5
  12. package/README.md +22 -3
  13. package/RELEASENOTES.md +19 -1
  14. package/bin/autonomous/auto-runner.js +14 -0
  15. package/bin/autonomous/intent-harvester.js +80 -0
  16. package/bin/autonomous/mesh-self-healer.js +67 -0
  17. package/bin/engine/logic-drift-detector.js +97 -0
  18. package/bin/engine/nexus-tracer.js +24 -4
  19. package/bin/engine/remediation-engine.js +72 -0
  20. package/bin/governance/impact-analyzer.js +75 -15
  21. package/bin/governance/policy-engine.js +120 -45
  22. package/bin/governance/quantum-crypto.js +90 -0
  23. package/bin/governance/ztai-manager.js +37 -1
  24. package/bin/installer-core.js +38 -7
  25. package/bin/mindforge-cli.js +30 -0
  26. package/bin/revops/market-evaluator.js +79 -0
  27. package/bin/revops/roi-engine.js +5 -0
  28. package/bin/revops/router-steering-v2.js +73 -0
  29. package/bin/wizard/theme.js +5 -1
  30. package/docs/CAPABILITIES-MANIFEST.md +64 -0
  31. package/docs/INTELLIGENCE-MESH.md +20 -32
  32. package/docs/MIND-FORGE-REFERENCE-V6.md +96 -0
  33. package/docs/architecture/README.md +4 -4
  34. package/docs/architecture/V5-ENTERPRISE.md +26 -12
  35. package/docs/architecture/V6-SOVEREIGN.md +43 -0
  36. package/docs/commands-reference.md +1 -1
  37. package/docs/feature-dashboard.md +9 -3
  38. package/docs/governance-guide.md +78 -48
  39. package/docs/registry/AGENTS.md +37 -0
  40. package/docs/registry/COMMANDS.md +87 -0
  41. package/docs/registry/HOOKS.md +38 -0
  42. package/docs/registry/PERSONAS.md +64 -0
  43. package/docs/registry/README.md +27 -0
  44. package/docs/registry/SKILLS.md +142 -0
  45. package/docs/registry/WORKFLOWS.md +72 -0
  46. package/docs/user-guide.md +36 -6
  47. package/docs/usp-features.md +63 -295
  48. package/package.json +2 -2
@@ -0,0 +1,80 @@
1
+ /**
2
+ * MindForge v7 — Proactive Semantic Homing (Pillar XII)
3
+ * Intent Harvester: Proactively scans and claims unassigned tasks.
4
+ */
5
+ 'use strict';
6
+
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+ const crypto = require('node:crypto');
10
+
11
+ class IntentHarvester {
12
+ constructor() {
13
+ this.planningDir = path.join(process.cwd(), '.planning');
14
+ this.backlogPath = path.join(this.planningDir, 'BACKLOG.json');
15
+ this.handoffPath = path.join(this.planningDir, 'HANDOFF.json');
16
+ }
17
+
18
+ /**
19
+ * Scans for unassigned intent in the backlog and peer handoffs.
20
+ */
21
+ async idleScan() {
22
+ console.log('[HOMING-SCAN] Agents transitioning to "Proactive Hunter" mode. Scanning FIM for unassigned intent...');
23
+
24
+ const tasks = [];
25
+ if (fs.existsSync(this.backlogPath)) {
26
+ const backlog = JSON.parse(fs.readFileSync(this.backlogPath, 'utf8'));
27
+ tasks.push(...backlog.filter(t => t.status === 'unassigned' || t.status === 'pending'));
28
+ }
29
+
30
+ if (fs.existsSync(this.handoffPath)) {
31
+ const handoff = JSON.parse(fs.readFileSync(this.handoffPath, 'utf8'));
32
+ tasks.push(...(handoff.open_intents || []));
33
+ }
34
+
35
+ return tasks;
36
+ }
37
+
38
+ /**
39
+ * Autonomous task claiming based on agent Skill-Score.
40
+ */
41
+ async intentGrab(agent, tasks) {
42
+ if (tasks.length === 0) return null;
43
+
44
+ console.log(`[HOMING-GRAB] Agent ${agent.did} evaluating ${tasks.length} unassigned intents...`);
45
+
46
+ // Sort tasks by Skill-Match affinity
47
+ const prioritized = tasks.map(task => ({
48
+ task,
49
+ score: this.calculateAffinity(agent, task)
50
+ })).sort((a, b) => b.score - a.score);
51
+
52
+ const bestMatch = prioritized[0];
53
+ if (bestMatch.score > 70) {
54
+ console.log(`[HOMING-GRAB] High affinity detected (${bestMatch.score}). Agent ${agent.did} claiming: ${bestMatch.task.description}`);
55
+ return this.claimTask(agent, bestMatch.task);
56
+ }
57
+
58
+ return null;
59
+ }
60
+
61
+ calculateAffinity(agent, task) {
62
+ // Simulated skill-affinity calculation
63
+ const skills = agent.skills || [];
64
+ const taskReqs = task.required_skills || [];
65
+
66
+ const matchCount = taskReqs.filter(s => skills.includes(s)).length;
67
+ return (matchCount / Math.max(taskReqs.length, 1)) * 100;
68
+ }
69
+
70
+ async claimTask(agent, task) {
71
+ task.assigned_to = agent.did;
72
+ task.status = 'active';
73
+ task.claimedAt = new Date().toISOString();
74
+
75
+ // Update local state (in a real system this would be a atomic mesh update)
76
+ return task;
77
+ }
78
+ }
79
+
80
+ module.exports = new IntentHarvester();
@@ -0,0 +1,67 @@
1
+ /**
2
+ * MindForge v7 — Proactive Semantic Homing (Pillar XII)
3
+ * Mesh Self-Healer: Peer agents "home in" on drifting nodes to provide collaborative reasoning.
4
+ */
5
+ 'use strict';
6
+
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+
10
+ class MeshSelfHealer {
11
+ constructor() {
12
+ this.auditPath = path.join(process.cwd(), '.planning', 'AUDIT.jsonl');
13
+ }
14
+
15
+ /**
16
+ * Peer agents "home in" on a node with high logic drift.
17
+ */
18
+ async homeIn(driftingAgentDid, driftScore) {
19
+ if (driftScore < 80) return null; // Only home in on major drift
20
+
21
+ console.log(`[HOMING-HEAL] Global Mesh Alert: Agent ${driftingAgentDid} experiencing critical logic drift (${driftScore}). Peer agents redirecting...`);
22
+
23
+ // Find nearby idle agents or specialists
24
+ const peers = this.findAvailablePeers(driftingAgentDid);
25
+ const healingNodes = [];
26
+
27
+ for (const peer of peers) {
28
+ console.log(`[HOMING-HEAL] Agent ${peer.did} homing in on ${driftingAgentDid} to provide collective reasoning support.`);
29
+ const supportTrace = await this.provideCollectiveReasoning(peer, driftingAgentDid);
30
+ healingNodes.push(supportTrace);
31
+ }
32
+
33
+ return this.reconcileReasoning(healingNodes);
34
+ }
35
+
36
+ findAvailablePeers(driftingAgentDid) {
37
+ // Simulated peer discovery
38
+ return [
39
+ { did: 'did:mindforge:peer-1-specialist', name: 'Refactor Specialist' },
40
+ { did: 'did:mindforge:peer-2-architect', name: 'Security Architect' }
41
+ ];
42
+ }
43
+
44
+ async provideCollectiveReasoning(peer, target) {
45
+ // Peer agent provides a second opinion/reasoning node
46
+ return {
47
+ provider: peer.did,
48
+ target: target,
49
+ reasoning: `Recommended steering for drift recovery based on Mesh-State: Re-syncing with Sovereign-Reason-Enclave.`,
50
+ confidence: 94
51
+ };
52
+ }
53
+
54
+ reconcileReasoning(nodes) {
55
+ // Merge peer reasoning nodes into a single corrective steering vector
56
+ const consensus = nodes[0].reasoning; // Mock consensus
57
+ console.log(`[HOMING-HEAL] Collective reasoning consensus acheived: 100% agreement on recovery vector.`);
58
+
59
+ return {
60
+ type: 'collective_repair',
61
+ consensus,
62
+ source: 'Mesh-Self-Healing'
63
+ };
64
+ }
65
+ }
66
+
67
+ module.exports = new MeshSelfHealer();
@@ -0,0 +1,97 @@
1
+ /**
2
+ * MindForge v6.1.0-alpha — Neural Drift Remediation (NDR)
3
+ * Component: Logic Drift Detector (Pillar X)
4
+ *
5
+ * Analyzes reasoning traces for "Semantic Decay" (repeated failure patterns,
6
+ * hallucination-like markers, or mission drift).
7
+ */
8
+ 'use strict';
9
+
10
+ class LogicDriftDetector {
11
+ constructor() {
12
+ this.sessionDriftHistory = new Map(); // spanId -> [scores]
13
+ this.DRIFT_THRESHOLD = 0.75;
14
+ }
15
+
16
+ /**
17
+ * Analyzes a specific thought for logic drift.
18
+ * @param {string} spanId
19
+ * @param {string} thought
20
+ */
21
+ analyze(spanId, thought) {
22
+ const semanticDensity = this._calculateSemanticDensity(thought);
23
+ const patternScore = this._detectRepetitivePatterns(spanId, thought);
24
+ const contradictionScore = this._checkHeuristicContradictions(thought);
25
+
26
+ // v6.1 Weights: Aggressive on contradictions and patterns
27
+ const driftScore = (semanticDensity * 0.1) + (patternScore * 0.5) + (contradictionScore * 0.4);
28
+
29
+ if (!this.sessionDriftHistory.has(spanId)) {
30
+ this.sessionDriftHistory.set(spanId, []);
31
+ }
32
+ this.sessionDriftHistory.get(spanId).push(driftScore);
33
+
34
+ return {
35
+ span_id: spanId,
36
+ drift_score: parseFloat(driftScore.toFixed(4)),
37
+ status: driftScore > this.DRIFT_THRESHOLD ? 'DRIFT_DETECTED' : 'STABLE',
38
+ markers: {
39
+ density: semanticDensity,
40
+ pattern: patternScore,
41
+ contradiction: contradictionScore
42
+ }
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Internal Heuristic: Detects low semantic density (rambling).
48
+ */
49
+ _calculateSemanticDensity(thought) {
50
+ const words = thought.split(/\s+/).length;
51
+ // Strip punctuation for keyword matching
52
+ const keywords = thought.toLowerCase().replace(/[^\w\s]/g, '').match(/\b(\w{5,})\b/g) || [];
53
+ const uniqueKeywords = new Set(keywords).size;
54
+
55
+ if (words === 0) return 0;
56
+ const ratio = uniqueKeywords / words;
57
+ // v6.1 Hardening: High sensitivity to rambling
58
+ return ratio < 0.25 ? 0.95 : 0.05;
59
+ }
60
+
61
+ /**
62
+ * Internal Heuristic: Detects circular reasoning across a span window
63
+ * and within the thought itself.
64
+ */
65
+ _detectRepetitivePatterns(spanId, currentThought) {
66
+ const history = this.sessionDriftHistory.get(spanId) || [];
67
+
68
+ // Internal Repetition Check (Strip punctuation)
69
+ const normalized = currentThought.toLowerCase().replace(/[^\w\s]/g, '');
70
+ const words = normalized.split(/\s+/).filter(w => w.length > 3);
71
+ const wordCounts = {};
72
+ words.forEach(w => wordCounts[w] = (wordCounts[w] || 0) + 1);
73
+
74
+ const maxRep = Math.max(0, ...Object.values(wordCounts));
75
+ const internalRepFactor = maxRep > 3 ? 0.9 : 0.1; // v6.1: Higher penalty
76
+
77
+ if (history.length < 2) return internalRepFactor;
78
+
79
+ // Window trending check
80
+ const recentScores = history.slice(-3);
81
+ const isTrendingUp = recentScores.length >= 2 && recentScores[recentScores.length-1] > recentScores[0];
82
+
83
+ return Math.max(internalRepFactor, isTrendingUp ? 0.7 : 0.1);
84
+ }
85
+
86
+ /**
87
+ * Internal Heuristic: Detects logic contradiction keywords.
88
+ */
89
+ _checkHeuristicContradictions(thought) {
90
+ const t = thought.toLowerCase();
91
+ const markers = ['nevertheless', 'however, i will instead', 'contradicting', 'error in reasoning', 'failed to', 'restart checking'];
92
+ const hits = markers.filter(m => t.includes(m)).length;
93
+ return Math.min(1.0, hits * 0.35); // v6.1: Higher impact per marker
94
+ }
95
+ }
96
+
97
+ module.exports = new LogicDriftDetector();
@@ -10,6 +10,8 @@ const path = require('path');
10
10
  const crypto = require('crypto');
11
11
  const ztai = require('../governance/ztai-manager');
12
12
  const SREManager = require('./sre-manager');
13
+ const driftDetector = require('./logic-drift-detector'); // v6.1 Pillar X
14
+ const remediationEngine = require('./remediation-engine'); // v6.1 Pillar X
13
15
 
14
16
  class NexusTracer {
15
17
  constructor(config = {}) {
@@ -21,9 +23,12 @@ class NexusTracer {
21
23
  this.enableZtai = config.enableZtai !== false;
22
24
  this.sreManager = new SREManager();
23
25
 
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]
26
+ // v5/v6: Reasoning Entropy Monitoring (RES)
27
+ this.RES_THRESHOLD = 0.8;
28
+ this.entropyCache = new Map();
29
+
30
+ // v6.1: Neural Drift Remediation (NDR)
31
+ this.DRIFT_SAMPLE_RATE = 1.0;
27
32
 
28
33
  // v5 Pillar IV: Agentic SBOM
29
34
  this.sbom = {
@@ -141,6 +146,20 @@ class NexusTracer {
141
146
  sanitizedThought = result.content || thought;
142
147
  }
143
148
 
149
+ // v6.1 Pillar X: Neural Drift Remediation (NDR)
150
+ const driftReport = driftDetector.analyze(spanId, sanitizedThought);
151
+ if (driftReport.status === 'DRIFT_DETECTED') {
152
+ const remediation = await remediationEngine.trigger(spanId, driftReport);
153
+
154
+ await this._recordEvent('drift_remediation_event', {
155
+ span_id: spanId,
156
+ score: driftReport.drift_score,
157
+ strategy: remediation.strategy,
158
+ remediation_id: remediation.remediation_id,
159
+ markers: driftReport.markers
160
+ });
161
+ }
162
+
144
163
  // v5 Pillar III: PES (Proactive Equilibrium Scoring)
145
164
  const entropy = this.calculateEntropy(spanId, sanitizedThought);
146
165
  const isStagnant = entropy > this.RES_THRESHOLD;
@@ -151,7 +170,8 @@ class NexusTracer {
151
170
  thought: sanitizedThought,
152
171
  resolution,
153
172
  entropy: parseFloat(entropy.toFixed(4)),
154
- is_stagnant: isStagnant
173
+ is_stagnant: isStagnant,
174
+ drift_score: driftReport.drift_score // Inclusion for consolidated audit
155
175
  });
156
176
 
157
177
  if (isStagnant) {
@@ -0,0 +1,72 @@
1
+ /**
2
+ * MindForge v6.1.0-alpha — Neural Drift Remediation (NDR)
3
+ * Component: Remediation Engine (Pillar X)
4
+ *
5
+ * Triggers corrective actions when logic drift or reasoning
6
+ * stagnation is detected.
7
+ */
8
+ 'use strict';
9
+
10
+ const driftDetector = require('./logic-drift-detector');
11
+
12
+ class RemediationEngine {
13
+ constructor() {
14
+ this.activeRemediations = new Set();
15
+ }
16
+
17
+ /**
18
+ * Triggers a specific remediation workflow.
19
+ * @param {string} spanId
20
+ * @param {Object} report - From LogicDriftDetector
21
+ */
22
+ async trigger(spanId, report) {
23
+ const { drift_score, markers } = report;
24
+ let strategy = 'NOT_REQUIRED';
25
+
26
+ // Tiered Remediation Logic
27
+ if (drift_score > 0.9) strategy = 'REASONING_RESTART';
28
+ else if (drift_score > 0.8) strategy = 'GOLDEN_TRACE_INJECTION';
29
+ else if (drift_score > 0.75) strategy = 'CONTEXT_COMPRESSION';
30
+
31
+ if (strategy === 'NOT_REQUIRED') return { status: 'STABLE', strategy };
32
+
33
+ const action = {
34
+ span_id: spanId,
35
+ strategy,
36
+ remediation_id: `rem_${Math.random().toString(36).substr(2, 6)}`,
37
+ timestamp: new Date().toISOString(),
38
+ effectiveness_prediction: 0.85
39
+ };
40
+
41
+ console.log(`[Remediation] Triggered ${strategy} for ${spanId} (Drift: ${drift_score})`);
42
+
43
+ this.activeRemediations.add(action);
44
+
45
+ // Simulating specific remediation actions
46
+ this._executeStrategy(strategy, spanId);
47
+
48
+ return action;
49
+ }
50
+
51
+ /**
52
+ * Mock implementation of remediation strategies.
53
+ */
54
+ async _executeStrategy(strategy, spanId) {
55
+ switch(strategy) {
56
+ case 'REASONING_RESTART':
57
+ console.log(`[Remediation] Forcing reasoner reset for ${spanId}`);
58
+ // Logic to clear local thought window for span
59
+ break;
60
+ case 'GOLDEN_TRACE_INJECTION':
61
+ console.log(`[Remediation] Injecting successful trace heuristics into ${spanId}`);
62
+ // Logic to pull from Semantic Hub successful past traces
63
+ break;
64
+ }
65
+ }
66
+
67
+ getActiveRemediations() {
68
+ return Array.from(this.activeRemediations);
69
+ }
70
+ }
71
+
72
+ module.exports = new RemediationEngine();
@@ -1,9 +1,12 @@
1
1
  /**
2
- * MindForge v5.4.0 — Impact Analyzer (Hardened Edition)
2
+ * MindForge v6.0.0 — Context-Aware Dynamic Impact Analysis (CADIA)
3
3
  * Calculates the 'Blast Radius' score of a proposed intent.
4
4
  */
5
5
  'use strict';
6
6
 
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+
7
10
  class ImpactAnalyzer {
8
11
  static CRITICAL_PATHS = [
9
12
  '.env',
@@ -27,18 +30,22 @@ class ImpactAnalyzer {
27
30
  'READ': 1,
28
31
  'WRITE': 5,
29
32
  'DELETE': 10,
30
- 'EXECUTE': 15, // Raised from 8
31
- 'GRANT': 20 // Raised from 15
33
+ 'EXECUTE': 15,
34
+ 'GRANT': 20
32
35
  };
33
36
 
37
+ // Cache for session-based entropy tracking
38
+ static sessionState = new Map();
39
+
34
40
  /**
35
- * Scores an intent based on action type, target path sensitivity, and recursion depth.
41
+ * [CADIA] Scores an intent based on architectural influence, session entropy, and trust tiers.
36
42
  * Score Range: 0 - 100
37
43
  */
38
- static analyze(intent) {
44
+ static analyze(intent, context = {}) {
39
45
  const { action, target, namespace } = intent;
40
-
41
- // 1. Critical Path Protection (Score 100)
46
+ const { sessionId = 'default', trustTier = 0, currentGoal = '' } = context;
47
+
48
+ // 1. Critical Path Protection (Hardened)
42
49
  const isCritical = this.CRITICAL_PATHS.some(cp =>
43
50
  (target && (target.endsWith(cp) || target.includes(`/${cp}`)))
44
51
  );
@@ -49,33 +56,86 @@ class ImpactAnalyzer {
49
56
 
50
57
  let score = this.ACTION_SCORES[action] || 5;
51
58
 
52
- // 2. Sensitive Namespace Multiplier
59
+ // 2. [NEW] Architectural Influence Engine (x2.5 multiplier)
60
+ if (this.isArchitecturallySignificant(target)) {
61
+ score *= 2.5;
62
+ }
63
+
64
+ // 3. Sensitive Namespace Multiplier (x4.0 multiplier)
53
65
  const isSensitive = this.SENSITIVE_NAMESPACES.some(ns =>
54
66
  (target && target.includes(ns)) || (namespace && namespace.includes(ns))
55
67
  );
56
68
 
57
69
  if (isSensitive) {
58
- score *= 4;
70
+ score *= 4.0;
59
71
  }
60
72
 
61
- // 3. Recursive Depth Penalty (Beast Mode)
73
+ // 4. [NEW] Session Entropy Tracker (+15 penalty)
74
+ const sessCount = (this.sessionState.get(sessionId) || 0) + 1;
75
+ this.sessionState.set(sessionId, sessCount);
76
+
77
+ if (sessCount > 5) {
78
+ score += (sessCount - 5) * 15;
79
+ }
80
+
81
+ // 5. [NEW] Goal-to-Path Alignment (+40 penalty)
82
+ if (currentGoal && !this.isGoalAligned(target, currentGoal)) {
83
+ score += 40;
84
+ }
85
+
86
+ // 6. [NEW] ZTAI-Trust Scaling (Risk buffer)
87
+ const trustBuffer = trustTier * 10;
88
+ score = Math.max(0, score - trustBuffer);
89
+
90
+ // 7. Recursive Depth Scale
62
91
  if (target && target.split('/').length > 5) {
63
- score *= 1.5; // Deeper actions are riskier (mass-scale silent mods)
92
+ score *= 1.25;
64
93
  }
65
94
 
66
- // Cap the score at 100
67
95
  return Math.min(Math.round(score), 100);
68
96
  }
69
97
 
98
+
99
+ /**
100
+ * Identifies files with high architectural side-effects.
101
+ */
102
+ static isArchitecturallySignificant(filePath) {
103
+ if (!filePath) return false;
104
+ const highWeightDirs = ['bin/governance', 'bin/engine', 'bin/models', '.mindforge/intelligence'];
105
+ const highWeightFiles = ['package.json', 'sdk/nexus-core.js', 'bin/mindforge-cli.js'];
106
+
107
+ return highWeightDirs.some(d => filePath.includes(d)) ||
108
+ highWeightFiles.some(f => filePath.endsWith(f));
109
+ }
110
+
70
111
  /**
71
- * Returns a risk tier based on the score.
112
+ * Checks if the target path semantically aligns with the current active goal/phase.
72
113
  */
114
+ static isGoalAligned(filePath, currentGoal) {
115
+ if (!currentGoal || !filePath) return true; // Default to neutral if no goal set
116
+
117
+ // Simple heuristic: Does the goal mention the file or directory?
118
+ const normalizedGoal = currentGoal.toLowerCase();
119
+ const normalizedPath = filePath.toLowerCase();
120
+
121
+ // Extract domain (e.g., 'auth', 'ui', 'api')
122
+ const domain = normalizedPath.split('/')[0];
123
+
124
+ return normalizedGoal.includes(domain) ||
125
+ normalizedGoal.includes(path.basename(normalizedPath, path.extname(normalizedPath)));
126
+ }
127
+
73
128
  static getRiskTier(score) {
74
- if (score < 20) return 'LOW';
129
+ if (score < 25) return 'LOW';
75
130
  if (score < 50) return 'MEDIUM';
76
- if (score < 80) return 'HIGH';
131
+ if (score < 75) return 'HIGH';
77
132
  return 'CRITICAL';
78
133
  }
134
+
135
+ static resetSession(sessionId) {
136
+ this.sessionState.delete(sessionId);
137
+ }
79
138
  }
80
139
 
81
140
  module.exports = ImpactAnalyzer;
141
+