Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion scripts/compute-kpi.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,15 @@ const latencies = [];
let exchanges = 0;
let failures = 0;

for (const line of lines) {
for (const [index, line] of lines.entries()) {
let record;
try {
record = JSON.parse(line);
} catch {
if (/^\s*[\[{]/.test(line)) {
console.error(`Malformed JSON in KPI log line ${index + 1}.`);
process.exit(1);
Comment on lines +30 to +32

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Malformed-JSON diagnostic reports wrong line number

filter(Boolean) drops blank lines before the loop, so the iteration index no longer matches the file line. When a blank line precedes a malformed record, Malformed JSON in KPI log line ${index + 1} names the wrong line and sends an operator to the wrong place.

Prompt for agents
The malformed-JSON diagnostic in scripts/compute-kpi.mjs reports a line number derived from the index of the post-filter array. Line 20 builds `lines` as `text.split("\n").filter(Boolean)`, which removes empty lines, so `index` from `lines.entries()` (line 25) no longer corresponds to the actual line number in the source file. When blank lines appear before a malformed record, the number in `Malformed JSON in KPI log line ${index + 1}` (line 31) is off. Fix by tracking the true line number, e.g. iterate over the unfiltered `text.split("\n")` result with its index and skip empty lines inside the loop, so the reported line number matches the file.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

}
Comment on lines +30 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Bracket-prefixed Wrangler diagnostics can fail closed

The new guard treats any non-parseable line starting with { or [ as fatal. Wrangler tail can emit bracket-prefixed diagnostic lines like [wrangler:info] ...; such a line would now exit 1, contradicting the intent to tolerate diagnostic noise. Depends on the actual capture format — confirm the tail output never produces bracket-prefixed non-JSON lines.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

// Wrangler tail can include non-JSON diagnostic noise; preserve that tolerance.
continue;
}
Expand Down
19 changes: 19 additions & 0 deletions test/compute-kpi-input-integrity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ describe("direct KPI computation input integrity", () => {
}
});

it("rejects malformed JSON-looking lines instead of silently dropping KPI evidence", () => {
const dir = mkdtempSync(join(tmpdir(), "noema-compute-kpi-"));
try {
const logPath = join(dir, "exchange-30d.ndjson");
writeFileSync(
logPath,
'{"event":"http_request","route":"/exchange","status_code":500,"latency_ms":120\n',
);

const result = runComputeKpi(logPath);

expect(result.status).toBe(1);
expect(result.stderr).toContain("Malformed JSON in KPI log line 1");
expect(result.stdout).toBe("");
} finally {
rmSync(dir, { recursive: true, force: true });
}
});

it("preserves valid UTF-8 metrics and ignores non-JSON lines", () => {
const dir = mkdtempSync(join(tmpdir(), "noema-compute-kpi-"));
try {
Expand Down
Loading