flowsense-engine 0.4.0__tar.gz → 0.5.1__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 (134) hide show
  1. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/CHANGELOG.md +72 -0
  2. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/MANIFEST.in +1 -0
  3. {flowsense_engine-0.4.0/src/flowsense_engine.egg-info → flowsense_engine-0.5.1}/PKG-INFO +51 -4
  4. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/README.md +49 -3
  5. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/architecture.md +8 -0
  6. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/authentication.md +11 -3
  7. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/grafana.md +25 -2
  8. flowsense_engine-0.5.1/docs/migrating-to-0.5.md +63 -0
  9. flowsense_engine-0.5.1/docs/production-quickstart.md +235 -0
  10. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/prometheus.md +8 -1
  11. flowsense_engine-0.5.1/docs/release-0.5.0.md +48 -0
  12. flowsense_engine-0.5.1/docs/release-0.5.1.md +21 -0
  13. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/releasing.md +6 -5
  14. flowsense_engine-0.5.1/docs/showcase.md +79 -0
  15. flowsense_engine-0.5.1/examples/dags/flowsense_demo.py +48 -0
  16. flowsense_engine-0.5.1/examples/dags/flowsense_showcase.py +91 -0
  17. flowsense_engine-0.5.1/examples/python/production_batch.py +86 -0
  18. flowsense_engine-0.5.1/examples/python/showcase.py +290 -0
  19. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/pyproject.toml +21 -1
  20. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/__init__.py +8 -0
  21. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/__init__.py +8 -0
  22. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/output.py +7 -2
  23. flowsense_engine-0.5.1/src/flowsense/application/policy_document.py +35 -0
  24. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/serialization.py +4 -0
  25. flowsense_engine-0.5.1/src/flowsense/cli/doctor.py +110 -0
  26. flowsense_engine-0.5.1/src/flowsense/cli/main.py +551 -0
  27. flowsense_engine-0.5.1/src/flowsense/cli/policy.py +103 -0
  28. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/__init__.py +2 -0
  29. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/enums.py +6 -0
  30. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/policy.py +6 -0
  31. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/results.py +3 -0
  32. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/drift.py +16 -15
  33. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/client.py +185 -35
  34. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/dto.py +1 -0
  35. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/mcp/server.py +4 -0
  36. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/observability/service.py +23 -2
  37. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1/src/flowsense_engine.egg-info}/PKG-INFO +51 -4
  38. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/SOURCES.txt +17 -0
  39. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/requires.txt +1 -0
  40. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_auth.py +66 -1
  41. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_client.py +208 -12
  42. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_compatibility.py +1 -1
  43. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_contract.py +2 -0
  44. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_resilience.py +4 -1
  45. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_golden.py +1 -1
  46. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_output.py +6 -0
  47. flowsense_engine-0.5.1/tests/test_analysis_policy_document.py +33 -0
  48. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_benchmark_analysis.py +1 -1
  49. flowsense_engine-0.5.1/tests/test_cli.py +778 -0
  50. flowsense_engine-0.5.1/tests/test_cli_policy.py +58 -0
  51. flowsense_engine-0.5.1/tests/test_doctor.py +84 -0
  52. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_domain.py +1 -1
  53. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_drift.py +38 -2
  54. flowsense_engine-0.5.1/tests/test_examples.py +22 -0
  55. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_mcp_integration.py +6 -2
  56. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_mcp_server.py +17 -3
  57. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_package_metadata.py +1 -1
  58. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_policy.py +34 -11
  59. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_prometheus.py +66 -2
  60. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_public_api.py +4 -0
  61. flowsense_engine-0.5.1/tests/test_showcase.py +50 -0
  62. flowsense_engine-0.4.0/src/flowsense/cli/main.py +0 -225
  63. flowsense_engine-0.4.0/tests/test_cli.py +0 -286
  64. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/LICENSE +0 -0
  65. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/alerting.md +0 -0
  66. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/benchmarks.md +0 -0
  67. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/migrating-to-0.3.md +0 -0
  68. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/docs/python-api.md +0 -0
  69. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/setup.cfg +0 -0
  70. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/analysis_engine.py +0 -0
  71. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/analyzer.py +0 -0
  72. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/batch.py +0 -0
  73. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/client.py +0 -0
  74. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/pipeline.py +0 -0
  75. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/ports.py +0 -0
  76. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/request.py +0 -0
  77. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/application/use_cases.py +0 -0
  78. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/cli/__init__.py +0 -0
  79. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/cli/report.py +0 -0
  80. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/collector/__init__.py +0 -0
  81. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/collector/airflow_client.py +0 -0
  82. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/config.py +0 -0
  83. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/exceptions.py +0 -0
  84. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/domain/models.py +0 -0
  85. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/__init__.py +0 -0
  86. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/analyzer.py +0 -0
  87. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/change_point.py +0 -0
  88. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/history.py +0 -0
  89. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/impact.py +0 -0
  90. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/propagation.py +0 -0
  91. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/root_cause.py +0 -0
  92. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/timing.py +0 -0
  93. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/trend.py +0 -0
  94. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/engine/validation.py +0 -0
  95. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/__init__.py +0 -0
  96. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/__init__.py +0 -0
  97. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/auth.py +0 -0
  98. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/config.py +0 -0
  99. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/exceptions.py +0 -0
  100. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/factory.py +0 -0
  101. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/infrastructure/airflow/mapper.py +0 -0
  102. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/mcp/__init__.py +0 -0
  103. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/models/__init__.py +0 -0
  104. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/models/dag_analysis.py +0 -0
  105. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/models/task_run.py +0 -0
  106. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/observability/__init__.py +0 -0
  107. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/observability/prometheus.py +0 -0
  108. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/py.typed +0 -0
  109. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense/version.py +0 -0
  110. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/dependency_links.txt +0 -0
  111. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/entry_points.txt +0 -0
  112. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/src/flowsense_engine.egg-info/top_level.txt +0 -0
  113. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_client_integration.py +0 -0
  114. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_factory.py +0 -0
  115. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_airflow_mapper.py +0 -0
  116. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_pipeline.py +0 -0
  117. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_request.py +0 -0
  118. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analysis_use_case.py +0 -0
  119. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_analyzer.py +0 -0
  120. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_architecture.py +0 -0
  121. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_batch_analysis_output.py +0 -0
  122. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_change_point.py +0 -0
  123. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_cli_report.py +0 -0
  124. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_dag_summary.py +0 -0
  125. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_deprecations.py +0 -0
  126. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_history.py +0 -0
  127. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_impact.py +0 -0
  128. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_library_client.py +0 -0
  129. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_observability_assets.py +0 -0
  130. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_observation_validation.py +0 -0
  131. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_propagation.py +0 -0
  132. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_root_cause.py +0 -0
  133. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_timing.py +0 -0
  134. {flowsense_engine-0.4.0 → flowsense_engine-0.5.1}/tests/test_trend.py +0 -0
@@ -5,6 +5,78 @@ All notable changes to FlowSense are documented in this file. The project uses
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ### Added
9
+
10
+ ### Changed
11
+
12
+ ### Fixed
13
+
14
+ ## [0.5.1] - 2026-09-25
15
+
16
+ ### Added
17
+
18
+ - Six controlled Airflow demo DAGs, each with 20 seeded runs, bounded live
19
+ execution waves, and a read-only execution-evidence verifier.
20
+ - Dedicated multi-DAG showcase dashboard with per-pipeline results and separate
21
+ queued/running activity metrics.
22
+ - FlowSense Engine wordmark in the README and PyPI package description.
23
+
24
+ ### Changed
25
+
26
+ - Overview dashboard now uses instant summary queries, clearer multi-DAG labels,
27
+ and a shorter default history window.
28
+
29
+ ### Fixed
30
+
31
+ - Corrected Airflow 3 GET state filters from `states` to `state`, preventing
32
+ running runs from shrinking the bounded successful-run analysis window.
33
+
34
+ ## [0.5.0] - 2026-09-23
35
+
36
+ ### Added
37
+
38
+ - Added a production quickstart and executable bounded batch-analysis example.
39
+ - Added `flowsense doctor` for safe configuration, Airflow API, authentication,
40
+ and DAG-visibility diagnostics.
41
+ - Added `flowsense dags` for read-only DAG discovery with table and JSON output.
42
+ - Added `flowsense analyze-batch` for bounded multi-DAG CLI analysis with the
43
+ versioned batch JSON contract.
44
+ - Added severity-based CI exit thresholds to batch analysis.
45
+ - Added full analysis-policy configuration to the batch CLI.
46
+ - Added bounded DAG discovery to batch analysis with `--all-dags`,
47
+ `--dag-limit`, and optional paused-DAG inclusion.
48
+ - Added CLI access to the versioned batch output JSON Schema through
49
+ `flowsense schema --document batch`.
50
+ - Added reliable versioned JSON file output to single-DAG analysis through
51
+ `flowsense analyze --output-file`.
52
+ - Added reusable, versioned JSON analysis policies for single and batch CLI
53
+ commands, with explicit command-line overrides and JSON Schema export.
54
+ - Added versioned analysis-policy support to the optional Prometheus metrics
55
+ command and propagated the selected policy through every collection cycle.
56
+ - Added a validated per-cycle history limit to the Prometheus metrics command
57
+ so Airflow collection remains explicitly bounded.
58
+ - Added expanded Ruff quality rules, a 90% CI coverage gate, and graceful MCP
59
+ test skipping when the optional dependency is not installed.
60
+ - Reduced Airflow collection overhead with bounded server-side DAG run filters
61
+ and batched task-instance retrieval, including compatibility fallbacks for
62
+ deployments that do not support the optimized endpoints.
63
+ - Added explicit drift direction and effective MAD fields to analysis results,
64
+ plus configurable relative and absolute dispersion floors.
65
+
66
+ ### Changed
67
+
68
+ - Airflow login tokens are now refreshed once after an unauthorized API
69
+ response, while static bearer, Basic, and custom authentication lifecycles
70
+ remain application-owned.
71
+ - Advanced the analysis output schema to version `1.2` for the new drift and
72
+ policy fields.
73
+
74
+ ### Fixed
75
+
76
+ - Constant and near-constant baselines no longer classify negligible timing
77
+ noise as an automatic critical anomaly when raw MAD is zero or extremely
78
+ small.
79
+
8
80
  ## [0.4.0] - 2026-09-20
9
81
 
10
82
  ### Added
@@ -1,2 +1,3 @@
1
1
  include CHANGELOG.md
2
2
  recursive-include docs *.md
3
+ recursive-include examples *.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowsense-engine
3
- Version: 0.4.0
3
+ Version: 0.5.1
4
4
  Summary: Temporal drift and anomaly detection for Apache Airflow
5
5
  Author: Omer Cengiz
6
6
  License-Expression: Apache-2.0
@@ -28,6 +28,7 @@ Provides-Extra: dev
28
28
  Requires-Dist: build>=1.2; extra == "dev"
29
29
  Requires-Dist: pyright>=1.1.400; extra == "dev"
30
30
  Requires-Dist: pytest>=8.0; extra == "dev"
31
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
31
32
  Requires-Dist: ruff>=0.6; extra == "dev"
32
33
  Provides-Extra: mcp
33
34
  Requires-Dist: mcp[cli]>=2.0; extra == "mcp"
@@ -35,12 +36,18 @@ Dynamic: license-file
35
36
 
36
37
  # FlowSense Engine
37
38
 
39
+ <p align="center">
40
+ <img src="https://raw.githubusercontent.com/omercengiz/flowsense-engine/27f7db5e55bfefbba6e355c53c7c84ff34e6f37b/assets/branding/flowsense-engine-logo-v2.png" alt="FlowSense Engine logo" width="640">
41
+ </p>
42
+
38
43
  Temporal drift, anomaly detection, and dependency-aware propagation analysis for Apache Airflow.
39
44
 
40
- Current package release: `0.4.0`. See [CHANGELOG.md](CHANGELOG.md) for release
45
+ Current package release: `0.5.1`. See [CHANGELOG.md](CHANGELOG.md) for release
41
46
  notes, [docs/architecture.md](docs/architecture.md) for the system architecture,
42
47
  [docs/benchmarks.md](docs/benchmarks.md) for performance measurement, and
43
- [docs/migrating-to-0.3.md](docs/migrating-to-0.3.md) for migration guidance.
48
+ [docs/production-quickstart.md](docs/production-quickstart.md) for a production
49
+ walkthrough. See [docs/migrating-to-0.5.md](docs/migrating-to-0.5.md) for the
50
+ current migration guidance.
44
51
  Maintainers can use [docs/releasing.md](docs/releasing.md) as the release checklist.
45
52
 
46
53
  FlowSense analyzes historical DAG executions to identify abnormal task behavior and trace how anomalies propagate through downstream dependencies.
@@ -153,6 +160,9 @@ Once published on PyPI, install the distribution with:
153
160
  pip install flowsense-engine
154
161
  ```
155
162
 
163
+ For an end-to-end Airflow setup, follow the
164
+ [production quickstart](docs/production-quickstart.md).
165
+
156
166
  The distribution name is `flowsense-engine`; Python imports and CLI commands
157
167
  remain `flowsense`.
158
168
 
@@ -218,9 +228,15 @@ export $(grep -v '^#' .env | xargs)
218
228
  Then run:
219
229
 
220
230
  ```bash
231
+ flowsense doctor
232
+ flowsense dags
221
233
  flowsense analyze <dag_id>
234
+ flowsense analyze-batch <dag_id> [<dag_id> ...]
222
235
  ```
223
236
 
237
+ Both single and batch analysis commands support `--fail-on` for CI severity
238
+ gates.
239
+
224
240
  The CLI report includes a DAG summary and separate tables for task drift,
225
241
  handoff drift, change points, trends, propagation paths, and diagnostics.
226
242
  Results are ordered by severity or subject so repeated analyses remain easy to
@@ -230,14 +246,30 @@ For automation and CI/CD integrations, request the versioned JSON document:
230
246
 
231
247
  ```bash
232
248
  flowsense analyze <dag_id> --output json
249
+ flowsense analyze <dag_id> --output-file flowsense-analysis.json
233
250
  ```
234
251
 
252
+ `--output-file` always writes the versioned JSON contract and avoids relying on
253
+ shell redirection in CI jobs.
254
+
235
255
  CI jobs can also fail when the analysis reaches a selected severity:
236
256
 
237
257
  ```bash
238
258
  flowsense analyze <dag_id> --output json --fail-on high
239
259
  ```
240
260
 
261
+ Store reusable analysis settings in a versioned JSON policy file and share it
262
+ between single and batch analysis:
263
+
264
+ ```bash
265
+ flowsense analyze <dag_id> --policy-file flowsense-policy.json
266
+ flowsense analyze-batch --all-dags --dag-limit 10 \
267
+ --policy-file flowsense-policy.json
268
+ ```
269
+
270
+ Explicit policy options override values loaded from the file. Generate its JSON
271
+ Schema with `flowsense schema --document policy`.
272
+
241
273
  `--fail-on` accepts `medium`, `high`, or `critical`. The report is always
242
274
  written before FlowSense exits: code `0` means the severity is below the
243
275
  threshold, code `2` means the threshold was reached, and code `1` remains
@@ -265,6 +297,8 @@ flowsense analyze <dag_id> --dag-run-id <dag_run_id>
265
297
 
266
298
  The MCP tool exposes the same option as `dag_run_id`. Analysis output includes
267
299
  `current_dag_run_id`; this field was introduced in output schema version `1.1`.
300
+ Output schema version `1.2` adds drift `direction`, the regularized
301
+ `effective_mad`, and the dispersion-floor policy values.
268
302
 
269
303
  The JSON document and MCP tool response share the same serialization contract
270
304
  and include a `schema_version` field. The serializer is also available from the
@@ -279,8 +313,13 @@ The same schema can be emitted without connecting to Airflow:
279
313
 
280
314
  ```bash
281
315
  flowsense schema > flowsense-analysis.schema.json
316
+ flowsense schema --document batch > flowsense-batch.schema.json
282
317
  ```
283
318
 
319
+ The default remains the single-DAG analysis schema. Use `--document batch` to
320
+ emit the versioned batch envelope schema, including successful analyses and
321
+ per-DAG failure records.
322
+
284
323
  This output is deterministic and can be used in CI contract checks, editor
285
324
  tooling, or client code generation.
286
325
 
@@ -332,6 +371,8 @@ policy = AnalysisPolicy(
332
371
  medium_threshold=2.5,
333
372
  high_threshold=4.0,
334
373
  critical_threshold=6.0,
374
+ minimum_relative_dispersion=0.01,
375
+ minimum_absolute_dispersion=0.001,
335
376
  mapped_task_aggregation=MappedTaskAggregation.MAX,
336
377
  change_point_minimum_segment_size=4,
337
378
  change_point_score_threshold=4.0,
@@ -344,6 +385,8 @@ policy = AnalysisPolicy(
344
385
  `baseline_window` limits the number of historical values used before the current
345
386
  run. Mapped task durations can be aggregated with `MAX`, `MEAN`, or `SUM`. The
346
387
  same policy options are available through the CLI and MCP tool.
388
+ The dispersion floors prevent constant or nearly constant baselines from
389
+ turning negligible timing noise into an automatic critical anomaly.
347
390
  Change-point and trend detection can also be disabled independently with
348
391
  `change_point_detection_enabled=False` or `trend_detection_enabled=False`.
349
392
 
@@ -383,7 +426,11 @@ information for a DAG.
383
426
  Run continuous analysis and expose the latest DAG and bounded task-level metrics:
384
427
 
385
428
  ```bash
386
- flowsense serve-metrics example_dag --host 0.0.0.0 --port 9108
429
+ flowsense serve-metrics example_dag \
430
+ --host 0.0.0.0 \
431
+ --port 9108 \
432
+ --history-run-limit 50 \
433
+ --policy-file flowsense-policy.json
387
434
  ```
388
435
 
389
436
  See [docs/prometheus.md](docs/prometheus.md) for the metric contract,
@@ -1,11 +1,17 @@
1
1
  # FlowSense Engine
2
2
 
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/omercengiz/flowsense-engine/27f7db5e55bfefbba6e355c53c7c84ff34e6f37b/assets/branding/flowsense-engine-logo-v2.png" alt="FlowSense Engine logo" width="640">
5
+ </p>
6
+
3
7
  Temporal drift, anomaly detection, and dependency-aware propagation analysis for Apache Airflow.
4
8
 
5
- Current package release: `0.4.0`. See [CHANGELOG.md](CHANGELOG.md) for release
9
+ Current package release: `0.5.1`. See [CHANGELOG.md](CHANGELOG.md) for release
6
10
  notes, [docs/architecture.md](docs/architecture.md) for the system architecture,
7
11
  [docs/benchmarks.md](docs/benchmarks.md) for performance measurement, and
8
- [docs/migrating-to-0.3.md](docs/migrating-to-0.3.md) for migration guidance.
12
+ [docs/production-quickstart.md](docs/production-quickstart.md) for a production
13
+ walkthrough. See [docs/migrating-to-0.5.md](docs/migrating-to-0.5.md) for the
14
+ current migration guidance.
9
15
  Maintainers can use [docs/releasing.md](docs/releasing.md) as the release checklist.
10
16
 
11
17
  FlowSense analyzes historical DAG executions to identify abnormal task behavior and trace how anomalies propagate through downstream dependencies.
@@ -118,6 +124,9 @@ Once published on PyPI, install the distribution with:
118
124
  pip install flowsense-engine
119
125
  ```
120
126
 
127
+ For an end-to-end Airflow setup, follow the
128
+ [production quickstart](docs/production-quickstart.md).
129
+
121
130
  The distribution name is `flowsense-engine`; Python imports and CLI commands
122
131
  remain `flowsense`.
123
132
 
@@ -183,9 +192,15 @@ export $(grep -v '^#' .env | xargs)
183
192
  Then run:
184
193
 
185
194
  ```bash
195
+ flowsense doctor
196
+ flowsense dags
186
197
  flowsense analyze <dag_id>
198
+ flowsense analyze-batch <dag_id> [<dag_id> ...]
187
199
  ```
188
200
 
201
+ Both single and batch analysis commands support `--fail-on` for CI severity
202
+ gates.
203
+
189
204
  The CLI report includes a DAG summary and separate tables for task drift,
190
205
  handoff drift, change points, trends, propagation paths, and diagnostics.
191
206
  Results are ordered by severity or subject so repeated analyses remain easy to
@@ -195,14 +210,30 @@ For automation and CI/CD integrations, request the versioned JSON document:
195
210
 
196
211
  ```bash
197
212
  flowsense analyze <dag_id> --output json
213
+ flowsense analyze <dag_id> --output-file flowsense-analysis.json
198
214
  ```
199
215
 
216
+ `--output-file` always writes the versioned JSON contract and avoids relying on
217
+ shell redirection in CI jobs.
218
+
200
219
  CI jobs can also fail when the analysis reaches a selected severity:
201
220
 
202
221
  ```bash
203
222
  flowsense analyze <dag_id> --output json --fail-on high
204
223
  ```
205
224
 
225
+ Store reusable analysis settings in a versioned JSON policy file and share it
226
+ between single and batch analysis:
227
+
228
+ ```bash
229
+ flowsense analyze <dag_id> --policy-file flowsense-policy.json
230
+ flowsense analyze-batch --all-dags --dag-limit 10 \
231
+ --policy-file flowsense-policy.json
232
+ ```
233
+
234
+ Explicit policy options override values loaded from the file. Generate its JSON
235
+ Schema with `flowsense schema --document policy`.
236
+
206
237
  `--fail-on` accepts `medium`, `high`, or `critical`. The report is always
207
238
  written before FlowSense exits: code `0` means the severity is below the
208
239
  threshold, code `2` means the threshold was reached, and code `1` remains
@@ -230,6 +261,8 @@ flowsense analyze <dag_id> --dag-run-id <dag_run_id>
230
261
 
231
262
  The MCP tool exposes the same option as `dag_run_id`. Analysis output includes
232
263
  `current_dag_run_id`; this field was introduced in output schema version `1.1`.
264
+ Output schema version `1.2` adds drift `direction`, the regularized
265
+ `effective_mad`, and the dispersion-floor policy values.
233
266
 
234
267
  The JSON document and MCP tool response share the same serialization contract
235
268
  and include a `schema_version` field. The serializer is also available from the
@@ -244,8 +277,13 @@ The same schema can be emitted without connecting to Airflow:
244
277
 
245
278
  ```bash
246
279
  flowsense schema > flowsense-analysis.schema.json
280
+ flowsense schema --document batch > flowsense-batch.schema.json
247
281
  ```
248
282
 
283
+ The default remains the single-DAG analysis schema. Use `--document batch` to
284
+ emit the versioned batch envelope schema, including successful analyses and
285
+ per-DAG failure records.
286
+
249
287
  This output is deterministic and can be used in CI contract checks, editor
250
288
  tooling, or client code generation.
251
289
 
@@ -297,6 +335,8 @@ policy = AnalysisPolicy(
297
335
  medium_threshold=2.5,
298
336
  high_threshold=4.0,
299
337
  critical_threshold=6.0,
338
+ minimum_relative_dispersion=0.01,
339
+ minimum_absolute_dispersion=0.001,
300
340
  mapped_task_aggregation=MappedTaskAggregation.MAX,
301
341
  change_point_minimum_segment_size=4,
302
342
  change_point_score_threshold=4.0,
@@ -309,6 +349,8 @@ policy = AnalysisPolicy(
309
349
  `baseline_window` limits the number of historical values used before the current
310
350
  run. Mapped task durations can be aggregated with `MAX`, `MEAN`, or `SUM`. The
311
351
  same policy options are available through the CLI and MCP tool.
352
+ The dispersion floors prevent constant or nearly constant baselines from
353
+ turning negligible timing noise into an automatic critical anomaly.
312
354
  Change-point and trend detection can also be disabled independently with
313
355
  `change_point_detection_enabled=False` or `trend_detection_enabled=False`.
314
356
 
@@ -348,7 +390,11 @@ information for a DAG.
348
390
  Run continuous analysis and expose the latest DAG and bounded task-level metrics:
349
391
 
350
392
  ```bash
351
- flowsense serve-metrics example_dag --host 0.0.0.0 --port 9108
393
+ flowsense serve-metrics example_dag \
394
+ --host 0.0.0.0 \
395
+ --port 9108 \
396
+ --history-run-limit 50 \
397
+ --policy-file flowsense-policy.json
352
398
  ```
353
399
 
354
400
  See [docs/prometheus.md](docs/prometheus.md) for the metric contract,
@@ -81,6 +81,14 @@ Authentication is supplied through `AirflowAuthProvider`. Built-in providers
81
81
  cover Basic Auth, Airflow login-token exchange, static bearer tokens, and custom
82
82
  headers without coupling request collection to a deployment's identity system.
83
83
 
84
+ Collection is bounded at the Airflow API boundary whenever the configured API
85
+ supports it. Airflow 2 uses the stable batch POST endpoints, while Airflow 3
86
+ uses filtered collection endpoints for successful DAG runs and task instances.
87
+ Unsupported filter or batch responses fall back to the paginated per-run API,
88
+ preserving compatibility with older Airflow 2 deployments. This optimization
89
+ belongs exclusively to the infrastructure adapter and does not leak transport
90
+ capabilities into application or domain contracts.
91
+
84
92
  ### Delivery adapters
85
93
 
86
94
  `flowsense.cli`, `flowsense.mcp`, and `flowsense.observability` translate user input into an
@@ -16,8 +16,11 @@ AIRFLOW_USERNAME=airflow
16
16
  AIRFLOW_PASSWORD=secret
17
17
  ```
18
18
 
19
- FlowSense exchanges the credentials once and caches the returned bearer token
20
- for the lifetime of the client.
19
+ FlowSense exchanges the credentials and caches the returned bearer token for
20
+ the lifetime of the client. If an Airflow API request returns `401`, FlowSense
21
+ invalidates a login-issued token, obtains a fresh token, and retries that API
22
+ request once. A second `401` is returned as `AirflowApiError`; it is never
23
+ retried indefinitely.
21
24
 
22
25
  ### Basic authentication
23
26
 
@@ -42,6 +45,9 @@ AIRFLOW_BEARER_TOKEN=secret-token
42
45
  Username and password are not required in bearer mode. Secrets are excluded
43
46
  from the `AirflowConfig` representation, but applications must still keep them
44
47
  out of logs, shell history, source control, and command-line arguments.
48
+ Static bearer tokens are not automatically replaced after `401`; their
49
+ lifecycle remains owned by the application or identity provider that issued
50
+ them.
45
51
 
46
52
  ## Custom provider
47
53
 
@@ -74,4 +80,6 @@ provider = BearerTokenAuthProvider(load_current_token)
74
80
 
75
81
  Custom providers should return only authentication material and leave request
76
82
  execution, retry, timeout, payload validation, and error translation to
77
- `AirflowClient`.
83
+ `AirflowClient`. A `401` from a custom provider is not interpreted as permission
84
+ to rotate external credentials; the owning application decides how to refresh
85
+ them.
@@ -12,9 +12,13 @@ Configure the required `AIRFLOW_*` environment variables, then run:
12
12
  flowsense serve-metrics example_dag another_dag \
13
13
  --host 0.0.0.0 \
14
14
  --port 9108 \
15
- --interval-seconds 60
15
+ --interval-seconds 60 \
16
+ --history-run-limit 50 \
17
+ --policy-file flowsense-policy.json
16
18
  ```
17
19
 
20
+ Omit `--policy-file` to use the default analysis policy.
21
+
18
22
  Binding to `0.0.0.0` makes the endpoint reachable from the local Prometheus
19
23
  container. Do not expose this port to untrusted networks without an appropriate
20
24
  network policy or reverse proxy.
@@ -52,7 +56,21 @@ The dashboard provides:
52
56
  - currently firing FlowSense alerts.
53
57
 
54
58
  Use the DAG and task variables at the top of the dashboard to narrow the view.
55
- The default time range is six hours and the dashboard refreshes every 30 seconds.
59
+ The default time range is 15 minutes and the dashboard refreshes every 30 seconds.
60
+ Summary cards use instant queries, so they remain populated independently of
61
+ the selected history window. Current task comparisons include both DAG and
62
+ task names to distinguish tasks across multiple DAGs.
63
+
64
+ The top row summarizes the selected DAGs: monitored count, highest severity,
65
+ analysis health (healthy only when every selected DAG succeeded), mean coverage,
66
+ and total anomalous and affected tasks. Task comparisons and history appear
67
+ below; collection diagnostics and active alerts follow.
68
+
69
+ Prometheus history starts when the metrics service is scraped; historical
70
+ Airflow runs are analyzed but are not backfilled into these charts. After
71
+ starting the exporter, use a recent time range and allow a few scrapes. An
72
+ existing browser URL can retain an older time range; select Last 15 minutes
73
+ manually in that case.
56
74
  See [alerting.md](alerting.md) for rule behavior, validation, and production
57
75
  notification configuration.
58
76
 
@@ -64,3 +82,8 @@ docker compose -f deploy/observability/docker-compose.yml down
64
82
 
65
83
  Prometheus and Grafana data remain in named volumes. To explicitly remove those
66
84
  local volumes, add `--volumes` to the command.
85
+
86
+ ## Multi-DAG demo with execution evidence
87
+
88
+ For six real Airflow workloads, 20 seeded runs per DAG, continued live activity,
89
+ and a dedicated presentation dashboard, see [showcase.md](showcase.md).
@@ -0,0 +1,63 @@
1
+ # Migrating to FlowSense 0.5
2
+
3
+ FlowSense 0.5 improves production-scale Airflow collection, authentication
4
+ resilience, and statistical drift accuracy. Existing Python, CLI, and MCP entry
5
+ points remain available, but JSON consumers must account for analysis output
6
+ schema version `1.2`.
7
+
8
+ ## Analysis output schema 1.2
9
+
10
+ Each task and handoff drift result now includes:
11
+
12
+ - `direction`: `INCREASE`, `DECREASE`, or `UNCHANGED`;
13
+ - `effective_mad`: the regularized dispersion used to calculate the robust
14
+ z-score.
15
+
16
+ The embedded policy also includes `minimum_relative_dispersion` and
17
+ `minimum_absolute_dispersion`. Consumers that validate JSON should regenerate
18
+ their model or schema with:
19
+
20
+ ```bash
21
+ flowsense schema --document analysis
22
+ ```
23
+
24
+ The batch envelope remains at schema version `1.0`; each successful analysis
25
+ inside it now uses schema version `1.2`.
26
+
27
+ ## Drift behavior
28
+
29
+ Raw MAD is still reported without modification. Score calculation now uses the
30
+ largest of raw MAD, the configured relative floor, and the configured absolute
31
+ floor. This prevents negligible timing noise on constant baselines from being
32
+ classified as an automatic critical anomaly.
33
+
34
+ The defaults are:
35
+
36
+ ```json
37
+ {
38
+ "minimum_relative_dispersion": 0.01,
39
+ "minimum_absolute_dispersion": 0.001
40
+ }
41
+ ```
42
+
43
+ Pin explicit values in a policy file if existing alert thresholds were tuned
44
+ around the previous zero-MAD behavior.
45
+
46
+ ## Airflow collection and authentication
47
+
48
+ Recent successful DAG runs and task instances use bounded or batch API calls
49
+ when supported. Older Airflow deployments automatically fall back to the
50
+ paginated per-run endpoints.
51
+
52
+ Airflow login tokens obtained through `AIRFLOW_AUTH_MODE=token` are refreshed
53
+ once after a `401` response. Basic, static bearer, and custom authentication
54
+ providers retain application-owned credential lifecycles.
55
+
56
+ ## Validation checklist
57
+
58
+ 1. Regenerate and compare the analysis JSON Schema.
59
+ 2. Validate alerting against representative historical DAG runs.
60
+ 3. Confirm the configured Airflow identity can use batch endpoints or fallback
61
+ endpoints.
62
+ 4. Run `flowsense doctor` against the target Airflow environment.
63
+ 5. Perform a canary analysis before replacing a pinned 0.4 installation.