@claude-flow/cli 3.23.0 → 3.24.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.
Files changed (52) hide show
  1. package/.claude/evolve-proof/generation-0.json +211 -0
  2. package/.claude/evolve-proof/real-generation-0.json +406 -0
  3. package/.claude/evolve-proof/real-generation-1.json +406 -0
  4. package/.claude/helpers/.helpers-version +1 -1
  5. package/.claude/helpers/intelligence.cjs +10 -0
  6. package/.claude/proven-config.manifest.json +37 -0
  7. package/.claude/proven-config.signed.json +41 -0
  8. package/.claude/proven-config.signed.rvf +0 -0
  9. package/dist/src/config/harness-feedback-applier.d.ts +50 -0
  10. package/dist/src/config/harness-feedback-applier.js +122 -0
  11. package/dist/src/config/proven-config-refresh.d.ts +39 -0
  12. package/dist/src/config/proven-config-refresh.js +154 -0
  13. package/dist/src/config/proven-config-rvfa.d.ts +23 -0
  14. package/dist/src/config/proven-config-rvfa.js +73 -0
  15. package/dist/src/config/proven-config.d.ts +86 -0
  16. package/dist/src/config/proven-config.js +176 -0
  17. package/dist/src/index.js +35 -0
  18. package/dist/src/mcp-tools/neural-tools.d.ts +10 -0
  19. package/dist/src/mcp-tools/neural-tools.js +107 -18
  20. package/dist/src/services/daemon-autostart.d.ts +17 -0
  21. package/dist/src/services/daemon-autostart.js +79 -0
  22. package/dist/src/services/evolve-proof.d.ts +247 -0
  23. package/dist/src/services/evolve-proof.js +341 -0
  24. package/dist/src/services/harness-benchmark.d.ts +68 -0
  25. package/dist/src/services/harness-benchmark.js +94 -0
  26. package/dist/src/services/harness-canary.d.ts +60 -0
  27. package/dist/src/services/harness-canary.js +69 -0
  28. package/dist/src/services/harness-corpus-harvester.d.ts +51 -0
  29. package/dist/src/services/harness-corpus-harvester.js +74 -0
  30. package/dist/src/services/harness-flywheel-generations.d.ts +111 -0
  31. package/dist/src/services/harness-flywheel-generations.js +354 -0
  32. package/dist/src/services/harness-flywheel-runtime.d.ts +25 -0
  33. package/dist/src/services/harness-flywheel-runtime.js +101 -0
  34. package/dist/src/services/harness-flywheel.d.ts +48 -0
  35. package/dist/src/services/harness-flywheel.js +207 -0
  36. package/dist/src/services/harness-hosts.d.ts +40 -0
  37. package/dist/src/services/harness-hosts.js +88 -0
  38. package/dist/src/services/harness-improvement-ledger.d.ts +63 -0
  39. package/dist/src/services/harness-improvement-ledger.js +101 -0
  40. package/dist/src/services/harness-loop.d.ts +53 -0
  41. package/dist/src/services/harness-loop.js +85 -0
  42. package/dist/src/services/harness-qualification.d.ts +66 -0
  43. package/dist/src/services/harness-qualification.js +143 -0
  44. package/dist/src/services/harness-replay.d.ts +37 -0
  45. package/dist/src/services/harness-replay.js +92 -0
  46. package/dist/src/services/harness-verify.d.ts +33 -0
  47. package/dist/src/services/harness-verify.js +26 -0
  48. package/dist/src/services/harness-worker.d.ts +23 -0
  49. package/dist/src/services/harness-worker.js +66 -0
  50. package/dist/src/services/worker-daemon.d.ts +8 -1
  51. package/dist/src/services/worker-daemon.js +42 -0
  52. package/package.json +1 -1
@@ -0,0 +1,406 @@
1
+ {
2
+ "label": "single-round proof-of-mechanism",
3
+ "disclaimers": [
4
+ "not flywheel proof",
5
+ "not compounding learning",
6
+ "not production learning"
7
+ ],
8
+ "generation": 1,
9
+ "parent": "sha256:3515c407c0555d491432fdce2405389fa6d33831fc64d342364defbf7cf7ffef",
10
+ "branch": "main",
11
+ "kind": "real",
12
+ "createdAt": 1700000201000,
13
+ "inputHoldoutHash": "sha256:9cdb7bdefd9d6897a5f6a5645c92a6616adefaf6d5c54b66f1a21b03ec6e841c",
14
+ "baselineManifestHash": "sha256:3515c407c0555d491432fdce2405389fa6d33831fc64d342364defbf7cf7ffef",
15
+ "candidateManifestHash": "sha256:fdb91acd74a34d71d5263f91fe230c87e18f8e69ef36bab77ca47b98692078c7",
16
+ "meetsPromotionRule": {
17
+ "version": "accept/v1+sig",
18
+ "result": true
19
+ },
20
+ "decisionReceipt": {
21
+ "promotionRuleVersion": "accept/v1+sig",
22
+ "verdictInputs": {
23
+ "heldOutScore": 0.8473484848484848,
24
+ "baselineHeldOutScore": 0.7575757575757577,
25
+ "redblue": "PASS",
26
+ "drift": 0,
27
+ "driftThreshold": 0.05,
28
+ "replayDeterministic": true,
29
+ "receiptCoverage": 1,
30
+ "canaryRollbackRate": 0,
31
+ "baselineRollbackRate": 0
32
+ },
33
+ "result": {
34
+ "accept": true,
35
+ "terms": {
36
+ "held_out_improves": {
37
+ "value": "0.8473 > 0.7576",
38
+ "pass": true
39
+ },
40
+ "redblue_pass": {
41
+ "value": "PASS",
42
+ "pass": true
43
+ },
44
+ "drift_within": {
45
+ "value": "0 <= 0.05",
46
+ "pass": true
47
+ },
48
+ "replay_deterministic": {
49
+ "value": true,
50
+ "pass": true
51
+ },
52
+ "receipt_coverage_full": {
53
+ "value": 1,
54
+ "pass": true
55
+ },
56
+ "canary_no_worse": {
57
+ "value": "0 <= 0",
58
+ "pass": true
59
+ }
60
+ },
61
+ "failed": []
62
+ },
63
+ "significant": true,
64
+ "deltaCILow": 0.038636363636363635,
65
+ "promoted": true,
66
+ "reason": "promoted (all accept/v1+sig terms held)"
67
+ },
68
+ "shadow": {
69
+ "registrationId": "shadow:8a148c1931e94b7f2b448e1327d08ba31924f3cd6773fc85064b4cc4b0a5359c",
70
+ "state": "shadow",
71
+ "served": false,
72
+ "candidateManifestHash": "sha256:fdb91acd74a34d71d5263f91fe230c87e18f8e69ef36bab77ca47b98692078c7",
73
+ "registeredAt": 1700000201000
74
+ },
75
+ "costReceipt": {
76
+ "usd": 0,
77
+ "llmCalls": 0,
78
+ "tier": "real-local",
79
+ "notes": "measured on the frozen anchor via live retrieval — no LLM, no network"
80
+ },
81
+ "mutationClass": "retrieval:multi",
82
+ "mutationSummary": "alpha:0.3→0.2, bodyWeight:1→1.5, mmrLambda:0.9→1, subjectWeight:1→0.5, typePenaltyFactor:1→0.75",
83
+ "deltas": {
84
+ "benchmark": 0.08977272727272712,
85
+ "security": 0,
86
+ "cost": 0
87
+ },
88
+ "promotion": {
89
+ "parentManifestHash": "sha256:3515c407c0555d491432fdce2405389fa6d33831fc64d342364defbf7cf7ffef",
90
+ "candidateManifestHash": "sha256:fdb91acd74a34d71d5263f91fe230c87e18f8e69ef36bab77ca47b98692078c7",
91
+ "mutationClass": "retrieval:multi",
92
+ "mutationSummary": "alpha:0.3→0.2, bodyWeight:1→1.5, mmrLambda:0.9→1, subjectWeight:1→0.5, typePenaltyFactor:1→0.75",
93
+ "deltas": {
94
+ "benchmark": 0.08977272727272712,
95
+ "security": 0,
96
+ "cost": 0
97
+ },
98
+ "decisionReceipt": {
99
+ "promotionRuleVersion": "accept/v1+sig",
100
+ "verdictInputs": {
101
+ "heldOutScore": 0.8473484848484848,
102
+ "baselineHeldOutScore": 0.7575757575757577,
103
+ "redblue": "PASS",
104
+ "drift": 0,
105
+ "driftThreshold": 0.05,
106
+ "replayDeterministic": true,
107
+ "receiptCoverage": 1,
108
+ "canaryRollbackRate": 0,
109
+ "baselineRollbackRate": 0
110
+ },
111
+ "result": {
112
+ "accept": true,
113
+ "terms": {
114
+ "held_out_improves": {
115
+ "value": "0.8473 > 0.7576",
116
+ "pass": true
117
+ },
118
+ "redblue_pass": {
119
+ "value": "PASS",
120
+ "pass": true
121
+ },
122
+ "drift_within": {
123
+ "value": "0 <= 0.05",
124
+ "pass": true
125
+ },
126
+ "replay_deterministic": {
127
+ "value": true,
128
+ "pass": true
129
+ },
130
+ "receipt_coverage_full": {
131
+ "value": 1,
132
+ "pass": true
133
+ },
134
+ "canary_no_worse": {
135
+ "value": "0 <= 0",
136
+ "pass": true
137
+ }
138
+ },
139
+ "failed": []
140
+ },
141
+ "significant": true,
142
+ "deltaCILow": 0.038636363636363635,
143
+ "promoted": true,
144
+ "reason": "promoted (all accept/v1+sig terms held)"
145
+ }
146
+ },
147
+ "regression": null,
148
+ "holdout": [
149
+ {
150
+ "taskId": "hv-pattern-1780161324685-1d-tgm8",
151
+ "baselineScore": 0.5,
152
+ "candidateScore": 0.5
153
+ },
154
+ {
155
+ "taskId": "hv-pattern-1780161324686-1g-p25o",
156
+ "baselineScore": 1,
157
+ "candidateScore": 1
158
+ },
159
+ {
160
+ "taskId": "hv-pattern-1780161324686-1j-m5hq",
161
+ "baselineScore": 0.5,
162
+ "candidateScore": 1
163
+ },
164
+ {
165
+ "taskId": "hv-pattern-1780161324686-1m-j0ig",
166
+ "baselineScore": 0,
167
+ "candidateScore": 1
168
+ },
169
+ {
170
+ "taskId": "hv-pattern-1780161324687-1p-2lpj",
171
+ "baselineScore": 0.5,
172
+ "candidateScore": 0.5
173
+ },
174
+ {
175
+ "taskId": "hv-pattern-1780161324687-1s-ibq9",
176
+ "baselineScore": 1,
177
+ "candidateScore": 1
178
+ },
179
+ {
180
+ "taskId": "hv-pattern-1780161324688-1v-qvm9",
181
+ "baselineScore": 0.5,
182
+ "candidateScore": 1
183
+ },
184
+ {
185
+ "taskId": "hv-pattern-1780161324688-1y-hjpj",
186
+ "baselineScore": 1,
187
+ "candidateScore": 1
188
+ },
189
+ {
190
+ "taskId": "hv-pattern-1780161324689-21-o5x6",
191
+ "baselineScore": 1,
192
+ "candidateScore": 1
193
+ },
194
+ {
195
+ "taskId": "hv-pattern-1780161324689-24-hkmf",
196
+ "baselineScore": 1,
197
+ "candidateScore": 1
198
+ },
199
+ {
200
+ "taskId": "hv-pattern-1780161324690-27-igfa",
201
+ "baselineScore": 1,
202
+ "candidateScore": 1
203
+ },
204
+ {
205
+ "taskId": "hv-pattern-1780161324690-2a-6t0p",
206
+ "baselineScore": 1,
207
+ "candidateScore": 1
208
+ },
209
+ {
210
+ "taskId": "hv-pattern-1780161324690-2d-5hqx",
211
+ "baselineScore": 1,
212
+ "candidateScore": 1
213
+ },
214
+ {
215
+ "taskId": "hv-pattern-1780161324691-2g-grco",
216
+ "baselineScore": 1,
217
+ "candidateScore": 1
218
+ },
219
+ {
220
+ "taskId": "hv-pattern-1780161324691-2j-zfni",
221
+ "baselineScore": 0.25,
222
+ "candidateScore": 0.25
223
+ },
224
+ {
225
+ "taskId": "hv-pattern-1780161324691-2m-wx6m",
226
+ "baselineScore": 0,
227
+ "candidateScore": 0.2
228
+ },
229
+ {
230
+ "taskId": "hv-pattern-1780161324692-2p-8jhd",
231
+ "baselineScore": 1,
232
+ "candidateScore": 1
233
+ },
234
+ {
235
+ "taskId": "hv-pattern-1780161324692-2s-c4t4",
236
+ "baselineScore": 1,
237
+ "candidateScore": 1
238
+ },
239
+ {
240
+ "taskId": "hv-pattern-1780161324692-2v-afrs",
241
+ "baselineScore": 1,
242
+ "candidateScore": 1
243
+ },
244
+ {
245
+ "taskId": "hv-pattern-1780161324693-2y-2ozh",
246
+ "baselineScore": 1,
247
+ "candidateScore": 1
248
+ },
249
+ {
250
+ "taskId": "hv-pattern-1780161324693-31-ac3v",
251
+ "baselineScore": 0.3333333333333333,
252
+ "candidateScore": 0.3333333333333333
253
+ },
254
+ {
255
+ "taskId": "hv-pattern-1780161324694-34-ysmt",
256
+ "baselineScore": 0.5,
257
+ "candidateScore": 0.5
258
+ },
259
+ {
260
+ "taskId": "hv-pattern-1780161324694-37-lvvk",
261
+ "baselineScore": 1,
262
+ "candidateScore": 1
263
+ },
264
+ {
265
+ "taskId": "hv-pattern-1780161324694-3a-i470",
266
+ "baselineScore": 0.25,
267
+ "candidateScore": 1
268
+ },
269
+ {
270
+ "taskId": "hv-pattern-1780161324695-3d-9awr",
271
+ "baselineScore": 1,
272
+ "candidateScore": 1
273
+ },
274
+ {
275
+ "taskId": "hv-pattern-1780161324695-3g-y9cu",
276
+ "baselineScore": 1,
277
+ "candidateScore": 1
278
+ },
279
+ {
280
+ "taskId": "hv-pattern-1780161324695-3j-wi4w",
281
+ "baselineScore": 1,
282
+ "candidateScore": 1
283
+ },
284
+ {
285
+ "taskId": "hv-pattern-1780161324696-3m-tzr2",
286
+ "baselineScore": 1,
287
+ "candidateScore": 1
288
+ },
289
+ {
290
+ "taskId": "hv-pattern-1780161324696-3p-49pp",
291
+ "baselineScore": 0,
292
+ "candidateScore": 0
293
+ },
294
+ {
295
+ "taskId": "hv-pattern-1780161324698-3s-5w1r",
296
+ "baselineScore": 1,
297
+ "candidateScore": 1
298
+ },
299
+ {
300
+ "taskId": "hv-pattern-1780161324698-3v-4fri",
301
+ "baselineScore": 1,
302
+ "candidateScore": 1
303
+ },
304
+ {
305
+ "taskId": "hv-pattern-1780161324698-3y-v3g2",
306
+ "baselineScore": 1,
307
+ "candidateScore": 1
308
+ },
309
+ {
310
+ "taskId": "hv-pattern-1780161324699-41-hvmz",
311
+ "baselineScore": 1,
312
+ "candidateScore": 1
313
+ },
314
+ {
315
+ "taskId": "hv-pattern-1780161324699-44-nys5",
316
+ "baselineScore": 1,
317
+ "candidateScore": 1
318
+ },
319
+ {
320
+ "taskId": "hv-pattern-1780161324699-47-jghz",
321
+ "baselineScore": 0.5,
322
+ "candidateScore": 0.5
323
+ },
324
+ {
325
+ "taskId": "hv-pattern-1780161324700-4a-3pj8",
326
+ "baselineScore": 1,
327
+ "candidateScore": 1
328
+ },
329
+ {
330
+ "taskId": "hv-pattern-1780161324700-4d-rmrn",
331
+ "baselineScore": 1,
332
+ "candidateScore": 1
333
+ },
334
+ {
335
+ "taskId": "hv-pattern-1780161324700-4g-tb58",
336
+ "baselineScore": 0,
337
+ "candidateScore": 0
338
+ },
339
+ {
340
+ "taskId": "hv-pattern-1780161324701-4j-kodm",
341
+ "baselineScore": 0,
342
+ "candidateScore": 0.5
343
+ },
344
+ {
345
+ "taskId": "hv-pattern-1780161324701-4m-dt4j",
346
+ "baselineScore": 0.5,
347
+ "candidateScore": 1
348
+ },
349
+ {
350
+ "taskId": "hv-pattern-1780161324701-4p-e7fi",
351
+ "baselineScore": 1,
352
+ "candidateScore": 1
353
+ },
354
+ {
355
+ "taskId": "hv-pattern-1780161324702-4s-bo8j",
356
+ "baselineScore": 1,
357
+ "candidateScore": 1
358
+ },
359
+ {
360
+ "taskId": "hv-pattern-1780161324702-4v-6orz",
361
+ "baselineScore": 1,
362
+ "candidateScore": 1
363
+ },
364
+ {
365
+ "taskId": "hv-pattern-1780161324702-4y-0o2q",
366
+ "baselineScore": 1,
367
+ "candidateScore": 1
368
+ }
369
+ ],
370
+ "baselineManifest": {
371
+ "schema": "ruflo.proven-config/v1",
372
+ "policy": {
373
+ "ref": "sha256:7caf5bfd2878b84825b5f641f447a9ecaf177258fecd8b4e82d823d98fb84097",
374
+ "value": {
375
+ "alpha": 0.3,
376
+ "subjectWeight": 1,
377
+ "mmrLambda": 0.9,
378
+ "bodyWeight": 1,
379
+ "typePenaltyFactor": 1
380
+ }
381
+ },
382
+ "layer": "real/retrieval",
383
+ "benchmark": {
384
+ "corpus": "harvested-selfsup-frozen-v1",
385
+ "corpusHash": "sha256:cfeda09c42a88e2dc86efd650ff167880d7482a8e1af176bf861a09e6cca01be"
386
+ }
387
+ },
388
+ "candidateManifest": {
389
+ "schema": "ruflo.proven-config/v1",
390
+ "policy": {
391
+ "ref": "sha256:046b42190078dd450c4baa5b409cbc369662cc4dec5e847c8b839f9a2aed0ff5",
392
+ "value": {
393
+ "alpha": 0.2,
394
+ "subjectWeight": 0.5,
395
+ "mmrLambda": 1,
396
+ "bodyWeight": 1.5,
397
+ "typePenaltyFactor": 0.75
398
+ }
399
+ },
400
+ "layer": "real/retrieval",
401
+ "benchmark": {
402
+ "corpus": "harvested-selfsup-frozen-v1",
403
+ "corpusHash": "sha256:cfeda09c42a88e2dc86efd650ff167880d7482a8e1af176bf861a09e6cca01be"
404
+ }
405
+ }
406
+ }
@@ -1 +1 @@
1
- 3.22.0
1
+ 3.23.0
@@ -587,6 +587,16 @@ function recordEdit(file, success) {
587
587
  sessionId: sessionGet('sessionId') || null,
588
588
  });
589
589
  fs.appendFileSync(PENDING_PATH, entry + '\n', 'utf-8');
590
+ // Runaway-storage guard: pending-insights is append-only and only drained by
591
+ // consolidation. If it grows past ~512KB (thousands of un-consolidated edits
592
+ // — e.g. the daemon never ran), keep only the most recent 2000 lines so it
593
+ // can never grow unbounded. Cheap (a statSync per edit; rewrite only when over).
594
+ try {
595
+ if (fs.statSync(PENDING_PATH).size > 512 * 1024) {
596
+ const lines = fs.readFileSync(PENDING_PATH, 'utf-8').split('\n').filter(Boolean);
597
+ if (lines.length > 2000) fs.writeFileSync(PENDING_PATH, lines.slice(-2000).join('\n') + '\n', 'utf-8');
598
+ }
599
+ } catch (e) { /* non-fatal */ }
590
600
  }
591
601
 
592
602
  /**
@@ -0,0 +1,37 @@
1
+ {
2
+ "schema": "ruflo.proven-config/v1",
3
+ "policy": {
4
+ "ref": "sha256:6141a8ea990c5063b77e090ae8f37f9c539d8aa8f58dcceb30f3a82f97e57319",
5
+ "value": {
6
+ "alpha": 0.3,
7
+ "subjectWeight": 1,
8
+ "mmrLambda": 0.5,
9
+ "bodyWeight": 1.5,
10
+ "typePenaltyFactor": 0.5
11
+ }
12
+ },
13
+ "layer": "framework/node-cli",
14
+ "compatibility": {
15
+ "ruflo": ">=3.24.0"
16
+ },
17
+ "benchmark": {
18
+ "corpus": "ADR-081-labelled-v1",
19
+ "corpusHash": "sha256:2f700b5c363e20a3bd88ce2bc9b87bbbbaa61732c6177894c6ec37890f888982"
20
+ },
21
+ "receipt": {
22
+ "heldOutDelta": 0.07381404928570845,
23
+ "redblue": "PASS",
24
+ "drift": 0,
25
+ "canary": {
26
+ "rollbackRate": 0,
27
+ "latencyP95": 244.612458000076,
28
+ "costPerTask": 0
29
+ },
30
+ "receiptCoverage": 1
31
+ },
32
+ "platform": [
33
+ "linux",
34
+ "macOS",
35
+ "windows"
36
+ ]
37
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "manifest": {
3
+ "schema": "ruflo.proven-config/v1",
4
+ "policy": {
5
+ "ref": "sha256:6141a8ea990c5063b77e090ae8f37f9c539d8aa8f58dcceb30f3a82f97e57319",
6
+ "value": {
7
+ "alpha": 0.3,
8
+ "subjectWeight": 1,
9
+ "mmrLambda": 0.5,
10
+ "bodyWeight": 1.5,
11
+ "typePenaltyFactor": 0.5
12
+ }
13
+ },
14
+ "layer": "framework/node-cli",
15
+ "compatibility": {
16
+ "ruflo": ">=3.24.0"
17
+ },
18
+ "benchmark": {
19
+ "corpus": "ADR-081-labelled-v1",
20
+ "corpusHash": "sha256:2f700b5c363e20a3bd88ce2bc9b87bbbbaa61732c6177894c6ec37890f888982"
21
+ },
22
+ "receipt": {
23
+ "heldOutDelta": 0.07381404928570845,
24
+ "redblue": "PASS",
25
+ "drift": 0,
26
+ "canary": {
27
+ "rollbackRate": 0,
28
+ "latencyP95": 244.612458000076,
29
+ "costPerTask": 0
30
+ },
31
+ "receiptCoverage": 1
32
+ },
33
+ "platform": [
34
+ "linux",
35
+ "macOS",
36
+ "windows"
37
+ ]
38
+ },
39
+ "signature": "gC7VYhZ+l1RQQ9vO4Ml2pVV3fUy38rBBn5vsMx8XQP4wWuZBOzNd1ZGAhtfNvkTeV1hXd3Dr5Ln09Etr1VcdCw==",
40
+ "algorithm": "ed25519"
41
+ }
Binary file
@@ -0,0 +1,50 @@
1
+ export declare const ADOPTED_CONFIG_FILE = "proven-config.json";
2
+ export declare const ACTIVE_POLICY_FILE = "harness-active-policy.json";
3
+ export interface ActivePolicy {
4
+ championId: string;
5
+ provenanceTier: string;
6
+ layer?: string;
7
+ appliedAt: number;
8
+ previous?: string | null;
9
+ rolledBack?: boolean;
10
+ params?: Record<string, unknown>;
11
+ }
12
+ export interface ApplyResult {
13
+ applied: boolean;
14
+ from?: string | null;
15
+ to?: string;
16
+ reason?: string;
17
+ }
18
+ /**
19
+ * Apply the adopted champion to the active harness policy. Idempotent (applying
20
+ * the same champion is a no-op), reversible (records the superseded champion),
21
+ * best-effort. `now` is injectable for tests.
22
+ */
23
+ export declare function applyChampion(cwd: string, opts?: {
24
+ now?: number;
25
+ }): ApplyResult;
26
+ /**
27
+ * Apply a champion directly by its config payload (local self-optimization,
28
+ * ADR-176 flywheel). Unlike applyChampion (which reads a propagated, signed,
29
+ * adopted record), this activates a LOCALLY-mined champion that just cleared the
30
+ * install's own measured gate — no signing, because nothing is propagated. Still
31
+ * reversible (records `previous`) and idempotent. Consumers read `params`.
32
+ */
33
+ export declare function applyChampionParams(cwd: string, opts: {
34
+ championId: string;
35
+ params?: Record<string, unknown>;
36
+ layer?: string;
37
+ previous?: string | null;
38
+ now?: number;
39
+ }): ApplyResult;
40
+ /**
41
+ * Reverse the last apply: point the active policy back at its `previous`
42
+ * champion (reversibility, ADR-177 rollback pointer). No-op if there is no
43
+ * previous. The previous champion's policy is fetched by ref by consumers.
44
+ */
45
+ export declare function rollbackActivePolicy(cwd: string, opts?: {
46
+ now?: number;
47
+ }): ApplyResult;
48
+ /** The champion routing/agents should currently use, or null. */
49
+ export declare function activeChampion(cwd: string): ActivePolicy | null;
50
+ //# sourceMappingURL=harness-feedback-applier.d.ts.map
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Feedback applier — close the loop (ADR-176 phase 9).
3
+ *
4
+ * A proven champion adopted by the propagation channel (ADR-177,
5
+ * proven-config-refresh.ts writes `.claude/proven-config.json`) is inert until
6
+ * something *applies* it to what ruflo actually runs. This applier promotes the
7
+ * adopted champion to the ACTIVE harness policy that routing/agents consume —
8
+ * reversibly (keeps the previous pointer) and provenance-tagged (ADR-171), so
9
+ * it composes with the promote-gate discipline rather than bypassing it. It only
10
+ * ever sets a pointer to a proven, signed champion; it never invents config.
11
+ * Zero deps, $0.
12
+ */
13
+ import * as fs from 'fs';
14
+ import * as path from 'path';
15
+ export const ADOPTED_CONFIG_FILE = 'proven-config.json'; // written by proven-config-refresh (in .claude)
16
+ export const ACTIVE_POLICY_FILE = 'harness-active-policy.json'; // consumed by routing/agents (in .claude-flow)
17
+ function readJson(p) {
18
+ try {
19
+ return JSON.parse(fs.readFileSync(p, 'utf-8'));
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ /**
26
+ * Apply the adopted champion to the active harness policy. Idempotent (applying
27
+ * the same champion is a no-op), reversible (records the superseded champion),
28
+ * best-effort. `now` is injectable for tests.
29
+ */
30
+ export function applyChampion(cwd, opts = {}) {
31
+ try {
32
+ const claudeDir = path.join(cwd, '.claude');
33
+ const adopted = readJson(path.join(claudeDir, ADOPTED_CONFIG_FILE));
34
+ if (!adopted?.championId)
35
+ return { applied: false, reason: 'no adopted champion' };
36
+ const cfDir = path.join(cwd, '.claude-flow');
37
+ const activePath = path.join(cfDir, ACTIVE_POLICY_FILE);
38
+ const current = readJson(activePath);
39
+ if (current?.championId === adopted.championId && !current.rolledBack) {
40
+ return { applied: false, reason: 'already active' }; // idempotent
41
+ }
42
+ const active = {
43
+ championId: adopted.championId,
44
+ // A champion only reaches adoption if it cleared the promote-gate, so it is
45
+ // oracle/judge-backed; proxy can never be here (ADR-171). Default oracle.
46
+ provenanceTier: 'oracle:test-exec',
47
+ layer: adopted.manifest?.layer,
48
+ appliedAt: opts.now ?? Date.now(),
49
+ previous: current?.championId ?? adopted.previous ?? null,
50
+ params: adopted.manifest?.policy?.value,
51
+ };
52
+ fs.mkdirSync(cfDir, { recursive: true });
53
+ fs.writeFileSync(activePath, JSON.stringify(active, null, 2), 'utf-8');
54
+ return { applied: true, from: active.previous, to: active.championId };
55
+ }
56
+ catch (e) {
57
+ return { applied: false, reason: `error: ${e?.message ?? e}` };
58
+ }
59
+ }
60
+ /**
61
+ * Apply a champion directly by its config payload (local self-optimization,
62
+ * ADR-176 flywheel). Unlike applyChampion (which reads a propagated, signed,
63
+ * adopted record), this activates a LOCALLY-mined champion that just cleared the
64
+ * install's own measured gate — no signing, because nothing is propagated. Still
65
+ * reversible (records `previous`) and idempotent. Consumers read `params`.
66
+ */
67
+ export function applyChampionParams(cwd, opts) {
68
+ try {
69
+ const cfDir = path.join(cwd, '.claude-flow');
70
+ const activePath = path.join(cfDir, ACTIVE_POLICY_FILE);
71
+ const current = readJson(activePath);
72
+ if (current?.championId === opts.championId && !current.rolledBack)
73
+ return { applied: false, reason: 'already active' };
74
+ const active = {
75
+ championId: opts.championId,
76
+ provenanceTier: 'oracle:test-exec', // only a gate-cleared champion reaches here
77
+ layer: opts.layer,
78
+ appliedAt: opts.now ?? Date.now(),
79
+ previous: opts.previous ?? current?.championId ?? null,
80
+ params: opts.params,
81
+ };
82
+ fs.mkdirSync(cfDir, { recursive: true });
83
+ fs.writeFileSync(activePath, JSON.stringify(active, null, 2), 'utf-8');
84
+ return { applied: true, from: active.previous, to: active.championId };
85
+ }
86
+ catch (e) {
87
+ return { applied: false, reason: `error: ${e?.message ?? e}` };
88
+ }
89
+ }
90
+ /**
91
+ * Reverse the last apply: point the active policy back at its `previous`
92
+ * champion (reversibility, ADR-177 rollback pointer). No-op if there is no
93
+ * previous. The previous champion's policy is fetched by ref by consumers.
94
+ */
95
+ export function rollbackActivePolicy(cwd, opts = {}) {
96
+ try {
97
+ const activePath = path.join(cwd, '.claude-flow', ACTIVE_POLICY_FILE);
98
+ const current = readJson(activePath);
99
+ if (!current)
100
+ return { applied: false, reason: 'no active policy' };
101
+ if (!current.previous)
102
+ return { applied: false, reason: 'no previous to roll back to' };
103
+ const reverted = {
104
+ championId: current.previous,
105
+ provenanceTier: current.provenanceTier,
106
+ layer: current.layer,
107
+ appliedAt: opts.now ?? Date.now(),
108
+ previous: null,
109
+ rolledBack: true,
110
+ };
111
+ fs.writeFileSync(activePath, JSON.stringify(reverted, null, 2), 'utf-8');
112
+ return { applied: true, from: current.championId, to: reverted.championId };
113
+ }
114
+ catch (e) {
115
+ return { applied: false, reason: `error: ${e?.message ?? e}` };
116
+ }
117
+ }
118
+ /** The champion routing/agents should currently use, or null. */
119
+ export function activeChampion(cwd) {
120
+ return readJson(path.join(cwd, '.claude-flow', ACTIVE_POLICY_FILE));
121
+ }
122
+ //# sourceMappingURL=harness-feedback-applier.js.map