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. |
||
|---|---|---|
| .. | ||
| 0001-content-server.md | ||
| 0002-library-storage-and-ownership.md | ||
| 0003-catalog-work-identity.md | ||
| 0004-metadata-and-categorization.md | ||
| 0005-upload-and-ingestion.md | ||
| 0006-catalog-api-and-opds.md | ||
| 0007-web-reader.md | ||
| 0008-liseur-android-client.md | ||
| 0009-liseur-desktop-client.md | ||
| 0010-duplicate-detection.md | ||
| 0011-web-ui-revamp.md | ||
| 0012-reader-engine-foliate.md | ||
| 0013-admin-panel.md | ||
| 0014-library-sources-and-storage.md | ||
| 0015-catalog-payloads-for-clients.md | ||
| 0016-token-self-introspection.md | ||
| 0017-folders-not-pipelines.md | ||
| 0018-series-overrides.md | ||
| 0019-library-wide-entities.md | ||
| 0020-series-renaming.md | ||
| 0021-series-merge-split.md | ||
| 0022-calibre-metadata-db-is-authoritative.md | ||
| 0023-uploads-land-in-a-folder.md | ||
| 0024-deleting-a-work.md | ||
| 0025-deleting-a-book.md | ||
| 0026-credential-enrolment-does-not-weaken-account-authentication.md | ||
| 0027-explicit-per-user-folder-access.md | ||
| 0028-annotation-sync.md | ||
| 0029-a-folder-somebody-can-read.md | ||
| 0030-web-reader-reading-sessions.md | ||
| 0031-web-reader-footer.md | ||
| 0032-reader-pages-are-readium-positions.md | ||
| 0033-a-device-outlives-its-token.md | ||
| 0034-live-notifications-say-only-that-something-changed.md | ||
| 0035-naming-a-shelf-is-one-request.md | ||
| README.md | ||
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, orRejected. - 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.