From 1ae4b88e060416b4733efe1ea994a1cc5552586e Mon Sep 17 00:00:00 2001 From: Eneko Ruiz <196690101+eneekoruiz@users.noreply.github.com> Date: Sun, 11 Oct 2026 11:35:31 +0200 Subject: [PATCH] fix: skip non-object skill execution JSONL rows --- scripts/lib/skill-evolution/tracker.js | 5 ++++- tests/lib/skill-evolution.test.js | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/scripts/lib/skill-evolution/tracker.js b/scripts/lib/skill-evolution/tracker.js index 0ea0ba1cc..8e6d48b10 100644 --- a/scripts/lib/skill-evolution/tracker.js +++ b/scripts/lib/skill-evolution/tracker.js @@ -102,7 +102,10 @@ function readJsonl(filePath) { .filter(Boolean) .reduce((rows, line) => { try { - rows.push(JSON.parse(line)); + const record = JSON.parse(line); + if (record && typeof record === 'object' && !Array.isArray(record)) { + rows.push(record); + } } catch { // Ignore malformed rows so analytics remain best-effort. } diff --git a/tests/lib/skill-evolution.test.js b/tests/lib/skill-evolution.test.js index f2dd4e6ec..3279d0dd4 100644 --- a/tests/lib/skill-evolution.test.js +++ b/tests/lib/skill-evolution.test.js @@ -294,13 +294,30 @@ function runTests() { duration_ms: 1, user_feedback: 'accepted', recorded_at: '2026-03-15T11:45:00.000Z', - })}\n{bad-json}\n`, + })}\n{bad-json}\nnull\n42\nfalse\n"not a record"\n[]\n`, 'utf8' ); const records = tracker.readSkillExecutionRecords({ runsFilePath: malformedRunsFile }); assert.strictEqual(records.length, 1); assert.strictEqual(records[0].skill_id, 'alpha'); + const report = health.collectSkillHealth({ + repoRoot, homeDir, runsFilePath: malformedRunsFile, now, + }); + assert.strictEqual(report.skills.find(skill => skill.skill_id === 'alpha').run_count_30d, 1); + + const result = runCli([ + '--json', + '--skills-root', skillsRoot, + '--learned-root', learnedRoot, + '--imported-root', importedRoot, + '--home', homeDir, + '--runs-file', malformedRunsFile, + '--now', now, + ]); + assert.strictEqual(result.status, 0, result.stderr); + const payload = JSON.parse(result.stdout); + assert.strictEqual(payload.skills.find(skill => skill.skill_id === 'alpha').run_count_30d, 1); })) passed++; else failed++; if (test('preserves zero-valued telemetry fields during normalization', () => {