Repository navigation
Releases
v0.9.8
v0.9.8 — security dependency updates
This maintenance release updates two dependencies for security fixes. It is cut from the 0.9.x line, so it contains nothing beyond v0.9.7 except these updates.
- Pillow 13.0.0 fixes several image decoder vulnerabilities, including unbounded memory use in the MSP RLE decoder and a crash in
Image.merge. Inky decodes downloaded reference images, so a malformed image could previously crash it or exhaust its memory. The package now requires Pillow 13.0.0 or newer, so a display install that uses pip replaces an older Pillow instead of keeping it. - certifi 2026.10.19 removes the distrusted emSign ECC Root CA - G3 after the eMudhra weak-key incident, and keeps the unaffected emSign roots.
To upgrade, pull ghcr.io/veteranbv/inky-bird-frame:0.9.8 for the container controller, or run uv sync --extra controller --locked for a native controller. On the display, rerun the display install. No configuration, catalog, or state migration is required.
v0.9.7
v0.9.7 — reliable controller diagnostics
This maintenance release fixes a false failure in doctor controller when it runs from a remote or non-login shell. The diagnostic now uses the same deterministic Codex runtime path as the managed controller services, so a Codex launcher that resolves Node through /usr/bin/env works consistently in both places.
The fix is deliberately local to the diagnostic. It does not change global shell configuration, SSH behavior, controller generation, or user configuration. No migration is required.
v0.9.6
v0.9.6 — make retained retries actionable
This patch fixes a quiet recovery gap. If a transient generation failure lasted longer than the observation that triggered it, Inky kept the retry record but stopped showing it as runnable work. An upgrade could fix the original problem while leaving that bird behind.
status now reports those records under generation.manual_retry_required once a fresh discovery confirms that the taxon is in neither the current observation nor the durable queue. Scheduled generation keeps them in its outstanding count and sends an actionable notification instead of incorrectly reporting recovery.
The safety boundary stays the same: Inky does not silently generate a plate for an expired observation. Review the retained error, then use retry TAXON_ID for each bird you still want processed. No configuration or state migration is required.
The reusable catalog also adds five newly reviewed plates since v0.9.5:
- Blackpoll Warbler
- Common Loon
- Dark-eyed Junco
- Savannah Sparrow
- Yellow-bellied Sapsucker
v0.9.5
v0.9.5 — reliable scheduled generation on macOS
This maintenance release fixes scheduled plate generation on native macOS controllers when Codex is installed through a package manager. Inky now gives each managed LaunchAgent a deterministic PATH that includes the configured Codex executable's directory, so wrapper scripts can find their neighboring runtime instead of failing before generation begins.
Linux controllers keep the same behavior through the shared path builder. No configuration change is needed: existing absolute, bare-name, and relative codex_path settings continue to work.
The release also hardens the repository's review gate against a GitHub edge case where an edited Codex summary could be mistaken for a newer review request. Regression coverage now protects both fixes.
v0.9.4
v0.9.4 — quieter, safer controller logs
This maintenance release puts a bound on the controller's macOS log files. Each managed service now keeps a small set of rotated logs, and the installer makes existing and future logs private to the controller account. Long-running services continue writing to the current file after rollover, so rotation does not hide new errors in an old archive.
Manual commands and Linux/systemd logging are unchanged. This release also includes the v0.9.3 catalog-publish recovery fix and all earlier v0.9.x work; no configuration change is needed.
Thanks to everyone helping us harden the path to 1.0. We'll restart the reference-installation soak only after both controller and display are verified on this exact release.
v0.9.3
This maintenance release fixes a catalog-publishing failure that could persist after disk space was restored. If an atomic file write ran out of space before it reached its cleanup step, it could leave a hidden temporary file behind. The catalog validator then rejected that file on subsequent runs. Failed writes now remove their temporary file while preserving the last complete destination.
The release also includes the approved Northern Waterthrush plate merged since v0.9.2 (PR #293).
No configuration change is required. Existing approved plates and other observation providers are unaffected. This change does not prevent disk exhaustion; the controller still needs adequate free space.
Validated with a regression test that reproduced the old failure, Ruff, strict MyPy, the full Pytest suite, catalog validation, package build, main-branch CI, CodeQL, and exact-head Codex review. See PR #294.
v0.9.2
A small reliability follow-up to v0.9.1. Live controller refreshes showed that eBird can take longer than the prior 45-second wait to return recent observations. This release gives only the eBird request a 90-second timeout; other provider limits, discovery queries, and notification behavior are unchanged.
The duplicate-discovery protection introduced in v0.9.1 remains in place. A genuinely unavailable eBird service can still fail without stopping other providers. No configuration change is required.
Validated with Ruff, strict MyPy, full Pytest, a package build, main-branch CI, CodeQL, and exact-head Codex review. See PR #290.
v0.9.1
Inky Bird Frame 0.9.1
This patch steadies discovery during provider trouble. A partial refresh no longer makes previously seen birds look new when the missing provider recovers. New birds from healthy providers still notify, and a bird that genuinely returns after a complete, healthy absence can notify again.
eBird recent-observation requests now have a 45-second timeout instead of the shared 10-second timeout. Successful requests in the release investigation took 12 to 27 seconds. The private provider diagnostics also include HTTP duration, so a future slowdown is easier to distinguish from an authentication or taxonomy problem. Other providers keep their existing limits and remain isolated if eBird fails.
Since 0.9.0, the tagged catalog also adds a Bay-breasted Warbler plate, and the repository includes routine GitHub Actions and Python dependency updates.
There are no configuration changes and no public catalog or display protocol changes. The private discovery snapshot gains a taxon-ID comparison field. If the previous snapshot was degraded at upgrade time, the first complete refresh quietly establishes a reliable baseline. The active catalog still follows current successful observations and private collection membership; the notification fix does not keep stale birds on the display.
The full test suite, strict typing, formatting, lint, catalog validation, package build, CI, CodeQL, and exact-head review passed on PR #289. Keep the pre-upgrade backup until the updated controller and display are verified. This patch starts a fresh stability observation period before 1.0.
v0.9.0
Inky Bird Frame 0.9.0
0.9.0 is the final planned soak release before 1.0. It focuses on safer upgrades and a Docker setup that is easier to understand and operate.
Safer catalog upgrades
A valid local plate can now survive an upgrade when that same species is later added to the public catalog through a separate approval. Inky still fails closed on changed identities, shared-history conflicts, malformed catalogs, and incomplete or tampered migration records.
This fixes #280 without replacing stable iNaturalist taxon IDs or weakening catalog validation.
Host-authoritative Docker configuration
Docker installations can now keep config.toml on the host as the source of truth. A short-lived, offline sync service validates it, installs a private mode-0600 runtime copy, and must succeed before the controller starts. Missing files, invalid edits, SELinux labeling, environment-backed settings, rootless Docker, and daemon user-namespace remapping all have explicit handling and documentation.
If you are upgrading from 0.8.1 or earlier, compare the host file with the configuration currently stored in controller-data before replacing your Compose file. The Docker upgrade guide walks through the private export and comparison safely.
This implements #281.
Thank you to @dwalters0 for reporting the catalog upgrade conflict and for the host-managed configuration feature request. Both reports made the pre-1.0 Docker experience safer and easier to operate.
Eight new field-journal plates
- Eastern Warbling Vireo
- Chestnut-sided Warbler
- Hooded Warbler
- Black-throated Green Warbler
- Tennessee Warbler
- Swainson’s Thrush
- Veery
- Sharp-shinned Hawk
Next: the 1.0 soak
This exact release will run on the reference controller and physical display for five days. During that soak, we will watch discovery, generation, catalog refresh, notifications, display rotation, and recovery behavior. If it stays quiet, the next planned release is the deliberately boring 1.0.0 stability milestone.
v0.8.1
v0.8.1 tightens the controller's CORS response boundary.
When a browser Origin matches the configured allowlist, Inky now returns the normalized configured origin rather than copying the request header into Access-Control-Allow-Origin. This preserves the existing exact-origin policy while closing the HTTP response-splitting data flow identified by CodeQL.
There is no configuration, private-state, catalog, CLI, or HTTP contract migration. Update the controller normally; the display protocol is unchanged.
Upgrade
Follow the existing controller-first update path. Keep the usual pre-upgrade backup until the updated controller and display have passed their doctor checks.