feat: ops & UX polish (TUI, healthz, telegram inbound, grafana)#6
Merged
devAsmodeus merged 9 commits intomainfrom May 2, 2026
Merged
feat: ops & UX polish (TUI, healthz, telegram inbound, grafana)#6devAsmodeus merged 9 commits intomainfrom
devAsmodeus merged 9 commits intomainfrom
Conversation
Adds src/hope_hash/banner.py (render_banner / print_banner) and 6 unit tests. ASCII-only on purpose so the banner survives consoles without UTF-8 (legacy Win, syslog with C locale). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces a thread-safe StatsProvider that miner pushes to and TUI/ healthz/web consume from — single source of truth for all observers. TUIApp wraps curses in a daemon thread, redraws every 1s, quits on q/ESC. On Windows without windows-curses we degrade gracefully (warn, keep mining). 13 tests cover provider thread safety, snapshot immutability, and format helpers. curses-loop itself is not unit-tested (TTY-only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends MetricsServer with a /healthz route returning JSON. Status is computed by a pluggable callable registered via set_health_provider(). Pure build_health_snapshot() encodes the state machine: ok/degraded (200) vs down (503), with a 30s hashrate-freshness window and configurable share-staleness. 11 tests cover both the snapshot matrix and the live HTTP layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds long-poll getUpdates thread (start_inbound/stop_inbound) and a register_command registry. Authz strictly by HOPE_HASH_TELEGRAM_CHAT_ID; foreign chat updates are dropped with a warning log. Opt-in via HOPE_HASH_TELEGRAM_INBOUND=1 — we don't open a network thread without explicit ack. test_notifier_timing.py is a regression test for the class of bugs where notify_share_accepted fires from the submit path before the pool acks: we now drive it exclusively from on_share_result(accepted=True), verified across submit-only, ack-true, ack-false, duplicate-ack, and multi-share scenarios. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cli.main() now: - prints the banner unless --no-banner / --tui - creates a StatsProvider shared between mine() and consumers - starts TUIApp when --tui (with curses-availability fallback) - registers a health provider on the metrics server - registers /stats /stop /restart Telegram handlers when opt-in env set - routes log INFO to --log-file in TUI mode (stderr stays at WARNING+) mine() accepts stats_provider; supervisor_loop() accepts restart_event for the /restart command. stratum.py gets full attribute type hints and dict[str, Any]/list[Any] params. Bumps __version__ to 0.5.0 and re-exports new public symbols. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Minimal Grafana 10.x dashboard with 5 panels: hashrate timeseries,
pool difficulty, shares accepted vs rejected (stacked bar), workers
gauge, uptime stat. Datasource templated as ${DS_PROMETHEUS} so it
imports clean against any Prometheus connection.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- CHANGELOG.md: v0.5.0 section (TUI, banner, healthz, telegram inbound, Grafana, type annotations, 145 tests). - README.md: short "What's new in v0.5.0" paragraph above the status table; bumped test count 101 → 145. Full README rewrite is PR C. - ROADMAP.md: ticked TUI (curses), banner, telegram inbound, Grafana, healthchecks endpoint. - docs/handoff/pr-a-summary.md: file map, new flags/env vars, gotchas and open questions for the PR B subagent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR A of the three-PR push described in
docs/superpowers/specs/2026-05-02-three-pr-roadmap.md.Closes Level 1 remainder + observability tail. Pure stdlib. No new pip dependencies.
What's in v0.5.0
--tui— curses dashboard (EMA hashrate, uptime, shares sent/ok/rej, job_id, pool diff, workers). Quit onq/ESC. Windows graceful skip ifwindows-cursesmissing.--no-banner./healthzJSON endpoint on the metrics server.ok/degraded(200) vsdown(503) for k8s liveness/readiness. Tunable--healthz-stale-after./stats/stop/restart/help. Long-poll thread,chat_idauthz, opt-in viaHOPE_HASH_TELEGRAM_INBOUND=1.deploy/grafana/hope-hash.json(5 panels, datasource templated).StatsProvider— single thread-safe data bus betweenmine()and consumers (TUI today, web in PR C).miner.pyandstratum.py.--log-file PATH— duplicate logs to a file (essential with--tui).notify_share_acceptedis now strictly driven from the pool ack callback, never from the submit path. Regression-tested in 5 scenarios.Tests
py -3.11 -m unittest discover -s tests -v→ 145 passed (was 101). Net +44 tests across 4 new files (test_banner.py,test_tui.py,test_healthz.py,test_notifier_timing.py) plus inbound dispatch tests appended totest_notifier.py.Files
See
docs/handoff/pr-a-summary.mdfor the file map, gotchas for the PR B agent, and open questions.Self-check
py -3.11 -m unittest discover -s tests -vpip installhappeneddocs/handoff/pr-a-summary.mdexists with file mapsrc/hope_hash/parallel.py/block.pyuntouched