Skip to content

feat: daily summary email + skip re-querying unresolvable mis-seeds#2

Merged
vidaks merged 1 commit into
mainfrom
feat/resolve-skip-and-daily-summary
Jun 4, 2026
Merged

feat: daily summary email + skip re-querying unresolvable mis-seeds#2
vidaks merged 1 commit into
mainfrom
feat/resolve-skip-and-daily-summary

Conversation

@vidaks

@vidaks vidaks commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Summary

Two related changes to the autonomous healer, plus a 0.2.0 bump.

1. Stop re-querying unresolvable mis-seeds

The nightly resolve sweep re-asked Hardcover + Haiku about the same permanently-unresolvable books every run (the ~10 NONEs + below-threshold matches), which was the load that tripped the HTTP 429 crash.

  • New resolve_skip table: mis-seeds that resolve to no-match or a below-threshold match are recorded and filtered out of later runs.
  • Skip key is the normalized title+author (stored as text, not the per-process-salted builtin hash()), so a book is re-queried automatically once its metadata changes — and a heal/lock removes it from review-misseed anyway.
  • Escape hatches: resolve --force (re-check all), resolve --clear-skips (forget), COLOPHON_RESOLVE_RETRY_DAYS (optional TTL, default 0 = never).
  • Below-threshold matches stay visible — reports surface them with a one-line manual-apply command. NONEs are a bare count.

2. Daily summary email

  • New maintain command runs backfill + resolve in one process (each phase guarded so a failure in one doesn't skip the other) and, with --email, always sends a one-page summary — a heartbeat that fires even on an aborted run (composed in a finally).
  • Exits non-zero on a phase failure (supervising timer is marked failed → retries); an SMTP failure does not change the exit code.
  • Reuses the existing SMTP_* / OVERSIGHT_TO env — no new secret.

Tests / checks

  • 15 stdlib unittest cases for the skip-list (fingerprint stability, TTL, store roundtrip, the apply-path skip-writing).
  • compileall + ruff (CI ruleset) green; no-network render smoke for clean / aborted / cached paths.

Deploy

The plexarr colophon-maintain.sh.j2 collapses to a single maintain --apply --email call (separate repo, deployed after merge).

Add a `maintain` command that runs backfill + resolve in one process (each
phase guarded so a failure in one doesn't skip the other) and, with --email,
always sends a one-page summary — a daily heartbeat that fires even on an
aborted run. Exits non-zero on a phase failure so a supervising timer is marked
failed and retries; an SMTP failure does not change the exit code.

Add a resolve skip-list: mis-seeds that resolve to no-match or a below-threshold
match are recorded (resolve_skip table) and not re-queried on later runs, cutting
the repeated Hardcover + Haiku calls for permanently-unresolvable books. The skip
key is the normalized title+author, so a book is re-queried automatically once its
metadata changes. `resolve --force` re-checks all; `resolve --clear-skips` forgets
the list; COLOPHON_RESOLVE_RETRY_DAYS sets an optional re-check TTL (default 0 = never).

Bump to 0.2.0; add unit tests for the skip-list logic.
@vidaks vidaks merged commit fd7f738 into main Jun 4, 2026
4 checks passed
@vidaks vidaks deleted the feat/resolve-skip-and-daily-summary branch June 4, 2026 07:16
vidaks added a commit that referenced this pull request Jun 18, 2026
…the lowest

book_by_id reported a book's position as bs[0] — the lowest-position
membership after order_by position asc. A book in several series has a
different position in each: an Expanse novella sits in "The Expanse"
(#2.7, the featured series grimmory derives) and "The Expanse
(Chronological)" (#0.1). The audit picked 0.1, "containment-matched" its
name to grimmory's "The Expanse", and flagged 2.7 != 0.1 — a false
number-mismatch. The heal set the (already-canonical) ISBN and refreshed,
grimmory re-derived 2.7 from the featured series, and the mismatch came
back next run: a heal that re-fired forever without converging. At an
hourly cadence the same four books "healed" every run, so every run
looked noteworthy and pushed a notification.

book_by_id now also returns the featured membership; the audit compares
grimmory's number against the FEATURED position — exactly what grimmory
derives on refresh. This fixes the four novellas (Drive, The Churn,
Butcher of Anderson Station, Spoils of War → number-ok) and, because it
uses featured rather than a name match, keeps a genuine mis-seed/variant
(grimmory's name disagrees with the featured series, e.g. an Old Man's
War book whose featured series is The Human Division) on the name path
instead of reclassifying it into a re-firing number-mismatch.

Verified on the live library: zero number-mismatch remain; the four
oscillating books read number-ok and the maintain run stays silent.
vidaks added a commit that referenced this pull request Jul 9, 2026
…the lowest

book_by_id reported a book's position as bs[0] — the lowest-position
membership after order_by position asc. A book in several series has a
different position in each: an Expanse novella sits in "The Expanse"
(#2.7, the featured series grimmory derives) and "The Expanse
(Chronological)" (#0.1). The audit picked 0.1, "containment-matched" its
name to grimmory's "The Expanse", and flagged 2.7 != 0.1 — a false
number-mismatch. The heal set the (already-canonical) ISBN and refreshed,
grimmory re-derived 2.7 from the featured series, and the mismatch came
back next run: a heal that re-fired forever without converging. At an
hourly cadence the same four books "healed" every run, so every run
looked noteworthy and pushed a notification.

book_by_id now also returns the featured membership; the audit compares
grimmory's number against the FEATURED position — exactly what grimmory
derives on refresh. This fixes the four novellas (Drive, The Churn,
Butcher of Anderson Station, Spoils of War → number-ok) and, because it
uses featured rather than a name match, keeps a genuine mis-seed/variant
(grimmory's name disagrees with the featured series, e.g. an Old Man's
War book whose featured series is The Human Division) on the name path
instead of reclassifying it into a re-firing number-mismatch.

Verified on the live library: zero number-mismatch remain; the four
oscillating books read number-ok and the maintain run stays silent.
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