Skip to main content
brain/ is the library of what you have read and kept: papers, blog posts, internal docs, video transcripts. It is the fastest part of px0 to get value from, because it needs no connections and no workflows - just a store. It can be px0’s own folder or any folder of Markdown you already keep, including an Obsidian vault. Unlike workflows/ and guidelines/, it is not versioned. That is intentional: this is bulk reference material, and anything in it is rebuildable from its source URL. Version history for a blog post you saved would be noise.

Add something

Extraction always runs locally and needs no API key. The destination folder is picked from the source type; override it with --to when you want something filed somewhere specific. Anything else is refused, and the error lists every accepted extension. pdftotext and pandoc are used when installed, but nothing depends on them being there.
--to accepts any relative path inside the brain, so a store pointed at a vault with its own structure is not limited to docs, blogs, papers, and work. It is refused if it would land outside the brain - an absolute path, ~, or a .. that climbs out - and nothing is written when it is. To ingest a whole backlog at once, one source per line:
Blank lines and lines starting with # are ignored, and the index is rebuilt once at the end rather than per file - which is what keeps a long list from being quadratic in the size of the library. A video with no published transcript is not rejected. px0 writes it as a stub: its metadata only - title, channel, description - marked kind: stub, with the refresh command to retry printed for you. A scanned PDF with no text layer is refused with a note that it needs OCR first.
refresh works on anything you have ingested, not just video: it re-fetches the source - a web page is fetched again, a local file re-read, a PDF or document re-extracted - and rewrites the file in place. A stub retries its transcript and is promoted to a full video if one has since been published.
A file with no retrieved date is always treated as stale.

Playlists are queued, not ingested inline

A YouTube playlist URL would be a long, failure-prone operation to run in the foreground, so px0 queues it as a job under .state/ingest/ and lets px0 daemon start drain it in the background, one brain file per video that has a transcript. Without yt-dlp installed, only the first ~100 videos of a playlist are reachable, because that is all YouTube renders into the page px0 can fetch - the shortfall is reported rather than passed off as a finished job. A job that keeps failing is retired to .state/ingest/failed/ rather than retried forever. A playlist therefore needs the daemon running to actually land:
See Schedules and the daemon.

When a source will not fetch

Ingest failures are reported, never raised as a traceback, and each names what actually went wrong:
An unrecognized source says what it accepts rather than guessing:

See what is in the library

show and rm accept any of these forms for a path: a library-relative path (blogs/x.md), a store-relative one (brain/blogs/x.md), an absolute path, or a bare filename matched anywhere in the brain - refused if the name is ambiguous. rm drops the file’s passages from the index too; deleting the file by hand works right up until you search, because the passages stay indexed until something rebuilds it. Or, for the whole store at once - workflows, guidelines, and the brain in one pass:
To copy the library elsewhere, keeping its folder structure:
The private folder is held back unless --include-private says otherwise - its whole promise is that it does not leave the machine by accident.

Where it lives

By default ~/.px0/brain, with folders that come from the ingest types: You are not limited to those. Create folders that suit how you think, and px0 will index them - retrieval walks brain/ recursively and does not care about the structure, the one exception being the private folder. If you already keep notes somewhere else, point px0 at that directory instead of copying files into the store:
Any folder of Markdown works: an Obsidian vault, a Logseq graph, a notes/ directory in a repo. px0 reads it in place - reindex, search, and ask never write to it. Skipped automatically: every dot-folder (.obsidian/, .trash/, .git/, .stversions/) and drawings stored as Markdown (*.excalidraw.md). Add your own patterns with brain.ignore:

brain/work/ never leaves the machine

Anything filed under the private folder - work/ by default - is excluded from every retrieval px0 performs: px0 brain search, px0 brain ask, and workflow retrieve: inputs alike, on both retrieval backends.
This is a hard exclusion, not a ranking penalty. Files under the private folder are never retrieved and therefore never inlined into a prompt that goes to your model backend. It is the right place for material you are willing to keep locally but not willing to send anywhere. See What leaves your machine.
The folder name is brain.private_folder, and it is configurable - set it to "" to disable the behaviour entirely, or rename it if your vault already has a top-level work/ you do want searched:
px0 config set brain.path warns when it spots a collision with an existing vault folder, px0 brain list marks such files (private), and px0 doctor reports the count.

Keep the index fresh

Every px0 brain add indexes what it just filed, and the daemon’s nightly pass reindexes the whole library. You only need to do it by hand after bulk changes - dropping in a folder of files, editing many at once, changing brain.path, brain.ignore, or brain.private_folder, or switching backends:
px0 doctor tells you when the index and the library have drifted apart:

Next steps

Search and ask

Query the library and get answers with citations.

Retrieval backends

Keyword search by default, semantic search when you want it.