Commit History
-
[NOTICKET] anomaly: name the anomalous rows + a flag-rate quality verdict (D-3)
analyze_anomaly's records carried only the scored numeric columns plus a score, so "which units look unusual?" could never name a unit; and it was the only ML tool with no quality block, so an 86%-flagged run reached the assembler as silence. - Add optional label_columns: identifier columns carried into each record (identifiers first), never fed to the model. Planner guidance to pass the id column follows on Rifqi's side (decided shape (a), tool-side). - Add the reserved quality block: metric anomaly_rate, weak only ABOVE a 0.5 ceiling. A20's flag-rate finding was re-measured, not re-assumed -- clean noise flags 0.14-0.22 (mean 0.17, p95 0.22), a genuine 30%-outlier frame 0.30, the demo's degenerate run 0.86 -- so 0.5 clears the noise floor and a real finding yet still catches "most rows flagged"; the note states the rate plainly either way. Logic in _flag_rate_quality() so both branches are unit-testable (the fit can't be pushed past 0.5 via contamination). PR-0 from…ae50194
-
[NOTICKET] anomaly: bound the returned sample at source, not just the assembler
analyze_anomaly's `anomalies` list could carry up to 200 records (all scored columns + score each). A30 capped the same bloat at the assembler (what reaches the LLM), but the tool output is ALSO persisted to results_snapshot and Langfuse-traced, so the 50k blob still landed there. Cap _MAX_ANOMALY_ROWS 200 -> 50 (a bounded top-by-score SAMPLE, not the full set) and add anomalies_total / anomalies_shown so "N of M" stays honest. The exact count (n_anomalies), rate, and chart are unchanged. Defense-in-depth with A30's assembler cap, not a duplicate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>a2089ed
-
[NOTICKET] feat(tools): analyze_anomaly (Isolation Forest) — second ML tool, DEFERRED
analyze_anomaly: scores rows across numeric column_ids with a scikit-learn IsolationForest (fit offloaded via run_fit, fixed random_state), flags outliers, returns summary + flagged rows + a scatter with anomaly points highlighted (reserved 'charts' key). output_kind 'stats' (dict), mirroring analyze_forecast's shape. Registered DEFERRED via spec_from_model. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>9f3267d