Repository navigation
Releases: VirInvictus/Colophon
Release list
## v2.6.0 (2026-09-15)
feat: the word-count axis ships (v2.6.0)
Version bump across every carrier with the release notes: per-book
words, words read, and true WPM behind the provided-EPUB gate;
lifetime words and the book-length distribution on the overview; the
Length and Pace personality traits. The granted zip dependency and
its vendored crates ride the train; the docs set (patchnotes, README,
CLAUDE.md, appdata, roadmap ticks) is current. 134 tests green.
## v2.5.0 (2026-09-15)
feat: page the years, recap by year, gather the annotations (v2.5.0)
The three GO'd features ship behind their spec definitions.
- The year heatmap shows one calendar year (January through December,
Monday-start, up to 53 weeks) with arrows stepping back through the
past and forward toward today. The old rolling 52-week window
silently clipped the oldest weeks the moment a year turned; that
invisible regression is now a visible pager. Default: current year. - The recap card gains a per-year variant of the same composite (a
finished work counts to its finish year, a started work to its first
reading year), stepping from All time down through the years and
back; the choice belongs to the card and never moves the global
window. recap_for_year derives from the cached base, so paging is
free. - An Annotations section on the overview lists every annotation from
every provided sidecar, grouped by book in library order with
entries in book order; a click opens the book's page. Hidden until a
sidecar carries annotations, like everything user-provided.
Suite 126 green; clippy -D warnings, fmt clean.
## v2.4.1 (2026-09-15)
v2.4.1 (2026-09-15)
A hardening release from the final audit. No new features, and none of
your numbers move.
- A corrupt or foreign database can no longer crash the app. The
import dialog accepts any*.db, and a file carrying timestamps no
calendar can name used to panic the day and hour charts when they
rendered. Events outside an honest epoch window (1970 through 9999)
are now dropped once at load, the same graceful treatment relative
dates already had. - A bad import can no longer touch your good snapshot. Staged
imports used to be validated by reading the book table only, so a
database that opened but could not be fully loaded was promoted and
failed afterwards, clobbering the snapshot it was supposed to be
checked against. Validation now fully loads the staged copy first,
and the promote-refuses path has an end-to-end test. - The year heatmap tooltip names books. The spec promised
"time + pages + books"; the count was already computed and now shows. - The import path no longer stats the source on the UI thread. The
source path can live on a network mount; the startup and
mount-change probes moved off the main thread so a hung mount cannot
freeze the window. - Read-through dates follow the reading day. A book finished just
after midnight under a non-midnight day start showed one day late;
completion rows now use the logical day. - The shortcuts window no longer documents a sidebar-resize
accelerator that does not exist. Nothing ever bound F8, and GTK
gives paned dividers no keyboard path; the false row is dropped.
Under the hood: the comment layer caught up with the post-D1 data
path, CLAUDE.md synced with the 2026-09-12 decisions, and the spec,
README, and RESEARCH records had their truth fixes (the junk threshold
is fixed, not configurable; Tier B renumbered 10-17; the default theme
is Follow-system, not Dragon). An advisory gate (cargo-deny) joined
CI, a SECURITY policy and a justfile landed, the MSRV is declared
(1.85), CI actions are SHA-pinned with a versioned Fedora container,
releases are now cut automatically from tags, and the approved
removals shipped (the unused directory-scan API and all_events;
rescaled_events stays as the test oracle).
Suite 124 green across the workspace; clippy -D warnings, fmt clean.
## v2.4.0 (2026-09-06)
v2.4.0 (2026-09-06)
Your margins, readable.
- The annotations browser. A book whose sidecar you have provided now
lists its highlights, notes, and bookmarks on the book page, in book
order. Each entry names what it is and where it falls (as a percent of
the book), shows the device-captured excerpt wrapped to full width, and
your own note beneath it in the dim style; bookmarks, which carry no
text, list as their position alone. KOReader stores annotations in the
order you made them, so Colophon orders them by where they fall in the
book instead. Books without a provided sidecar show nothing new, as
always. The activity-strip markers and the counts on the stat cards are
unchanged.
Suite 119 green across the workspace; clippy -D warnings and fmt clean.
## v2.3.1 (2026-09-06)
v2.3.1 (2026-09-06)
- The Flatpak build is offline-capable. Every crate dependency is now
vendored into the build (generated-sources.json, generated from
Cargo.lock), so the build sandbox needs no network access and the
--share=networkbuild-time escape hatch is gone. Verified with a real
localflatpak-builderrun: the app builds and runs under the GNOME 50
runtime with no network. This closes the one gap between the manifest and
a Flathub submission (the app-id question is a separate, workspace-wide
decision). Nothing about the app itself changed.
Suite 117 green across the workspace; clippy -D warnings and fmt clean.
## v2.3.0 (2026-09-06)
v2.3.0 (2026-09-06)
For night owls: the reading day can start when yours does.
- A configurable day start. Preferences gains a "Reading day" group:
pick the minute past midnight your reading day begins (arrows step 30
minutes, or type HH:MM; the default 00:00 is the plain calendar day).
With a 04:00 day start, reading done between midnight and 04:00 counts
toward the previous day, so one late-night sitting reads as one day
everywhere a day appears: daily totals, streaks, the year heatmap,
monthly bars, speed buckets, the 30/90/365-day windows, and every
displayed date, including "today" in the streak rules. The change
applies live. What never moves: the clock hours. The when-do-I-read
heatmap still shows the real hour you read, and speed by hour and
session starts stay on the clock.
Suite 117 green across the workspace; clippy -D warnings and fmt clean.
# v2.2.0 (2026-09-04)
v2.2.0 (2026-09-04)
Data-quality fixes from the 2026-09-04 audit (D1-D3), each with its spec
amendment as the first step.
- D1 — merged books no longer conflate pagination axes.
page_totals
andrescaled_eventsrescale every merged row's events onto the
canonical row's page count in SQL (the canonical page count is bound as
a parameter; the per-rowbookJOIN is gone). Previously thepage_stat
view rescaled each row against its ownpages, so merged rows recorded
under different paginations summed positions from two different axes into
one bucket. Zero-total_pagesrows drop out exactly as they did in the
view (the division yields NULL and the fan-out predicate rejects them). - D2 — an unknown page count hides page-derived stats instead of
printing confident zeros.Book::pagesis nowOption<i64>; a book
whose page count KOReader never learned hides unique pages, rescaled
positions, completions, capped totals, and the per-page strip, while its
time-derived stats keep rendering.unique_pages_readand
rescaled_last_pagekeepi64signatures; theOptionis unwrapped at
the loader boundary. - D3 — library-wide aggregations key on the full work identity.
forgotten_books,finished_timeline, and the Recap's started/finished
sets now key onlibrary::group_key's(title, authors)instead of the
trimmed title alone, so two different works sharing a title no longer
collide (and the Recap's completion rate stops undercounting). The
title-keyed sites inside series/author buckets are correct and
untouched; the Jingo one-work-two-files case has a test proving the fix
doesn't overshoot.
Suite 112 green across the workspace; clippy -D warnings, fmt, and
pyright strict all clean.