What you’re building
Three pieces work together. Keep them straight and the rest of the guide is just connecting cables.
The engine
Software that drafts sourced records, finds archival images, and renders dossier PDFs. You run it with ./sotfn.
Your workspace
Your topic, voice, and files — plain Markdown on disk. One engine can drive many workspaces. This is the archive you own.
The Researcher Agent
Hermes, on a schedule. It wakes up, does one job, and (for new records) texts you. You are the editor. It never publishes without you.
Backlog of topics→ Agent drafts a record→ PDF to Telegram→ You approve→ It joins the archive
What you need
- A Mac that can stay on (Linux works; Windows is not the path we document here).
- About 45–90 minutes for the first setup.
- A Telegram account on your phone.
- An API key for a language model. The simplest route is Nous Portal via Hermes setup; OpenRouter or Anthropic also work.
- Budget: once the full day-one roster is running, plan on roughly $5–15 per day depending on model and how often it drafts. You can always pause the schedule.
What you do not need
- To write code, host a website, or post to social media. Those are optional later.
- To understand cron, Python, or “profiles” beyond what this page explains in one sentence each.
The one rule The Agent drafts. You decide. Automation is forbidden from marking a record approved. If a dossier is wrong, you deny it and it leaves the live set.
Install Hermes Agent
Hermes is the always-on assistant that will run your research jobs and talk to Telegram. Install it first, before the research software, so you can prove a model key works in isolation.
Follow the official instructions — we will not fork their docs:
hermes-agent.nousresearch.com — Installation
- Mac: the Hermes Desktop installer is the comfortable path.
- Command line:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
When it finishes, close and reopen Terminal (or run source ~/.zshrc), then:
hermes
You should get a chat prompt. If the installer did not already walk you through a model, run:
hermes setup
# or, if you have a Nous Portal account:
hermes setup --portal
Send one test: Reply with the word ready. When it does, Hermes can think. Quit the chat (Ctrl+C or /quit).
Give the Researcher Agent its own profile
A profile is just a separate folder of Hermes settings, so a personal assistant and this research loop do not share schedules. In Terminal:
mkdir -p ~/.hermes/profiles/research
echo 'export HERMES_HOME="$HOME/.hermes/profiles/research"' >> ~/.zshrc
source ~/.zshrc
From now on, commands in this guide assume that HERMES_HOME points at the research profile. You can check with echo $HERMES_HOME.
Checkpoint hermes opens a chat and answers. echo $HERMES_HOME prints a path ending in profiles/research.
Download the Researcher Agent software
The engine lives on GitHub. You are copying it onto your disk — not installing an app from a store.
Option A — GitHub Desktop (gentler)
- Install GitHub Desktop and sign in.
- Open github.com/sotfn/researcher → Code → Open with GitHub Desktop.
- Choose a folder you will remember (for example
Documents/researcher) and clone. - In GitHub Desktop: Repository → Open in Terminal.
Option B — Terminal
git clone https://github.com/sotfn/researcher.git
cd researcher
Install Python packages
Python is the language the engine is written in. You need version 3.11 or newer. Check with python3 --version. If that fails, install Python from python.org and try again.
A virtual environment is a private toolbox so these packages do not mix with other projects:
python3.11 -m venv .venv
.venv/bin/pip install -U pip
.venv/bin/pip install -r requirements.txt
./sotfn --help
./sotfn status
Monorepo If you cloned the full SoTFN repository instead of sotfn/researcher, run the same ./sotfn commands from the repository root. Python lives in engine/.venv — create it with python3.11 -m venv engine/.venv and install from engine/requirements.txt.
Checkpoint ./sotfn --help prints a list of commands. ./sotfn status may say there is no workspace yet. That is expected.
Create your workspace (topic and domain)
A workspace is one research collection: a name, a subject, a voice, and a folder of records. Pick something you actually want to live with — maritime history, a scientific field, a regional archive, a craft tradition. Bound it in one sentence so the Agent knows what is in and what is out.
./sotfn new \
--path workspaces/maritime \
--name "Maritime" \
--topic "shipwrecks, navigation, and lost vessels" \
--brand-short MARITIME
Then point every later command at it. Paste this in the same Terminal window (it lasts until you close the window):
export SOTFN_WORKSPACE="$(pwd)/workspaces/maritime"
To make it permanent, add that same line to ~/.zshrc with the real path.
Starter brand seals are written for you so PDFs can render on day one. Replace assets/brand/seal-inline.png and seal-watermark.jpg with your own mark whenever you have one.
Tell it how to write, and what to queue
Open the workspace folder in any text editor. These are the files that make the collection yours:
| File | What to put there |
|---|---|
workspace.toml → [workspace] |
Name, topic sentence, default entry type (for example entry or artifact). |
[voice] |
Stance (how it should sound) and phrases to avoid. This is handed to the drafting Agent. |
[validation].required_sections |
The four headings on every record. You may rename “The Anomaly” to something that fits your field; keep four sections. |
[drip].pending_cap |
How many drafts may pile up before the Agent stops writing new ones and re-asks you to clear the pile. Default 15. |
data/backlog.jsonl |
The queue. Seed 5–10 real topics before you turn the Agent on — one JSON object per line. |
data/search-term-bank.md |
Concrete phrases (names, places, dates, object types) for discovery and image search. |
data/synonyms.json and strong_nouns.json |
Optional at first. Fill these when you see near-duplicates: synonym groups, and proper names that should force a conflict. |
A backlog line looks like this (one topic, one line, real quotes):
{"topic":"The wreck of the Medusa, 1816","notes":"navigation disaster; Géricault painting as visual hook","added":"2026-08-12"}
Then smoke-test the engine:
./sotfn status
./sotfn rebuild
./sotfn doctor
Checkpoint Status shows your workspace name. Doctor may warn that Hermes/Telegram are not wired yet — that is the next chapter. Errors about missing folders should be zero.
Telegram bot and the Hermes gateway
Telegram is how the Agent reaches you. The gateway is a small background program that keeps the bot online. Treat the bot token like a password: anyone who has it can talk to the bot as you.
Create the bot
- Open Telegram. Search for @BotFather (the official one, with a blue check).
- Send
/newbot. - Give it a display name you will recognize, for example “Maritime Researcher”.
- Give it a username ending in
bot, for examplemaritime_researcher_bot. - BotFather replies with a token that looks like
123456789:AAH…. Copy it. Do not paste it into a chat, an email, or a git commit.
Find your numeric user id
Search Telegram for @userinfobot and send it any message. It replies with a number — that is your user id. In a private chat with your bot, this is also the chat id the engine needs.
Connect Hermes
hermes gateway setup
Choose Telegram. Paste the bot token and your user id when asked. Then start the gateway in the foreground once, to prove it:
hermes gateway
In Telegram, open a chat with your new bot and send hello. You should get a Hermes reply. Stop the foreground gateway with Ctrl+C, then install it so it survives reboot:
hermes gateway install
hermes gateway status
Tell the engine where to send dossiers
Open workspace.toml and set:
[social]
telegram_chat_id = "YOUR_NUMERIC_ID"
Use the same number @userinfobot gave you, in quotes. Save the file.
Access Only your user id should be allowed. The bot can run commands on the machine Hermes is installed on. Do not add a group chat until you understand that risk.
Checkpoint A DM to the bot gets a reply. hermes gateway status says it is running. workspace.toml has your chat id.
Wire the Approve / Deny buttons
When a drip succeeds you should see a PDF, then a short message with three buttons. Tapping a button is the whole editorial act — you should not have to open Terminal.
Telegram · your bot
MAR-1842-…--wreck-of-the-medusa.pdf
The next chapter copies an approval skill into your Hermes profile. A skill is a short instruction file the Agent reads when a button is tapped (or when you type “approve”). It runs the engine’s approve/deny command and replies with a one-line confirmation.
If a button ever does nothing, you still have a safety net: reply in the chat with approve or deny and the UID printed on the dossier (or just “approve the last one”). Speech-to-text often hears “approved” as “moved” — treat that as approval.
Fix image If the writing is good but the picture is wrong, do not deny the whole record. Reply “fix the image.” The Agent re-sources a real archival photograph, rebuilds the PDF, and sends it again. Status stays pending until you approve.
Plumb the schedule
A cron is a wake-up alarm: at these times, Hermes reads a job description, does the work, and (for drip and morning status) messages you. Times are your Mac’s local timezone — set System Settings → Date & Time if you care about clock-hour accuracy.
From the repository root, with SOTFN_WORKSPACE still set:
./sotfn agent install-crons --dry-run # preview
./sotfn agent install-crons
hermes gateway restart --profile research
HERMES_HOME=~/.hermes/profiles/research hermes cron list
Day-one jobs — including enrichment and image QA, which keep sources and pictures honest:
| Job | When | What you notice |
|---|---|---|
| Morning Status | 9:00 | A short counts message in Telegram. |
| Daily Drip | 10:00, 14:00, 18:00 | A dossier PDF + Approve / Edit / Deny. |
| Backlog Refill | 11:00 | Usually silent. Adds verified topic candidates to the queue. |
| Image QA | 11:30 and 19:30 | Silent unless a pending picture is wrong; then it replaces it. |
| Enrichment Pass | every 6 hours, at :20 | Silent. Attaches extra verified sources to approved records. |
| Watchdog | 9:10 and 21:10 | Silent if healthy. Messages you only if doctor cannot self-repair. |
| Daily Cost Report | 23:00 | Today’s model spend, if any. |
Social posting (Bluesky / X) and a public website are not required to run a research process. Add them later with ./sotfn social install-crons and ./sotfn site install-crons if you want them.
Checkpoint hermes cron list shows seven jobs named after your brand. The gateway is running.
First drip, first approval
You can wait for the next scheduled Daily Drip, or trigger it from hermes cron list (run the drip job now). The first run often takes several minutes: it picks a backlog topic, writes a record, finds a real image, builds a PDF, and delivers.
Read the dossier. Then:
- Approve — it joins the permanent archive. You should get a one-line confirmation.
- Deny — it is moved aside and will not appear in the live set.
- Edit — ask for a revision; status stays pending.
Confirm on disk:
./sotfn status
Approved should be 1 (or one higher than before). That is the “it works” moment.
If the Agent re-sends an old PDF instead of writing a new one
That is the gate. When too many drafts are waiting (pending_cap, default 15), the Agent stops inventing new records and cycles the pile back to you. Approve or deny until you are under the cap. This is how the system refuses to bury you.
Never automatic If a cron “succeeds,” that does not mean the record is approved. Only your tap (or an explicit ./sotfn approve you typed) changes status.
Shape the research process
The loop is alive. Now you tune it the way an editor tunes a desk.
- Add and remove lines in
data/backlog.jsonl. Specific beats vague: a dated wreck, not “famous ships.” - After three or four dossiers, tighten
[voice]and the four section headings so they match how you actually want the page to read. - When two records feel like the same subject, add synonym groups and strong proper nouns so the next drip is flagged.
./sotfn doctor --fixwhen something feels off../sotfn costs --todayif you care about spend.- Pause the schedule when you travel:
HERMES_HOME=~/.hermes/profiles/research hermes cron listand disable jobs from there (or stop the gateway).
Optional later
- Social — only after you like the records. Publishing still requires an explicit Publish tap. Never auto-post.
- A public site —
./sotfn site buildexports approved entries. Hosting is yours; the research process does not depend on a website.
When it breaks
| What you see | First check |
|---|---|
hermes: command not found |
Close and reopen Terminal, or source ~/.zshrc. Confirm the installer put hermes on your PATH. |
| No Telegram messages | hermes gateway status. Bot token in ~/.hermes/.env. Allowed user id is yours. You started a chat with the bot at least once. |
| Buttons do nothing | Re-run ./sotfn agent install-crons so the approval skill is in the profile. Reply “approve” in the chat as a fallback. Look at engine/logs/drip_action.log (or logs/ in the single-package layout). |
| PDF missing or tiny | Brand seals in assets/brand/. ./sotfn doctor. Rebuild with ./sotfn build --entry entries/…. |
| Drip skipped / old PDF again | Gate closed — too many pending. Approve or deny the pile. ./sotfn gate prints the count. |
| Wrong picture, good writing | Fix image, do not deny the record. |
| Bill higher than you like | Lower drip frequency in hermes cron list before turning off enrichment or image QA. Those two exist to keep the archive honest. |
| Doctor reports errors | ./sotfn doctor --fix, then hermes doctor for the assistant itself. |
Software: github.com/sotfn/researcher. A live collection built on this engine: Misrule.