# `SuperPi.Workers.MemoryHarvestWorker`
[🔗](https://github.com/oleksandr/super-pi-beam/blob/v0.1.0/lib/super_pi/workers/memory_harvest_worker.ex#L1)

Oban worker in the `:compaction` queue that saves durable facts from the entries a compaction cuts.

Compaction destroys information, which makes it the best moment to keep some of it. The work is
asynchronous because `before_compact` sits on the machine's critical path
(`SuperPi.Plugins.Memory.before_compact/2` only enqueues, and compaction proceeds unchanged).
It shares the queue because a queue of its own would push the sum of the queue limits above the
SQLite pool size, which a config test forbids. The cost is that two slow harvests can delay a
background compaction.

## Job

Args: `conversation_id`, `head_entry_id`, `entry_ids`, `scope_kind`, `scope_id`. The job is unique
on `conversation_id` and `head_entry_id`, so a repeated compaction of the same cut enqueues one job.
A retry or a re-run is also safe: a fact gets a slug from the head entry and a hash of its title, so
a second run updates the same notes.

## Facts

The worker renders the entries as a transcript (each message cut at 1 500 characters, at most
24 000 characters in all, the newest kept) and asks the model for JSON:
`{"facts": [{"title", "body", "topics"}]}`. At most `:harvest_max_facts` facts (8) are stored, with
`compaction` provenance, confidence 0.3 and `source` naming the conversation and head entry. Such a
note cannot be pinned, and the index lists its title only. The transcript may hold hostile web
content, which is why the facts stay low-trust.

The model is `:harvest_model` (a fast one). Tests set `config :super_pi, :memory, harvest_llm: fun`,
a function from the prompt text to `{:ok, text}` or `{:error, reason}`. Unusable model output
fails the job, and Oban retries it up to 3 times.

# `parse`

```elixir
@spec parse(String.t()) :: {:ok, [map()]} | {:error, :bad_reply}
```

Parses the model reply into facts. Accepts a fenced block or text around the JSON object.

# `prompt`

The prompt text for a transcript.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
