moflo 4.8.21 → 4.8.22
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/.claude/agents/browser/browser-agent.yaml +182 -182
- package/.claude/agents/core/coder.md +265 -265
- package/.claude/agents/core/planner.md +167 -167
- package/.claude/agents/core/researcher.md +189 -189
- package/.claude/agents/core/reviewer.md +325 -325
- package/.claude/agents/core/tester.md +318 -318
- package/.claude/agents/database-specialist.yaml +21 -21
- package/.claude/agents/dual-mode/codex-coordinator.md +224 -224
- package/.claude/agents/dual-mode/codex-worker.md +211 -211
- package/.claude/agents/dual-mode/dual-orchestrator.md +291 -291
- package/.claude/agents/github/code-review-swarm.md +537 -537
- package/.claude/agents/github/github-modes.md +172 -172
- package/.claude/agents/github/issue-tracker.md +318 -318
- package/.claude/agents/github/multi-repo-swarm.md +552 -552
- package/.claude/agents/github/pr-manager.md +190 -190
- package/.claude/agents/github/project-board-sync.md +508 -508
- package/.claude/agents/github/release-manager.md +366 -366
- package/.claude/agents/github/release-swarm.md +582 -582
- package/.claude/agents/github/repo-architect.md +397 -397
- package/.claude/agents/github/swarm-issue.md +572 -572
- package/.claude/agents/github/swarm-pr.md +427 -427
- package/.claude/agents/github/sync-coordinator.md +451 -451
- package/.claude/agents/github/workflow-automation.md +634 -634
- package/.claude/agents/goal/code-goal-planner.md +445 -445
- package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +129 -129
- package/.claude/agents/hive-mind/queen-coordinator.md +202 -202
- package/.claude/agents/hive-mind/scout-explorer.md +241 -241
- package/.claude/agents/hive-mind/swarm-memory-manager.md +192 -192
- package/.claude/agents/hive-mind/worker-specialist.md +216 -216
- package/.claude/agents/index.yaml +17 -17
- package/.claude/agents/neural/safla-neural.md +73 -73
- package/.claude/agents/project-coordinator.yaml +15 -15
- package/.claude/agents/python-specialist.yaml +21 -21
- package/.claude/agents/reasoning/goal-planner.md +72 -72
- package/.claude/agents/security-auditor.yaml +20 -20
- package/.claude/agents/swarm/adaptive-coordinator.md +395 -395
- package/.claude/agents/swarm/hierarchical-coordinator.md +326 -326
- package/.claude/agents/swarm/mesh-coordinator.md +391 -391
- package/.claude/agents/templates/migration-plan.md +745 -745
- package/.claude/agents/typescript-specialist.yaml +21 -21
- package/.claude/checkpoints/1767754460.json +8 -8
- package/.claude/commands/agents/agent-spawning.md +28 -28
- package/.claude/commands/github/github-modes.md +146 -146
- package/.claude/commands/github/github-swarm.md +121 -121
- package/.claude/commands/github/issue-tracker.md +291 -291
- package/.claude/commands/github/pr-manager.md +169 -169
- package/.claude/commands/github/release-manager.md +337 -337
- package/.claude/commands/github/repo-architect.md +366 -366
- package/.claude/commands/github/sync-coordinator.md +300 -300
- package/.claude/commands/memory/neural.md +47 -47
- package/.claude/commands/sparc/analyzer.md +51 -51
- package/.claude/commands/sparc/architect.md +53 -53
- package/.claude/commands/sparc/ask.md +97 -97
- package/.claude/commands/sparc/batch-executor.md +54 -54
- package/.claude/commands/sparc/code.md +89 -89
- package/.claude/commands/sparc/coder.md +54 -54
- package/.claude/commands/sparc/debug.md +83 -83
- package/.claude/commands/sparc/debugger.md +54 -54
- package/.claude/commands/sparc/designer.md +53 -53
- package/.claude/commands/sparc/devops.md +109 -109
- package/.claude/commands/sparc/docs-writer.md +80 -80
- package/.claude/commands/sparc/documenter.md +54 -54
- package/.claude/commands/sparc/innovator.md +54 -54
- package/.claude/commands/sparc/integration.md +83 -83
- package/.claude/commands/sparc/mcp.md +117 -117
- package/.claude/commands/sparc/memory-manager.md +54 -54
- package/.claude/commands/sparc/optimizer.md +54 -54
- package/.claude/commands/sparc/orchestrator.md +131 -131
- package/.claude/commands/sparc/post-deployment-monitoring-mode.md +83 -83
- package/.claude/commands/sparc/refinement-optimization-mode.md +83 -83
- package/.claude/commands/sparc/researcher.md +54 -54
- package/.claude/commands/sparc/reviewer.md +54 -54
- package/.claude/commands/sparc/security-review.md +80 -80
- package/.claude/commands/sparc/sparc-modes.md +174 -174
- package/.claude/commands/sparc/sparc.md +111 -111
- package/.claude/commands/sparc/spec-pseudocode.md +80 -80
- package/.claude/commands/sparc/supabase-admin.md +348 -348
- package/.claude/commands/sparc/swarm-coordinator.md +54 -54
- package/.claude/commands/sparc/tdd.md +54 -54
- package/.claude/commands/sparc/tester.md +54 -54
- package/.claude/commands/sparc/tutorial.md +79 -79
- package/.claude/commands/sparc/workflow-manager.md +54 -54
- package/.claude/commands/sparc.md +166 -166
- package/.claude/commands/swarm/analysis.md +95 -95
- package/.claude/commands/swarm/development.md +96 -96
- package/.claude/commands/swarm/examples.md +168 -168
- package/.claude/commands/swarm/maintenance.md +102 -102
- package/.claude/commands/swarm/optimization.md +117 -117
- package/.claude/commands/swarm/research.md +136 -136
- package/.claude/commands/swarm/testing.md +131 -131
- package/.claude/commands/workflows/development.md +77 -77
- package/.claude/commands/workflows/research.md +62 -62
- package/.claude/guidance/moflo-bootstrap.md +126 -126
- package/.claude/guidance/shipped/agent-bootstrap.md +126 -126
- package/.claude/guidance/shipped/guidance-memory-strategy.md +262 -262
- package/.claude/guidance/shipped/memory-strategy.md +204 -204
- package/.claude/guidance/shipped/moflo.md +668 -653
- package/.claude/guidance/shipped/task-swarm-integration.md +441 -441
- package/.claude/helpers/intelligence.cjs +207 -207
- package/.claude/helpers/statusline.cjs +851 -851
- package/.claude/settings.local.json +18 -0
- package/.claude/skills/fl/SKILL.md +583 -583
- package/.claude/skills/flo/SKILL.md +583 -583
- package/.claude/skills/github-code-review/SKILL.md +1140 -1140
- package/.claude/skills/github-multi-repo/SKILL.md +874 -874
- package/.claude/skills/github-project-management/SKILL.md +1277 -1277
- package/.claude/skills/github-release-management/SKILL.md +1081 -1081
- package/.claude/skills/github-workflow-automation/SKILL.md +1065 -1065
- package/.claude/skills/hive-mind-advanced/SKILL.md +712 -712
- package/.claude/skills/hooks-automation/SKILL.md +1201 -1201
- package/.claude/skills/performance-analysis/SKILL.md +563 -563
- package/.claude/skills/sparc-methodology/SKILL.md +1115 -1115
- package/.claude/skills/swarm-advanced/SKILL.md +973 -973
- package/.claude/workflow-state.json +4 -4
- package/LICENSE +21 -21
- package/README.md +685 -685
- package/bin/cli.js +0 -0
- package/bin/gate-hook.mjs +50 -50
- package/bin/gate.cjs +138 -138
- package/bin/generate-code-map.mjs +775 -775
- package/bin/hook-handler.cjs +83 -83
- package/bin/hooks.mjs +656 -656
- package/bin/index-guidance.mjs +892 -892
- package/bin/index-tests.mjs +709 -709
- package/bin/lib/process-manager.mjs +243 -243
- package/bin/lib/registry-cleanup.cjs +41 -41
- package/bin/prompt-hook.mjs +72 -72
- package/bin/semantic-search.mjs +472 -472
- package/bin/session-start-launcher.mjs +238 -238
- package/bin/setup-project.mjs +250 -250
- package/package.json +123 -123
- package/src/@claude-flow/cli/README.md +452 -452
- package/src/@claude-flow/cli/bin/cli.js +180 -180
- package/src/@claude-flow/cli/bin/preinstall.cjs +2 -2
- package/src/@claude-flow/cli/dist/src/commands/completions.js +409 -409
- package/src/@claude-flow/cli/dist/src/commands/doctor.js +5 -1
- package/src/@claude-flow/cli/dist/src/commands/embeddings.js +25 -25
- package/src/@claude-flow/cli/dist/src/commands/github.js +61 -61
- package/src/@claude-flow/cli/dist/src/commands/hive-mind.js +90 -90
- package/src/@claude-flow/cli/dist/src/commands/hooks.js +9 -9
- package/src/@claude-flow/cli/dist/src/commands/ruvector/import.js +14 -14
- package/src/@claude-flow/cli/dist/src/commands/ruvector/setup.js +624 -624
- package/src/@claude-flow/cli/dist/src/config/moflo-config.d.ts +3 -0
- package/src/@claude-flow/cli/dist/src/config/moflo-config.js +101 -91
- package/src/@claude-flow/cli/dist/src/index.d.ts +5 -0
- package/src/@claude-flow/cli/dist/src/index.js +44 -0
- package/src/@claude-flow/cli/dist/src/init/claudemd-generator.d.ts +29 -29
- package/src/@claude-flow/cli/dist/src/init/claudemd-generator.js +43 -43
- package/src/@claude-flow/cli/dist/src/init/executor.js +453 -453
- package/src/@claude-flow/cli/dist/src/init/helpers-generator.js +482 -482
- package/src/@claude-flow/cli/dist/src/init/moflo-init.d.ts +30 -30
- package/src/@claude-flow/cli/dist/src/init/moflo-init.js +140 -140
- package/src/@claude-flow/cli/dist/src/init/statusline-generator.js +876 -876
- package/src/@claude-flow/cli/dist/src/memory/memory-initializer.js +371 -371
- package/src/@claude-flow/cli/dist/src/runtime/headless.js +28 -28
- package/src/@claude-flow/cli/dist/src/services/container-worker-pool.d.ts +197 -0
- package/src/@claude-flow/cli/dist/src/services/container-worker-pool.js +584 -0
- package/src/@claude-flow/cli/dist/src/services/daemon-lock.d.ts +14 -0
- package/src/@claude-flow/cli/dist/src/services/daemon-lock.js +1 -1
- package/src/@claude-flow/cli/dist/src/services/headless-worker-executor.js +84 -84
- package/src/@claude-flow/cli/package.json +1 -1
- package/src/@claude-flow/guidance/README.md +1195 -1195
- package/src/@claude-flow/guidance/package.json +198 -198
- package/src/@claude-flow/memory/README.md +587 -587
- package/src/@claude-flow/memory/dist/agent-memory-scope.test.js +4 -7
- package/src/@claude-flow/memory/dist/agentdb-backend.d.ts +2 -0
- package/src/@claude-flow/memory/dist/agentdb-backend.js +28 -26
- package/src/@claude-flow/memory/dist/auto-memory-bridge.test.js +36 -39
- package/src/@claude-flow/memory/dist/benchmark.test.js +1 -1
- package/src/@claude-flow/memory/dist/controller-registry.test.js +43 -0
- package/src/@claude-flow/memory/dist/database-provider.d.ts +2 -2
- package/src/@claude-flow/memory/dist/database-provider.js +6 -3
- package/src/@claude-flow/memory/dist/database-provider.test.js +1 -3
- package/src/@claude-flow/memory/dist/hybrid-backend.d.ts +245 -0
- package/src/@claude-flow/memory/dist/hybrid-backend.js +569 -0
- package/src/@claude-flow/memory/dist/hybrid-backend.test.d.ts +8 -0
- package/src/@claude-flow/memory/dist/hybrid-backend.test.js +320 -0
- package/src/@claude-flow/memory/dist/index.d.ts +3 -0
- package/src/@claude-flow/memory/dist/index.js +3 -0
- package/src/@claude-flow/memory/dist/sqlite-backend.d.ts +121 -0
- package/src/@claude-flow/memory/dist/sqlite-backend.js +572 -0
- package/src/@claude-flow/memory/dist/sqljs-backend.d.ts +4 -3
- package/src/@claude-flow/memory/dist/sqljs-backend.js +31 -30
- package/src/@claude-flow/memory/package.json +44 -44
- package/src/@claude-flow/shared/README.md +323 -323
- package/src/@claude-flow/shared/dist/core/config/defaults.js +1 -1
- package/src/@claude-flow/shared/dist/core/config/loader.js +1 -1
- package/src/@claude-flow/shared/dist/core/config/schema.js +1 -1
- package/src/@claude-flow/shared/dist/events/event-store.js +34 -50
- package/src/@claude-flow/shared/dist/events/event-store.test.js +4 -8
- package/src/@claude-flow/shared/dist/hooks/executor.js +4 -7
- package/src/@claude-flow/shared/dist/hooks/safety/file-organization.js +1 -1
- package/src/@claude-flow/shared/dist/hooks/safety/git-commit.js +3 -3
- package/src/@claude-flow/shared/dist/hooks/verify-exports.test.js +6 -6
- package/src/@claude-flow/shared/dist/utils/secure-logger.js +1 -1
- package/src/README.md +493 -493
- package/src/@claude-flow/guidance/dist/adversarial.d.ts +0 -284
- package/src/@claude-flow/guidance/dist/adversarial.js +0 -572
- package/src/@claude-flow/guidance/dist/analyzer.d.ts +0 -530
- package/src/@claude-flow/guidance/dist/analyzer.js +0 -2518
- package/src/@claude-flow/guidance/dist/artifacts.d.ts +0 -283
- package/src/@claude-flow/guidance/dist/artifacts.js +0 -356
- package/src/@claude-flow/guidance/dist/authority.d.ts +0 -290
- package/src/@claude-flow/guidance/dist/authority.js +0 -558
- package/src/@claude-flow/guidance/dist/capabilities.d.ts +0 -209
- package/src/@claude-flow/guidance/dist/capabilities.js +0 -485
- package/src/@claude-flow/guidance/dist/coherence.d.ts +0 -233
- package/src/@claude-flow/guidance/dist/coherence.js +0 -372
- package/src/@claude-flow/guidance/dist/compiler.d.ts +0 -87
- package/src/@claude-flow/guidance/dist/compiler.js +0 -419
- package/src/@claude-flow/guidance/dist/conformance-kit.d.ts +0 -225
- package/src/@claude-flow/guidance/dist/conformance-kit.js +0 -629
- package/src/@claude-flow/guidance/dist/continue-gate.d.ts +0 -214
- package/src/@claude-flow/guidance/dist/continue-gate.js +0 -353
- package/src/@claude-flow/guidance/dist/crypto-utils.d.ts +0 -17
- package/src/@claude-flow/guidance/dist/crypto-utils.js +0 -24
- package/src/@claude-flow/guidance/dist/evolution.d.ts +0 -282
- package/src/@claude-flow/guidance/dist/evolution.js +0 -500
- package/src/@claude-flow/guidance/dist/gates.d.ts +0 -79
- package/src/@claude-flow/guidance/dist/gates.js +0 -302
- package/src/@claude-flow/guidance/dist/gateway.d.ts +0 -206
- package/src/@claude-flow/guidance/dist/gateway.js +0 -452
- package/src/@claude-flow/guidance/dist/generators.d.ts +0 -153
- package/src/@claude-flow/guidance/dist/generators.js +0 -682
- package/src/@claude-flow/guidance/dist/headless.d.ts +0 -177
- package/src/@claude-flow/guidance/dist/headless.js +0 -342
- package/src/@claude-flow/guidance/dist/hooks.d.ts +0 -109
- package/src/@claude-flow/guidance/dist/hooks.js +0 -347
- package/src/@claude-flow/guidance/dist/index.d.ts +0 -205
- package/src/@claude-flow/guidance/dist/index.js +0 -321
- package/src/@claude-flow/guidance/dist/ledger.d.ts +0 -162
- package/src/@claude-flow/guidance/dist/ledger.js +0 -375
- package/src/@claude-flow/guidance/dist/manifest-validator.d.ts +0 -289
- package/src/@claude-flow/guidance/dist/manifest-validator.js +0 -838
- package/src/@claude-flow/guidance/dist/memory-gate.d.ts +0 -222
- package/src/@claude-flow/guidance/dist/memory-gate.js +0 -382
- package/src/@claude-flow/guidance/dist/meta-governance.d.ts +0 -265
- package/src/@claude-flow/guidance/dist/meta-governance.js +0 -348
- package/src/@claude-flow/guidance/dist/optimizer.d.ts +0 -104
- package/src/@claude-flow/guidance/dist/optimizer.js +0 -329
- package/src/@claude-flow/guidance/dist/persistence.d.ts +0 -189
- package/src/@claude-flow/guidance/dist/persistence.js +0 -464
- package/src/@claude-flow/guidance/dist/proof.d.ts +0 -185
- package/src/@claude-flow/guidance/dist/proof.js +0 -238
- package/src/@claude-flow/guidance/dist/retriever.d.ts +0 -116
- package/src/@claude-flow/guidance/dist/retriever.js +0 -394
- package/src/@claude-flow/guidance/dist/ruvbot-integration.d.ts +0 -370
- package/src/@claude-flow/guidance/dist/ruvbot-integration.js +0 -738
- package/src/@claude-flow/guidance/dist/temporal.d.ts +0 -426
- package/src/@claude-flow/guidance/dist/temporal.js +0 -658
- package/src/@claude-flow/guidance/dist/trust.d.ts +0 -283
- package/src/@claude-flow/guidance/dist/trust.js +0 -473
- package/src/@claude-flow/guidance/dist/truth-anchors.d.ts +0 -276
- package/src/@claude-flow/guidance/dist/truth-anchors.js +0 -488
- package/src/@claude-flow/guidance/dist/types.d.ts +0 -378
- package/src/@claude-flow/guidance/dist/types.js +0 -10
- package/src/@claude-flow/guidance/dist/uncertainty.d.ts +0 -372
- package/src/@claude-flow/guidance/dist/uncertainty.js +0 -619
- package/src/@claude-flow/guidance/dist/wasm-kernel.d.ts +0 -48
- package/src/@claude-flow/guidance/dist/wasm-kernel.js +0 -158
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Evolution Pipeline
|
|
3
|
-
*
|
|
4
|
-
* Every change to prompts, policies, tools, and code becomes a signed change
|
|
5
|
-
* proposal that goes through simulation, replay comparison, and staged rollout.
|
|
6
|
-
*
|
|
7
|
-
* Pipeline stages:
|
|
8
|
-
* 1. Propose - Create a signed ChangeProposal
|
|
9
|
-
* 2. Simulate - Replay golden traces with baseline vs candidate config
|
|
10
|
-
* 3. Compare - Approve or reject based on divergence threshold
|
|
11
|
-
* 4. Stage - Create a staged rollout plan (canary -> partial -> full)
|
|
12
|
-
* 5. Advance - Progress through stages with metric gates
|
|
13
|
-
* 6. Promote / Rollback - Apply permanently or revert
|
|
14
|
-
*
|
|
15
|
-
* @module @claude-flow/guidance/evolution
|
|
16
|
-
*/
|
|
17
|
-
import { createHash, createHmac, randomUUID } from 'node:crypto';
|
|
18
|
-
const DEFAULT_MAX_DIVERGENCE = 0.3;
|
|
19
|
-
const DEFAULT_STAGES = [
|
|
20
|
-
{
|
|
21
|
-
name: 'canary',
|
|
22
|
-
percentage: 5,
|
|
23
|
-
durationMs: 60_000,
|
|
24
|
-
metrics: {},
|
|
25
|
-
divergenceThreshold: 0.2,
|
|
26
|
-
passed: null,
|
|
27
|
-
startedAt: null,
|
|
28
|
-
completedAt: null,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: 'partial',
|
|
32
|
-
percentage: 50,
|
|
33
|
-
durationMs: 300_000,
|
|
34
|
-
metrics: {},
|
|
35
|
-
divergenceThreshold: 0.25,
|
|
36
|
-
passed: null,
|
|
37
|
-
startedAt: null,
|
|
38
|
-
completedAt: null,
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: 'full',
|
|
42
|
-
percentage: 100,
|
|
43
|
-
durationMs: 600_000,
|
|
44
|
-
metrics: {},
|
|
45
|
-
divergenceThreshold: 0.3,
|
|
46
|
-
passed: null,
|
|
47
|
-
startedAt: null,
|
|
48
|
-
completedAt: null,
|
|
49
|
-
},
|
|
50
|
-
];
|
|
51
|
-
// ============================================================================
|
|
52
|
-
// EvolutionPipeline
|
|
53
|
-
// ============================================================================
|
|
54
|
-
/**
|
|
55
|
-
* The Evolution Pipeline manages the lifecycle of change proposals through
|
|
56
|
-
* signing, simulation, comparison, staged rollout, and promotion or rollback.
|
|
57
|
-
*/
|
|
58
|
-
export class EvolutionPipeline {
|
|
59
|
-
signingKey;
|
|
60
|
-
maxDivergence;
|
|
61
|
-
defaultStages;
|
|
62
|
-
proposals = new Map();
|
|
63
|
-
simulations = new Map();
|
|
64
|
-
rollouts = new Map();
|
|
65
|
-
constructor(config = {}) {
|
|
66
|
-
if (!config.signingKey) {
|
|
67
|
-
throw new Error('EvolutionPipeline requires an explicit signingKey — hardcoded defaults are not secure');
|
|
68
|
-
}
|
|
69
|
-
this.signingKey = config.signingKey;
|
|
70
|
-
this.maxDivergence = config.maxDivergence ?? DEFAULT_MAX_DIVERGENCE;
|
|
71
|
-
this.defaultStages = config.stages ?? DEFAULT_STAGES;
|
|
72
|
-
}
|
|
73
|
-
// ==========================================================================
|
|
74
|
-
// Propose
|
|
75
|
-
// ==========================================================================
|
|
76
|
-
/**
|
|
77
|
-
* Create and sign a new change proposal.
|
|
78
|
-
*/
|
|
79
|
-
propose(params) {
|
|
80
|
-
const proposalId = randomUUID();
|
|
81
|
-
const createdAt = Date.now();
|
|
82
|
-
const proposal = {
|
|
83
|
-
proposalId,
|
|
84
|
-
kind: params.kind,
|
|
85
|
-
title: params.title,
|
|
86
|
-
description: params.description,
|
|
87
|
-
author: params.author,
|
|
88
|
-
targetPath: params.targetPath,
|
|
89
|
-
diff: params.diff,
|
|
90
|
-
rationale: params.rationale,
|
|
91
|
-
riskAssessment: params.riskAssessment,
|
|
92
|
-
signature: '', // placeholder, signed below
|
|
93
|
-
createdAt,
|
|
94
|
-
status: 'draft',
|
|
95
|
-
};
|
|
96
|
-
proposal.signature = this.signProposal(proposal);
|
|
97
|
-
proposal.status = 'signed';
|
|
98
|
-
this.proposals.set(proposalId, proposal);
|
|
99
|
-
return proposal;
|
|
100
|
-
}
|
|
101
|
-
// ==========================================================================
|
|
102
|
-
// Simulate
|
|
103
|
-
// ==========================================================================
|
|
104
|
-
/**
|
|
105
|
-
* Run golden traces through both baseline and candidate configs to measure
|
|
106
|
-
* divergence. The evaluator is called once per golden trace per config.
|
|
107
|
-
*/
|
|
108
|
-
simulate(proposalId, goldenTraces, evaluator) {
|
|
109
|
-
const proposal = this.proposals.get(proposalId);
|
|
110
|
-
if (!proposal) {
|
|
111
|
-
throw new Error(`Proposal not found: ${proposalId}`);
|
|
112
|
-
}
|
|
113
|
-
proposal.status = 'simulating';
|
|
114
|
-
// Evaluate each trace against both configs
|
|
115
|
-
const baselineResults = goldenTraces.map(t => evaluator(t, 'baseline'));
|
|
116
|
-
const candidateResults = goldenTraces.map(t => evaluator(t, 'candidate'));
|
|
117
|
-
// Compute composite trace hashes
|
|
118
|
-
const baselineTraceHash = this.hashTraceResults(baselineResults.map(r => r.traceHash));
|
|
119
|
-
const candidateTraceHash = this.hashTraceResults(candidateResults.map(r => r.traceHash));
|
|
120
|
-
// Compute decision diffs
|
|
121
|
-
const decisionDiffs = [];
|
|
122
|
-
for (let i = 0; i < goldenTraces.length; i++) {
|
|
123
|
-
const bDecisions = baselineResults[i].decisions;
|
|
124
|
-
const cDecisions = candidateResults[i].decisions;
|
|
125
|
-
const maxLen = Math.max(bDecisions.length, cDecisions.length);
|
|
126
|
-
for (let seq = 0; seq < maxLen; seq++) {
|
|
127
|
-
const bVal = seq < bDecisions.length ? bDecisions[seq] : undefined;
|
|
128
|
-
const cVal = seq < cDecisions.length ? cDecisions[seq] : undefined;
|
|
129
|
-
if (JSON.stringify(bVal) !== JSON.stringify(cVal)) {
|
|
130
|
-
decisionDiffs.push({
|
|
131
|
-
seq,
|
|
132
|
-
baseline: bVal,
|
|
133
|
-
candidate: cVal,
|
|
134
|
-
severity: this.classifyDiffSeverity(bVal, cVal),
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// Aggregate metrics
|
|
140
|
-
const baselineMetrics = this.aggregateMetrics(baselineResults.map(r => r.metrics));
|
|
141
|
-
const candidateMetrics = this.aggregateMetrics(candidateResults.map(r => r.metrics));
|
|
142
|
-
// Compute divergence score (0-1)
|
|
143
|
-
const divergenceScore = this.computeDivergenceScore(baselineTraceHash, candidateTraceHash, decisionDiffs, goldenTraces.length);
|
|
144
|
-
const passed = divergenceScore <= this.maxDivergence;
|
|
145
|
-
const reason = passed
|
|
146
|
-
? `Divergence ${divergenceScore.toFixed(3)} is within threshold ${this.maxDivergence}`
|
|
147
|
-
: `Divergence ${divergenceScore.toFixed(3)} exceeds threshold ${this.maxDivergence}`;
|
|
148
|
-
const result = {
|
|
149
|
-
proposalId,
|
|
150
|
-
baselineTraceHash,
|
|
151
|
-
candidateTraceHash,
|
|
152
|
-
divergenceScore,
|
|
153
|
-
decisionDiffs,
|
|
154
|
-
metricsComparison: {
|
|
155
|
-
baseline: baselineMetrics,
|
|
156
|
-
candidate: candidateMetrics,
|
|
157
|
-
},
|
|
158
|
-
passed,
|
|
159
|
-
reason,
|
|
160
|
-
};
|
|
161
|
-
this.simulations.set(proposalId, result);
|
|
162
|
-
return result;
|
|
163
|
-
}
|
|
164
|
-
// ==========================================================================
|
|
165
|
-
// Compare
|
|
166
|
-
// ==========================================================================
|
|
167
|
-
/**
|
|
168
|
-
* Compare a simulation result against acceptance criteria.
|
|
169
|
-
*
|
|
170
|
-
* Checks:
|
|
171
|
-
* 1. Divergence is below threshold
|
|
172
|
-
* 2. No regression in key metrics (candidate >= baseline)
|
|
173
|
-
*/
|
|
174
|
-
compare(proposalId, simulationResult) {
|
|
175
|
-
const proposal = this.proposals.get(proposalId);
|
|
176
|
-
if (!proposal) {
|
|
177
|
-
throw new Error(`Proposal not found: ${proposalId}`);
|
|
178
|
-
}
|
|
179
|
-
// Check divergence threshold
|
|
180
|
-
if (simulationResult.divergenceScore > this.maxDivergence) {
|
|
181
|
-
proposal.status = 'rejected';
|
|
182
|
-
return {
|
|
183
|
-
approved: false,
|
|
184
|
-
reason: `Divergence ${simulationResult.divergenceScore.toFixed(3)} exceeds threshold ${this.maxDivergence}`,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
// Check for metric regressions
|
|
188
|
-
const { baseline, candidate } = simulationResult.metricsComparison;
|
|
189
|
-
const regressions = [];
|
|
190
|
-
for (const key of Object.keys(baseline)) {
|
|
191
|
-
if (candidate[key] !== undefined && candidate[key] < baseline[key]) {
|
|
192
|
-
const pctDrop = ((baseline[key] - candidate[key]) / Math.max(baseline[key], 1)) * 100;
|
|
193
|
-
// Only flag significant regressions (> 5%)
|
|
194
|
-
if (pctDrop > 5) {
|
|
195
|
-
regressions.push(`${key} regressed by ${pctDrop.toFixed(1)}%`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (regressions.length > 0) {
|
|
200
|
-
proposal.status = 'rejected';
|
|
201
|
-
return {
|
|
202
|
-
approved: false,
|
|
203
|
-
reason: `Metric regressions detected: ${regressions.join('; ')}`,
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
proposal.status = 'compared';
|
|
207
|
-
return {
|
|
208
|
-
approved: true,
|
|
209
|
-
reason: `Divergence ${simulationResult.divergenceScore.toFixed(3)} within threshold, no metric regressions`,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
// ==========================================================================
|
|
213
|
-
// Stage
|
|
214
|
-
// ==========================================================================
|
|
215
|
-
/**
|
|
216
|
-
* Create a staged rollout plan for a proposal.
|
|
217
|
-
*/
|
|
218
|
-
stage(proposalId) {
|
|
219
|
-
const proposal = this.proposals.get(proposalId);
|
|
220
|
-
if (!proposal) {
|
|
221
|
-
throw new Error(`Proposal not found: ${proposalId}`);
|
|
222
|
-
}
|
|
223
|
-
const now = Date.now();
|
|
224
|
-
// Deep-clone default stages so each rollout has independent state
|
|
225
|
-
const stages = this.defaultStages.map(s => ({
|
|
226
|
-
...s,
|
|
227
|
-
metrics: { ...s.metrics },
|
|
228
|
-
passed: null,
|
|
229
|
-
startedAt: null,
|
|
230
|
-
completedAt: null,
|
|
231
|
-
}));
|
|
232
|
-
// Start the first stage immediately
|
|
233
|
-
stages[0].startedAt = now;
|
|
234
|
-
const rollout = {
|
|
235
|
-
rolloutId: randomUUID(),
|
|
236
|
-
proposalId,
|
|
237
|
-
stages,
|
|
238
|
-
currentStage: 0,
|
|
239
|
-
status: 'in-progress',
|
|
240
|
-
startedAt: now,
|
|
241
|
-
completedAt: null,
|
|
242
|
-
};
|
|
243
|
-
proposal.status = 'staged';
|
|
244
|
-
this.rollouts.set(rollout.rolloutId, rollout);
|
|
245
|
-
return rollout;
|
|
246
|
-
}
|
|
247
|
-
// ==========================================================================
|
|
248
|
-
// Advance Stage
|
|
249
|
-
// ==========================================================================
|
|
250
|
-
/**
|
|
251
|
-
* Advance to the next rollout stage or auto-rollback.
|
|
252
|
-
*
|
|
253
|
-
* If `stageMetrics.divergence` exceeds the current stage's threshold,
|
|
254
|
-
* the rollout is automatically rolled back.
|
|
255
|
-
*/
|
|
256
|
-
advanceStage(rolloutId, stageMetrics) {
|
|
257
|
-
const rollout = this.rollouts.get(rolloutId);
|
|
258
|
-
if (!rollout) {
|
|
259
|
-
throw new Error(`Rollout not found: ${rolloutId}`);
|
|
260
|
-
}
|
|
261
|
-
if (rollout.status !== 'in-progress') {
|
|
262
|
-
return {
|
|
263
|
-
advanced: false,
|
|
264
|
-
rolledBack: false,
|
|
265
|
-
reason: `Rollout is ${rollout.status}, not in-progress`,
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
const current = rollout.stages[rollout.currentStage];
|
|
269
|
-
const now = Date.now();
|
|
270
|
-
// Record metrics on the current stage
|
|
271
|
-
current.metrics = { ...stageMetrics };
|
|
272
|
-
// Check divergence against threshold
|
|
273
|
-
const divergence = stageMetrics.divergence ?? 0;
|
|
274
|
-
if (divergence > current.divergenceThreshold) {
|
|
275
|
-
// Auto-rollback
|
|
276
|
-
current.passed = false;
|
|
277
|
-
current.completedAt = now;
|
|
278
|
-
this.rollback(rolloutId, `Stage "${current.name}" divergence ${divergence.toFixed(3)} exceeded threshold ${current.divergenceThreshold}`);
|
|
279
|
-
return {
|
|
280
|
-
advanced: false,
|
|
281
|
-
rolledBack: true,
|
|
282
|
-
reason: `Auto-rollback: divergence ${divergence.toFixed(3)} exceeded threshold ${current.divergenceThreshold} at stage "${current.name}"`,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
// Current stage passed
|
|
286
|
-
current.passed = true;
|
|
287
|
-
current.completedAt = now;
|
|
288
|
-
// Check if there are more stages
|
|
289
|
-
if (rollout.currentStage < rollout.stages.length - 1) {
|
|
290
|
-
rollout.currentStage += 1;
|
|
291
|
-
rollout.stages[rollout.currentStage].startedAt = now;
|
|
292
|
-
return {
|
|
293
|
-
advanced: true,
|
|
294
|
-
rolledBack: false,
|
|
295
|
-
reason: `Advanced to stage "${rollout.stages[rollout.currentStage].name}"`,
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
// All stages complete - auto-promote
|
|
299
|
-
rollout.status = 'completed';
|
|
300
|
-
rollout.completedAt = now;
|
|
301
|
-
const proposal = this.proposals.get(rollout.proposalId);
|
|
302
|
-
if (proposal) {
|
|
303
|
-
proposal.status = 'promoted';
|
|
304
|
-
}
|
|
305
|
-
return {
|
|
306
|
-
advanced: true,
|
|
307
|
-
rolledBack: false,
|
|
308
|
-
reason: 'All stages completed successfully; proposal promoted',
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
// ==========================================================================
|
|
312
|
-
// Rollback
|
|
313
|
-
// ==========================================================================
|
|
314
|
-
/**
|
|
315
|
-
* Roll back a staged rollout.
|
|
316
|
-
*/
|
|
317
|
-
rollback(rolloutId, reason) {
|
|
318
|
-
const rollout = this.rollouts.get(rolloutId);
|
|
319
|
-
if (!rollout) {
|
|
320
|
-
throw new Error(`Rollout not found: ${rolloutId}`);
|
|
321
|
-
}
|
|
322
|
-
rollout.status = 'rolled-back';
|
|
323
|
-
rollout.completedAt = Date.now();
|
|
324
|
-
const proposal = this.proposals.get(rollout.proposalId);
|
|
325
|
-
if (proposal) {
|
|
326
|
-
proposal.status = 'rolled-back';
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
// ==========================================================================
|
|
330
|
-
// Promote
|
|
331
|
-
// ==========================================================================
|
|
332
|
-
/**
|
|
333
|
-
* Promote a rollout, permanently applying the change.
|
|
334
|
-
*/
|
|
335
|
-
promote(rolloutId) {
|
|
336
|
-
const rollout = this.rollouts.get(rolloutId);
|
|
337
|
-
if (!rollout) {
|
|
338
|
-
throw new Error(`Rollout not found: ${rolloutId}`);
|
|
339
|
-
}
|
|
340
|
-
rollout.status = 'completed';
|
|
341
|
-
rollout.completedAt = Date.now();
|
|
342
|
-
const proposal = this.proposals.get(rollout.proposalId);
|
|
343
|
-
if (proposal) {
|
|
344
|
-
proposal.status = 'promoted';
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
// ==========================================================================
|
|
348
|
-
// Queries
|
|
349
|
-
// ==========================================================================
|
|
350
|
-
/**
|
|
351
|
-
* Get a proposal by ID.
|
|
352
|
-
*/
|
|
353
|
-
getProposal(id) {
|
|
354
|
-
return this.proposals.get(id);
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Get all proposals, optionally filtered by status.
|
|
358
|
-
*/
|
|
359
|
-
getProposals(status) {
|
|
360
|
-
const all = Array.from(this.proposals.values());
|
|
361
|
-
if (status === undefined) {
|
|
362
|
-
return all;
|
|
363
|
-
}
|
|
364
|
-
return all.filter(p => p.status === status);
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Get a rollout by ID.
|
|
368
|
-
*/
|
|
369
|
-
getRollout(id) {
|
|
370
|
-
return this.rollouts.get(id);
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Get the full evolution history across all proposals.
|
|
374
|
-
*/
|
|
375
|
-
getHistory() {
|
|
376
|
-
return Array.from(this.proposals.values()).map(proposal => ({
|
|
377
|
-
proposal,
|
|
378
|
-
simulation: this.simulations.get(proposal.proposalId),
|
|
379
|
-
rollout: this.findRolloutByProposal(proposal.proposalId),
|
|
380
|
-
outcome: proposal.status,
|
|
381
|
-
}));
|
|
382
|
-
}
|
|
383
|
-
// ==========================================================================
|
|
384
|
-
// Private Helpers
|
|
385
|
-
// ==========================================================================
|
|
386
|
-
/**
|
|
387
|
-
* Produce an HMAC-SHA256 signature for a proposal.
|
|
388
|
-
*
|
|
389
|
-
* The signature covers every field except `signature` and `status`.
|
|
390
|
-
*/
|
|
391
|
-
signProposal(proposal) {
|
|
392
|
-
const body = {
|
|
393
|
-
proposalId: proposal.proposalId,
|
|
394
|
-
kind: proposal.kind,
|
|
395
|
-
title: proposal.title,
|
|
396
|
-
description: proposal.description,
|
|
397
|
-
author: proposal.author,
|
|
398
|
-
targetPath: proposal.targetPath,
|
|
399
|
-
diff: proposal.diff,
|
|
400
|
-
rationale: proposal.rationale,
|
|
401
|
-
riskAssessment: proposal.riskAssessment,
|
|
402
|
-
createdAt: proposal.createdAt,
|
|
403
|
-
};
|
|
404
|
-
const payload = JSON.stringify(body);
|
|
405
|
-
return createHmac('sha256', this.signingKey).update(payload).digest('hex');
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* Compute a composite hash from an array of trace hashes.
|
|
409
|
-
*/
|
|
410
|
-
hashTraceResults(traceHashes) {
|
|
411
|
-
const payload = traceHashes.join(':');
|
|
412
|
-
return createHash('sha256').update(payload).digest('hex');
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Classify how severe a single decision diff is.
|
|
416
|
-
*/
|
|
417
|
-
classifyDiffSeverity(baseline, candidate) {
|
|
418
|
-
// If one is undefined (extra/missing decision), it is high
|
|
419
|
-
if (baseline === undefined || candidate === undefined) {
|
|
420
|
-
return 'high';
|
|
421
|
-
}
|
|
422
|
-
const bStr = JSON.stringify(baseline);
|
|
423
|
-
const cStr = JSON.stringify(candidate);
|
|
424
|
-
// Very different lengths suggest structural changes
|
|
425
|
-
if (Math.abs(bStr.length - cStr.length) > bStr.length * 0.5) {
|
|
426
|
-
return 'high';
|
|
427
|
-
}
|
|
428
|
-
// Moderate difference
|
|
429
|
-
if (bStr.length > 0 && Math.abs(bStr.length - cStr.length) > bStr.length * 0.2) {
|
|
430
|
-
return 'medium';
|
|
431
|
-
}
|
|
432
|
-
return 'low';
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Compute an overall divergence score (0-1).
|
|
436
|
-
*/
|
|
437
|
-
computeDivergenceScore(baselineHash, candidateHash, diffs, traceCount) {
|
|
438
|
-
// If hashes are identical, divergence = 0
|
|
439
|
-
if (baselineHash === candidateHash) {
|
|
440
|
-
return 0;
|
|
441
|
-
}
|
|
442
|
-
// If there are no golden traces, treat as fully divergent
|
|
443
|
-
if (traceCount === 0) {
|
|
444
|
-
return 1;
|
|
445
|
-
}
|
|
446
|
-
// Weight diffs by severity
|
|
447
|
-
const severityWeights = {
|
|
448
|
-
low: 0.1,
|
|
449
|
-
medium: 0.4,
|
|
450
|
-
high: 1.0,
|
|
451
|
-
};
|
|
452
|
-
const totalWeight = diffs.reduce((sum, d) => sum + (severityWeights[d.severity] ?? 0.5), 0);
|
|
453
|
-
// Normalize: max possible weight is traceCount * maxDecisionsPerTrace
|
|
454
|
-
// Use a heuristic cap to keep score in [0, 1]
|
|
455
|
-
const maxExpected = traceCount * 5; // assume ~5 decisions per trace at max weight
|
|
456
|
-
const raw = totalWeight / Math.max(maxExpected, 1);
|
|
457
|
-
return Math.min(1, Math.max(0, raw));
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Aggregate an array of metric records into averages.
|
|
461
|
-
*/
|
|
462
|
-
aggregateMetrics(records) {
|
|
463
|
-
if (records.length === 0)
|
|
464
|
-
return {};
|
|
465
|
-
const sums = {};
|
|
466
|
-
const counts = {};
|
|
467
|
-
for (const record of records) {
|
|
468
|
-
for (const [key, value] of Object.entries(record)) {
|
|
469
|
-
sums[key] = (sums[key] ?? 0) + value;
|
|
470
|
-
counts[key] = (counts[key] ?? 0) + 1;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
const result = {};
|
|
474
|
-
for (const key of Object.keys(sums)) {
|
|
475
|
-
result[key] = sums[key] / counts[key];
|
|
476
|
-
}
|
|
477
|
-
return result;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Find the rollout associated with a proposal.
|
|
481
|
-
*/
|
|
482
|
-
findRolloutByProposal(proposalId) {
|
|
483
|
-
for (const rollout of this.rollouts.values()) {
|
|
484
|
-
if (rollout.proposalId === proposalId) {
|
|
485
|
-
return rollout;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
return undefined;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
// ============================================================================
|
|
492
|
-
// Factory
|
|
493
|
-
// ============================================================================
|
|
494
|
-
/**
|
|
495
|
-
* Create an EvolutionPipeline instance.
|
|
496
|
-
*/
|
|
497
|
-
export function createEvolutionPipeline(config) {
|
|
498
|
-
return new EvolutionPipeline(config);
|
|
499
|
-
}
|
|
500
|
-
//# sourceMappingURL=evolution.js.map
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook-based Enforcement Gates
|
|
3
|
-
*
|
|
4
|
-
* Uses Claude Flow hooks to enforce non-negotiable rules.
|
|
5
|
-
* The model can forget. The hook does not.
|
|
6
|
-
*
|
|
7
|
-
* Gates:
|
|
8
|
-
* 1. Destructive ops gate - requires confirmation + rollback plan
|
|
9
|
-
* 2. Tool allowlist gate - blocks non-allowlisted tools
|
|
10
|
-
* 3. Diff size gate - requires plan + staged commits for large diffs
|
|
11
|
-
* 4. Secrets gate - redacts and warns on secret patterns
|
|
12
|
-
*
|
|
13
|
-
* @module @claude-flow/guidance/gates
|
|
14
|
-
*/
|
|
15
|
-
import type { GateConfig, GateResult, GateDecision, GuidanceRule } from './types.js';
|
|
16
|
-
export declare class EnforcementGates {
|
|
17
|
-
private config;
|
|
18
|
-
private activeRules;
|
|
19
|
-
constructor(config?: Partial<GateConfig>);
|
|
20
|
-
/**
|
|
21
|
-
* Update active rules from retrieval
|
|
22
|
-
*/
|
|
23
|
-
setActiveRules(rules: GuidanceRule[]): void;
|
|
24
|
-
/**
|
|
25
|
-
* Update configuration
|
|
26
|
-
*/
|
|
27
|
-
updateConfig(config: Partial<GateConfig>): void;
|
|
28
|
-
/**
|
|
29
|
-
* Evaluate all gates for a command
|
|
30
|
-
*/
|
|
31
|
-
evaluateCommand(command: string): GateResult[];
|
|
32
|
-
/**
|
|
33
|
-
* Evaluate all gates for a tool use
|
|
34
|
-
*/
|
|
35
|
-
evaluateToolUse(toolName: string, params: Record<string, unknown>): GateResult[];
|
|
36
|
-
/**
|
|
37
|
-
* Evaluate all gates for a file edit
|
|
38
|
-
*/
|
|
39
|
-
evaluateEdit(filePath: string, content: string, diffLines: number): GateResult[];
|
|
40
|
-
/**
|
|
41
|
-
* Gate 1: Destructive Operations
|
|
42
|
-
*
|
|
43
|
-
* If command includes delete, drop, rm, force, migration,
|
|
44
|
-
* require explicit confirmation and a rollback plan.
|
|
45
|
-
*/
|
|
46
|
-
evaluateDestructiveOps(command: string): GateResult | null;
|
|
47
|
-
/**
|
|
48
|
-
* Gate 2: Tool Allowlist
|
|
49
|
-
*
|
|
50
|
-
* If tool not in allowlist, block and ask for permission.
|
|
51
|
-
*/
|
|
52
|
-
evaluateToolAllowlist(toolName: string): GateResult | null;
|
|
53
|
-
/**
|
|
54
|
-
* Gate 3: Diff Size
|
|
55
|
-
*
|
|
56
|
-
* If patch exceeds threshold, require a plan and staged commits.
|
|
57
|
-
*/
|
|
58
|
-
evaluateDiffSize(filePath: string, diffLines: number): GateResult | null;
|
|
59
|
-
/**
|
|
60
|
-
* Gate 4: Secrets Detection
|
|
61
|
-
*
|
|
62
|
-
* If output matches secret patterns, redact and warn.
|
|
63
|
-
*/
|
|
64
|
-
evaluateSecrets(content: string): GateResult | null;
|
|
65
|
-
/**
|
|
66
|
-
* Get the most restrictive decision from multiple gate results
|
|
67
|
-
*/
|
|
68
|
-
aggregateDecision(results: GateResult[]): GateDecision;
|
|
69
|
-
/**
|
|
70
|
-
* Get gate statistics
|
|
71
|
-
*/
|
|
72
|
-
getActiveGateCount(): number;
|
|
73
|
-
private findTriggeredRules;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Create enforcement gates
|
|
77
|
-
*/
|
|
78
|
-
export declare function createGates(config?: Partial<GateConfig>): EnforcementGates;
|
|
79
|
-
//# sourceMappingURL=gates.d.ts.map
|