Repository navigation
Releases: ezapmar/brainless-public
Release list
brainless 0.9.0
Windows, Linux without systemd, a public site, and the batch brain on a monthly API credit.
- The batch brain on an API credit. Claude Max and Team plans carry a monthly Claude
Platform credit that pays for raw API calls, not for the interactive CLI. Theanthropic
provider oftools/llm.pynow has what it takes to run the night on it: a cost ledger
(.agents/state/llm_costs.jsonl, every call with its tokens and list price), a budget
(api_budget_usdinbrainless.toml; past the warn ratio the health check and the
watchdog say so, past the stop ratio every API lane runs on its fallback until the reset
day), abillingerror class that hands an exhausted balance to the fallback, and
python3 tools/llm.py --usagefor the spend per lane. A key linked to an account rather
than a workspace sendsanthropic_workspace_id. Guide:docs/shed.md. - A system prompt for the raw API. The API carries none of the context the Claude Code
CLI loads from the vault, soanthropiccalls send_Agent-Context/LLM-SYSTEM.md(house
rules, a few lines) plus the owner's language from the profile. Measured the same day:
one emptyclaude -pcall carries about 18k tokens of CLI context, which is why the
credit goes through the API and not the CLI. - The CLI's own receipt.
claude-clicalls run with--output-format json, so the
ledger also records what the subscription absorbed, at the price the CLI reports, and the
answer is read past any notice a tool manager prints first. - Shared git sync for the workers.
git_sync.shreplaces the inline pull in the
wrappers: it aborts a conflicting rebase, restores the autostash, alerts once per
incident and exits non-zero while the tree is unsafe, so a job skips its run instead of
committing conflict markers. A timer that fires in the seconds after wake waits for the
network, and the worker pushes every hour. - One installer owns every unit.
install.shsubstitutes the vault path into each unit,
setsBRAINLESS_VAULT, skips the owner-only units unless asked (owner-only.txt), and
seven timers gainedPersistent=true. A test parses every unit and fails on drift. - Engine hygiene.
fsutil.atomic_writebehind every live wiki page, one timestamped
log line (logline.py), one frontmatter parser, one JSON reader, utf-8 named on every
file open for the Windows port, ruff in CI, a generated script index indocs/scripts.md
with a test that fails when it goes stale. Six bugs from a code scan fixed (a Buzz reply
with media, the lite path importing fcntl, a crashed job's lease, the compile digest
depending on the machine, Telegram redirects re-checked on every hop). Dead code and a
June-old archive removed; the entity phase reads the corpus once per run. - The AI shed. The always-on worker as a home for standing agent panes:
brainless-herdr.serviceruns a headless herdr server, attach from a laptop with
herdr --remoteor a saved machine, from a phone with any SSH client.docs/shed.md
covers the billing split (what runs on the credit, what stays on the subscription), the
three layers that keep the credit the only money spent, and the first week's checks. - A public site.
docs/now serves as a GitHub Pages site: a front page on the kilim
brand with the loop, the six voices, the Medium and X writing and the install lines, and
a what's new page with every release in plain words.tools/build_site.pywrites
docs/whats-new.htmland the Atom feeddocs/feed.xmlfrom this changelog; run it after
editing this file (--checkfails CI when they are stale). - Night dialectic experiment closed.
brainless-dialectic-night.timeris removed:
after 11 nights the local 4B model never produced a usable night (22 of 132 persona
replies passed, best night 6/12 against a bar of 8/12). The personas collapse into one
voice.--run nightand its service remain for manual runs. Result in
docs/local-inference.md. - Windows install.
irm .../install.ps1 | iexin PowerShell does whatinstall.sh
does: checks git and Python (it skips the Microsoft Store stub), clones, makes the
venv, putsbrainlesson your PATH and runsbrainless init. It works in Windows
PowerShell 5.1, the one that ships with Windows. - One command line for every platform. The commands moved from the bash script into
tools/cli.py.bin/brainlessand the newbin/brainless.cmdonly find the vault and
its Python. - Keys in Credential Manager on Windows, through the system API, never on a command
line. - A Task Scheduler task for the background runs: at logon and every 15 minutes, with
catch-up after sleep, on battery too, and with no console window popping up. - Linux without systemd (WSL, containers, some distros) gets one crontab line.
brainless doctorcrashed there before. - No more fcntl on the lite path. The compile reached it through the concept review,
so Windows failed at import. A small portable lock replaces it. - Outside folders link as a directory junction on Windows when a symlink needs admin
rights. Ollama installs through winget when you say yes. - CI installs on Windows as well, and runs the scheduled task once.
brainless 0.8.6
Runs that did nothing now say so.
- A failed model call fails the run.
weekly_reconcile.pyandevening_closeout.py
returned 0 when the model gave nothing back, so the run log read "ok" over a drift
report that was two weeks old. Both now exit 1, name the cause (timeout, auth, error)
and reportreport=0orcloseout=0. An idle day is still a clean exit. - Scans are parked, not retried for good. A document with no text in it, or in a
format the converter does not know, failed the same way every week and raised the same
notification.smart_processor.pynow parks it: one notice, then nothing until the file
itself changes. The empty_raw.mda failed conversion left behind is removed, and
records of files that are gone are pruned. - The briefing is pushed within the hour. With two machines, the laptop held the
morning briefing until the evening backup while the worker's 21:00 close-out created
the same file. Two new files on one path, and every pull failed.vault_backup.sh --only <path>commits and pushes named paths alone, with the same remote guard and
retry, andcron_wrapper.shuses it for today's briefing. - Scores no longer add up. The run log summed every number in a day, so two compiles
at hit@5 88 read 176 and the next single run looked like a fall. Scores and levels keep
the day's last value; tallies still add up. - An idea is written once. The compiler took whatever slug the model chose, night
after night, and one idea ended up on four pages. The prompt now names the ideas
already held, and a proposal is skipped when a page has its slug, answers to its title
or alias, or was archived by a merge. Existing idea pages are no longer rewritten. lint --fix-linksfollows titles and aliases. A link that names a page by its
title, an alias or another spelling is repointed when one page alone answers to that
name, and keeps its wording as the display text.- Fenced drafts survive the dialectic. The splitter read a heading inside a fenced
proposal as a section break, cut the draft and lost its closing fence, so the rest of
the filed page rendered as code. - The pile count skips machine ledgers.
Inbox/CRM, the per-organisation log that
crm_capture.pykeeps, no longer counts as Inbox files waiting on anyone.
brainless 0.8.5
Docs, and one line of tidying.
- Where the logo is set, written down. Design
now says how the icon reaches the three places outside the repo: the GitHub social
preview (by hand, no API), the Telegram bot (setMyProfilePhoto) and the Buzz agents
(the installers). A manual Buzz profile write must repeat the name and about text, or
they are wiped. The reference deployment points to it from the persona install step. - One deny rule less. The persona settings no longer deny
MultiEdit, a tool Claude
Code no longer has. Nothing else in the sandbox changes.
brainless 0.8.4
Two fixes to the new brand.
- The social card keeps the whole name. The 0.8.3 card was cropped to 2:1 and lost
the b of brainless. It is now the full banner, padded top and bottom with its own
night-blue ground. - Buzz agents keep their avatar. The installers set the kilim icon together with the
display name. A Buzz profile update replaces the whole profile, so a reinstall that
set only the name would have wiped the picture.BUZZ_AVATAR_URLpoints it elsewhere.
brainless 0.8.3
A face. No behaviour changes.
- A new mark: the kilim brain. Anatolian weaving motifs on the nodes of a network,
notes as motifs, links as threads. The README and the wiki open with the banner. - One palette, written down. docs/design.md holds the design point
of view: eleven colours with their roles, logo rules, terminal colour rules, and CSS
variables for an interface that does not exist yet.tools/brand.pyis the code copy. - Logo files for every place a logo goes: SVG and PNG mark in four sizes, WebP, a
square icon on night blue for avatars, a favicon, the banner, and a 1280x640 social
preview, all indocs/assets/. - The installer speaks in the same colours, and only on a real terminal.
NO_COLOR,
pipes andTERM=dumbget plain text as before.
brainless 0.8.2
Security. A full audit after the repo went out more widely; if you run an earlier version,
update.
- A file name can no longer run commands on a Mac. Notifications put the name of a
document that failed to convert straight into AppleScript, so a file named with a quote
anddo shell scriptran a shell command on the next hourly job. The text now reaches
osascriptas an argument, never as script. Same fix in health check, worker reach and
the compiler. - Automated Claude calls get exactly the tools they are granted. A deny list left Read,
Glob and Grep open, so the research lane could read the vault and hand it to WebFetch if
a page it read told it to. Every call now passes--toolswith its grant (none by
default, WebSearch and WebFetch for research, Read for photos) and--strict-mcp-config,
so the MCP servers you use interactively (mail, chat, drives) never load in a timer. - The personas and writing agents read only your vault. Their settings named the
author's home directory, so on anyone else's machine nothing was denied, and the persona
installer did not template them. Read is now scoped to the vault, every dotfile in home
is denied (keys, tokens, shell history), and the unit, env file and team rules are filled
in for the installing user. The writing agents lost WebFetch: an injected page could
otherwise carry vault text out in a URL. WebSearch stays. - The backup never pushes a vault to a public repo. It commits everything, and a clone
of the engine (or a public fork) has the public repo as origin. It now pushes only when
GitHub answers 404 to an anonymous request for the remote, and keeps the commit local
otherwise. - The leak scan passes when clean. It no longer reads
__pycache__, and its private
word lists live next to the registry instead of in the shipped script. - Examples and fixtures use invented names and topics.
brainless 0.8.1
What the first full lite install found, from the published one-liner to an uninstall.
- A second digest on the same day no longer replaces the first. A laptop can digest
twice in a day; the later one is now appended to the day's file. Before, the earlier
digest was lost while its notes were already archived. - Chatter in front of a digest is cut, and caught. A digest that opened with the model
explaining it could not search the wiki was saved as it came. The page is now kept and
the preamble dropped, and the guard knows the new phrasing. The stricter check also
finds older damaged pages, which lint now lists. - Search returns your notes before the command prompts. "What did I decide about
price" used to rank the/decideinstructions first..wiki/_commands/is out of the
search. - The nightly change brief works on a lite clone. It listed nothing, because it skipped
every page git ignores. It now keeps them when the brief itself is untracked. - Generated wiki files stay out of git. The index pages, which name your documents, and
the lint report were visible togit add .in a public clone. - Aliases in your language. An English vault got Turkish aliases; they now follow the
vault's language, with English added for other languages. initsays which vault the command opens. When another vault is already the
default, the closing screen says how to use the new one. The Lite guide says where the
day's notes go after the digest.
brainless 0.8.0
The lite profile: brainless on one computer, with a folder of notes and any model. It is
now what the installer sets up. The multi-machine setup is install.sh --profile full.
Guide: docs/lite.md.
-
Concepts decided in the terminal.
brainless concepts reviewshows each waiting
proposal and takes yes, no or skip (evet, hayır, atla);brainless concepts decide
does one from a script. The same effect as a Buzz reply. -
A lite command set. The lite profile hides the commands that assume the full setup;
brainless profilelists them andbrainless profile enable <command>turns one on. -
An install test on every push. A second workflow installs on macOS and Ubuntu against
a stub model and runsdoctor --probe,addandtick. -
Docs.
docs/lite.md; the README install section now describesbrainless init. -
brainless.toml. One settings file at the vault root (
tools/config.py). It fills
the existingBRAINLESS_*variables as defaults, so the environment still wins and a
vault without the file behaves as before.brainless config showprints what it sets.
Template:brainless.toml.example. -
Keys in the OS keychain.
brainless config secret set llm_api_keystores a key in the
macOS Keychain, libsecret on Linux, or a mode 600 file elsewhere. A key written into
brainless.toml is ignored with a warning. -
Folders by role, not by name.
tools/paths.pyresolves inbox, library, thinking,
daily, beliefs, decisions and ideas from[folders], so a vault can call its notes
Notlar. Compile, digest, dialectic, calibrate, concepts and media import read the
roles. Localised names for new vaults live intools/locale/<lang>/folders.json. -
Any model. New providers in
tools/llm.py:anthropic(API key),ollama,
openai,grok,gemini,openrouter(each with its own key, never another's),
gemini-cliandcodex-cli(your own sign-in, run from an empty folder, Codex in its
read-only sandbox). One model setting,BRAINLESS_LLM_MODEL, per lane if needed.
llm.py --models <provider>lists models. Ollama and loopback endpoints count as local,
so the no-cloud-fallback rule covers them. -
brainless init. The installer now asks instead of assuming.install.shsets up
Python and the command, then hands over tobrainless init: your name and language,
folders named in that language, other notes folders to read (linked, never changed),
the model (Ollama, which it can install; an API key, kept in the OS keychain; or a CLI
you are signed in to), one test call, optional semantic search, the background entry
and the permissions it needs, and a first run if you want one.--yeswith flags runs
it unattended. Your folders go into.git/info/exclude, so notes never reach git.
Python 3.11 is now the minimum.install.sh --profile fullkeeps the old setup. -
brainless doctor. One line per check: folders, model, key, Ollama, scheduler, failed
jobs, last compile.--probesends one tiny prompt. -
One machine, one queue.
brainless tickruns what is due from a SQLite queue:
convert hourly, digest and compile each evening, lint and prune weekly. A night the
laptop slept through runs at the next wake; jobs that need the network or the model
wait for them; failures back off and then show inbrainless queue.
brainless schedule installadds the single launchd, systemd or Task Scheduler entry
that calls it, on the lite profile only.brainless addcaptures a note or a file.
On the lite profile a document dropped in the inbox is converted there. -
Concept proposals wait without Buzz. On a machine with no Buzz identity they stay
pending instead of going to an outbox nobody delivers. -
Summaries without write access.
smart_processor.pyno longer lets the model write
files: the model returns text and the script writes it. Book summaries run on any
provider; photo OCR still needs the claude CLI and leaves photos in the inbox otherwise. -
The research lane says when it cannot search. Without the claude CLI a web lane is
skipped with a note instead of failing. -
The vault is where the engine is. With
BRAINLESS_VAULTunset, tools use the
checkout they run from instead of a fixed home path.
brainless 0.7.0
Take a bad source back out, one document per source, concepts decided in Buzz, and
frontmatter that Obsidian can read.
- Retract a source.
tools/retract_source.pytraces a source that turned out wrong:
its summaries (raw twin and book folder included), the concept pages that cite it, the
pages that link to it. With--apply --reason "..."it goes into
_Agent-Context/retracted.mdand the compiler never compiles it again. A concept claim
that stood on it alone is struck and kept in Superseded, marked retracted with the
reason; a claim with other sources keeps them. The validator lets only the retracted
links go, and a page it refuses stays as it was and is named for a hand edit. - One document, one source. A raw conversion beside its cleaned file, and a reading
sheet beside a book summary, stop compiling as separate sources. Their old summaries go
to.wiki/_archive/summaries/with the reason inLOG.md, and links move to the copy
that stays. Concepts read one summary per document. - Concepts are decided in Buzz.
tools/concept_review.pyposts each concept proposal
to#dreaming; replyevet,hayıroratla. The Sunday proposal pass reads the whole
catalogue and stops while five proposals wait. - Contradiction check.
tools/contradiction_check.pyreads each night's new summaries
against their nearest pages and writes real conflicts to
_Agent-Context/CONTRADICTIONS.mdand the change brief. No page is edited. - Run log fix. The run log dropped any line with a digit in a key, so a night of
failed calls could read as ok. Fixed, and a partial run now warns in health. - Quoted frontmatter. A colon followed by a space in a title or summary made the whole
frontmatter block invalid YAML, and Obsidian dropped the page's properties. The tools
never noticed because they read values by regex.tools/file_query.pyand the idea
writer now quote a value when it needs quotes (concepts.yaml_scalar), and every page
the model writes passes throughconcepts.quote_frontmatterbefore it lands: summaries,
projects, digests and concept pages. Lists, block scalars and quoted values stay as they
are, and a second pass changes nothing. A#inside a summary, which YAML reads as a
comment and cuts off, is quoted too. - Readers strip the quotes.
concepts.fm_valueandlint_wiki.parse_fmreturn the
value without its quotes, so search, the index and the graph export see the same text as
before. - Repair existing pages once, from the vault root:
python3 -c "import sys;sys.path.insert(0,'tools');import concepts as C;from pathlib import Path;[p.write_text(n) for p in Path('.wiki').rglob('*.md') if (n:=C.quote_frontmatter(t:=p.read_text()))!=t]" - Test:
tools/tests/test_file_query.py.
brainless 0.6.1
Health sees the worker's LLM login.
- Worker LLM row. The LLM breadcrumb (
.agents/state/llm_status) is per machine, and
the worker does the heavy LLM work.tools/worker_reach.pynow copies the worker's
breadcrumb over ssh each hour, with the worker's own file time, into
.agents/state/worker_llm_status.json.health_checkshows it as a second LLM row, red
on an authentication error, so an expired worker login no longer hides behind the main
machine's green row.BRAINLESS_WORKER_VAULTsets the worker's vault path, relative to
its home (defaultprojects/brainless).