mindforge-cc 10.0.3 → 11.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/.mindforge/MINDFORGE-V2-SCHEMA.json +43 -10
- package/.mindforge/config.json +30 -2
- package/.mindforge/engine/cross-model-eval.md +74 -0
- package/.mindforge/engine/proactive/signal-detector.md +60 -0
- package/.mindforge/engine/proactive/suggestion-engine.md +100 -0
- package/.mindforge/personas/agent-architect.md +57 -0
- package/.mindforge/personas/agent-evaluator.md +162 -0
- package/.mindforge/personas/agent-memory-designer.md +157 -0
- package/.mindforge/personas/agent-ops-engineer.md +120 -0
- package/.mindforge/personas/agent-orchestrator.md +112 -0
- package/.mindforge/personas/ai-economist.md +57 -0
- package/.mindforge/personas/ai-safety-engineer.md +57 -0
- package/.mindforge/personas/analytics-engineer.md +57 -0
- package/.mindforge/personas/anti-pattern-hunter.md +61 -0
- package/.mindforge/personas/api-gateway-designer.md +132 -0
- package/.mindforge/personas/auth-engineer.md +112 -0
- package/.mindforge/personas/build-engineer.md +57 -0
- package/.mindforge/personas/business-analyst.md +56 -0
- package/.mindforge/personas/cache-architect.md +100 -0
- package/.mindforge/personas/causal-scientist.md +57 -0
- package/.mindforge/personas/cdn-architect.md +118 -0
- package/.mindforge/personas/change-agent.md +104 -0
- package/.mindforge/personas/code-narrator.md +52 -0
- package/.mindforge/personas/codegen-specialist.md +68 -0
- package/.mindforge/personas/communication-architect.md +102 -0
- package/.mindforge/personas/compliance-engineer.md +96 -0
- package/.mindforge/personas/consensus-engineer.md +116 -0
- package/.mindforge/personas/contract-tester.md +60 -192
- package/.mindforge/personas/data-architect.md +108 -0
- package/.mindforge/personas/data-mesh-architect.md +57 -0
- package/.mindforge/personas/data-pipeline-architect.md +120 -0
- package/.mindforge/personas/de-sloppifier.md +60 -0
- package/.mindforge/personas/debt-manager.md +66 -0
- package/.mindforge/personas/decision-architect.md +82 -51
- package/.mindforge/personas/deployment-captain.md +74 -0
- package/.mindforge/personas/design-system-lead.md +112 -0
- package/.mindforge/personas/dmux-orchestrator.md +75 -0
- package/.mindforge/personas/dx-engineer.md +96 -0
- package/.mindforge/personas/ecommerce-engineer.md +57 -0
- package/.mindforge/personas/edge-engineer.md +94 -0
- package/.mindforge/personas/edtech-architect.md +106 -0
- package/.mindforge/personas/embedding-architect.md +57 -0
- package/.mindforge/personas/environment-engineer.md +57 -0
- package/.mindforge/personas/eval-judge.md +55 -0
- package/.mindforge/personas/event-architect.md +102 -0
- package/.mindforge/personas/experiment-designer.md +138 -0
- package/.mindforge/personas/feature-store-engineer.md +57 -0
- package/.mindforge/personas/finops-analyst.md +66 -0
- package/.mindforge/personas/fintech-architect.md +57 -0
- package/.mindforge/personas/flutter-engineer.md +104 -0
- package/.mindforge/personas/gaming-engineer.md +57 -0
- package/.mindforge/personas/graphql-designer.md +73 -0
- package/.mindforge/personas/healthcare-engineer.md +57 -0
- package/.mindforge/personas/hiring-strategist.md +105 -0
- package/.mindforge/personas/hitl-architect.md +165 -0
- package/.mindforge/personas/i18n-architect.md +69 -0
- package/.mindforge/personas/iot-architect.md +105 -0
- package/.mindforge/personas/knowledge-curator.md +139 -0
- package/.mindforge/personas/knowledge-engineer.md +57 -0
- package/.mindforge/personas/lakehouse-architect.md +57 -0
- package/.mindforge/personas/llm-orchestrator.md +57 -0
- package/.mindforge/personas/logistics-architect.md +106 -0
- package/.mindforge/personas/market-analyst.md +53 -0
- package/.mindforge/personas/marketplace-engineer.md +105 -0
- package/.mindforge/personas/mcp-designer.md +54 -0
- package/.mindforge/personas/meeting-designer.md +104 -0
- package/.mindforge/personas/mentorship-lead.md +106 -0
- package/.mindforge/personas/migration-architect.md +57 -0
- package/.mindforge/personas/ml-ops-engineer.md +101 -0
- package/.mindforge/personas/mobile-architect.md +105 -0
- package/.mindforge/personas/mobile-security-engineer.md +106 -0
- package/.mindforge/personas/multi-tenancy-architect.md +71 -0
- package/.mindforge/personas/multimodal-engineer.md +57 -0
- package/.mindforge/personas/offline-specialist.md +105 -0
- package/.mindforge/personas/onboarding-navigator.md +63 -0
- package/.mindforge/personas/payments-engineer.md +135 -0
- package/.mindforge/personas/pipeline-engineer.md +115 -0
- package/.mindforge/personas/platform-engineer.md +97 -0
- package/.mindforge/personas/platform-lead.md +57 -0
- package/.mindforge/personas/privacy-engineer.md +57 -0
- package/.mindforge/personas/product-owner.md +56 -0
- package/.mindforge/personas/productivity-analyst.md +57 -0
- package/.mindforge/personas/prompt-architect.md +101 -0
- package/.mindforge/personas/proofreader.md +53 -0
- package/.mindforge/personas/pwa-architect.md +105 -0
- package/.mindforge/personas/quality-scorer.md +63 -0
- package/.mindforge/personas/react-native-engineer.md +106 -0
- package/.mindforge/personas/resilience-engineer.md +69 -0
- package/.mindforge/personas/rfc-architect.md +64 -0
- package/.mindforge/personas/saga-orchestrator.md +80 -0
- package/.mindforge/personas/secrets-engineer.md +57 -0
- package/.mindforge/personas/skill-smith.md +79 -0
- package/.mindforge/personas/sre-lead.md +107 -0
- package/.mindforge/personas/stream-engineer.md +57 -0
- package/.mindforge/personas/streaming-engineer.md +64 -0
- package/.mindforge/personas/swarm-templates.json +674 -44
- package/.mindforge/personas/system-designer.md +57 -0
- package/.mindforge/personas/team-coach.md +120 -0
- package/.mindforge/personas/tech-lead-coach.md +103 -0
- package/.mindforge/personas/technical-writer-lead.md +111 -0
- package/.mindforge/personas/vibe-checker.md +75 -0
- package/.mindforge/personas/worktree-manager.md +56 -0
- package/.mindforge/personas/zero-trust-engineer.md +113 -0
- package/.mindforge/skills/a11y-testing/SKILL.md +143 -0
- package/.mindforge/skills/agent-evaluation-framework/SKILL.md +227 -0
- package/.mindforge/skills/agent-memory-design/SKILL.md +199 -0
- package/.mindforge/skills/agent-orchestration-patterns/SKILL.md +129 -0
- package/.mindforge/skills/agent-tool-selection/SKILL.md +204 -0
- package/.mindforge/skills/ai-agent-deployment/SKILL.md +176 -0
- package/.mindforge/skills/ai-cost-management/SKILL.md +57 -0
- package/.mindforge/skills/ai-safety-alignment/SKILL.md +53 -0
- package/.mindforge/skills/analytics-instrumentation/SKILL.md +172 -0
- package/.mindforge/skills/api-gateway-patterns/SKILL.md +177 -0
- package/.mindforge/skills/api-marketplace/SKILL.md +56 -0
- package/.mindforge/skills/api-versioning/SKILL.md +100 -0
- package/.mindforge/skills/app-store-deployment/SKILL.md +44 -0
- package/.mindforge/skills/architecture-tradeoff-analysis/SKILL.md +97 -0
- package/.mindforge/skills/audit-logging/SKILL.md +140 -0
- package/.mindforge/skills/auth-patterns/SKILL.md +148 -0
- package/.mindforge/skills/autonomous-agent-harness/SKILL.md +218 -0
- package/.mindforge/skills/autonomous-agents/SKILL.md +59 -0
- package/.mindforge/skills/build-system-optimization/SKILL.md +54 -0
- package/.mindforge/skills/build-vs-buy/SKILL.md +80 -0
- package/.mindforge/skills/bundle-optimization/SKILL.md +174 -0
- package/.mindforge/skills/business-analyst/SKILL.md +82 -0
- package/.mindforge/skills/caching-strategies/SKILL.md +132 -0
- package/.mindforge/skills/capacity-planning/SKILL.md +96 -0
- package/.mindforge/skills/causal-inference/SKILL.md +42 -0
- package/.mindforge/skills/cdn-optimization/SKILL.md +212 -0
- package/.mindforge/skills/change-management/SKILL.md +106 -0
- package/.mindforge/skills/chaos-engineering/SKILL.md +99 -0
- package/.mindforge/skills/ci-cd-pipeline/SKILL.md +118 -0
- package/.mindforge/skills/cli-design/SKILL.md +118 -0
- package/.mindforge/skills/code-generation-patterns/SKILL.md +92 -0
- package/.mindforge/skills/code-review-methodology/SKILL.md +180 -0
- package/.mindforge/skills/code-tour/SKILL.md +145 -0
- package/.mindforge/skills/codebase-onboarding/SKILL.md +95 -0
- package/.mindforge/skills/compliance-as-code/SKILL.md +195 -0
- package/.mindforge/skills/conflict-resolution/SKILL.md +87 -0
- package/.mindforge/skills/connection-pooling/SKILL.md +151 -0
- package/.mindforge/skills/container-security/SKILL.md +151 -0
- package/.mindforge/skills/context-engineering/SKILL.md +114 -0
- package/.mindforge/skills/contract-testing/SKILL.md +85 -0
- package/.mindforge/skills/cost-estimation/SKILL.md +82 -0
- package/.mindforge/skills/cqrs-event-sourcing/SKILL.md +95 -0
- package/.mindforge/skills/cross-platform-testing/SKILL.md +43 -0
- package/.mindforge/skills/data-governance/SKILL.md +42 -0
- package/.mindforge/skills/data-lakehouse/SKILL.md +42 -0
- package/.mindforge/skills/data-mesh/SKILL.md +42 -0
- package/.mindforge/skills/data-modeling/SKILL.md +107 -0
- package/.mindforge/skills/data-pipeline-design/SKILL.md +171 -0
- package/.mindforge/skills/data-privacy-engineering/SKILL.md +42 -0
- package/.mindforge/skills/database-performance/SKILL.md +174 -0
- package/.mindforge/skills/database-sharding-advanced/SKILL.md +206 -0
- package/.mindforge/skills/de-sloppify/SKILL.md +120 -0
- package/.mindforge/skills/defense-in-depth/SKILL.md +84 -0
- package/.mindforge/skills/delegation-patterns/SKILL.md +123 -0
- package/.mindforge/skills/dependency-management/SKILL.md +94 -0
- package/.mindforge/skills/deployment-workflow/SKILL.md +135 -0
- package/.mindforge/skills/design-system/SKILL.md +113 -0
- package/.mindforge/skills/developer-onboarding/SKILL.md +99 -0
- package/.mindforge/skills/developer-productivity-metrics/SKILL.md +59 -0
- package/.mindforge/skills/distributed-consensus/SKILL.md +141 -0
- package/.mindforge/skills/dmux-workflows/SKILL.md +141 -0
- package/.mindforge/skills/dns-architecture/SKILL.md +167 -0
- package/.mindforge/skills/ecommerce-architecture/SKILL.md +41 -0
- package/.mindforge/skills/edge-computing/SKILL.md +91 -0
- package/.mindforge/skills/edtech-platform/SKILL.md +41 -0
- package/.mindforge/skills/email-deliverability/SKILL.md +177 -0
- package/.mindforge/skills/embedding-systems/SKILL.md +55 -0
- package/.mindforge/skills/environment-management/SKILL.md +54 -0
- package/.mindforge/skills/error-handling-architecture/SKILL.md +118 -0
- package/.mindforge/skills/estimation-techniques/SKILL.md +113 -0
- package/.mindforge/skills/eval-harness/SKILL.md +180 -0
- package/.mindforge/skills/event-driven-architecture/SKILL.md +162 -0
- package/.mindforge/skills/experiment-design/SKILL.md +139 -0
- package/.mindforge/skills/experiment-platform/SKILL.md +43 -0
- package/.mindforge/skills/feature-engineering/SKILL.md +42 -0
- package/.mindforge/skills/feature-flag-management/SKILL.md +183 -0
- package/.mindforge/skills/fine-tuning-workflow/SKILL.md +189 -0
- package/.mindforge/skills/fintech-patterns/SKILL.md +41 -0
- package/.mindforge/skills/flutter-architecture/SKILL.md +42 -0
- package/.mindforge/skills/gaming-backend/SKILL.md +41 -0
- package/.mindforge/skills/git-workflow-design/SKILL.md +129 -0
- package/.mindforge/skills/graceful-degradation/SKILL.md +95 -0
- package/.mindforge/skills/graphql-patterns/SKILL.md +243 -0
- package/.mindforge/skills/guardrails-and-safety/SKILL.md +137 -0
- package/.mindforge/skills/healthcare-systems/SKILL.md +40 -0
- package/.mindforge/skills/hiring-engineering/SKILL.md +119 -0
- package/.mindforge/skills/human-in-the-loop-design/SKILL.md +234 -0
- package/.mindforge/skills/i18n-architecture/SKILL.md +147 -0
- package/.mindforge/skills/idempotency-patterns/SKILL.md +84 -0
- package/.mindforge/skills/incident-communication/SKILL.md +96 -0
- package/.mindforge/skills/incident-management/SKILL.md +97 -0
- package/.mindforge/skills/infrastructure-as-code/SKILL.md +98 -0
- package/.mindforge/skills/instinct-clustering/SKILL.md +190 -0
- package/.mindforge/skills/internal-developer-platform/SKILL.md +51 -0
- package/.mindforge/skills/iot-platform/SKILL.md +41 -0
- package/.mindforge/skills/k8s-deployment/SKILL.md +358 -0
- package/.mindforge/skills/knowledge-graphs/SKILL.md +56 -0
- package/.mindforge/skills/knowledge-sharing-systems/SKILL.md +112 -0
- package/.mindforge/skills/llm-cost-optimization/SKILL.md +198 -0
- package/.mindforge/skills/llm-orchestration/SKILL.md +56 -0
- package/.mindforge/skills/load-testing/SKILL.md +84 -0
- package/.mindforge/skills/logistics-optimization/SKILL.md +40 -0
- package/.mindforge/skills/market-researcher/SKILL.md +99 -0
- package/.mindforge/skills/marketplace-trust/SKILL.md +40 -0
- package/.mindforge/skills/mcp-server-patterns/SKILL.md +264 -0
- package/.mindforge/skills/media-streaming/SKILL.md +41 -0
- package/.mindforge/skills/meeting-architecture/SKILL.md +146 -0
- package/.mindforge/skills/mentoring-patterns/SKILL.md +77 -0
- package/.mindforge/skills/microservices-patterns/SKILL.md +83 -0
- package/.mindforge/skills/migration-platform/SKILL.md +61 -0
- package/.mindforge/skills/migration-strategies/SKILL.md +129 -0
- package/.mindforge/skills/ml-feature-store/SKILL.md +56 -0
- package/.mindforge/skills/ml-monitoring/SKILL.md +42 -0
- package/.mindforge/skills/mobile-performance/SKILL.md +44 -0
- package/.mindforge/skills/mobile-security/SKILL.md +45 -0
- package/.mindforge/skills/model-evaluation/SKILL.md +53 -0
- package/.mindforge/skills/monorepo-management/SKILL.md +100 -0
- package/.mindforge/skills/multi-tenancy-patterns/SKILL.md +145 -0
- package/.mindforge/skills/multi-turn-conversation-design/SKILL.md +206 -0
- package/.mindforge/skills/multimodal-ai/SKILL.md +51 -0
- package/.mindforge/skills/mutation-testing/SKILL.md +97 -0
- package/.mindforge/skills/notification-system-design/SKILL.md +168 -0
- package/.mindforge/skills/observability-stack/SKILL.md +136 -0
- package/.mindforge/skills/offline-first-design/SKILL.md +43 -0
- package/.mindforge/skills/on-call-design/SKILL.md +111 -0
- package/.mindforge/skills/pagination-patterns/SKILL.md +230 -0
- package/.mindforge/skills/payment-integration/SKILL.md +176 -0
- package/.mindforge/skills/performance-reviews/SKILL.md +140 -0
- package/.mindforge/skills/platform-observability/SKILL.md +58 -0
- package/.mindforge/skills/platform-reliability/SKILL.md +52 -0
- package/.mindforge/skills/post-incident-learning/SKILL.md +96 -0
- package/.mindforge/skills/product-manager/SKILL.md +104 -0
- package/.mindforge/skills/progressive-web-app/SKILL.md +44 -0
- package/.mindforge/skills/prompt-engineering/SKILL.md +94 -0
- package/.mindforge/skills/proofreader/SKILL.md +158 -0
- package/.mindforge/skills/push-notification-architecture/SKILL.md +45 -0
- package/.mindforge/skills/python-performance/SKILL.md +183 -0
- package/.mindforge/skills/quality-audit/SKILL.md +171 -0
- package/.mindforge/skills/queue-design/SKILL.md +85 -0
- package/.mindforge/skills/rag-architecture/SKILL.md +176 -0
- package/.mindforge/skills/rate-limiting-design/SKILL.md +94 -0
- package/.mindforge/skills/react-native-patterns/SKILL.md +42 -0
- package/.mindforge/skills/react-performance/SKILL.md +229 -0
- package/.mindforge/skills/real-time-analytics/SKILL.md +42 -0
- package/.mindforge/skills/real-time-sync/SKILL.md +83 -0
- package/.mindforge/skills/responsive-native/SKILL.md +44 -0
- package/.mindforge/skills/responsive-patterns/SKILL.md +141 -0
- package/.mindforge/skills/rfc-pipeline/SKILL.md +114 -0
- package/.mindforge/skills/saas-multi-tenant/SKILL.md +41 -0
- package/.mindforge/skills/santa-method/SKILL.md +134 -0
- package/.mindforge/skills/search-implementation/SKILL.md +98 -0
- package/.mindforge/skills/secrets-platform/SKILL.md +56 -0
- package/.mindforge/skills/secrets-rotation/SKILL.md +173 -0
- package/.mindforge/skills/self-serve-infrastructure/SKILL.md +51 -0
- package/.mindforge/skills/serverless-patterns/SKILL.md +119 -0
- package/.mindforge/skills/skill-creator-meta/SKILL.md +146 -0
- package/.mindforge/skills/sprint-retrospective-facilitation/SKILL.md +112 -0
- package/.mindforge/skills/stakeholder-communication/SKILL.md +85 -0
- package/.mindforge/skills/state-management/SKILL.md +104 -0
- package/.mindforge/skills/stream-processing/SKILL.md +43 -0
- package/.mindforge/skills/streaming-architecture/SKILL.md +81 -0
- package/.mindforge/skills/supply-chain-security/SKILL.md +145 -0
- package/.mindforge/skills/synthetic-data-generation/SKILL.md +52 -0
- package/.mindforge/skills/system-design/SKILL.md +88 -0
- package/.mindforge/skills/team-topology-design/SKILL.md +107 -0
- package/.mindforge/skills/technical-debt-management/SKILL.md +86 -0
- package/.mindforge/skills/technical-interview-design/SKILL.md +98 -0
- package/.mindforge/skills/technical-leadership/SKILL.md +75 -0
- package/.mindforge/skills/technical-writing/SKILL.md +237 -0
- package/.mindforge/skills/technology-radar/SKILL.md +88 -0
- package/.mindforge/skills/testing-anti-patterns/SKILL.md +288 -0
- package/.mindforge/skills/tool-design/SKILL.md +138 -0
- package/.mindforge/skills/typescript-advanced/SKILL.md +198 -0
- package/.mindforge/skills/using-git-worktrees/SKILL.md +139 -0
- package/.mindforge/skills/verification-loop/SKILL.md +13 -1
- package/.mindforge/skills/vibe-security/SKILL.md +165 -0
- package/.mindforge/skills/visual-regression-testing/SKILL.md +97 -0
- package/.mindforge/skills/websocket-patterns/SKILL.md +203 -0
- package/.mindforge/skills/writing-plans/SKILL.md +170 -0
- package/.mindforge/skills/writing-skills/SKILL.md +216 -0
- package/.mindforge/skills/zero-trust-architecture/SKILL.md +166 -0
- package/CHANGELOG.md +240 -0
- package/MINDFORGE.md +4 -4
- package/README.md +49 -4
- package/RELEASENOTES.md +80 -0
- package/SECURITY.md +20 -8
- package/bin/autonomous/audit-writer.js +13 -0
- package/bin/autonomous/auto-runner.js +74 -16
- package/bin/autonomous/context-refactorer.js +26 -11
- package/bin/autonomous/state-manager.js +62 -6
- package/bin/autonomous/stuck-monitor.js +46 -7
- package/bin/autonomous/wave-executor.js +66 -25
- package/bin/dashboard/api-router.js +43 -0
- package/bin/dashboard/metrics-aggregator.js +28 -1
- package/bin/dashboard/server.js +67 -4
- package/bin/dashboard/sse-bridge.js +4 -4
- package/bin/engine/feedback-loop.js +8 -0
- package/bin/engine/intelligence-interlock.js +32 -15
- package/bin/engine/logic-drift-detector.js +2 -1
- package/bin/engine/nexus-tracer.js +3 -2
- package/bin/engine/remediation-engine.js +155 -32
- package/bin/engine/self-corrective-synthesizer.js +84 -10
- package/bin/engine/sre-manager.js +12 -4
- package/bin/engine/temporal-hub.js +131 -34
- package/bin/governance/approve.js +41 -5
- package/bin/governance/impact-analyzer.js +28 -0
- package/bin/governance/policy-engine.js +10 -3
- package/bin/governance/quantum-crypto.js +32 -19
- package/bin/governance/rbac-manager.js +74 -2
- package/bin/governance/ztai-manager.js +49 -7
- package/bin/hindsight-injector.js +3 -3
- package/bin/memory/eis-client.js +71 -34
- package/bin/memory/embedding-engine.js +61 -0
- package/bin/memory/knowledge-graph.js +58 -5
- package/bin/memory/knowledge-indexer.js +53 -6
- package/bin/memory/knowledge-store.js +22 -0
- package/bin/migrations/10.7.0-to-11.0.0.js +110 -0
- package/bin/migrations/schema-versions.js +13 -0
- package/bin/models/anthropic-provider.js +45 -0
- package/bin/models/cloud-broker.js +68 -20
- package/bin/models/gemini-provider.js +51 -0
- package/bin/models/model-client.js +20 -0
- package/bin/models/model-router.js +28 -8
- package/bin/models/openai-provider.js +44 -0
- package/bin/utils/file-io.js +63 -1
- package/bin/utils/index.js +58 -0
- package/docs/getting-started.md +1 -1
- package/docs/user-guide.md +2 -2
- package/package.json +2 -2
- package/.mindforge/personas/data-privacy-engineer.md +0 -187
|
@@ -326,6 +326,32 @@ function getCosts(windowDays = 7) {
|
|
|
326
326
|
return stats;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
// ── Heap Health ──────────────────────────────────────────────────────────────
|
|
330
|
+
function checkHeapHealth() {
|
|
331
|
+
const heapUsed = process.memoryUsage().heapUsed;
|
|
332
|
+
const maxHeap = getMaxOldSpaceSize();
|
|
333
|
+
const usagePct = Math.round(heapUsed / maxHeap * 100);
|
|
334
|
+
|
|
335
|
+
let status = 'healthy';
|
|
336
|
+
if (usagePct > 85) {
|
|
337
|
+
status = 'critical';
|
|
338
|
+
} else if (usagePct > 70) {
|
|
339
|
+
status = 'warning';
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return { status, usage_pct: usagePct };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function getMaxOldSpaceSize() {
|
|
346
|
+
// Parse --max-old-space-size from process args, default 1.4GB
|
|
347
|
+
const flag = process.execArgv.find(a => a.startsWith('--max-old-space-size'));
|
|
348
|
+
if (flag) {
|
|
349
|
+
const mb = parseInt(flag.split('=')[1], 10);
|
|
350
|
+
if (mb > 0) return mb * 1024 * 1024;
|
|
351
|
+
}
|
|
352
|
+
return 1.4 * 1024 * 1024 * 1024;
|
|
353
|
+
}
|
|
354
|
+
|
|
329
355
|
module.exports = {
|
|
330
356
|
getStatus,
|
|
331
357
|
getAuditEntries,
|
|
@@ -333,5 +359,6 @@ module.exports = {
|
|
|
333
359
|
getApprovals,
|
|
334
360
|
getTeamActivity,
|
|
335
361
|
getMemory,
|
|
336
|
-
getCosts
|
|
362
|
+
getCosts,
|
|
363
|
+
checkHeapHealth
|
|
337
364
|
};
|
package/bin/dashboard/server.js
CHANGED
|
@@ -42,12 +42,18 @@ const RevOpsAPI = require('./revops-api');
|
|
|
42
42
|
const app = express();
|
|
43
43
|
|
|
44
44
|
// ── Bearer token authentication ──────────────────────────────────────────────
|
|
45
|
-
|
|
45
|
+
let currentToken = crypto.randomBytes(32).toString('hex');
|
|
46
46
|
const TOKEN_FILE = path.join(process.cwd(), '.mindforge', '.dashboard-token');
|
|
47
|
+
const TOKEN_EXPIRY_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
48
|
+
let tokenCreatedAt = Date.now();
|
|
49
|
+
|
|
50
|
+
function isTokenExpired() {
|
|
51
|
+
return (Date.now() - tokenCreatedAt) > TOKEN_EXPIRY_MS;
|
|
52
|
+
}
|
|
47
53
|
|
|
48
54
|
// Write token to file with restrictive permissions (owner-only read/write)
|
|
49
55
|
fs.mkdirSync(path.dirname(TOKEN_FILE), { recursive: true });
|
|
50
|
-
fs.writeFileSync(TOKEN_FILE,
|
|
56
|
+
fs.writeFileSync(TOKEN_FILE, currentToken, { mode: 0o600 });
|
|
51
57
|
|
|
52
58
|
/**
|
|
53
59
|
* requireAuth — Validates Bearer token on mutating requests (POST/PUT/DELETE).
|
|
@@ -56,6 +62,11 @@ fs.writeFileSync(TOKEN_FILE, DASHBOARD_TOKEN, { mode: 0o600 });
|
|
|
56
62
|
function requireAuth(req, res, next) {
|
|
57
63
|
if (req.method === 'GET' || req.method === 'OPTIONS') return next();
|
|
58
64
|
|
|
65
|
+
// Check token expiration first
|
|
66
|
+
if (isTokenExpired()) {
|
|
67
|
+
return res.status(401).json({ error: 'token_expired' });
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
const authHeader = req.headers.authorization;
|
|
60
71
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
61
72
|
return res.status(401).json({
|
|
@@ -65,7 +76,9 @@ function requireAuth(req, res, next) {
|
|
|
65
76
|
|
|
66
77
|
const provided = authHeader.slice(7);
|
|
67
78
|
// Constant-time comparison to prevent timing attacks
|
|
68
|
-
|
|
79
|
+
const tokenBuf = Buffer.from(currentToken);
|
|
80
|
+
const providedBuf = Buffer.from(provided);
|
|
81
|
+
if (tokenBuf.length !== providedBuf.length || !crypto.timingSafeEqual(providedBuf, tokenBuf)) {
|
|
69
82
|
return res.status(401).json({
|
|
70
83
|
error: 'Authentication required. Use the token printed at dashboard startup.'
|
|
71
84
|
});
|
|
@@ -74,6 +87,44 @@ function requireAuth(req, res, next) {
|
|
|
74
87
|
next();
|
|
75
88
|
}
|
|
76
89
|
|
|
90
|
+
// ── Rate limiting (100 req/min/IP) ───────────────────────────────────────────
|
|
91
|
+
const rateLimitMap = new Map(); // ip -> { count, resetAt }
|
|
92
|
+
const RATE_LIMIT = 100;
|
|
93
|
+
const RATE_WINDOW_MS = 60000;
|
|
94
|
+
|
|
95
|
+
function rateLimitMiddleware(req, res, next) {
|
|
96
|
+
const ip = req.ip || req.connection.remoteAddress;
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
let entry = rateLimitMap.get(ip);
|
|
99
|
+
|
|
100
|
+
if (!entry || now > entry.resetAt) {
|
|
101
|
+
entry = { count: 0, resetAt: now + RATE_WINDOW_MS };
|
|
102
|
+
rateLimitMap.set(ip, entry);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
entry.count++;
|
|
106
|
+
|
|
107
|
+
if (entry.count > RATE_LIMIT) {
|
|
108
|
+
return res.status(429).json({
|
|
109
|
+
error: 'rate_limit_exceeded',
|
|
110
|
+
retry_after_ms: entry.resetAt - now
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
next();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Periodically clean stale rate-limit entries to prevent memory growth
|
|
118
|
+
const rateLimitCleanupInterval = setInterval(() => {
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
for (const [ip, entry] of rateLimitMap.entries()) {
|
|
121
|
+
if (now > entry.resetAt) {
|
|
122
|
+
rateLimitMap.delete(ip);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}, 60000);
|
|
126
|
+
if (rateLimitCleanupInterval.unref) rateLimitCleanupInterval.unref();
|
|
127
|
+
|
|
77
128
|
// Security middleware
|
|
78
129
|
app.use((req, res, next) => {
|
|
79
130
|
const addr = req.socket.remoteAddress;
|
|
@@ -84,6 +135,9 @@ app.use((req, res, next) => {
|
|
|
84
135
|
next();
|
|
85
136
|
});
|
|
86
137
|
|
|
138
|
+
// ── Rate limiting — applied after localhost check, before auth ────────────────
|
|
139
|
+
app.use(rateLimitMiddleware);
|
|
140
|
+
|
|
87
141
|
// CORS — restrict to dashboard's own origin only (prevent cross-origin attacks)
|
|
88
142
|
const DASHBOARD_ORIGIN = `http://127.0.0.1:${PORT}`;
|
|
89
143
|
app.use((req, res, next) => {
|
|
@@ -124,6 +178,15 @@ app.get('/', (req, res) => {
|
|
|
124
178
|
res.sendFile(FRONTEND);
|
|
125
179
|
});
|
|
126
180
|
|
|
181
|
+
// ── Token refresh endpoint (requires valid existing token) ───────────────────
|
|
182
|
+
app.post('/api/v1/token/refresh', requireAuth, (req, res) => {
|
|
183
|
+
const newToken = crypto.randomBytes(32).toString('hex');
|
|
184
|
+
fs.writeFileSync(TOKEN_FILE, newToken, { mode: 0o600 });
|
|
185
|
+
tokenCreatedAt = Date.now();
|
|
186
|
+
currentToken = newToken;
|
|
187
|
+
res.json({ success: true, token: newToken, expires_in_ms: TOKEN_EXPIRY_MS });
|
|
188
|
+
});
|
|
189
|
+
|
|
127
190
|
// ── Register API routes ───────────────────────────────────────────────────────
|
|
128
191
|
API.register(app);
|
|
129
192
|
app.use('/api/temporal', TemporalAPI);
|
|
@@ -143,7 +206,7 @@ server.listen(PORT, '127.0.0.1', () => {
|
|
|
143
206
|
console.log(` Status: http://localhost:${PORT}/api/status`);
|
|
144
207
|
console.log(` Events: http://localhost:${PORT}/events`);
|
|
145
208
|
console.log(` PID: ${process.pid}`);
|
|
146
|
-
console.log(
|
|
209
|
+
console.log('[Dashboard] Auth token written to token file (not logged for security).');
|
|
147
210
|
console.log(` Token file: ${TOKEN_FILE}`);
|
|
148
211
|
console.log('\n Press CTRL+C to stop\n');
|
|
149
212
|
|
|
@@ -80,14 +80,14 @@ function pollAuditLog() {
|
|
|
80
80
|
const newSize = stat.size;
|
|
81
81
|
const newIno = stat.ino;
|
|
82
82
|
|
|
83
|
-
// File rotation detected: inode changed or
|
|
84
|
-
if (newIno !== _auditInode && _auditInode !== 0) {
|
|
85
|
-
process.stderr.write(`[sse-bridge] AUDIT.jsonl rotation detected (
|
|
83
|
+
// File rotation detected: inode changed or file shrunk (truncated after archival)
|
|
84
|
+
if ((newIno !== _auditInode && _auditInode !== 0) || (newSize < _lastAuditSize)) {
|
|
85
|
+
process.stderr.write(`[sse-bridge] AUDIT.jsonl rotation detected (size: ${_lastAuditSize} -> ${newSize}, ino: ${_auditInode} -> ${newIno})\n`);
|
|
86
86
|
_lastAuditSize = 0;
|
|
87
87
|
}
|
|
88
88
|
_auditInode = newIno;
|
|
89
89
|
|
|
90
|
-
if (newSize <= _lastAuditSize) return;
|
|
90
|
+
if (newSize <= _lastAuditSize) return;
|
|
91
91
|
|
|
92
92
|
// Read only the new bytes appended since last poll
|
|
93
93
|
const fd = fs.openSync(AUDIT_PATH, 'r');
|
|
@@ -98,6 +98,14 @@ class WaveFeedbackLoop {
|
|
|
98
98
|
return { shouldPause: false };
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
recordRemediationOutcome(remediationId, outcome) {
|
|
102
|
+
this.recordPerformance(
|
|
103
|
+
outcome.strategy,
|
|
104
|
+
'remediation',
|
|
105
|
+
outcome.effective
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
101
109
|
reset() {
|
|
102
110
|
this.waveState = { completed: 0, failed: 0, skipped: 0, total: 0 };
|
|
103
111
|
}
|
|
@@ -15,24 +15,41 @@ class IntelligenceInterlock {
|
|
|
15
15
|
this.UPGRADE_THRESHOLD = 0.50; // v6.3.0 Threshold (Recalibrated for IDC readiness)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* Evaluates if a model upgrade is required based on reasoning drift.
|
|
20
|
-
* @param {string} spanId
|
|
21
|
-
* @param {string} thought
|
|
22
|
-
*/
|
|
23
18
|
evaluate(spanId, thought) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
const driftReport = driftDetector.analyze(spanId, thought);
|
|
20
|
+
const driftScore = driftReport.drift_score;
|
|
21
|
+
|
|
22
|
+
if (driftScore <= this.UPGRADE_THRESHOLD) {
|
|
23
|
+
return { action: 'CONTINUE', drift_score: driftScore };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let tierIncrease;
|
|
27
|
+
if (driftScore > 0.80) {
|
|
28
|
+
tierIncrease = 'MAX';
|
|
29
|
+
} else if (driftScore > 0.65) {
|
|
30
|
+
tierIncrease = 2;
|
|
31
|
+
} else {
|
|
32
|
+
tierIncrease = 1;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
let costWarning = false;
|
|
36
|
+
try {
|
|
37
|
+
const CostTracker = require('../models/cost-tracker');
|
|
38
|
+
const dailySpend = CostTracker.getDailySpend ? CostTracker.getDailySpend() : 0;
|
|
39
|
+
const hardLimit = CostTracker.getHardLimit ? CostTracker.getHardLimit() : Infinity;
|
|
40
|
+
if (dailySpend / hardLimit > 0.8) {
|
|
41
|
+
costWarning = true;
|
|
42
|
+
tierIncrease = Math.min(tierIncrease === 'MAX' ? 3 : tierIncrease, 1);
|
|
43
|
+
}
|
|
44
|
+
} catch { /* cost tracker unavailable */ }
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
action: 'UPGRADE_MIR',
|
|
48
|
+
tier_increase: tierIncrease,
|
|
49
|
+
drift_score: driftScore,
|
|
50
|
+
cost_constrained: costWarning,
|
|
51
|
+
reason: driftReport.markers
|
|
52
|
+
};
|
|
36
53
|
}
|
|
37
54
|
}
|
|
38
55
|
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
const configManager = require('../governance/config-manager');
|
|
11
|
+
const { LRUMap } = require('../utils/index');
|
|
11
12
|
|
|
12
13
|
class LogicDriftDetector {
|
|
13
14
|
constructor() {
|
|
14
|
-
this.sessionDriftHistory = new
|
|
15
|
+
this.sessionDriftHistory = new LRUMap(500);
|
|
15
16
|
this.DRIFT_THRESHOLD = configManager.get('governance.drift_threshold', 0.75);
|
|
16
17
|
this.CRITICAL_DRIFT_THRESHOLD = configManager.get('governance.critical_drift_threshold', 0.50);
|
|
17
18
|
}
|
|
@@ -16,6 +16,7 @@ const remediationEngine = require('./remediation-engine'); // v6.1 Pillar X
|
|
|
16
16
|
const logicValidator = require('./logic-validator'); // v7 Pillar X
|
|
17
17
|
const vectorHub = require('../memory/vector-hub'); // v8 Pillar XV
|
|
18
18
|
const { AuditWriter } = require('../utils/file-io');
|
|
19
|
+
const { LRUMap } = require('../utils/index');
|
|
19
20
|
|
|
20
21
|
class NexusTracer {
|
|
21
22
|
constructor(config = {}) {
|
|
@@ -29,8 +30,8 @@ class NexusTracer {
|
|
|
29
30
|
this.vhInitialized = false;
|
|
30
31
|
|
|
31
32
|
// v7: Centralized Thresholds
|
|
32
|
-
this.RES_THRESHOLD = configManager.get('governance.res_threshold', 0.8);
|
|
33
|
-
this.entropyCache = new
|
|
33
|
+
this.RES_THRESHOLD = configManager.get('governance.res_threshold', 0.8);
|
|
34
|
+
this.entropyCache = new LRUMap(1000);
|
|
34
35
|
|
|
35
36
|
// v9: Async Audit Writer (replaces sync appendFileSync)
|
|
36
37
|
this._auditWriter = new AuditWriter(this.auditPath);
|
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MindForge
|
|
2
|
+
* MindForge v11.0.0 — Neural Drift Remediation (NDR)
|
|
3
3
|
* Component: Remediation Engine (Pillar X)
|
|
4
|
-
*
|
|
5
|
-
* Triggers corrective actions when logic drift or reasoning
|
|
6
|
-
* stagnation is detected.
|
|
4
|
+
*
|
|
5
|
+
* Triggers corrective actions when logic drift or reasoning
|
|
6
|
+
* stagnation is detected. v11: Full strategy implementations
|
|
7
|
+
* for CONTEXT_COMPRESSION, GOLDEN_TRACE_INJECTION, and REASONING_RESTART.
|
|
7
8
|
*/
|
|
8
9
|
'use strict';
|
|
9
10
|
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
10
13
|
const remediationQueue = require('../revops/remediation-queue');
|
|
11
14
|
const logicValidator = require('./logic-validator');
|
|
12
|
-
|
|
15
|
+
|
|
16
|
+
const MAX_PENDING_REMEDIATIONS = 50;
|
|
13
17
|
|
|
14
18
|
class RemediationEngine {
|
|
15
19
|
constructor() {
|
|
16
|
-
this.activeRemediations = new
|
|
20
|
+
this.activeRemediations = new Map();
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* Triggers a specific remediation workflow.
|
|
21
|
-
* @param {string} spanId
|
|
25
|
+
* @param {string} spanId
|
|
22
26
|
* @param {Object} report - From LogicDriftDetector
|
|
23
27
|
*/
|
|
24
28
|
async trigger(spanId, report) {
|
|
25
29
|
const { drift_score, markers } = report;
|
|
26
30
|
let strategy = 'NOT_REQUIRED';
|
|
27
31
|
|
|
28
|
-
// Tiered Remediation Logic
|
|
29
32
|
if (drift_score > 0.9) strategy = 'REASONING_RESTART';
|
|
30
33
|
else if (drift_score > 0.8 || report.invalid_logic) strategy = 'GOLDEN_TRACE_INJECTION';
|
|
31
34
|
else if (drift_score > 0.75) strategy = 'CONTEXT_COMPRESSION';
|
|
@@ -41,40 +44,160 @@ class RemediationEngine {
|
|
|
41
44
|
};
|
|
42
45
|
|
|
43
46
|
console.log(`[Remediation] Triggered ${strategy} for ${spanId} (Score: ${drift_score})`);
|
|
44
|
-
|
|
45
|
-
// v7: Finalize with Stateful Queueing
|
|
47
|
+
|
|
46
48
|
await remediationQueue.enqueue(action);
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const result = await this._executeStrategy(strategy, spanId);
|
|
51
|
+
|
|
52
|
+
this.activeRemediations.set(action.remediation_id, {
|
|
53
|
+
spanId,
|
|
54
|
+
strategy: action.strategy,
|
|
55
|
+
timestamp: Date.now(),
|
|
56
|
+
preScore: drift_score
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Evict oldest entries if map exceeds bound
|
|
60
|
+
if (this.activeRemediations.size > MAX_PENDING_REMEDIATIONS) {
|
|
61
|
+
const firstKey = this.activeRemediations.keys().next().value;
|
|
62
|
+
this.activeRemediations.delete(firstKey);
|
|
63
|
+
}
|
|
50
64
|
|
|
51
|
-
return action;
|
|
65
|
+
return { ...action, execution: result };
|
|
52
66
|
}
|
|
53
67
|
|
|
54
|
-
/**
|
|
55
|
-
* functional implementation of remediation strategies.
|
|
56
|
-
*/
|
|
57
68
|
async _executeStrategy(strategy, spanId) {
|
|
58
|
-
switch(strategy) {
|
|
59
|
-
case '
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
switch (strategy) {
|
|
70
|
+
case 'CONTEXT_COMPRESSION': return this._executeContextCompression(spanId);
|
|
71
|
+
case 'GOLDEN_TRACE_INJECTION': return this._executeGoldenTraceInjection(spanId);
|
|
72
|
+
case 'REASONING_RESTART': return this._executeReasoningRestart(spanId);
|
|
73
|
+
default: return { strategy, result: 'unknown_strategy' };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async _executeContextCompression(spanId) {
|
|
78
|
+
try {
|
|
79
|
+
const { ContextEntropyGuard } = require('./context-entropy-guard');
|
|
80
|
+
const guard = typeof ContextEntropyGuard === 'function'
|
|
81
|
+
? new ContextEntropyGuard()
|
|
82
|
+
: ContextEntropyGuard;
|
|
83
|
+
|
|
84
|
+
const traces = this._getRecentTraces(spanId, 20);
|
|
85
|
+
const compressed = guard.compress(traces);
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
strategy: 'CONTEXT_COMPRESSION',
|
|
89
|
+
result: 'applied',
|
|
90
|
+
tracesCompressed: traces.length,
|
|
91
|
+
outputSize: compressed.length
|
|
92
|
+
};
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
strategy: 'CONTEXT_COMPRESSION',
|
|
96
|
+
result: 'error',
|
|
97
|
+
message: err.message
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async _executeGoldenTraceInjection(spanId) {
|
|
103
|
+
try {
|
|
104
|
+
let SemanticHub;
|
|
105
|
+
try {
|
|
106
|
+
SemanticHub = require('../memory/semantic-hub');
|
|
107
|
+
} catch {
|
|
108
|
+
return { strategy: 'GOLDEN_TRACE_INJECTION', result: 'unavailable' };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await SemanticHub.ensureInit();
|
|
112
|
+
const goldenTraces = await SemanticHub.getGoldenTraces({ limit: 3 });
|
|
113
|
+
|
|
114
|
+
if (!goldenTraces || goldenTraces.length === 0) {
|
|
115
|
+
return { strategy: 'GOLDEN_TRACE_INJECTION', result: 'no_traces_found' };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
strategy: 'GOLDEN_TRACE_INJECTION',
|
|
120
|
+
result: 'injected',
|
|
121
|
+
tracesInjected: goldenTraces.length,
|
|
122
|
+
traceIds: goldenTraces.map(t => t.id || t.trace_id).filter(Boolean)
|
|
123
|
+
};
|
|
124
|
+
} catch (err) {
|
|
125
|
+
return {
|
|
126
|
+
strategy: 'GOLDEN_TRACE_INJECTION',
|
|
127
|
+
result: 'error',
|
|
128
|
+
message: err.message
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async _executeReasoningRestart(spanId) {
|
|
134
|
+
try {
|
|
135
|
+
return {
|
|
136
|
+
strategy: 'REASONING_RESTART',
|
|
137
|
+
result: 'signalled',
|
|
138
|
+
instruction: 'Clear current reasoning context and re-read project constitution',
|
|
139
|
+
spanId
|
|
140
|
+
};
|
|
141
|
+
} catch (err) {
|
|
142
|
+
return {
|
|
143
|
+
strategy: 'REASONING_RESTART',
|
|
144
|
+
result: 'error',
|
|
145
|
+
message: err.message
|
|
146
|
+
};
|
|
73
147
|
}
|
|
74
148
|
}
|
|
75
149
|
|
|
150
|
+
_getRecentTraces(spanId, limit) {
|
|
151
|
+
try {
|
|
152
|
+
const NexusTracer = require('./nexus-tracer');
|
|
153
|
+
const spans = NexusTracer.activeSpans || new Map();
|
|
154
|
+
return Array.from(spans.values()).slice(-limit);
|
|
155
|
+
} catch {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
evaluateOutcome(spanId, currentDriftScore) {
|
|
161
|
+
const results = [];
|
|
162
|
+
for (const [remId, rem] of this.activeRemediations) {
|
|
163
|
+
if (rem.spanId === spanId) {
|
|
164
|
+
const improved = currentDriftScore < rem.preScore;
|
|
165
|
+
const effectiveness = improved ? (rem.preScore - currentDriftScore) / rem.preScore : 0;
|
|
166
|
+
results.push({
|
|
167
|
+
remediation_id: remId,
|
|
168
|
+
strategy: rem.strategy,
|
|
169
|
+
effective: improved,
|
|
170
|
+
effectiveness_score: Math.round(effectiveness * 100) / 100,
|
|
171
|
+
pre_score: rem.preScore,
|
|
172
|
+
post_score: currentDriftScore
|
|
173
|
+
});
|
|
174
|
+
this.activeRemediations.delete(remId);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (results.length > 0) {
|
|
178
|
+
this._persistEffectivenessStats(results);
|
|
179
|
+
}
|
|
180
|
+
return results;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
_persistEffectivenessStats(results) {
|
|
184
|
+
try {
|
|
185
|
+
const statsPath = path.join(process.cwd(), 'bin', 'models', 'performance-stats.json');
|
|
186
|
+
let stats = {};
|
|
187
|
+
if (fs.existsSync(statsPath)) {
|
|
188
|
+
stats = JSON.parse(fs.readFileSync(statsPath, 'utf8'));
|
|
189
|
+
}
|
|
190
|
+
if (!stats.remediation_effectiveness) stats.remediation_effectiveness = [];
|
|
191
|
+
stats.remediation_effectiveness.push(...results);
|
|
192
|
+
if (stats.remediation_effectiveness.length > 100) {
|
|
193
|
+
stats.remediation_effectiveness = stats.remediation_effectiveness.slice(-100);
|
|
194
|
+
}
|
|
195
|
+
fs.writeFileSync(statsPath, JSON.stringify(stats, null, 2));
|
|
196
|
+
} catch { /* non-critical */ }
|
|
197
|
+
}
|
|
198
|
+
|
|
76
199
|
getActiveRemediations() {
|
|
77
|
-
return Array.from(this.activeRemediations);
|
|
200
|
+
return Array.from(this.activeRemediations.entries()).map(([id, data]) => ({ id, ...data }));
|
|
78
201
|
}
|
|
79
202
|
}
|
|
80
203
|
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MindForge
|
|
2
|
+
* MindForge v11.0.0 — Self-Corrective Synthesis (SCS)
|
|
3
3
|
* Component: Self-Corrective Synthesizer (Pillar XII)
|
|
4
|
-
*
|
|
5
|
-
* Analyzes mission drift and logic stagnation to synthesize
|
|
4
|
+
*
|
|
5
|
+
* Analyzes mission drift and logic stagnation to synthesize
|
|
6
6
|
* corrective steering signals (Homing Instructions).
|
|
7
|
+
*
|
|
8
|
+
* v11: Expanded analysis window (50 events), exponential decay weighting,
|
|
9
|
+
* and correction effectiveness tracking.
|
|
7
10
|
*/
|
|
8
11
|
'use strict';
|
|
9
12
|
|
|
10
13
|
const rsa = require('./reason-source-aligner.js');
|
|
11
14
|
|
|
15
|
+
const HISTORY_LIMIT = 50;
|
|
16
|
+
const DECAY_FACTOR = 0.95;
|
|
17
|
+
const MAX_CORRECTION_HISTORY = 20;
|
|
18
|
+
|
|
12
19
|
class SelfCorrectiveSynthesizer {
|
|
13
20
|
constructor() {
|
|
14
|
-
this.historyLimit =
|
|
21
|
+
this.historyLimit = HISTORY_LIMIT;
|
|
15
22
|
this.synthesisCount = 0;
|
|
23
|
+
this.correctionHistory = [];
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
/**
|
|
@@ -22,9 +30,18 @@ class SelfCorrectiveSynthesizer {
|
|
|
22
30
|
*/
|
|
23
31
|
async synthesizeCorrection(auditTrail, context) {
|
|
24
32
|
console.log('[SCS] Critical drift detected. Initiating internal alignment pass...');
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
|
|
34
|
+
this._evaluatePreviousCorrection(auditTrail);
|
|
35
|
+
|
|
36
|
+
const recentEvents = auditTrail.slice(-this.historyLimit);
|
|
37
|
+
|
|
38
|
+
// Weight events by recency: newest = 1.0, decays by 0.95^position
|
|
39
|
+
const weightedEvents = recentEvents.map((event, i) => ({
|
|
40
|
+
...event,
|
|
41
|
+
weight: Math.pow(DECAY_FACTOR, recentEvents.length - 1 - i)
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
const failureEvents = weightedEvents.filter(e =>
|
|
28
45
|
e.type === 'mission_fidelity' && e.alignment.confidence < 0.50
|
|
29
46
|
);
|
|
30
47
|
|
|
@@ -32,27 +49,84 @@ class SelfCorrectiveSynthesizer {
|
|
|
32
49
|
return this._generateGenericRefocus(context);
|
|
33
50
|
}
|
|
34
51
|
|
|
35
|
-
//
|
|
36
|
-
const
|
|
52
|
+
// Weighted sort: higher weight (more recent) failures surface first
|
|
53
|
+
const sortedFailures = [...failureEvents].sort((a, b) => b.weight - a.weight);
|
|
54
|
+
|
|
55
|
+
const targetId = sortedFailures[0].alignment.best_match_id;
|
|
37
56
|
const requirement = rsa.getRequirementDetails(targetId);
|
|
38
57
|
|
|
39
58
|
if (!requirement) {
|
|
40
59
|
return this._generateGenericRefocus(context);
|
|
41
60
|
}
|
|
42
61
|
|
|
43
|
-
// 3. Synthesize the "Homing Signal"
|
|
44
62
|
this.synthesisCount++;
|
|
63
|
+
|
|
64
|
+
const currentConfidence = sortedFailures[0].alignment.confidence;
|
|
65
|
+
const correctionId = `scs_${Date.now()}_${this.synthesisCount}`;
|
|
66
|
+
|
|
45
67
|
const correction = {
|
|
46
68
|
type: 'scs_refocus',
|
|
69
|
+
correctionId,
|
|
47
70
|
req_id: targetId,
|
|
48
71
|
instruction: `[SCS-REFOCUS] Targeting [${targetId}]: ${requirement.summary}. Action: Resuming strict alignment with core requirement: ${requirement.description.split('\n')[0]}`,
|
|
49
72
|
confidence: 0.98
|
|
50
73
|
};
|
|
51
74
|
|
|
75
|
+
this._recordCorrection(correctionId, currentConfidence);
|
|
76
|
+
|
|
52
77
|
console.log(`[SCS] Synthesis complete. Correction targeted at ${targetId}.`);
|
|
53
78
|
return correction;
|
|
54
79
|
}
|
|
55
80
|
|
|
81
|
+
_evaluatePreviousCorrection(auditTrail) {
|
|
82
|
+
if (this.correctionHistory.length === 0) return;
|
|
83
|
+
|
|
84
|
+
const lastCorrection = this.correctionHistory[this.correctionHistory.length - 1];
|
|
85
|
+
if (lastCorrection.effective !== undefined) return;
|
|
86
|
+
|
|
87
|
+
const recentEvents = auditTrail.slice(-this.historyLimit);
|
|
88
|
+
const fidelityEvents = recentEvents.filter(e =>
|
|
89
|
+
e.type === 'mission_fidelity' && e.alignment
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (fidelityEvents.length === 0) return;
|
|
93
|
+
|
|
94
|
+
const latestConfidence = fidelityEvents[fidelityEvents.length - 1].alignment.confidence;
|
|
95
|
+
const improved = latestConfidence > lastCorrection.preConfidence;
|
|
96
|
+
|
|
97
|
+
// Immutable update: replace last entry with effectiveness result
|
|
98
|
+
const updatedEntry = {
|
|
99
|
+
...lastCorrection,
|
|
100
|
+
postConfidence: latestConfidence,
|
|
101
|
+
effective: improved
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
this.correctionHistory = [
|
|
105
|
+
...this.correctionHistory.slice(0, -1),
|
|
106
|
+
updatedEntry
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
_recordCorrection(correctionId, preConfidence) {
|
|
111
|
+
const entry = {
|
|
112
|
+
correctionId,
|
|
113
|
+
timestamp: new Date().toISOString(),
|
|
114
|
+
preConfidence
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
if (this.correctionHistory.length >= MAX_CORRECTION_HISTORY) {
|
|
118
|
+
this.correctionHistory = [...this.correctionHistory.slice(1), entry];
|
|
119
|
+
} else {
|
|
120
|
+
this.correctionHistory = [...this.correctionHistory, entry];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
getEffectivenessRate() {
|
|
125
|
+
if (this.correctionHistory.length === 0) return null;
|
|
126
|
+
const effective = this.correctionHistory.filter(c => c.effective).length;
|
|
127
|
+
return effective / this.correctionHistory.length;
|
|
128
|
+
}
|
|
129
|
+
|
|
56
130
|
_generateGenericRefocus(context) {
|
|
57
131
|
return {
|
|
58
132
|
type: 'scs_refocus',
|