A second brain from the future: PARA and a Zettelkasten slip-box in one place. Pirsig is a
Loco app in Rust. A desktop app, a REST API and a terminal CLI, psg,
share one model layer, so the rules are the same wherever you work.
Pirsig is named for Robert M. Pirsig (1928–2017), the author of Zen and the Art of Motorcycle Maintenance (1974) and Lila (1991). He is my favorite author and a great inspiration to all of my work. On 24 April 2027 it will be ten years without him.
The logo is ç„¡, mu, "no thing": in chapter 26 of Zen and the Art of Motorcycle Maintenance, Pirsig takes it from Zen as the answer that is neither yes nor no, and writes that "science grows by its mu answers more than by its yes or no answer" (p. 413 in the edition LitCharts cites; see docs/drawings).
You need Rust (the repository pins the version) and
just.
git clone https://github.com/h0ffmann/pirsig.git && cd pirsig
just desktop # the desktop app; or `just dev` and open http://localhost:5150Or stay in the terminal:
just install # puts `psg` on your PATH
psg note -c "Atomic notes beat long documents" # capture a thought (the inbox)
psg note -c -t "Links beat folders" -k permanent -b "Because [[1]] says so. #pkm"
psg area -c -n Health && psg project -c -n "Run a 10k" -a 1 --due 2027-04-18
psg ready # what the brain still lacks, and how to fix itThen pick a starting point: just fork-state loads my public notes, just brain-reset
fills the brain from your own GitHub (see below).
| How | Status | |
|---|---|---|
| Self-hosted, live | The desktop app (Tauri, Rust): just desktop. Or the server alone, just dev, with the same UI in a browser. Your brain stays on your machine, in SQLite. |
available |
| Android app | The same app on your phone (Tauri): just android-dev on a device or emulator, just android for an APK. The brain lives on the phone. |
from source |
| Mobile cloud | Pirsig hosted for you at piabrota.art/pirsig. | coming |
How to read this figure
Takeaway. Whatever you use, the terminal, the desktop app or HTTP, goes through the same rules, and the brain can leave Pirsig as a diagram or as a knowledge graph.
How to read. Top to bottom, one lane per role. Arrows say what flows. The orange border marks where you come in and the outside tools that draw the result.
Not shown. Auth, the background workers, and the archive (--archived) and done tasks
(--all) switches of the exports.
Evidence. docs/archify/how-pirsig-works.json, the source of
the figure; src/cli/mod.rs, src/controllers/, src/figures/.
This repository is a GitHub template: Use this template → Create a new repository, and make the new repository private, because your brain is personal data. Then:
git clone git@github.com:<you>/<brain>.git && cd <brain>
just adopt <you> <brain> # its URLs, app id, owners and contacts become yours; review with git diff
just brain-reset # your own GitHub in the brain (or: just fork-state, to start from mine)
git commit -am "Adopt Pirsig" && git pushThen make it work your way in pirsig.toml: the repository a new brain is
bootstrapped from (just adopt points it at your copy), the fork state's folder, the defaults
of psg gh, and what the macOS and Android apps start from on first launch. Every key is
optional, and a key Pirsig does not know is an error, so a typo shows. The Loco side (port,
database, logging) stays in config/.
To take later versions of Pirsig, add this repository as upstream:
git remote add upstream https://github.com/h0ffmann/pirsig.git, then
git pull upstream main --allow-unrelated-histories the first time and git pull upstream main
after that. just template-check says whether a copy is still fit to be a template itself;
docs/template-readiness.md is the full survey.
This repository carries my brain's public notes in brain/, a Markdown vault (the
Obsidian export format) that reads well on GitHub too:
- Featured repositories, my own repositories pushed in the last two years: a note and a resource each, indexed by category in hub notes under the areas I keep.
- Public forks, one index note, a line per fork, by category.
- Cold repositories, the own ones with no push for two years, in one more index note.
just fork-state # start from brain/: my note structure, in your brain
just brain-reset # or replace the whole brain with your own GitHub (psg gh --overwrite)
just fork-export # write your brain to brain/, for whoever copies yours
psg bootstrap repo acme/brain # or start from any Pirsig repository's brain/, no clone neededpsg bootstrap repo takes owner/repo, a GitHub URL or a local checkout, and defaults to
[template] repo in pirsig.toml; it downloads one tarball and reads only its fork state. The
macOS app does the same on first launch, so an installed app starts from the template's brain.
psg gh takes the same depth controls: --cold-after MONTHS (default 24) and
--forks index|notes|skip, with their defaults in pirsig.toml's [github]. Both fork-state and brain-reset back the brain up next to its
database file before they replace it. psg fork export leaves out every note tagged
#private, the resources only those notes cite, and any link or list line that would name
them, so private repositories never reach brain/.
Your brain is personal data; this repository is public code. Keep your own brain in a private copy of this repository, so nothing you write ends up on the web because it is in git:
# create an empty private repository first, e.g. github.com/<you>/brain
git clone https://github.com/h0ffmann/pirsig.git brain && cd brain
git remote rename origin upstream
git remote add origin git@github.com:<you>/brain.git
git push -u origin main
git pull upstream main # later, to update PirsigPublishing will be a separate, explicit step (designed, not built): psg publish shows a
plan of exactly what would become public, like terraform plan, and only
psg publish --apply does it. See docs/design.
| What | API | CLI | |
|---|---|---|---|
| Projects | outcomes with an end, inside an area | /api/projects |
psg project |
| Areas | ongoing responsibilities | /api/areas |
psg area |
| Resources | reference material, optionally tied to an area or project | /api/resources |
psg resource |
| Archives | archived_at on areas, projects, resources |
POST /api/<kind>/{id}/archive, ?archived=true |
--archive ID, --archived |
Tasks (/api/tasks, psg task) are next actions inside a project. The same rules hold in
every interface:
- Names are never blank, and area names are unique. A project's
statusisactive(the default),waiting,somedayordone;--duegives it its end date. - Nothing active lives in the archive. Archiving an area archives its projects and resources, and nothing new goes into an archived area or project.
- Deleting an area or project that still has children needs
--force(?force=true). - A resource can carry a
kind(paper,book,repo, ...) and a uniquecitekeythat literature notes cite. - A project pulls notes in by link, without owning them:
psg project --pull 2 --note 1a -w "the training plan".
Notes have Luhmann-style ids (zid): 1 starts a train of thought, 1a continues it,
1a1 branches off 1a, 2 starts the next one.
- Kinds, after How to Take Smart Notes:
fleeting(the inbox),literature(cites asourceor the resource it was written from),permanent(your own words) andhub(structure). - Links:
[[1a]]or[[Some title]]in a body becomes a link on save, even when the target comes later. Renaming a note rewrites the links to it. Hand-made links (psg link A B -w "why") carry a reason. - Labels:
#hashtagsin the body plus--tag(labels and tags). - Views: backlinks, inbox, orphans, random, the Folgezettel tree, the graph, stats.
psg note -c -t "Links beat folders" -a 1 -k permanent -e # continue 1 as 1a, in $EDITOR
psg note -s 1a # the note, its links and backlinks
psg note rust # search; also -k KIND, --tag TAG
psg link 1a 2 -w "contradicts"
psg box tree # also inbox, orphans, random, graph, statsA Hippo is a way of thinking: a name, a description and fixations, the subjects its
notes gather around. Its notes form a rhizome, not a tree: each note is linked in when it
is saved (to notes that share a fixation, a tag or a title word, else to the last one
captured, and every link says why), --after is refused, and deleting a note links its
neighbours to each other.
psg hippo -c -n h0 --fixation "rogue waves" --fixation chess
psg note -c "the Draupner wave was linear focusing?" -H 1 # woven in on save
psg hippo --map 1 # where you left off, each fixation's notes, any pieces
psg hippo --weave 1 # join the piecesA plast is a kind of quick exercise that trains the brain itself: six ship, one per domain (math, abstraction, logic, music, literature, languages), five levels each. Right answers push a plast out and three in a row raise its level; wrong ones bring it back.
psg plast go # five exercises, the most due first (or: just plast)
psg plast go -d music # one domain| Channel | CLI | API |
|---|---|---|
| GitHub repos in: featured notes, fork and cold indexes | psg gh [--private minimal] [--readme] [--cold-after 24] [--forks index] [--overwrite] |
|
| The fork state out and in | psg fork export, psg fork import [--overwrite] |
|
| Obsidian vault out and in | psg obsidian export ./vault, psg obsidian import ./vault [--dry-run] |
|
| RSS/Atom feeds in, as resources | psg rss add URL -a AREA, psg rss pull |
/api/feeds |
| The slip-box out, as RSS | psg rss out -o feed.xml |
GET /api/slipbox/feed.xml |
| arXiv papers in: cited, filed, deduplicated | psg arxiv add ID... [--note], psg arxiv search QUERY |
POST /api/ingest/arxiv |
| Methodology readiness | psg ready |
GET /api/readiness |
psg ready checks the brain against PARA, the Zettelkasten method and the channels, and says
what to run for each gap. docs/methodology.md has the readiness
matrix: what is enforced, what is only reported, and where each rule is tested.
The app (desktop/, Tauri 2) targets macOS and Android. just desktop
opens it on the same brain as psg; just desktop-build makes a Pirsig.app, which keeps its
brain in its own data folder and, on first launch, bootstraps it from the template's fork
state. just android-dev and just android run it on a phone. Everything is managed there: PARA and the archive, notes with their links and
backlinks, the slip-box views, Hippos, feeds and arXiv, Plasticity and readiness. The app runs
the REST API inside itself and the API serves the UI, so just dev shows the same UI in a
browser. just desktop-e2e drives it end to end in WebKit.
The pirsig plugin brings three skills to Claude Code: pirsig (work in the brain),
zk-method (check notes against the method) and hippo (grow a Hippo's rhizome).
claude plugin marketplace add h0ffmann/pirsig
claude plugin install pirsig@pirsigscripts/plugin-smoke.sh installs it from a checkout into an empty config, as a third party
would; CI runs it on every change. The evals in plugins/pirsig/evals/ run by hand
(Actions → plugin), because they cost API credits.
An Obsidian plugin in obsidian-painter/, mostly Rust compiled
to WebAssembly: ```desmos blocks draw offline, ```archify blocks show
figures, and "Export note to PDF" writes a paper-quality PDF through pandoc. just painter
builds and tests it.
psg figure exports the PARA tree as archify JSON, and
psg graph the brain as a graphify graph.json
(also GET /api/figures/tree and /graph).
psg figure -o docs/archify/para.json && just figure # -> docs/img/para.png
just graph # -> graphify-out/graph.htmlHow to read this figure
Takeaway. This is psg para as a picture: every area, project, open task and resource in its
place.
How to read. Top down, each line means "contains". Below the root are the areas, then their projects, then tasks and resources. Small grey text is the description, status, due date or URL.
Not shown. Done tasks and the archive; psg figure --all --archived puts them in.
Evidence. docs/archify/para.json, written by psg figure from the
demo brain of just figure-para; the drawing is archify's.
Diagrams follow the figure skill: sources in docs/archify/, just figure draws them with
the vendored archify, and just figure-check says whether a PNG is stale.
- CLI.
just installputspsgon your PATH (orcargo run --bin psg -- <cmd>). Every command takes--json.psgreads the config ofLOCO_ENV(defaultdevelopment) from./config, and./pirsig.toml(or the filePIRSIG_CONFIGnames);DATABASE_URLpicks another brain. Pending migrations run on their own. - justfile.
just n "An idea",just show 1a,just find rust,just ready,just dev,just check(fmt, clippy and tests, as CI).justlists them all. - Server.
cargo loco startserves the API and the UI on http://localhost:5150. Rust 1.94 or newer;rust-toolchain.tomlpins it, so rustup installs it on the firstcargocommand. - Drawing. The logo at the top is ç„¡ drawn from its Desmos expressions by
cargo run -p pirsig-drawings --bin pirsig-art; see docs/drawings. - Use cases. docs/use-cases.md builds a brain out of one person's
GitHub repositories, with a sample slip-box in
examples/slipbox/.
Pirsig is licensed under the Mozilla Public License 2.0 (MPL-2.0): use it, change it and ship it, and share your changes to its files under the same license.

