Skip to content

feat: pre-cutover cleanup — smoke-test refresh, remediation→TelegramNotifier, coverage config (rc3)#23

Merged
cipher813 merged 2 commits into
mainfrom
feat/rc3-cleanup
May 13, 2026
Merged

feat: pre-cutover cleanup — smoke-test refresh, remediation→TelegramNotifier, coverage config (rc3)#23
cipher813 merged 2 commits into
mainfrom
feat/rc3-cleanup

Conversation

@cipher813
Copy link
Copy Markdown
Owner

Summary

Three coordinated cleanups before the morning-signal consumer cutover. Bumps to 0.5.0rc3.

1. examples/smoke_test.py rewritten for the rc-era surface

Leads with FlowDoctor.builder() + TelegramNotifierConfig instead of the now-@deprecated flow_doctor.init() yaml flow. Adds smoke checks for flow_doctor.context() propagation, report_async() from an asyncio context, and flow_doctor.otel.report_to_otel_span_event. All offline (FLOW_DOCTOR_SKIP_PREFLIGHT=1 + fake creds + sqlite at temp path).

2. RemediationExecutor's orphan Telegram path migrated to TelegramNotifier

Previously RemediationExecutor had a bespoke _notify_telegram POST to an arbitrary webhook URL — a misnomer (Telegram doesn't have user-installable webhooks the way Slack does) and a duplicate code path that didn't compose with the rest of the notifier surface.

Added: TelegramNotifier.send_raw(text, *, parse_mode=, disable_notification=) for adjacent subsystems firing ad-hoc messages without conforming to the Report shape. Sentinel-based parse_mode / disable_notification lets callers distinguish "use instance default" from "explicit override".

Added to RemediationConfig: telegram_bot_token + telegram_chat_id + telegram_message_thread_id. _init_remediation in core/client.py builds a real TelegramNotifier from these (with the FLOW_DOCTOR_TELEGRAM_* env-var fallback chain) and hands it to RemediationExecutor via a new telegram_notifier= kwarg.

Deprecated: RemediationConfig.telegram_webhook_url — kept for 0.4.x yaml back-compat through the 0.5.x series, removed in 0.6.0. When both paths are configured, the notifier wins.

Remediation pings going through the new path pick up Markdown rendering, threading, target-id audit (actions.target row populated with the non-secret telegram:<chat_id>[:<thread>] identifier), and the same validate() preflight as the rest of the notifier surface.

3. Canonical coverage entry in pyproject.toml

pytest-cov was misreporting coverage on Pydantic-derived modules under editable installs because it instruments after the import has already happened — flow_doctor/notify/configs.py registered as 17% when it's actually 98%. The direct python -m coverage run -m pytest && python -m coverage report path measures correctly. Real project-wide coverage is 84%, not the 67% pytest-cov reported (still over the v0.5.0 plan's 80% target).

Also: .coverage artifact + htmlcov/ added to .gitignore.

Test plan

  • pytest tests/ → 393/393 pass (376 prior + 17 new for the remediation-Telegram migration).
  • python examples/smoke_test.py → all 10 smoke checks pass offline.
  • Coverage measured via python -m coverage run -m pytest && python -m coverage report → 84% suite-wide, telegram.py 83%, executor.py 68% (was 56% — the migration tests lifted it).
  • PyPI publish of 0.5.0rc3 after merge.
  • Then morning-signal cutover in a separate PR (alpha-engine-morning-signal repo).

🤖 Generated with Claude Code

cipher813 and others added 2 commits May 13, 2026 14:06
Three coordinated cleanups before crossing into the morning-signal
consumer cutover:

1. examples/smoke_test.py rewritten to lead with FlowDoctor.builder()
   + TelegramNotifierConfig instead of the now-@deprecated
   flow_doctor.init() yaml flow. Adds smoke checks for
   flow_doctor.context() propagation, report_async() from an asyncio
   context, and flow_doctor.otel.report_to_otel_span_event. All
   offline (FLOW_DOCTOR_SKIP_PREFLIGHT=1 + fake creds + sqlite at
   temp path).

2. RemediationExecutor's orphan _notify_telegram path migrated to
   consume a first-class TelegramNotifier instance. Adds
   TelegramNotifier.send_raw(text) for adjacent subsystems firing
   ad-hoc messages without conforming to the Report shape; the
   sentinel pattern on parse_mode / disable_notification lets callers
   distinguish "use instance default" from "explicit override".

   RemediationConfig gains telegram_bot_token + telegram_chat_id +
   telegram_message_thread_id; _init_remediation builds a real
   TelegramNotifier from those (with FLOW_DOCTOR_TELEGRAM_* env-var
   fallback chain) and hands it to RemediationExecutor. The legacy
   telegram_webhook_url path stays — soft-deprecated for 0.4.x yaml
   back-compat, removed in 0.6.0. When both are configured, the
   notifier wins.

   Remediation pings going through the new path pick up Markdown
   rendering, threading, target-id audit (actions.target row), and
   the same validate() preflight as the rest of the notifier surface.

3. [tool.coverage.run] section added to pyproject.toml. pytest-cov
   was misreporting coverage on Pydantic-derived modules under
   editable installs because it instruments AFTER the import has
   already happened; the direct ``python -m coverage run -m pytest
   && python -m coverage report`` path measures correctly. Real
   project-wide coverage is 84%, not the 67% pytest-cov reported.

17 new tests cover: send_raw POST shape + chat/thread/parse_mode
override (sentinel-based), never-raise behavior on network failure
and API ok=false, 4096-char truncation, HTTP non-200 returning None,
RemediationExecutor invoking send_raw with the formatted message,
emoji + dry-run tag + error-truncation in the formatted body,
RemediationExecutor preferring the notifier when both paths are
configured, legacy webhook URL still working unchanged for 0.4.x
back-compat, and _init_remediation building the notifier from
RemediationConfig fields + env-var fallbacks.

Version bump 0.5.0rc2 → 0.5.0rc3.

Suite: 393/393 pass (376 prior + 17 new).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cipher813 cipher813 merged commit b1e7e10 into main May 13, 2026
1 check passed
@cipher813 cipher813 deleted the feat/rc3-cleanup branch May 13, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant