rlhf-feedback-loop 0.5.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 (73) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +21 -0
  3. package/README.md +308 -0
  4. package/adapters/README.md +8 -0
  5. package/adapters/amp/skills/rlhf-feedback/SKILL.md +20 -0
  6. package/adapters/chatgpt/INSTALL.md +80 -0
  7. package/adapters/chatgpt/openapi.yaml +292 -0
  8. package/adapters/claude/.mcp.json +8 -0
  9. package/adapters/codex/config.toml +4 -0
  10. package/adapters/gemini/function-declarations.json +95 -0
  11. package/adapters/mcp/server-stdio.js +444 -0
  12. package/bin/cli.js +167 -0
  13. package/config/mcp-allowlists.json +29 -0
  14. package/config/policy-bundles/constrained-v1.json +53 -0
  15. package/config/policy-bundles/default-v1.json +80 -0
  16. package/config/rubrics/default-v1.json +52 -0
  17. package/config/subagent-profiles.json +32 -0
  18. package/openapi/openapi.yaml +292 -0
  19. package/package.json +91 -0
  20. package/plugins/amp-skill/INSTALL.md +52 -0
  21. package/plugins/amp-skill/SKILL.md +31 -0
  22. package/plugins/claude-skill/INSTALL.md +55 -0
  23. package/plugins/claude-skill/SKILL.md +46 -0
  24. package/plugins/codex-profile/AGENTS.md +20 -0
  25. package/plugins/codex-profile/INSTALL.md +57 -0
  26. package/plugins/gemini-extension/INSTALL.md +74 -0
  27. package/plugins/gemini-extension/gemini_prompt.txt +10 -0
  28. package/plugins/gemini-extension/tool_contract.json +28 -0
  29. package/scripts/billing.js +471 -0
  30. package/scripts/budget-guard.js +173 -0
  31. package/scripts/code-reasoning.js +307 -0
  32. package/scripts/context-engine.js +547 -0
  33. package/scripts/contextfs.js +513 -0
  34. package/scripts/contract-audit.js +198 -0
  35. package/scripts/dpo-optimizer.js +208 -0
  36. package/scripts/export-dpo-pairs.js +316 -0
  37. package/scripts/export-training.js +448 -0
  38. package/scripts/feedback-attribution.js +313 -0
  39. package/scripts/feedback-inbox-read.js +162 -0
  40. package/scripts/feedback-loop.js +838 -0
  41. package/scripts/feedback-schema.js +300 -0
  42. package/scripts/feedback-to-memory.js +165 -0
  43. package/scripts/feedback-to-rules.js +109 -0
  44. package/scripts/generate-paperbanana-diagrams.sh +99 -0
  45. package/scripts/hybrid-feedback-context.js +676 -0
  46. package/scripts/intent-router.js +164 -0
  47. package/scripts/mcp-policy.js +92 -0
  48. package/scripts/meta-policy.js +194 -0
  49. package/scripts/plan-gate.js +154 -0
  50. package/scripts/prove-adapters.js +364 -0
  51. package/scripts/prove-attribution.js +364 -0
  52. package/scripts/prove-automation.js +393 -0
  53. package/scripts/prove-data-quality.js +219 -0
  54. package/scripts/prove-intelligence.js +256 -0
  55. package/scripts/prove-lancedb.js +370 -0
  56. package/scripts/prove-loop-closure.js +255 -0
  57. package/scripts/prove-rlaif.js +404 -0
  58. package/scripts/prove-subway-upgrades.js +250 -0
  59. package/scripts/prove-training-export.js +324 -0
  60. package/scripts/prove-v2-milestone.js +273 -0
  61. package/scripts/prove-v3-milestone.js +381 -0
  62. package/scripts/rlaif-self-audit.js +123 -0
  63. package/scripts/rubric-engine.js +230 -0
  64. package/scripts/self-heal.js +127 -0
  65. package/scripts/self-healing-check.js +111 -0
  66. package/scripts/skill-quality-tracker.js +284 -0
  67. package/scripts/subagent-profiles.js +79 -0
  68. package/scripts/sync-gh-secrets-from-env.sh +29 -0
  69. package/scripts/thompson-sampling.js +331 -0
  70. package/scripts/train_from_feedback.py +914 -0
  71. package/scripts/validate-feedback.js +580 -0
  72. package/scripts/vector-store.js +100 -0
  73. package/src/api/server.js +497 -0
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ const PROJECT_ROOT = path.join(__dirname, '..');
6
+ const FEEDBACK_DIR = process.env.RLHF_FEEDBACK_DIR || path.join(PROJECT_ROOT, '.claude', 'memory', 'feedback');
7
+ const LEDGER_PATH = path.join(FEEDBACK_DIR, 'budget-ledger.json');
8
+ const LOCK_PATH = `${LEDGER_PATH}.lock`;
9
+
10
+ function parseMonthlyBudget(rawValue) {
11
+ const parsed = Number(rawValue);
12
+ if (!Number.isFinite(parsed) || parsed <= 0) {
13
+ throw new Error(`Invalid RLHF_MONTHLY_BUDGET_USD value: '${rawValue}'`);
14
+ }
15
+ return parsed;
16
+ }
17
+
18
+ function getMonthlyBudget() {
19
+ const rawValue = process.env.RLHF_MONTHLY_BUDGET_USD || '10';
20
+ return parseMonthlyBudget(rawValue);
21
+ }
22
+
23
+ function currentMonthKey() {
24
+ const now = new Date();
25
+ return `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, '0')}`;
26
+ }
27
+
28
+ function loadLedger() {
29
+ if (!fs.existsSync(LEDGER_PATH)) return { months: {} };
30
+ return JSON.parse(fs.readFileSync(LEDGER_PATH, 'utf-8'));
31
+ }
32
+
33
+ function saveLedger(ledger) {
34
+ fs.mkdirSync(path.dirname(LEDGER_PATH), { recursive: true });
35
+ fs.writeFileSync(LEDGER_PATH, `${JSON.stringify(ledger, null, 2)}\n`);
36
+ }
37
+
38
+ function blockMs(ms) {
39
+ const start = Date.now();
40
+ while (Date.now() - start < ms) {
41
+ // Intentional synchronous short wait while lock clears.
42
+ }
43
+ }
44
+
45
+ function acquireLock({ timeoutMs = 5000, staleMs = 15000 } = {}) {
46
+ const startedAt = Date.now();
47
+ fs.mkdirSync(path.dirname(LOCK_PATH), { recursive: true });
48
+
49
+ while (true) {
50
+ try {
51
+ return fs.openSync(LOCK_PATH, 'wx');
52
+ } catch (err) {
53
+ if (err.code !== 'EEXIST') throw err;
54
+
55
+ try {
56
+ const stat = fs.statSync(LOCK_PATH);
57
+ if (Date.now() - stat.mtimeMs > staleMs) {
58
+ fs.rmSync(LOCK_PATH, { force: true });
59
+ continue;
60
+ }
61
+ } catch {
62
+ // lock disappeared between retries
63
+ }
64
+
65
+ if (Date.now() - startedAt > timeoutMs) {
66
+ throw new Error('Could not acquire budget ledger lock');
67
+ }
68
+ blockMs(20);
69
+ }
70
+ }
71
+ }
72
+
73
+ function releaseLock(lockFd) {
74
+ try {
75
+ fs.closeSync(lockFd);
76
+ } finally {
77
+ fs.rmSync(LOCK_PATH, { force: true });
78
+ }
79
+ }
80
+
81
+ function addSpend({ amountUsd, source, note }) {
82
+ if (!Number.isFinite(amountUsd) || amountUsd < 0) {
83
+ throw new Error('amountUsd must be a non-negative number');
84
+ }
85
+
86
+ const budgetUsd = getMonthlyBudget();
87
+ const lockFd = acquireLock();
88
+ try {
89
+ const ledger = loadLedger();
90
+ const month = currentMonthKey();
91
+ if (!ledger.months[month]) {
92
+ ledger.months[month] = {
93
+ totalUsd: 0,
94
+ entries: [],
95
+ };
96
+ }
97
+
98
+ const nextTotal = ledger.months[month].totalUsd + amountUsd;
99
+ if (nextTotal > budgetUsd) {
100
+ throw new Error(`Budget exceeded: ${nextTotal.toFixed(2)} > ${budgetUsd.toFixed(2)} USD/month`);
101
+ }
102
+
103
+ ledger.months[month].totalUsd = nextTotal;
104
+ ledger.months[month].entries.push({
105
+ ts: new Date().toISOString(),
106
+ source: source || 'unknown',
107
+ note: note || '',
108
+ amountUsd,
109
+ });
110
+
111
+ saveLedger(ledger);
112
+ return {
113
+ month,
114
+ totalUsd: ledger.months[month].totalUsd,
115
+ budgetUsd,
116
+ };
117
+ } finally {
118
+ releaseLock(lockFd);
119
+ }
120
+ }
121
+
122
+ function getBudgetStatus() {
123
+ const budgetUsd = getMonthlyBudget();
124
+ const ledger = loadLedger();
125
+ const month = currentMonthKey();
126
+ const total = ledger.months[month] ? ledger.months[month].totalUsd : 0;
127
+ return {
128
+ month,
129
+ totalUsd: total,
130
+ budgetUsd,
131
+ remainingUsd: Math.max(0, budgetUsd - total),
132
+ };
133
+ }
134
+
135
+ function runCli() {
136
+ const args = process.argv.slice(2);
137
+ if (args.includes('--status')) {
138
+ console.log(JSON.stringify(getBudgetStatus(), null, 2));
139
+ return;
140
+ }
141
+
142
+ const addArg = args.find((a) => a.startsWith('--add='));
143
+ if (!addArg) {
144
+ console.log('Usage: node scripts/budget-guard.js --status');
145
+ console.log('Usage: node scripts/budget-guard.js --add=0.15 --source=paperbanana --note="diagram generation"');
146
+ process.exit(1);
147
+ }
148
+
149
+ const amountUsd = Number(addArg.replace('--add=', ''));
150
+ const sourceArg = args.find((a) => a.startsWith('--source='));
151
+ const noteArg = args.find((a) => a.startsWith('--note='));
152
+
153
+ const result = addSpend({
154
+ amountUsd,
155
+ source: sourceArg ? sourceArg.replace('--source=', '') : 'unknown',
156
+ note: noteArg ? noteArg.replace('--note=', '') : '',
157
+ });
158
+
159
+ console.log(JSON.stringify(result, null, 2));
160
+ }
161
+
162
+ module.exports = {
163
+ addSpend,
164
+ getBudgetStatus,
165
+ getMonthlyBudget,
166
+ parseMonthlyBudget,
167
+ LEDGER_PATH,
168
+ LOCK_PATH,
169
+ };
170
+
171
+ if (require.main === module) {
172
+ runCli();
173
+ }
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agentic Code Reasoning — Structured Trace Engine
4
+ *
5
+ * Based on Meta's "Agentic Code Reasoning" paper (arxiv 2603.01896).
6
+ * Forces structured line-level reasoning instead of pattern-matching guesses.
7
+ *
8
+ * Produces a verification trace for every code change claim, self-heal fix,
9
+ * or DPO pair, requiring explicit evidence for each assertion.
10
+ */
11
+
12
+ const crypto = require('node:crypto');
13
+
14
+ /**
15
+ * @typedef {Object} TraceStep
16
+ * @property {string} location - File path and line range (e.g. "scripts/self-heal.js:49-69")
17
+ * @property {string} claim - What this step asserts about correctness
18
+ * @property {string} evidence - Concrete evidence supporting the claim
19
+ * @property {'verified'|'unverified'|'refuted'} verdict - Assessment of the claim
20
+ */
21
+
22
+ /**
23
+ * @typedef {Object} ReasoningTrace
24
+ * @property {string} traceId - Unique identifier for this trace
25
+ * @property {string} timestamp - ISO 8601 timestamp
26
+ * @property {string} type - Trace type: 'self-heal' | 'dpo-pair' | 'proof-gate' | 'verification'
27
+ * @property {string} subject - What is being verified (script name, pair ID, etc.)
28
+ * @property {TraceStep[]} steps - Ordered reasoning steps
29
+ * @property {string[]} edgeCases - Edge cases explicitly addressed or ruled out
30
+ * @property {Object} summary - Aggregated verdict
31
+ * @property {number} summary.totalSteps - Total reasoning steps
32
+ * @property {number} summary.verified - Steps with verified verdict
33
+ * @property {number} summary.unverified - Steps with unverified verdict
34
+ * @property {number} summary.refuted - Steps with refuted verdict
35
+ * @property {number} summary.confidence - Ratio of verified to total (0-1)
36
+ * @property {boolean} summary.passed - True if confidence >= threshold and refuted === 0
37
+ */
38
+
39
+ const DEFAULT_CONFIDENCE_THRESHOLD = 0.7;
40
+
41
+ function generateTraceId() {
42
+ return `trace-${crypto.randomBytes(6).toString('hex')}`;
43
+ }
44
+
45
+ function createTrace(type, subject) {
46
+ return {
47
+ traceId: generateTraceId(),
48
+ timestamp: new Date().toISOString(),
49
+ type,
50
+ subject,
51
+ steps: [],
52
+ edgeCases: [],
53
+ summary: null,
54
+ };
55
+ }
56
+
57
+ function addStep(trace, { location, claim, evidence, verdict = 'unverified' }) {
58
+ if (!location || !claim) {
59
+ throw new Error('TraceStep requires location and claim');
60
+ }
61
+ const validVerdicts = ['verified', 'unverified', 'refuted'];
62
+ if (!validVerdicts.includes(verdict)) {
63
+ throw new Error(`Invalid verdict: ${verdict}. Must be one of: ${validVerdicts.join(', ')}`);
64
+ }
65
+ trace.steps.push({ location, claim, evidence: evidence || '', verdict });
66
+ return trace;
67
+ }
68
+
69
+ function addEdgeCase(trace, description) {
70
+ if (description) trace.edgeCases.push(description);
71
+ return trace;
72
+ }
73
+
74
+ function finalizeTrace(trace, { confidenceThreshold = DEFAULT_CONFIDENCE_THRESHOLD } = {}) {
75
+ const totalSteps = trace.steps.length;
76
+ const verified = trace.steps.filter((s) => s.verdict === 'verified').length;
77
+ const unverified = trace.steps.filter((s) => s.verdict === 'unverified').length;
78
+ const refuted = trace.steps.filter((s) => s.verdict === 'refuted').length;
79
+ const confidence = totalSteps > 0 ? Math.round((verified / totalSteps) * 1000) / 1000 : 0;
80
+
81
+ trace.summary = {
82
+ totalSteps,
83
+ verified,
84
+ unverified,
85
+ refuted,
86
+ confidence,
87
+ passed: confidence >= confidenceThreshold && refuted === 0,
88
+ };
89
+
90
+ return trace;
91
+ }
92
+
93
+ /**
94
+ * Build a reasoning trace for a self-heal fix execution.
95
+ *
96
+ * @param {Object} fixResult - Result from runFixPlan for a single script
97
+ * @param {string} fixResult.script - Script name
98
+ * @param {string} fixResult.status - 'success' | 'failed'
99
+ * @param {number} fixResult.exitCode
100
+ * @param {string} fixResult.outputTail - Last 2000 chars of output
101
+ * @param {string[]} changedFiles - Files changed by this fix
102
+ * @returns {ReasoningTrace}
103
+ */
104
+ function traceForSelfHealFix(fixResult, changedFiles = []) {
105
+ const trace = createTrace('self-heal', fixResult.script);
106
+
107
+ addStep(trace, {
108
+ location: `npm run ${fixResult.script}`,
109
+ claim: `Fix script "${fixResult.script}" executes without error`,
110
+ evidence: fixResult.status === 'success'
111
+ ? `Exit code ${fixResult.exitCode}, completed in ${fixResult.durationMs}ms`
112
+ : `Exit code ${fixResult.exitCode}, error: ${fixResult.error || 'non-zero exit'}`,
113
+ verdict: fixResult.status === 'success' ? 'verified' : 'refuted',
114
+ });
115
+
116
+ if (changedFiles.length > 0) {
117
+ addStep(trace, {
118
+ location: changedFiles.join(', '),
119
+ claim: `Fix modified ${changedFiles.length} file(s) — changes are intentional`,
120
+ evidence: `Changed: ${changedFiles.join(', ')}`,
121
+ verdict: 'verified',
122
+ });
123
+ } else {
124
+ addStep(trace, {
125
+ location: `npm run ${fixResult.script}`,
126
+ claim: 'Fix produced no file changes (idempotent or no-op)',
127
+ evidence: 'git diff --name-only returned empty after execution',
128
+ verdict: 'verified',
129
+ });
130
+ }
131
+
132
+ const outputTail = (fixResult.outputTail || '').toLowerCase();
133
+ const hasErrors = /error|fail|exception|fatal/i.test(outputTail);
134
+ addStep(trace, {
135
+ location: `npm run ${fixResult.script} (output)`,
136
+ claim: 'Script output contains no error indicators',
137
+ evidence: hasErrors
138
+ ? `Output contains error keywords: ${outputTail.slice(-200)}`
139
+ : 'No error keywords in output tail',
140
+ verdict: hasErrors && fixResult.status === 'success' ? 'unverified' : (hasErrors ? 'refuted' : 'verified'),
141
+ });
142
+
143
+ addEdgeCase(trace, 'Script timeout not triggered (completed within deadline)');
144
+ if (changedFiles.length === 0) {
145
+ addEdgeCase(trace, 'No files changed — fix may already be applied or script is no-op');
146
+ }
147
+
148
+ return finalizeTrace(trace);
149
+ }
150
+
151
+ /**
152
+ * Build a reasoning trace for a DPO preference pair.
153
+ *
154
+ * @param {Object} pair - The DPO pair with prompt, chosen, rejected, metadata
155
+ * @returns {ReasoningTrace}
156
+ */
157
+ function traceForDpoPair(pair) {
158
+ const trace = createTrace('dpo-pair', `${pair.metadata.errorId}->${pair.metadata.learningId}`);
159
+
160
+ addStep(trace, {
161
+ location: `error:${pair.metadata.errorId}`,
162
+ claim: 'Rejected response represents a genuine mistake',
163
+ evidence: `Error title: "${pair.metadata.errorTitle}"`,
164
+ verdict: pair.metadata.errorTitle ? 'verified' : 'unverified',
165
+ });
166
+
167
+ addStep(trace, {
168
+ location: `learning:${pair.metadata.learningId}`,
169
+ claim: 'Chosen response represents a correct approach',
170
+ evidence: `Learning title: "${pair.metadata.learningTitle}"`,
171
+ verdict: pair.metadata.learningTitle ? 'verified' : 'unverified',
172
+ });
173
+
174
+ const matchedKeys = pair.metadata.matchedKeys || [];
175
+ addStep(trace, {
176
+ location: 'domain-matching',
177
+ claim: `Error and learning share domain context (${matchedKeys.length} key(s))`,
178
+ evidence: `Matched keys: [${matchedKeys.join(', ')}], overlap score: ${pair.metadata.overlapScore}`,
179
+ verdict: matchedKeys.length > 0 ? 'verified' : 'refuted',
180
+ });
181
+
182
+ const rubric = pair.metadata.rubric;
183
+ if (rubric) {
184
+ const hasDelta = rubric.weightedDelta != null && rubric.weightedDelta > 0;
185
+ addStep(trace, {
186
+ location: 'rubric-delta',
187
+ claim: 'Learning scores higher than error on rubric (positive delta)',
188
+ evidence: `Learning: ${rubric.learningWeightedScore}, Error: ${rubric.errorWeightedScore}, Delta: ${rubric.weightedDelta}`,
189
+ verdict: hasDelta ? 'verified' : (rubric.weightedDelta === 0 ? 'unverified' : 'refuted'),
190
+ });
191
+
192
+ const failingCriteria = rubric.errorFailingCriteria || rubric.failingCriteria || [];
193
+ if (failingCriteria.length > 0) {
194
+ addStep(trace, {
195
+ location: 'rubric-failures',
196
+ claim: `Error had ${failingCriteria.length} failing rubric criteria`,
197
+ evidence: `Failing: [${failingCriteria.join(', ')}]`,
198
+ verdict: 'verified',
199
+ });
200
+ }
201
+ } else {
202
+ addStep(trace, {
203
+ location: 'rubric-delta',
204
+ claim: 'Rubric scores provide quantitative quality signal',
205
+ evidence: 'No rubric data available for this pair',
206
+ verdict: 'unverified',
207
+ });
208
+ }
209
+
210
+ addStep(trace, {
211
+ location: 'prompt-inference',
212
+ claim: 'Inferred prompt captures the shared scenario correctly',
213
+ evidence: `Prompt: "${pair.prompt}"`,
214
+ verdict: pair.prompt && pair.prompt.length > 10 ? 'verified' : 'unverified',
215
+ });
216
+
217
+ addEdgeCase(trace, 'Pair may lack temporal proximity — error and learning from different sessions');
218
+ addEdgeCase(trace, 'Domain overlap is keyword-based — semantic similarity not verified');
219
+
220
+ return finalizeTrace(trace);
221
+ }
222
+
223
+ /**
224
+ * Build a reasoning trace for a proof harness check.
225
+ *
226
+ * @param {Object} checkResult - A check from the proof report
227
+ * @param {string} checkResult.name - Check name
228
+ * @param {boolean} checkResult.passed - Whether the check passed
229
+ * @param {Object} checkResult.details - Check-specific details
230
+ * @returns {ReasoningTrace}
231
+ */
232
+ function traceForProofCheck(checkResult) {
233
+ const trace = createTrace('proof-gate', checkResult.name);
234
+
235
+ addStep(trace, {
236
+ location: `check:${checkResult.name}`,
237
+ claim: `Proof check "${checkResult.name}" passes`,
238
+ evidence: checkResult.passed
239
+ ? `Passed with details: ${JSON.stringify(checkResult.details)}`
240
+ : `Failed: ${JSON.stringify(checkResult.details)}`,
241
+ verdict: checkResult.passed ? 'verified' : 'refuted',
242
+ });
243
+
244
+ if (checkResult.details) {
245
+ const details = checkResult.details;
246
+ if (details.status !== undefined) {
247
+ addStep(trace, {
248
+ location: `check:${checkResult.name}/status`,
249
+ claim: 'HTTP/response status is expected value',
250
+ evidence: `Status: ${details.status}`,
251
+ verdict: checkResult.passed ? 'verified' : 'refuted',
252
+ });
253
+ }
254
+ if (details.accepted !== undefined) {
255
+ addStep(trace, {
256
+ location: `check:${checkResult.name}/accepted`,
257
+ claim: `Acceptance state is ${details.accepted}`,
258
+ evidence: `accepted=${details.accepted}`,
259
+ verdict: 'verified',
260
+ });
261
+ }
262
+ }
263
+
264
+ return finalizeTrace(trace);
265
+ }
266
+
267
+ /**
268
+ * Aggregate multiple traces into a verification summary.
269
+ *
270
+ * @param {ReasoningTrace[]} traces
271
+ * @returns {Object} Aggregated summary
272
+ */
273
+ function aggregateTraces(traces) {
274
+ const totalTraces = traces.length;
275
+ const passedTraces = traces.filter((t) => t.summary && t.summary.passed).length;
276
+ const allSteps = traces.flatMap((t) => t.steps);
277
+ const totalSteps = allSteps.length;
278
+ const verified = allSteps.filter((s) => s.verdict === 'verified').length;
279
+ const refuted = allSteps.filter((s) => s.verdict === 'refuted').length;
280
+ const avgConfidence = totalTraces > 0
281
+ ? Math.round(traces.reduce((sum, t) => sum + (t.summary ? t.summary.confidence : 0), 0) / totalTraces * 1000) / 1000
282
+ : 0;
283
+
284
+ return {
285
+ totalTraces,
286
+ passedTraces,
287
+ failedTraces: totalTraces - passedTraces,
288
+ totalSteps,
289
+ verified,
290
+ unverified: totalSteps - verified - refuted,
291
+ refuted,
292
+ averageConfidence: avgConfidence,
293
+ allPassed: passedTraces === totalTraces,
294
+ };
295
+ }
296
+
297
+ module.exports = {
298
+ createTrace,
299
+ addStep,
300
+ addEdgeCase,
301
+ finalizeTrace,
302
+ traceForSelfHealFix,
303
+ traceForDpoPair,
304
+ traceForProofCheck,
305
+ aggregateTraces,
306
+ DEFAULT_CONFIDENCE_THRESHOLD,
307
+ };