Write an audit receipt to QODEX_RECEIPT_FILE (set by the scheduler) from ground-truth * signals: the git diff + the verify ledger. Status/PR come from the model's headline (a * checkable claim); the FACTS (files, checks) are what QodeX measured. Best-effort.
(opts: { reachedFinal: boolean; merged: boolean; finalContent: string; changedFiles: string[]; signal?: AbortSignal })
| 874 | ); |
| 875 | await writeCandidate(candidate); |
| 876 | capturedThisRun = true; |
| 877 | await recordLearningEvent({ event: 'capture', name: candidate.name, confidence }); |
| 878 | // Code-graph grounding: how much of this skill references symbols that really exist here. |
| 879 | let fitSuffix = ''; |
| 880 | try { |
| 881 | const { getCodeGraphDB } = await import('../codegraph/tools.js'); |
| 882 | const db = getCodeGraphDB(); |
| 883 | if (db) { |
| 884 | const { extractSymbolHints, codebaseFitScore } = await import('../skills/learning/codebase-fit.js'); |
| 885 | const fit = codebaseFitScore(extractSymbolHints(candidate.skillMd), n => db.findSymbolsByName(n, undefined, 1).length > 0); |
| 886 | if (!fit.noSignal) fitSuffix = ` · codebase-fit ${Math.round(fit.score * 100)}%`; |
| 887 | } |
| 888 | } catch { /* code graph optional */ } |
| 889 | const draftSuffix = draft ? ` · ${draft.steps.length}-step draft` : ''; |
| 890 | yield { type: 'notice', data: { message: `🎓 Captured candidate skill "${candidate.name}" (confidence ${confidence}/100${fitSuffix}${draftSuffix}) — review with \`qodex skill candidates\`, promote with \`qodex skill promote ${candidate.name}\`.` } }; |
| 891 | |
| 892 | // Auto-Evaluation (opt-in): immediately replay the captured skill in a clean |
| 893 | // worktree and record whether it produces verified code. Costs a model call + |
| 894 | // worktree, so it's behind learning.autoEval. Best-effort — the task already |
| 895 | // succeeded; an eval failure here never affects it. |
| 896 | if (learningCfg.autoEval) { |
| 897 | try { |
| 898 | const { evalSkillMd } = await import('../skills/learning/eval.js'); |
| 899 | const { formatEvalSection, upsertEvalSection, skillContentHash } = await import('../skills/learning/eval-record.js'); |
| 900 | const { candidatesDir } = await import('../skills/learning/candidate-store.js'); |
| 901 | const { result } = await evalSkillMd(this.cwd, candidate.skillMd, { noCache: true }); |
| 902 | if (result) { |
| 903 | const fsmod = await import('fs'); |
| 904 | const pathmod = await import('path'); |
no test coverage detected