detectkit 0.17.0__tar.gz → 0.18.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. {detectkit-0.17.0/detectkit.egg-info → detectkit-0.18.0}/PKG-INFO +1 -1
  2. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/__init__.py +1 -1
  3. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/rules/detectors.md +2 -1
  4. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/statistical/_windowed.py +15 -3
  5. {detectkit-0.17.0 → detectkit-0.18.0/detectkit.egg-info}/PKG-INFO +1 -1
  6. {detectkit-0.17.0 → detectkit-0.18.0}/LICENSE +0 -0
  7. {detectkit-0.17.0 → detectkit-0.18.0}/MANIFEST.in +0 -0
  8. {detectkit-0.17.0 → detectkit-0.18.0}/README.md +0 -0
  9. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/__init__.py +0 -0
  10. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/__init__.py +0 -0
  11. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/base.py +0 -0
  12. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/branding.py +0 -0
  13. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/email.py +0 -0
  14. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/factory.py +0 -0
  15. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/mattermost.py +0 -0
  16. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/slack.py +0 -0
  17. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/telegram.py +0 -0
  18. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/channels/webhook.py +0 -0
  19. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/__init__.py +0 -0
  20. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/_base.py +0 -0
  21. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/_cooldown.py +0 -0
  22. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/_decision.py +0 -0
  23. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/_dispatch.py +0 -0
  24. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/_recovery.py +0 -0
  25. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/_types.py +0 -0
  26. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/alerting/orchestrator/orchestrator.py +0 -0
  27. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/__init__.py +0 -0
  28. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/_output.py +0 -0
  29. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/CLAUDE.section.md +0 -0
  30. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/rules/alerting.md +0 -0
  31. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/rules/cli.md +0 -0
  32. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/rules/metrics.md +0 -0
  33. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/rules/overview.md +0 -0
  34. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/rules/project.md +0 -0
  35. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/skills/dtk-feedback/SKILL.md +0 -0
  36. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/skills/dtk-new-metric/SKILL.md +0 -0
  37. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/assets/claude/skills/dtk-setup-project/SKILL.md +0 -0
  38. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/__init__.py +0 -0
  39. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/clean.py +0 -0
  40. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/init.py +0 -0
  41. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/init_claude.py +0 -0
  42. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/run.py +0 -0
  43. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/test_alert.py +0 -0
  44. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/commands/unlock.py +0 -0
  45. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/cli/main.py +0 -0
  46. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/config/__init__.py +0 -0
  47. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/config/metric_config.py +0 -0
  48. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/config/profile.py +0 -0
  49. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/config/project_config.py +0 -0
  50. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/config/validator.py +0 -0
  51. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/core/__init__.py +0 -0
  52. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/core/interval.py +0 -0
  53. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/core/models.py +0 -0
  54. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/__init__.py +0 -0
  55. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/_sql_manager.py +0 -0
  56. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/clickhouse_manager.py +0 -0
  57. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/__init__.py +0 -0
  58. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_alert_states.py +0 -0
  59. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_base.py +0 -0
  60. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_datapoints.py +0 -0
  61. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_detections.py +0 -0
  62. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_maintenance.py +0 -0
  63. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_metrics.py +0 -0
  64. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_schema.py +0 -0
  65. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/_tasks.py +0 -0
  66. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/internal_tables/manager.py +0 -0
  67. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/manager.py +0 -0
  68. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/mysql_manager.py +0 -0
  69. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/postgres_manager.py +0 -0
  70. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/database/tables.py +0 -0
  71. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/__init__.py +0 -0
  72. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/base.py +0 -0
  73. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/factory.py +0 -0
  74. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/seasonality.py +0 -0
  75. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/statistical/__init__.py +0 -0
  76. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/statistical/iqr.py +0 -0
  77. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/statistical/mad.py +0 -0
  78. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/statistical/manual_bounds.py +0 -0
  79. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/detectors/statistical/zscore.py +0 -0
  80. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/loaders/__init__.py +0 -0
  81. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/loaders/metric_loader.py +0 -0
  82. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/loaders/query_template.py +0 -0
  83. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/__init__.py +0 -0
  84. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/error_dispatch.py +0 -0
  85. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/__init__.py +0 -0
  86. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/_alert_step.py +0 -0
  87. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/_base.py +0 -0
  88. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/_detect_step.py +0 -0
  89. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/_load_step.py +0 -0
  90. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/_types.py +0 -0
  91. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/orchestration/task_manager/manager.py +0 -0
  92. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/utils/__init__.py +0 -0
  93. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/utils/datetime_utils.py +0 -0
  94. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/utils/env_interpolation.py +0 -0
  95. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/utils/json_utils.py +0 -0
  96. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit/utils/stats.py +0 -0
  97. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit.egg-info/SOURCES.txt +0 -0
  98. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit.egg-info/dependency_links.txt +0 -0
  99. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit.egg-info/entry_points.txt +0 -0
  100. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit.egg-info/requires.txt +0 -0
  101. {detectkit-0.17.0 → detectkit-0.18.0}/detectkit.egg-info/top_level.txt +0 -0
  102. {detectkit-0.17.0 → detectkit-0.18.0}/pyproject.toml +0 -0
  103. {detectkit-0.17.0 → detectkit-0.18.0}/requirements.txt +0 -0
  104. {detectkit-0.17.0 → detectkit-0.18.0}/setup.cfg +0 -0
  105. {detectkit-0.17.0 → detectkit-0.18.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: detectkit
3
- Version: 0.17.0
3
+ Version: 0.18.0
4
4
  Summary: Metric monitoring with automatic anomaly detection
5
5
  Author: detectkit team
6
6
  License: MIT
@@ -4,7 +4,7 @@ detectk - Anomaly Detection for Time-Series Metrics
4
4
  A Python library for data analysts and engineers to monitor metrics with automatic anomaly detection.
5
5
  """
6
6
 
7
- __version__ = "0.17.0"
7
+ __version__ = "0.18.0"
8
8
 
9
9
  from detectkit.core.interval import Interval
10
10
  from detectkit.core.models import ColumnDefinition, TableModel
@@ -126,7 +126,8 @@ every point starts to look "below" → false alerts. Two shared params fix this:
126
126
  - `window_weights: exponential` + `half_life: "3d"` — recent points weigh more,
127
127
  so the interval follows the new normal. `half_life` is the age at which a
128
128
  point's weight halves (int = points; `"3d"`/`"12h"` converted via the grid
129
- step; default `window_size/20`). `linear` weighting is also available.
129
+ step; default `max(window_size/20, min_samples/2)`). `linear` weighting is
130
+ also available.
130
131
  - `detrend: linear` — removes a robust in-window linear trend before computing
131
132
  statistics; gradual drift no longer pulls the metric out of its interval,
132
133
  while sharp deviations are still caught.
@@ -73,7 +73,9 @@ class WindowedStatDetector(BaseDetector):
73
73
  half_life (int | str | None): For exponential weights: the age at
74
74
  which a point's weight halves. Integer = points, string =
75
75
  duration ("1d", "12h", parsed against the data grid step).
76
- Default None = window_size / 20.
76
+ Default None = max(window_size / 20, min_samples / 2) points —
77
+ the window/20 adaptation horizon, floored so the effective
78
+ (weighted) sample size never drops below the raw min_samples gate.
77
79
  weight_decay (float | None): Deprecated alias for half_life:
78
80
  per-point multiplier in (0, 1); decay d is equivalent to
79
81
  half_life = ln(0.5)/ln(d) points. Mutually exclusive with
@@ -99,7 +101,10 @@ class WindowedStatDetector(BaseDetector):
99
101
  # v2: σ-equivalent MAD scaling, Hazen-midpoint weighted percentiles,
100
102
  # unified severity convention — same params now produce different
101
103
  # bounds than v1, so the ID must change to force recomputation.
102
- ALGORITHM_VERSION = 2
104
+ # v3: default half_life floored at min_samples/2 (was window_size/20
105
+ # unconditionally) — exponential weighting with an unset half_life now
106
+ # produces different bounds, so the ID must change to recompute.
107
+ ALGORITHM_VERSION = 3
103
108
 
104
109
  def __init__(
105
110
  self,
@@ -291,7 +296,14 @@ class WindowedStatDetector(BaseDetector):
291
296
  # decay d per point <=> half-life ln(0.5)/ln(d) points
292
297
  return math.log(0.5) / math.log(weight_decay)
293
298
  if half_life is None:
294
- return max(window_size / 20.0, 1.0)
299
+ # /20 preserves the adaptation horizon the large-window trending
300
+ # recipe is tuned for (window 8640 -> 432 pts ≈ "3d"); the
301
+ # min_samples/2 floor keeps the effective (Kish) sample size at
302
+ # parity with the raw min_samples gate (exponential-window ESS
303
+ # ≈ 2.9·half_life), so small/default windows aren't more
304
+ # trigger-happy than the legacy weight_decay=0.95 default this
305
+ # replaced (window 100: 5 pts/ESS≈14 -> 15 pts/ESS≈42).
306
+ return max(window_size / 20.0, self.params["min_samples"] / 2.0, 1.0)
295
307
  if isinstance(half_life, int):
296
308
  return float(half_life)
297
309
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: detectkit
3
- Version: 0.17.0
3
+ Version: 0.18.0
4
4
  Summary: Metric monitoring with automatic anomaly detection
5
5
  Author: detectkit team
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes