Whiskers' storage, version 1. SCHEMA.md says what each table is and how it merges.
What Whiskers remembers: one current row per memory.
4CREATE TABLE fact ( 5 id INTEGER PRIMARY KEY AUTOINCREMENT, 6 gid TEXT NOT NULL UNIQUE CHECK (gid <> ''), 7 text TEXT NOT NULL, 8 text_at_ms INTEGER NOT NULL DEFAULT 0, 9 learned_at_ms INTEGER NOT NULL, 10 kind TEXT NOT NULL CHECK (kind IN ('person', 'pet', 'toy', 'place', 'event', 'thing', 'other')), 11 who TEXT NOT NULL DEFAULT '[]', 12 place TEXT, 13 said_when TEXT, 14 hidden INTEGER NOT NULL DEFAULT 0 CHECK (hidden IN (0, 1)), 15 visibility_at_ms INTEGER NOT NULL DEFAULT 0, 16 icon TEXT, 17 cover_picture TEXT, 18 cover_at_ms INTEGER, 19 CHECK ((cover_picture IS NULL) = (cover_at_ms IS NULL)) 20) STRICT;
Every time she said it: append-only, merged by union. These are the timeline's entries.
The words a memory had before they changed: append-only, kept for debugging. Nothing on the way to a
prompt reads this. at_ms is when the words were replaced.
The embedding of the current words: 32-bit floats, little-endian.
Which pictures go with a memory, in order. A name may be here before its bytes have arrived.
What the parents forgot: the identity, when and on which device, never content.
A forgotten memory cannot be written again, whatever arrives later.
Writing a tombstone deletes the memory, and with it (ON DELETE CASCADE) every mention, revision, embedding and picture link. There is no state that holds both.
A picture, byte for byte, under the name every device knows it by. Never replaced.
The one append-only log of everything said, as a device wrote it. On a device this holds its own lines and
the copy of everyone else's it has pulled; on the service, every device's, in arrival order (position).
Which pictures a logged conversation shows, so a picture a log line still needs is not deleted with a memory.
93CREATE TABLE journal_picture ( 94 device TEXT NOT NULL, 95 seq INTEGER NOT NULL, 96 picture_id TEXT NOT NULL, 97 PRIMARY KEY (device, seq, picture_id), 98 FOREIGN KEY (device, seq) REFERENCES journal_line (device, seq) 99) STRICT, WITHOUT ROWID; 100CREATE INDEX journal_picture_by_picture ON journal_picture (picture_id);
A picture goes with the last thing that used it: when a memory's last link to it goes (the memory was forgotten) and no logged conversation shows it, its bytes go too.
104CREATE TRIGGER picture_unused AFTER DELETE ON fact_picture 105BEGIN 106 DELETE FROM picture 107 WHERE id = OLD.picture_id 108 AND NOT EXISTS (SELECT 1 FROM fact_picture WHERE picture_id = OLD.picture_id) 109 AND NOT EXISTS (SELECT 1 FROM journal_picture WHERE picture_id = OLD.picture_id); 110END;
The running chat: one row for the session, and its recent turns in order.
The grown-ups' choices: one row per setting, each with the moment it was written.
Time spent with Whiskers, by device and day, in milliseconds. A device writes only its own rows, so they cannot conflict; the day's total is their sum. Counts only ever rise.
Small facts about this database itself.
What the service has spent on thinking: when and how many tokens, inside the window the ledger keeps.