liseur-sync/docs/adr
Chmouel Boudjnah 9699ca3308
Some checks are pending
build / binary (push) Waiting to run
build / container (push) Waiting to run
test / test (push) Waiting to run
test / lint-openapi (push) Waiting to run
docs: write down how a fresh device starts up
The batch resolve route joins docs/integrating.md and the OpenAPI
description, and ADR-0035 records why a route for many books exists
when one for a single book already does.

Alongside it, the sequence a device follows on its first day is now
spelled out: name everything, ask where each book stands through
/v1/heads, then sync normally. Every client wants that order and none
of it was written down, which is part of why the first attempt at it
took several refreshes to settle.
2026-09-07 09:22:23 +02:00
..
0001-content-server.md docs: ADRs for the two gaps client work hit 2026-08-15 20:22:08 +02:00
0002-library-storage-and-ownership.md docs: a library is three things, and one of them can be Calibre 2026-08-15 20:22:06 +02:00
0003-catalog-work-identity.md docs: write down how a fresh device starts up 2026-09-07 09:22:23 +02:00
0004-metadata-and-categorization.md docs: Record external metadata lookup as built 2026-08-15 20:22:01 +02:00
0005-upload-and-ingestion.md docs: Record cover extraction as built 2026-08-15 20:21:57 +02:00
0006-catalog-api-and-opds.md feat: Separate OPDS rate limiter from authentication limits 2026-08-28 23:08:28 +02:00
0007-web-reader.md feat: Notify connected clients of reading changes 2026-09-05 12:43:36 +02:00
0008-liseur-android-client.md docs: Update Android architecture decision record and API limits 2026-08-16 13:59:38 +02:00
0009-liseur-desktop-client.md docs: ADRs for the two gaps client work hit 2026-08-15 20:22:08 +02:00
0010-duplicate-detection.md feat(store): Ask about books that look like one book 2026-08-15 20:21:59 +02:00
0011-web-ui-revamp.md feat: group library books by series 2026-08-21 10:47:21 +02:00
0012-reader-engine-foliate.md fix: Show the same page number as the app in the web reader 2026-09-04 07:03:46 +02:00
0013-admin-panel.md feat: Consolidate account controls into unified settings hub 2026-08-19 11:10:43 +02:00
0014-library-sources-and-storage.md feat: Expose all admin CLI commands in the web panel 2026-08-15 20:22:07 +02:00
0015-catalog-payloads-for-clients.md feat: Unify catalog book payloads across all endpoints 2026-08-15 20:22:08 +02:00
0016-token-self-introspection.md feat: return account_id from GET /v1/token 2026-09-04 13:09:05 +02:00
0017-folders-not-pipelines.md feat: Make Calibre metadata authoritative during reconciliation 2026-08-17 15:41:45 +02:00
0018-series-overrides.md feat(catalog): reader-editable series, library-wide entities 2026-08-16 17:37:12 +02:00
0019-library-wide-entities.md docs(adr): decide how a series gets renamed 2026-08-16 18:51:06 +02:00
0020-series-renaming.md feat(series): merge two shelves, split one in two 2026-08-16 20:54:44 +02:00
0021-series-merge-split.md docs(adr): record ADR-0021 as implemented 2026-08-16 20:57:30 +02:00
0022-calibre-metadata-db-is-authoritative.md refactor: Improve Calibre reconciliation and orphan cleanup 2026-08-17 16:09:08 +02:00
0023-uploads-land-in-a-folder.md fix(upload): join an uploaded book to the work it belongs to 2026-08-19 00:21:25 +02:00
0024-deleting-a-work.md feat(webui): a way to delete a work, and to retire a missing book 2026-08-18 23:59:26 +02:00
0025-deleting-a-book.md docs(adr): a book may be deleted where a book may be written 2026-08-19 08:16:27 +02:00
0026-credential-enrolment-does-not-weaken-account-authentication.md fix: harden credential enrolment 2026-08-20 06:10:51 +02:00
0027-explicit-per-user-folder-access.md fix: Grant creator access on folder creation to fix empty shelves 2026-08-29 21:54:49 +02:00
0028-annotation-sync.md docs: record ADR-0028, annotation sync as mutable reading state 2026-08-25 07:39:29 +02:00
0029-a-folder-somebody-can-read.md fix: Grant creator access on folder creation to fix empty shelves 2026-08-29 21:54:49 +02:00
0030-web-reader-reading-sessions.md feat: Count reading sessions in the web reader 2026-09-03 21:15:10 +02:00
0031-web-reader-footer.md fix: Show the same page number as the app in the web reader 2026-09-04 07:03:46 +02:00
0032-reader-pages-are-readium-positions.md fix: Show the same page number as the app in the web reader 2026-09-04 07:03:46 +02:00
0033-a-device-outlives-its-token.md feat: let a new token inherit a device id 2026-09-04 13:09:05 +02:00
0034-live-notifications-say-only-that-something-changed.md feat: Notify connected clients of reading changes 2026-09-05 12:43:36 +02:00
0035-naming-a-shelf-is-one-request.md docs: write down how a fresh device starts up 2026-09-07 09:22:23 +02:00
README.md docs: write down how a fresh device starts up 2026-09-07 09:22:23 +02:00

Architecture decision records

This directory is the living implementation plan for expanding liseur-sync. DESIGN.md remains the protocol authority; ADRs explain decisions that add to or supersede parts of that design.

Index

Scope says whether an ADR is needed for the first release, as defined in ADR-0001. Later does not mean unlikely; it means the decision is recorded so it cannot invalidate storage or identity choices made now, and is not a commitment to build yet. Client means the server work is needed for the first release of a client (ADR-0008, ADR-0009) rather than of the server.

Implemented in the state column means every phase of that ADR is built and nothing is outstanding: it is archived in place rather than moved, so the links that point at it from the other records keep working, and it is read as history rather than as a plan.

Next is the one thing to build next under that ADR, so the table can be read instead of the whole directory. The ordering between ADRs, and the loose ends that must come before any of it, are in ADR-0001.

ADR Title Scope State Next
0001 Become a content server — MVP implemented Nothing outstanding
0002 Library storage and ownership MVP Superseded by 0017 Nothing outstanding
0003 Catalog and sync work identity MVP Implemented Nothing outstanding
0004 Metadata and categorization MVP Implemented; external lookup and manual editing superseded by 0017 Nothing outstanding
0005 Upload and ingestion pipeline MVP Superseded by 0017 Nothing outstanding
0006 Catalog API and OPDS MVP Implemented; book payload amended by 0015 Nothing outstanding
0007 Web reader Later Implemented Nothing outstanding
0008 Liseur Android client plan Later Other repository Add stable account identity in 0016 so replacement tokens do not force a full replay
0009 Liseur Desktop client plan Later Other repository Add stable account identity in 0016 so replacement tokens do not force a full replay
0010 Duplicate detection MVP Superseded by 0017 Nothing outstanding
0011 Web UI revamp Later Implemented Nothing outstanding
0012 Replace the reader engine with foliate-js Later Implemented Nothing outstanding
0013 The admin panel Later Implemented Nothing outstanding
0014 Library sources, storage modes and Calibre Later Implemented; storage modes, refresh leases and the review queue superseded by 0017 Nothing outstanding
0015 Catalog payloads clients can walk Client Implemented Nothing outstanding
0016 Token self-introspection Client Accepted; phases 1–2 implemented Return a stable opaque account_id for safe reconnect detection
0017 Folders, watched — not an ingest pipeline MVP Implemented Nothing outstanding
0018 Series a reader can shape Later Accepted Phases 1–4; Calibre write-back deferred to its own ADR
0019 Catalog entities belong to the library Later Accepted Renaming decided in 0020, merge and split in 0021
0020 Renaming a series Later Accepted; implemented Merge and split decided in 0021
0021 Merging and splitting a series Later Accepted; implemented All four phases; Calibre write-back constrained here, decided in its own ADR
0022 A Calibre library's metadata.db is authoritative Later Accepted; implemented Purge, unservable observations and digest re-registration; amends rules on 0017
0023 An upload is a file written into a folder Later Accepted; implemented Folder opt-in, library-upload scope, plain and Calibre folders; amends rule 3 of 0017 and reinstates phase C of 0008
0024 Deleting is a reader forgetting, or an administrator retiring Later Accepted; implemented Per-user work delete for a work no book backs, admin delete of a missing catalog row; amends the append-only rule for that one case
0025 A book may be deleted where a book may be written Later Accepted Deleting a book's file and row from an accepts_uploads folder; library-delete scope over the API, admin in the browser; amends 0024 and rule 3 of 0017 again
0026 Credential enrolment does not weaken account authentication MVP Accepted; implemented Kosync pairing only; administrator password re-verification before creating an account or invite
0027 Explicit per-user folder access MVP Accepted; implemented Folder grants across storage, catalog surfaces, administration and CLI; amends 0017
0028 Annotations are mutable reading state, not history Later Accepted Phase 1: the annotations table, second per-user counter and store methods in both backends, with the storetest suite
0029 A folder somebody can read MVP Accepted; implemented Creator grant in the folder's own transaction, guarded backfill migration 6, a Library page that names which situation it is in; amends 0027
0030 The web reader counts its sittings Later Accepted; implemented Visibility-bounded sittings, three-minute idle cap, ten-second minimum, no local persistence; amends 0007
0031 The web reader's footer mirrors the app Later Accepted; implemented Percent, middle slot, page in the engine's bottom margin; pages are engine locations, never fabricated; click cycles the middle; a browser preference; amends 0012
0032 The reader's page is the app's page Later Accepted; implemented Pages counted as Readium positions so the browser and the app name the same page; display only, no server or API change; three recorded patches to the vendored engine; amends 0031 and 0012
0033 A device outlives its token MVP Accepted; implemented POST /v1/tokens inherits a device_id the account already carried, 400 unknown_device otherwise; account_id on GET /v1/token; the store keeps comparing devices; amends 0016
0034 A live notification says only that something changed Client Accepted GET /v1/events as topic-only SSE, published post-commit by the store, authorized per topic; correctness stays in the existing feeds; amends 0007
0035 Naming a shelf is one request Client Accepted; implemented POST /v1/books/resolve for up to 500 books, one transaction and one answer each, 200 with per-item not_found/ambiguous; same library-read + sync pair; amends 0003

Convention

  • Files use a four-digit sequence: NNNN-short-title.md.
  • New ADRs are appended. Do not renumber an active ADR.
  • Status is one of Proposed, Accepted, Deferred, Superseded, or Rejected.
  • Each ADR records context, decision, consequences, implementation phases, and acceptance criteria.
  • An ADR states the current decision. It is not a changelog. Record what is true and what remains, in a sentence or two per phase — not a narration of what each commit added. If a phase's status needs a paragraph, it is being written as a diary.
  • Prefer deferring a decision to over-specifying one. A section describing mechanics for code that does not exist is a liability: it will be wrong by the time it is built, and it hides the decisions that are actually load bearing.
  • These ADRs are active implementation documents. Remove one from this directory and index only after its complete behavior is implemented, reviewed, covered by CI-equivalent tests, and absorbed into permanent design, API, deployment, and integration documentation.