Skip to content

Repository files navigation

ariadne

CI License: MIT

You are three hundred pages into a long novel, somebody walks into the room, and you have no idea who they are.

Every place you could look to find out will tell you something you haven't reached. A wiki article is written from the ending. A character list on a retail page names who survives to be worth naming. Searching the name finds a forum thread about what they do in the last act. So you either read on and stay lost, or you spoil the book to stop being lost — and a lot of people just put it down. That's the problem this is for.

The blurb was never going to save you. Measured over 113 fiction nominees from the 2025 Goodreads Choice Awards, a synopsis names a median of two people; over 53 novels measured whole, a book has introduced nineteen by a tenth of the way in and finishes with sixty.

What Ariadne does about it

It builds the book's cast as you read it, from your own copy, and shows you nothing past your bookmark.

Point it at a book you own. It reads the file, works out who appears in which chapter, and gives you an index with a bookmark on it. Move the bookmark to chapter 40 and you see the book as it stands at chapter 40 — who you have met, who you haven't seen for a while, who tends to be in the room with whom, where the book has been. Chapter 41 doesn't exist in the view.

The spoiler rule is structural, not a filter. Every view is built from the chapters behind your position, so there's no later data sitting in the page waiting to be revealed by a bug. That property is asserted by a test that runs on every commit.

The cast of War and Peace as it stands at chapter 180, ranked by how much of the book each person has had

Early days. It works on the sixteen books below and on any DRM-free epub you own. It's also convinced that Moby Dick is a place until you tell it otherwise, and nobody has read a whole book with it yet.

Installing it

From a release — the .deb is on the releases page:

sudo apt install ./ariadne_*_all.deb

As a Flatpak — the bundle is on the releases page beside the .deb:

flatpak install ./ariadne_0.1.0.flatpak

Or build one yourself with make flatpak to install it locally, or make bundle for the single file.

Needs org.gnome.Platform//50 and org.gnome.Sdk//50. It asks for your home directory so you can browse to a book without going through the file portal every time. It asks for no network at all.

From a clone:

make venv && make install

This puts ariadne on your PATH and a launcher entry in your applications menu. make help lists everything else, and make uninstall removes all of it.

Pick one or the other. make install puts a wrapper in ~/bin, which on most setups comes before /usr/bin on PATH — so with both present, ariadne is the wrapper and the packaged binary is never reached. which -a ariadne settles it.

Python 3.12 or newer, and nothing else — the engine needs only the standard library, and tests/test_layering.py proves it by importing every engine module with the toolkit blocked.

If the window doesn't open

The GTK parts come from your system rather than from pip, so they may not be there. Run:

ariadne --doctor

It says what is missing and gives you the command to install it. Everything else works fine without them — pages, --inspect, --about, --refusals, the whole command line.

The desktop reader

ariadne ~/Books/some-book.epub --app

Or open Ariadne from your applications menu and pick a book.

The window shows what the page shows, and here you can also correct it. When it lists Prince Andrew and Prince Andrew Bolkónski as two people, click one and tell it they are the same man. Notes, merges and warnings go into a small file of your own, and there are fifty steps of undo.

Across the top is the bookmark, and it is also the chapter axis. Every strip and band below it is drawn to that same scale, so a line dropped through your position lands on the same chapter everywhere on screen. Drag it, or click any chapter on any strip. [ and ] step one chapter; Ctrl+G, or the position in the title bar, jumps to one you type.

Down the left: the cast, where the book has been, a map of who shares chapters with whom, a pace chart, and your warnings. The cast has four cuts across the top of it — everyone, people, places, and the ones you have not seen for a while. Click any name and a panel opens with everything known about them so far, and nothing after.

The detail drawer, asking whether two names are one person, with the chapters that name is in below it

It doesn't guess at any of this. Two names might be one person or they might be two, and in some books that's the plot.

Where your rulings are kept

In ~/.local/share/ariadne/books/, one small JSON file per book. ariadne --doctor prints the path and how many books are in it.

They used to live next to the book, and that broke on the books people actually own. A novel on a removable drive, on a read-only share, or opened through the Flatpak file portal — which hands over the one file you picked and nothing around it — is somewhere Ariadne cannot write. Every save failed quietly and the window said it had saved.

A book is found by what's in it, not where it is. The filename is the book's title and a hash of its contents, and only the hash decides which book it is. Divergent.epub, 01 - Divergent - Veronica Roth (2011).epub and [1] divergent_RETAIL.epub are one file with one set of rulings — move your library, rename a file, or copy it to another disk and they follow. The name comes from the book's own title rather than your filename, because a filename is a shelving convention and it changes; whatever name a book gets first is the one it keeps. Editing the book is a different matter: a re-download or a metadata change makes it a different file, and the old rulings stay under the old one.

If you already have a .ariadne.json next to a book, it's read once and moved into the store. Nothing is written next to your books again. --decisions PATH still puts one wherever you want it.

Where the book has been

One band per setting, chapters left to right, in the order the book arrived at them

One row per place, chapters running left to right, in the order the book got to them. Reading down the list is reading the journey.

It isn't a map of the world and won't become one. Bald Hills and Thrushcross Grange aren't on any map, and there are two Ithacas. What this draws is where the book spends its time.

Each row starts as a guess. The guess is right about four times in five, so you keep or bin each one — Moby Dick is a whale.

Pace

Four measures of every chapter on a shared axis, with one cursor down all of them

How much of the chapter is dialogue, how many people are in it, how many names are new, and how long it runs. Move the cursor and all four move together, so you can see that chapter 140 was quiet and crowded at the same time.

They run on the same axis as the bookmark, so the lines stop where you are and the rest of the book is empty space you can see the size of.

There's no score anywhere on it. A slow chapter might be exactly what the author wanted.

Making a page

ariadne ~/Books/some-book.epub -o some-book.html

An epub, a Word document, a folder of Markdown, or plain text. It takes about a second, even for War and Peace.

What comes out is one HTML file. No install, no account, nothing to sign up for, and it works offline. It contains no text from the book at all — names, counts and chapter numbers — so you can send it to a friend reading the same thing.

ariadne <file> --inspect     # what it found, without writing anything
ariadne <file> --about       # what you are in for, before you start

What it won't do

Of 59 books tried, it handles 48. The other 11 it turns down and tells you why, usually because it can't work out where the chapters start.

It also won't tell you who is speaking a line of dialogue, decide whether something was written by a machine, match a book against other authors to guess who wrote it, or give a book a score.

ariadne --refusals

Each of those has a reason and a number behind it. Attributing dialogue, for instance, works on 6.6% of lines — which isn't a rough answer, it's a wrong one nine times out of ten.

Warning yourself about a chapter

ariadne book.epub --warn "24=someone does not make it through this chapter"

At chapter 23 it says something is coming and keeps the text folded shut until you open it.

Ariadne finds none of these itself. Tagging books by what happens in them is a fight it has no business joining, and a false positive costs somebody a book they would have been fine with. The warning is yours, it sits in your own file, and you can hand it to someone else reading it.

Layout

src/ariadne/
  core/         the refusal, the tunable numbers, the quoted-span pattern
  ingest/       files in, chapters out
  model/        chapters in, the index out — and the clipping every view uses
  decisions/    the reader's own rulings, in a sidecar keyed to the book
  position/     where the reader is
  analysis/     what can be said about a book without spoiling it
  ai/           the two commands that need an account
  invariant.py  the property that must never regress
  render/       the page
  app/          the desktop reader
  cli/          the command line

Each layer may use the ones above it and none below. The engine is everything above render, and it runs on a machine with no GUI toolkit at all.

Neither of those is a promise in a file. tests/test_layering.py reads the imports, fails on a folder nobody declared, and imports the whole engine in a subprocess with GTK blocked.

Reading further

Getting started Install it, open a book, and what to do first
Why Ariadne exists The problem it was built for, and what that decided
CONTRIBUTING.md How to change it without breaking the one rule
SECURITY.md What it reads, what leaves your machine, and what is still open
CHANGELOG.md What changed

License

MIT. See LICENSE.

About

A reading companion that builds a book's cast as you read and never shows you anything past your bookmark. Point it at an epub you own: it writes one self-contained page holding no text from the book, or opens a GTK 4 window where you rule on who is who. Offline, no account. A prototype.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages