Commit Graph
2 Commits
Author SHA1 Message Date
Justin BollingerandClaude 665c8ab47c fix(ci): add test CI, repair auto-tag releases, harden action pins (2.11.4)
The repo had no CI: ruff/ty/pytest ran only in local prek pre-push hooks, so
a commit pushed without hooks installed reached main unvalidated -- and
auto-tag would then cut a release from it. Adds ci.yml (ruff, ty, pytest on
3.13) and gates tagging on it.

Auto-tagged versions also never produced a release. The tag is pushed with
the default GITHUB_TOKEN, and GitHub suppresses workflow triggers for
GITHUB_TOKEN-created events, so the tag-triggered release.yml never fired --
v2.11.3 was tagged with no release. auto-tag now creates the release itself,
idempotently; release.yml stays as the manual-tag path.

Also fixes version logic that matched the `!` breaking marker but only ever
bumped minor (and never saw BREAKING CHANGE: footers, since only subjects
were inspected), serializes concurrent merges that both computed the same
tag, and repins softprops/action-gh-release from an arbitrary master commit
to v2.6.2 with all workflows on one actions/checkout version.

Clears the pre-existing ty error in notify/tailer.py that would have made
the new type-check step red: _read_new_lines read self._file_pos
(int | None) while its only None-guard lived in the caller, so the position
is passed in explicitly as an int. Behavior unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 16:39:59 -04:00
Justin BollingerandClaude Sonnet 4.6 aae5ce8e90 feat(notify): add notification package with Pushover backend
Introduce hate_crack.notify package with a small functional public API
and a CrackTailer thread for polling hashcat output files. Package
layout keeps the HTTP call (_send_pushover) isolated so future backends
(Slack, generic webhooks) can be added as a sibling function rather
than a framework rewrite.

Core pieces:
- settings.py: NotifySettings dataclass plus atomic config persistence
  (save_enabled, add_to_allowlist) via read-modify-write + os.replace.
- pushover.py: single _send_pushover() that never raises; network
  errors, missing requests, and missing creds all funnel to False.
- _suppress.py: thread-local suppression context manager so
  orchestrator attacks can chain primitives without flooding
  notifications.
- tailer.py: CrackTailer(threading.Thread) that seeks to EOF on start,
  polls at a user-configurable interval, and collapses per-tick bursts
  into a single aggregate notification when they exceed the cap.
- __init__.py: public API (init, prompt_notify_for_attack,
  notify_job_done, notify_crack, start_tailer, stop_tailer,
  toggle_enabled, suppressed_notifications). Privacy guarantee:
  notification payloads contain only attack name, counts, and hash
  path, never plaintexts.

72 new tests cover dataclass defaults, atomic config writes, idempotent
allowlist updates, HTTP payload privacy, suppression nesting and
thread-locality, tailer EOF seek, burst cap, truncation recovery, and
the per-attack prompt's [y/n/always] flow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 14:41:38 -04:00