@claude-flow/cli 3.32.24 → 3.32.26
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/helpers/.helpers-version +1 -1
- package/.claude/helpers/auto-memory-hook.mjs +430 -430
- package/.claude/helpers/helpers.manifest.json +6 -6
- package/.claude/helpers/hook-handler.cjs +565 -565
- package/.claude/helpers/intelligence.cjs +1058 -1058
- package/.claude/helpers/statusline.cjs +1060 -1060
- package/catalog-manifest.json +4 -4
- package/dist/src/commands/metaharness.js +80 -2
- package/dist/src/mcp-tools/metaharness-tools.js +81 -2
- package/dist/src/services/distill-oracle.d.ts +1 -0
- package/dist/src/services/distill-oracle.js +11 -3
- package/dist/src/services/flywheel-proposer.d.ts +87 -0
- package/dist/src/services/flywheel-proposer.js +165 -0
- package/dist/src/services/flywheel-receipt.d.ts +136 -0
- package/dist/src/services/flywheel-receipt.js +309 -0
- package/dist/src/services/flywheel-transaction.d.ts +77 -0
- package/dist/src/services/flywheel-transaction.js +378 -0
- package/dist/src/services/harness-flywheel-runtime.d.ts +9 -0
- package/dist/src/services/harness-flywheel-runtime.js +67 -2
- package/dist/src/services/harness-flywheel.d.ts +23 -0
- package/dist/src/services/harness-flywheel.js +111 -21
- package/package.json +4 -1
- package/.claude/.proven-config-version +0 -1
- package/.claude/proven-config.json +0 -42
|
@@ -11,10 +11,9 @@
|
|
|
11
11
|
* 4. GATE the winner through the shipped runHarnessLoop on the HELD-OUT split:
|
|
12
12
|
* held_out_improves AND redblue(anchor-no-regress) AND drift<=thr AND
|
|
13
13
|
* replay-deterministic AND receipt_coverage AND canary-no-worse.
|
|
14
|
-
* 5. On accept →
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* the unsigned champion for optional promotion to the signed global channel.
|
|
14
|
+
* 5. On accept → emit + persist an immutable evaluation receipt. Evaluation
|
|
15
|
+
* never mutates active policy. Explicit promotion is handled by the
|
|
16
|
+
* ADR-322A transaction service.
|
|
18
17
|
*
|
|
19
18
|
* Trust split: LOCAL self-optimization is unsigned (an install trusting its own
|
|
20
19
|
* measured gate); CROSS-install propagation still requires the config-signed
|
|
@@ -27,6 +26,8 @@ import { hashCorpus } from './harness-benchmark.js';
|
|
|
27
26
|
import { harvestSelfSupervisedTasks, blendCorpus } from './harness-corpus-harvester.js';
|
|
28
27
|
import { applyChampionParams } from '../config/harness-feedback-applier.js';
|
|
29
28
|
import { appendLedger, bootstrapDeltaCILow } from './harness-improvement-ledger.js';
|
|
29
|
+
import { createFlywheelReceipt, sha256Ref, } from './flywheel-receipt.js';
|
|
30
|
+
import { readFlywheelTransactionState, registerFlywheelReceipt, } from './flywheel-transaction.js';
|
|
30
31
|
export const DEFAULT_CONFIG = { alpha: 0.5, subjectWeight: 2.0, mmrLambda: 0.7, bodyWeight: 1.0, typePenaltyFactor: 1.0 };
|
|
31
32
|
const EPS = 1e-3;
|
|
32
33
|
const cfgCanon = (c) => JSON.stringify(Object.fromEntries(Object.keys(c).sort().map((k) => [k, c[k]])));
|
|
@@ -50,7 +51,7 @@ function grade(ranked, expected) {
|
|
|
50
51
|
const idx = ranked.findIndex((r) => r.id === expected);
|
|
51
52
|
return idx >= 0 ? 1 / (idx + 1) : 0;
|
|
52
53
|
}
|
|
53
|
-
function
|
|
54
|
+
export function retrievalPolicyNeighbors(base) {
|
|
54
55
|
const steps = { alpha: 0.1, subjectWeight: 0.5, mmrLambda: 0.1, bodyWeight: 0.5, typePenaltyFactor: 0.25 };
|
|
55
56
|
const out = [];
|
|
56
57
|
const seen = new Set();
|
|
@@ -89,7 +90,7 @@ function split(tasks, frac) {
|
|
|
89
90
|
* Returns a rich result AND (as a side effect) appends to the improvement ledger
|
|
90
91
|
* and — on accept — applies the champion locally + chains it.
|
|
91
92
|
*/
|
|
92
|
-
export async function
|
|
93
|
+
export async function evaluateFlywheelCandidate(projectRoot, deps) {
|
|
93
94
|
try {
|
|
94
95
|
const patterns = await deps.getPatterns();
|
|
95
96
|
if (!patterns || patterns.length < 8)
|
|
@@ -100,7 +101,9 @@ export async function runFlywheelTick(projectRoot, deps) {
|
|
|
100
101
|
const blended = blendCorpus(deps.anchorTasks, harvested);
|
|
101
102
|
const anchorIdSet = new Set(blended.anchorIds);
|
|
102
103
|
const baseline = { ...DEFAULT_CONFIG, ...(deps.activeParams?.() ?? {}) };
|
|
103
|
-
const candidates =
|
|
104
|
+
const candidates = deps.candidatePolicies?.length
|
|
105
|
+
? deps.candidatePolicies.map((candidate) => ({ ...candidate }))
|
|
106
|
+
: retrievalPolicyNeighbors(baseline);
|
|
104
107
|
// OBJECTIVE = the human-labeled anchor (the relevance we actually care about,
|
|
105
108
|
// where headroom is known to exist). GUARD = the large, growing harvested set
|
|
106
109
|
// (don't wreck broad retrieval while tuning the objective). Optimize the
|
|
@@ -171,7 +174,76 @@ export async function runFlywheelTick(projectRoot, deps) {
|
|
|
171
174
|
const heldDeltas = held.map((t) => heldScoreFor(candidate, t) - heldScoreFor(baseline, t));
|
|
172
175
|
const deltaCILow = bootstrapDeltaCILow(heldDeltas);
|
|
173
176
|
const significant = deltaCILow > 0;
|
|
174
|
-
const
|
|
177
|
+
const provisionalGates = Object.fromEntries(Object.entries(result.verdict?.terms ?? {}).map(([k, v]) => [k, v.pass]));
|
|
178
|
+
const txState = readFlywheelTransactionState(projectRoot);
|
|
179
|
+
const safetyEnvelopeRef = deps.safetyEnvelopeRef ?? sha256Ref(JSON.stringify({
|
|
180
|
+
schema: 'ruflo.safety-envelope/local-default-v1',
|
|
181
|
+
authorizationExpansion: false,
|
|
182
|
+
networkExpansion: false,
|
|
183
|
+
spendExpansion: false,
|
|
184
|
+
}));
|
|
185
|
+
const receipt = createFlywheelReceipt({
|
|
186
|
+
lineageId: deps.lineageId,
|
|
187
|
+
evaluationRunId: deps.evaluationRunId,
|
|
188
|
+
baselineRef: refOf(baseline),
|
|
189
|
+
expectedLedgerHead: txState.ledgerHead,
|
|
190
|
+
candidatePolicy: candidate,
|
|
191
|
+
safetyEnvelopeRef,
|
|
192
|
+
requestedProposer: deps.requestedProposer ?? 'local',
|
|
193
|
+
effectiveProposer: deps.effectiveProposer ?? 'local',
|
|
194
|
+
proposerSubstitution: deps.proposerSubstitution,
|
|
195
|
+
corpusVersion: blended.version,
|
|
196
|
+
corpusHash: blended.corpusHash,
|
|
197
|
+
baselineScore,
|
|
198
|
+
candidateScore,
|
|
199
|
+
heldOutDeltas: heldDeltas,
|
|
200
|
+
frozenAnchorRegression: guardRegressed ? 1 : 0,
|
|
201
|
+
gates: provisionalGates,
|
|
202
|
+
resourceEvidence: {
|
|
203
|
+
p95LatencyMicros: 0,
|
|
204
|
+
costMicrosPerTask: 0,
|
|
205
|
+
tokensPerTask: 0,
|
|
206
|
+
failureRate: '0',
|
|
207
|
+
evaluationCostMicros: 0,
|
|
208
|
+
currency: 'USD',
|
|
209
|
+
},
|
|
210
|
+
evidence: {
|
|
211
|
+
corpusRoles: {
|
|
212
|
+
selectionTaskIds: train.map((task) => task.id),
|
|
213
|
+
promotionHoldoutTaskIds: held.map((task) => task.id),
|
|
214
|
+
guardTaskIds: guard.map((task) => task.id),
|
|
215
|
+
},
|
|
216
|
+
verification: {
|
|
217
|
+
redblue: result.verify?.redblue ?? 'SKIPPED',
|
|
218
|
+
drift: result.verify?.drift ?? -1,
|
|
219
|
+
driftThreshold: result.verify?.driftThreshold ?? 0.2,
|
|
220
|
+
driftVerdict: result.verify?.driftVerdict ?? 'skipped',
|
|
221
|
+
adversarialPass: result.verify?.adversarialPass ?? false,
|
|
222
|
+
},
|
|
223
|
+
canary: {
|
|
224
|
+
candidate: result.canary?.candidate ?? {},
|
|
225
|
+
baseline: result.canary?.baseline ?? {},
|
|
226
|
+
pass: result.canary?.pass ?? false,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
termVerification: Object.keys(provisionalGates).map((term) => ({
|
|
230
|
+
term,
|
|
231
|
+
verification: 'recomputed',
|
|
232
|
+
evidenceRef: sha256Ref(JSON.stringify({
|
|
233
|
+
term,
|
|
234
|
+
corpusHash: blended.corpusHash,
|
|
235
|
+
heldOutDeltas: heldDeltas,
|
|
236
|
+
verification: result.verify,
|
|
237
|
+
canary: result.canary,
|
|
238
|
+
})),
|
|
239
|
+
})),
|
|
240
|
+
now: deps.now,
|
|
241
|
+
privateKeyPem: deps.receiptPrivateKeyPem,
|
|
242
|
+
publicKeyPem: deps.receiptPublicKeyPem,
|
|
243
|
+
bootstrapIterations: deps.bootstrapIterations,
|
|
244
|
+
});
|
|
245
|
+
await registerFlywheelReceipt(projectRoot, receipt, deps.now ?? Date.now());
|
|
246
|
+
const finalAccept = result.accepted && significant && receipt.payload.decision === 'accepted';
|
|
175
247
|
const entry = {
|
|
176
248
|
ts: deps.now ?? Date.now(),
|
|
177
249
|
corpusVersion: blended.version, corpusHash: blended.corpusHash,
|
|
@@ -180,28 +252,46 @@ export async function runFlywheelTick(projectRoot, deps) {
|
|
|
180
252
|
baselineScore, candidateScore, delta: candidateScore - baselineScore,
|
|
181
253
|
deltaCILow, significant, loopAccepted: result.accepted,
|
|
182
254
|
anchorRegressed, accepted: finalAccept,
|
|
183
|
-
gates:
|
|
255
|
+
gates: provisionalGates,
|
|
184
256
|
reason: finalAccept ? result.reason : (result.accepted ? `held back — improvement not significant (CI low ${deltaCILow.toFixed(4)})` : result.reason),
|
|
185
257
|
};
|
|
186
|
-
let applied = false;
|
|
187
|
-
if (finalAccept && result.manifest) {
|
|
188
|
-
entry.championRef = refOf(candidate);
|
|
189
|
-
// Apply locally (self-optimization) + chain to the previous champion.
|
|
190
|
-
const ap = applyChampionParams(projectRoot, {
|
|
191
|
-
championId: refOf(candidate), params: candidate,
|
|
192
|
-
layer: 'repo/local', previous: refOf(baseline), now: deps.now,
|
|
193
|
-
});
|
|
194
|
-
applied = ap.applied;
|
|
195
|
-
}
|
|
196
258
|
appendLedger(`${projectRoot}/.claude-flow/metrics`, entry);
|
|
197
259
|
return {
|
|
198
|
-
ran: true, reason: entry.reason, accepted: finalAccept, applied,
|
|
260
|
+
ran: true, reason: entry.reason, accepted: finalAccept, applied: false,
|
|
199
261
|
baselineScore, candidateScore, delta: candidateScore - baselineScore,
|
|
200
|
-
anchorRegressed, championRef:
|
|
262
|
+
anchorRegressed, championRef: finalAccept ? refOf(candidate) : undefined,
|
|
263
|
+
corpusVersion: blended.version, candidateConfig: candidate,
|
|
264
|
+
receiptId: receipt.payload.receiptId, receipt, promotable: finalAccept && !!receipt.signature,
|
|
201
265
|
};
|
|
202
266
|
}
|
|
203
267
|
catch (e) {
|
|
204
268
|
return { ran: false, reason: `error: ${e?.message ?? e}` };
|
|
205
269
|
}
|
|
206
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Compatibility wrapper. New callers get evaluation-only semantics. The legacy
|
|
273
|
+
* implicit apply path exists for one release behind an explicit opt-in flag.
|
|
274
|
+
*/
|
|
275
|
+
export async function runFlywheelTick(projectRoot, deps) {
|
|
276
|
+
const result = await evaluateFlywheelCandidate(projectRoot, deps);
|
|
277
|
+
if (process.env.RUFLO_FLYWHEEL_LEGACY_APPLY === '1'
|
|
278
|
+
&& result.accepted
|
|
279
|
+
&& result.candidateConfig
|
|
280
|
+
&& result.championRef) {
|
|
281
|
+
const applied = applyChampionParams(projectRoot, {
|
|
282
|
+
championId: result.championRef,
|
|
283
|
+
params: result.candidateConfig,
|
|
284
|
+
layer: 'repo/local',
|
|
285
|
+
previous: result.receipt?.payload.baselineRef,
|
|
286
|
+
now: deps.now,
|
|
287
|
+
});
|
|
288
|
+
return {
|
|
289
|
+
...result,
|
|
290
|
+
applied: applied.applied,
|
|
291
|
+
legacyDeprecation: true,
|
|
292
|
+
reason: `${result.reason}; deprecated implicit apply path`,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
207
297
|
//# sourceMappingURL=harness-flywheel.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.32.
|
|
3
|
+
"version": "3.32.26",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
],
|
|
87
87
|
"scripts": {
|
|
88
88
|
"build": "tsc",
|
|
89
|
+
"check:metaharness-pins": "node ../../../scripts/check-metaharness-pins.mjs",
|
|
89
90
|
"test": "vitest run",
|
|
90
91
|
"test:plugin-store": "npx tsx src/plugins/tests/standalone-test.ts",
|
|
91
92
|
"test:pattern-store": "npx tsx src/transfer/store/tests/standalone-test.ts",
|
|
@@ -115,6 +116,8 @@
|
|
|
115
116
|
"optionalDependencies": {
|
|
116
117
|
"@claude-flow/memory": "^3.0.0-alpha.21",
|
|
117
118
|
"@claude-flow/security": "^3.0.0-alpha.12",
|
|
119
|
+
"@metaharness/darwin": "^0.8.0",
|
|
120
|
+
"@metaharness/flywheel": "^0.1.7",
|
|
118
121
|
"agentdb": "^3.0.0-alpha.17",
|
|
119
122
|
"agentic-flow": "^3.0.0-alpha.1",
|
|
120
123
|
"better-sqlite3": "^12.9.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
sha256:6141a8ea990c5063b77e090ae8f37f9c539d8aa8f58dcceb30f3a82f97e57319
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"adoptedAt": 1785208363552,
|
|
3
|
-
"championId": "sha256:6141a8ea990c5063b77e090ae8f37f9c539d8aa8f58dcceb30f3a82f97e57319",
|
|
4
|
-
"manifest": {
|
|
5
|
-
"schema": "ruflo.proven-config/v1",
|
|
6
|
-
"policy": {
|
|
7
|
-
"ref": "sha256:6141a8ea990c5063b77e090ae8f37f9c539d8aa8f58dcceb30f3a82f97e57319",
|
|
8
|
-
"value": {
|
|
9
|
-
"alpha": 0.3,
|
|
10
|
-
"subjectWeight": 1,
|
|
11
|
-
"mmrLambda": 0.5,
|
|
12
|
-
"bodyWeight": 1.5,
|
|
13
|
-
"typePenaltyFactor": 0.5
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"layer": "framework/node-cli",
|
|
17
|
-
"compatibility": {
|
|
18
|
-
"ruflo": ">=3.24.0"
|
|
19
|
-
},
|
|
20
|
-
"benchmark": {
|
|
21
|
-
"corpus": "ADR-081-labelled-v1",
|
|
22
|
-
"corpusHash": "sha256:2f700b5c363e20a3bd88ce2bc9b87bbbbaa61732c6177894c6ec37890f888982"
|
|
23
|
-
},
|
|
24
|
-
"receipt": {
|
|
25
|
-
"heldOutDelta": 0.07381404928570845,
|
|
26
|
-
"redblue": "PASS",
|
|
27
|
-
"drift": 0,
|
|
28
|
-
"canary": {
|
|
29
|
-
"rollbackRate": 0,
|
|
30
|
-
"latencyP95": 244.612458000076,
|
|
31
|
-
"costPerTask": 0
|
|
32
|
-
},
|
|
33
|
-
"receiptCoverage": 1
|
|
34
|
-
},
|
|
35
|
-
"platform": [
|
|
36
|
-
"linux",
|
|
37
|
-
"macOS",
|
|
38
|
-
"windows"
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
|
-
"previous": ""
|
|
42
|
-
}
|