1# whiskers-core
2
3The conversation pipeline and what hangs off it. `Conversation::respond(heard)`
4takes what the child said (and any pictures they showed) and returns what Whiskers may
5say back. Every turn runs the same path: keep any pictures, log what the child said,
6ask the guard, ask the model, log what it wrote, ask the guard again, log what is
7said.
8
9The parents' log gets everything, including model text the guard kept from the child.
10If any step fails, or the guard cannot be reached, the answer is one of a few
11fixed lines (`Fallback`), so the child is never met with silence or an error message.
12Something that means the child is hurt or unsafe is its own outcome, `NeedsAGrownUp`.
13
14The chat is persistent (`chat.json`): a running summary plus the recent turns, so
15closing the app or folding the phone loses nothing, and it greets the child only the first
16time or after a long quiet. Once it grows past a limit the oldest turns are folded into
17the summary.
18
19Remembering happens off to the side, never inside a turn. After a reply the shell calls
20the engine's `reflect`, and the `Reflector` asks the model for structured facts (kind,
21who, place, when, pictures), passes the batch through the guard, embeds what passes and
22stores it, skipping near-duplicates. On the next turn `Recall` finds the facts that matter:
23all of them while few, otherwise the nearest by embedding, reranked by Jev. If the embedder
24or ranker is down it degrades to recency or embedding order. Parents can remove a fact with
25`forget`, which is permanent and tombstones its identity on every device.
26
27**Putting away is not forgetting.** She can put a fact away (`Memory::hide`): it stays, the parents
28still see it under "removed by her" and can restore it (`Memory::restore`), but Whiskers stops using it
29(recall, prompts, search never see it). It is a last-writer-wins register on the fact
30(`Visibility`, `src/visibility.rs`), so merging in any order gives the same memory; the parents'
31`forgotten` beats everything.
32
33| File | What |
34|---|---|
35| `src/conversation.rs` | `Conversation`, `Parts`, `Reply`, `Speakable`, memory reflection, the fixed fallback lines. |
36| `src/ports.rs` | The traits an adapter implements: `Model`, `Guard`, `Log`, `Pictures`, `Memory`, `Clock`. |
37| `src/profile.rs` | The child's profile (`Child`, `ChildName`, `Age`), the `Audience` prompts are written for, and the `SharedProfile` the app updates. |
38| `src/persona.rs` | The prompts and greeting, written for an `Audience`. |
39| `src/visibility.rs` | `Visibility`: whether she has put a fact away, and the register's merge. |
40| `src/types.rs` | Turns, pictures, verdicts, outcomes, facts and the log entry format. |
41| `src/log.rs` | `JsonlLog` (append-only, flushed per line) and `DirPictures`. |
42| `src/chat.rs`, `src/shared.rs` | The persistent chat and the shared, lock-light handles to log, memory and chat. |
43| `src/reflect.rs`, `src/recall.rs` | Background remembering and compression; finding the facts for a turn. |
44| `src/memory.rs` | `MemoryDoc` (the memory with no storage attached, and its pure merge) and `JsonMemory`, which keeps one in a file replaced atomically on every change. |
45| `src/wire.rs` | What the tablet and the service say on the Jev routes (`CheckRequest`, `EmbedRequest`, `RankRequest` and their replies). In the core because both ends need it. |
46| `src/digest.rs` | Reading the log back and shaping a day for the parents' view, with the model-written summary. |
47| `src/voice.rs` | The natural voice's daily character allowance. |
48| `tests/` | The pipeline against fakes; the storage adapters on a real directory. |
49
50Nothing that touches a file, the system clock or stderr is compiled for `wasm32-unknown-unknown`
51(`atomic.rs`, `log.rs`, `logging.rs`, `JsonChat`, `JsonMemory`, `TimeKeeper`, `read_log`,
52`read_shared_log` are `cfg(not(target_family = "wasm"))`), so a Worker that links the core for the
53documents and their merge rules ([`whiskers-ports`](../whiskers-ports/) does) cannot reach file code by
54accident. The merge rules themselves (`MemoryDoc::merge`, `Household::merge`, `ChatState::merge`) are pure.
55Note this module's `ports.rs` are what a *device's* pipeline runs through; the backend's ports are in
56`whiskers-ports`.