Dead Code Removed: Deleted unused _VALID_LEVELS constant in tsqc/checker.py, removed redundant inner import warnings as _warnings in _normalize_timestamps, and dropped unused **kwargs from build_timeline_figure() in tsqc/viz/timeline.py.
Restored data/ Directory: Re-created data/ at repo root for generated example datasets (git-ignored). All three generators now write CSVs there; notebooks and smoke test reference this location.
Example Notebooks Fixed: examples/solar_farm.ipynb and examples/oilfield.ipynb now work end-to-end — generator subprocess paths and YAML rules paths correctly point to synthetic_data_generation/.
CI Least-Privilege Permissions: Added explicit contents: read workflow permissions to ci.yml, resolving all CodeQL actions/missing-workflow-permissions alerts. (#55)
Deploy Fix: Corrected the apt package name in the GitHub Pages deploy workflow from libzlib1g-dev to zlib1g-dev, which caused the Pages build to fail. (#51)
Vectorized QC Hot Path: Rewrote the core check loop for vectorized pandas operations, dramatically improving performance on large multi-tag datasets. (#50)
SEO/AEO Documentation Overhaul: Added structured data (FAQPage JSON-LD), llms.txt/llms-full.txt, robots.txt, and a search-friendly sitemap to the documentation site. (#50)
Windows Console Compatibility: Replaced non-ASCII → characters in generate_solar_data.py and generate_hydro_data.py output, which crashed with UnicodeEncodeError on Windows (cp1252) consoles.
Smoke Test Rules Path: synthetic_data_generation/smoke_test.py now resolves hydro_rules.yaml relative to its own directory instead of a non-existent data/ path.
Contributing Guide: Fixed the repository clone URL and aligned the documented coverage threshold (75%) with CI enforcement.
Flatline Value in Reasons: The FlatlineRule now includes the actual stuck value in the reason string, formatted as flatline @ 42.5000 instead of just flatline. This provides immediate visibility into the severity of the flatline condition without requiring cross-reference to raw data. Special values (NaN, inf, -inf) are handled gracefully. Implemented via new get_reason() method in Rule base class, designed to be extensible for future rules. (#46)
Renamed External Quality Reason Prefix: Changed the reason string prefix from external_quality_value: to source_data_quality: for clearer user-facing semantics. The parameter names (external_quality_col, quality_mode) remain unchanged. (#46)
Hover Tooltip Label Update: Timeline chart hover tooltips now show Reason: instead of Cause: for consistency with the quality_reasons column naming convention. (#46)
New Method: Rule.get_reason(series, idx) — Override this method in custom rules to include contextual information (e.g., actual values) in reason strings. Default implementation returns self.name for backward compatibility.
FlatlineRule: Now overrides get_reason() to append the flatline value with 4 decimal places.
YAML Config Validation: YAML rule files are now batch-validated before construction. All errors (unknown top-level keys, misspelled check names, missing required params, type mismatches) are collected and reported in a single ValueError with location paths. Unknown keys get fuzzy-match suggestions via difflib.get_close_matches(). (#26)
OutlierRule: New built-in statistical outlier detection rule with three configurable methods:
zscore: Classic (value - mean) / std — best for normally distributed data
Critical: Add missing OutlierRule import in tests/test_rules.py — previously caused 19 OutlierRule tests to fail with NameError
Fix test_global_zscore_flags_outlier: Increase sample size from 10 to 21 points to make z-score > 3.0 mathematically achievable (with n=10, max z-score is ~2.85)
Fix test_rolling_mad_flags_spike: Add Gaussian jitter to constant baseline to prevent MAD=0 (which causes NaN scores)
External Quality Column (external_quality_col): Intake a pre-existing quality/status column from SCADA historians and either use it exclusively (quality_mode="exclusive") or merge it with internal rules (quality_mode="combined"). Value-to-level mapping via YAML quality_map section or quality_map= dict parameter. Unmapped values become bad. Configure via quality_mode="none" to ignore the external column entirely. (#PR)
Column Conflict Auto-Rename: When the external quality column name matches the default output column name (e.g. both named quality), the output is automatically renamed to qc_quality / qc_quality_reasons and the input column is preserved. A warning is issued.
FlatlineRule: Added optional min_duration parameter. Suppresses flags for flat runs shorter than the given duration (pandas offset string). Useful when short-lived flat periods are normal (e.g. pump starts, cloud edges).
DeltaRule: Replaced single threshold parameter with two independent thresholds:
max_delta: flags when absolute change is too large (sensor spike / step change)
min_delta: flags when absolute change is too small (stuck / frozen sensor)
At least one of min_delta or max_delta must be provided
Breaking change: old threshold parameter removed; existing YAML configs must be updated