<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>brainless releases</title>
  <subtitle>What changed in each release of the brainless engine.</subtitle>
  <link href="https://ezapmar.github.io/brainless-public/whats-new.html"/>
  <link rel="self" href="https://ezapmar.github.io/brainless-public/feed.xml"/>
  <id>tag:brainless.ezapmar,2026:releases</id>
  <updated>2026-10-08T00:00:00Z</updated>
  <author><name>Tunca Üçer</name></author>
  <entry>
    <title>brainless 0.9.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-9-0"/>
    <id>tag:brainless.ezapmar,2026-10-08:v0.9.0</id>
    <updated>2026-10-08T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Windows, Linux without systemd, a public site, and the batch brain on a monthly API credit.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The batch brain on an API credit.&lt;/strong&gt; Claude Max and Team plans carry a monthly Claude Platform credit that pays for raw API calls, not for the interactive CLI. The &lt;code&gt;anthropic&lt;/code&gt; provider of &lt;code&gt;tools/llm.py&lt;/code&gt; now has what it takes to run the night on it: a cost ledger (&lt;code&gt;.agents/state/llm_costs.jsonl&lt;/code&gt;, every call with its tokens and list price), a budget (&lt;code&gt;api_budget_usd&lt;/code&gt; in &lt;code&gt;brainless.toml&lt;/code&gt;; 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), a &lt;code&gt;billing&lt;/code&gt; error class that hands an exhausted balance to the fallback, and &lt;code&gt;python3 tools/llm.py --usage&lt;/code&gt; for the spend per lane. A key linked to an account rather than a workspace sends &lt;code&gt;anthropic_workspace_id&lt;/code&gt;. Guide: &lt;code&gt;docs/shed.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A system prompt for the raw API.&lt;/strong&gt; The API carries none of the context the Claude Code CLI loads from the vault, so &lt;code&gt;anthropic&lt;/code&gt; calls send &lt;code&gt;_Agent-Context/LLM-SYSTEM.md&lt;/code&gt; (house rules, a few lines) plus the owner&amp;#x27;s language from the profile. Measured the same day: one empty &lt;code&gt;claude -p&lt;/code&gt; call carries about 18k tokens of CLI context, which is why the credit goes through the API and not the CLI.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The CLI&amp;#x27;s own receipt.&lt;/strong&gt; &lt;code&gt;claude-cli&lt;/code&gt; calls run with &lt;code&gt;--output-format json&lt;/code&gt;, 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Shared git sync for the workers.&lt;/strong&gt; &lt;code&gt;git_sync.sh&lt;/code&gt; replaces 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;One installer owns every unit.&lt;/strong&gt; &lt;code&gt;install.sh&lt;/code&gt; substitutes the vault path into each unit, sets &lt;code&gt;BRAINLESS_VAULT&lt;/code&gt;, skips the owner-only units unless asked (&lt;code&gt;owner-only.txt&lt;/code&gt;), and seven timers gained &lt;code&gt;Persistent=true&lt;/code&gt;. A test parses every unit and fails on drift.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Engine hygiene.&lt;/strong&gt; &lt;code&gt;fsutil.atomic_write&lt;/code&gt; behind every live wiki page, one timestamped log line (&lt;code&gt;logline.py&lt;/code&gt;), one frontmatter parser, one JSON reader, utf-8 named on every file open for the Windows port, ruff in CI, a generated script index in &lt;code&gt;docs/scripts.md&lt;/code&gt; 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&amp;#x27;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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The AI shed.&lt;/strong&gt; The always-on worker as a home for standing agent panes: &lt;code&gt;brainless-herdr.service&lt;/code&gt; runs a headless herdr server, attach from a laptop with &lt;code&gt;herdr --remote&lt;/code&gt; or a saved machine, from a phone with any SSH client. &lt;code&gt;docs/shed.md&lt;/code&gt; 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&amp;#x27;s checks.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A public site.&lt;/strong&gt; &lt;code&gt;docs/&lt;/code&gt; 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&amp;#x27;s new page with every release in plain words. &lt;code&gt;tools/build_site.py&lt;/code&gt; writes &lt;code&gt;docs/whats-new.html&lt;/code&gt; and the Atom feed &lt;code&gt;docs/feed.xml&lt;/code&gt; from this changelog; run it after editing this file (&lt;code&gt;--check&lt;/code&gt; fails CI when they are stale).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Night dialectic experiment closed.&lt;/strong&gt; &lt;code&gt;brainless-dialectic-night.timer&lt;/code&gt; is 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. &lt;code&gt;--run night&lt;/code&gt; and its service remain for manual runs. Result in &lt;code&gt;docs/local-inference.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Windows install.&lt;/strong&gt; &lt;code&gt;irm .../install.ps1 | iex&lt;/code&gt; in PowerShell does what &lt;code&gt;install.sh&lt;/code&gt; does: checks git and Python (it skips the Microsoft Store stub), clones, makes the venv, puts &lt;code&gt;brainless&lt;/code&gt; on your PATH and runs &lt;code&gt;brainless init&lt;/code&gt;. It works in Windows PowerShell 5.1, the one that ships with Windows.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;One command line for every platform.&lt;/strong&gt; The commands moved from the bash script into &lt;code&gt;tools/cli.py&lt;/code&gt;. &lt;code&gt;bin/brainless&lt;/code&gt; and the new &lt;code&gt;bin/brainless.cmd&lt;/code&gt; only find the vault and its Python.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Keys in Credential Manager&lt;/strong&gt; on Windows, through the system API, never on a command line.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A Task Scheduler task&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Linux without systemd&lt;/strong&gt; (WSL, containers, some distros) gets one crontab line. &lt;code&gt;brainless doctor&lt;/code&gt; crashed there before.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;No more fcntl on the lite path.&lt;/strong&gt; The compile reached it through the concept review, so Windows failed at import. A small portable lock replaces it.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Outside folders link as a directory junction&lt;/strong&gt; on Windows when a symlink needs admin rights. Ollama installs through winget when you say yes.&lt;/li&gt;&lt;li&gt;CI installs on Windows as well, and runs the scheduled task once.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.6</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-6"/>
    <id>tag:brainless.ezapmar,2026-10-04:v0.8.6</id>
    <updated>2026-10-04T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Runs that did nothing now say so.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;A failed model call fails the run.&lt;/strong&gt; &lt;code&gt;weekly_reconcile.py&lt;/code&gt; and &lt;code&gt;evening_closeout.py&lt;/code&gt; returned 0 when the model gave nothing back, so the run log read &amp;quot;ok&amp;quot; over a drift report that was two weeks old. Both now exit 1, name the cause (timeout, auth, error) and report &lt;code&gt;report=0&lt;/code&gt; or &lt;code&gt;closeout=0&lt;/code&gt;. An idle day is still a clean exit.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Scans are parked, not retried for good.&lt;/strong&gt; 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. &lt;code&gt;smart_processor.py&lt;/code&gt; now parks it: one notice, then nothing until the file itself changes. The empty &lt;code&gt;_raw.md&lt;/code&gt; a failed conversion left behind is removed, and records of files that are gone are pruned.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The briefing is pushed within the hour.&lt;/strong&gt; With two machines, the laptop held the morning briefing until the evening backup while the worker&amp;#x27;s 21:00 close-out created the same file. Two new files on one path, and every pull failed. &lt;code&gt;vault_backup.sh --only &amp;lt;path&amp;gt;&lt;/code&gt; commits and pushes named paths alone, with the same remote guard and retry, and &lt;code&gt;cron_wrapper.sh&lt;/code&gt; uses it for today&amp;#x27;s briefing.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Scores no longer add up.&lt;/strong&gt; 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&amp;#x27;s last value; tallies still add up.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;An idea is written once.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;lint --fix-links&lt;/code&gt; follows titles and aliases.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Fenced drafts survive the dialectic.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The pile count skips machine ledgers.&lt;/strong&gt; &lt;code&gt;Inbox/CRM&lt;/code&gt;, the per-organisation log that &lt;code&gt;crm_capture.py&lt;/code&gt; keeps, no longer counts as Inbox files waiting on anyone.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.5</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-5"/>
    <id>tag:brainless.ezapmar,2026-09-28:v0.8.5</id>
    <updated>2026-09-28T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Docs, and one line of tidying.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Where the logo is set, written down.&lt;/strong&gt; &lt;a href=&quot;https://github.com/ezapmar/brainless-public/blob/main/docs/design.md#where-the-logo-is-set&quot;&gt;Design&lt;/a&gt; now says how the icon reaches the three places outside the repo: the GitHub social preview (by hand, no API), the Telegram bot (&lt;code&gt;setMyProfilePhoto&lt;/code&gt;) 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;One deny rule less.&lt;/strong&gt; The persona settings no longer deny &lt;code&gt;MultiEdit&lt;/code&gt;, a tool Claude Code no longer has. Nothing else in the sandbox changes.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.4</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-4"/>
    <id>tag:brainless.ezapmar,2026-09-28:v0.8.4</id>
    <updated>2026-09-28T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Two fixes to the new brand.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The social card keeps the whole name.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Buzz agents keep their avatar.&lt;/strong&gt; 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. &lt;code&gt;BUZZ_AVATAR_URL&lt;/code&gt; points it elsewhere.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.3</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-3"/>
    <id>tag:brainless.ezapmar,2026-09-28:v0.8.3</id>
    <updated>2026-09-28T00:00:00Z</updated>
    <content type="html">&lt;p&gt;A face. No behaviour changes.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;A new mark: the kilim brain.&lt;/strong&gt; Anatolian weaving motifs on the nodes of a network, notes as motifs, links as threads. The README and the wiki open with the banner.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;One palette, written down.&lt;/strong&gt; &lt;a href=&quot;https://github.com/ezapmar/brainless-public/blob/main/docs/design.md&quot;&gt;docs/design.md&lt;/a&gt; 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. &lt;code&gt;tools/brand.py&lt;/code&gt; is the code copy.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Logo files for every place a logo goes:&lt;/strong&gt; 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 in &lt;code&gt;docs/assets/&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The installer speaks in the same colours&lt;/strong&gt;, and only on a real terminal. &lt;code&gt;NO_COLOR&lt;/code&gt;, pipes and &lt;code&gt;TERM=dumb&lt;/code&gt; get plain text as before.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.2</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-2"/>
    <id>tag:brainless.ezapmar,2026-09-28:v0.8.2</id>
    <updated>2026-09-28T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Security. A full audit after the repo went out more widely; if you run an earlier version,&lt;/p&gt;&lt;p&gt;update.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;A file name can no longer run commands on a Mac.&lt;/strong&gt; Notifications put the name of a document that failed to convert straight into AppleScript, so a file named with a quote and &lt;code&gt;do shell script&lt;/code&gt; ran a shell command on the next hourly job. The text now reaches &lt;code&gt;osascript&lt;/code&gt; as an argument, never as script. Same fix in health check, worker reach and the compiler.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Automated Claude calls get exactly the tools they are granted.&lt;/strong&gt; 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 &lt;code&gt;--tools&lt;/code&gt; with its grant (none by default, WebSearch and WebFetch for research, Read for photos) and &lt;code&gt;--strict-mcp-config&lt;/code&gt;, so the MCP servers you use interactively (mail, chat, drives) never load in a timer.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The personas and writing agents read only your vault.&lt;/strong&gt; Their settings named the author&amp;#x27;s home directory, so on anyone else&amp;#x27;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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The backup never pushes a vault to a public repo.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The leak scan passes when clean.&lt;/strong&gt; It no longer reads &lt;code&gt;__pycache__&lt;/code&gt;, and its private word lists live next to the registry instead of in the shipped script.&lt;/li&gt;&lt;li&gt;Examples and fixtures use invented names and topics.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.1</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-1"/>
    <id>tag:brainless.ezapmar,2026-09-26:v0.8.1</id>
    <updated>2026-09-26T00:00:00Z</updated>
    <content type="html">&lt;p&gt;What the first full lite install found, from the published one-liner to an uninstall.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;A second digest on the same day no longer replaces the first.&lt;/strong&gt; A laptop can digest twice in a day; the later one is now appended to the day&amp;#x27;s file. Before, the earlier digest was lost while its notes were already archived.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Chatter in front of a digest is cut, and caught.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Search returns your notes before the command prompts.&lt;/strong&gt; &amp;quot;What did I decide about price&amp;quot; used to rank the &lt;code&gt;/decide&lt;/code&gt; instructions first. &lt;code&gt;.wiki/_commands/&lt;/code&gt; is out of the search.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The nightly change brief works on a lite clone.&lt;/strong&gt; It listed nothing, because it skipped every page git ignores. It now keeps them when the brief itself is untracked.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Generated wiki files stay out of git.&lt;/strong&gt; The index pages, which name your documents, and the lint report were visible to &lt;code&gt;git add .&lt;/code&gt; in a public clone.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Aliases in your language.&lt;/strong&gt; An English vault got Turkish aliases; they now follow the vault&amp;#x27;s language, with English added for other languages.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;init&lt;/code&gt; says which vault the command opens.&lt;/strong&gt; When another vault is already the default, the closing screen says how to use the new one. The Lite guide says where the day&amp;#x27;s notes go after the digest.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.8.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-8-0"/>
    <id>tag:brainless.ezapmar,2026-09-26:v0.8.0</id>
    <updated>2026-09-26T00:00:00Z</updated>
    <content type="html">&lt;p&gt;The lite profile: brainless on one computer, with a folder of notes and any model. It is&lt;/p&gt;&lt;p&gt;now what the installer sets up. The multi-machine setup is &lt;code&gt;install.sh --profile full&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Guide: &lt;code&gt;docs/lite.md&lt;/code&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Concepts decided in the terminal.&lt;/strong&gt; &lt;code&gt;brainless concepts review&lt;/code&gt; shows each waiting proposal and takes yes, no or skip (evet, hayır, atla); &lt;code&gt;brainless concepts decide&lt;/code&gt; does one from a script. The same effect as a Buzz reply.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A lite command set.&lt;/strong&gt; The lite profile hides the commands that assume the full setup; &lt;code&gt;brainless profile&lt;/code&gt; lists them and &lt;code&gt;brainless profile enable &amp;lt;command&amp;gt;&lt;/code&gt; turns one on.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;An install test on every push.&lt;/strong&gt; A second workflow installs on macOS and Ubuntu against a stub model and runs &lt;code&gt;doctor --probe&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;tick&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Docs.&lt;/strong&gt; &lt;code&gt;docs/lite.md&lt;/code&gt;; the README install section now describes &lt;code&gt;brainless init&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;brainless.toml.&lt;/strong&gt; One settings file at the vault root (&lt;code&gt;tools/config.py&lt;/code&gt;). It fills the existing &lt;code&gt;BRAINLESS_*&lt;/code&gt; variables as defaults, so the environment still wins and a vault without the file behaves as before. &lt;code&gt;brainless config show&lt;/code&gt; prints what it sets. Template: &lt;code&gt;brainless.toml.example&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Keys in the OS keychain.&lt;/strong&gt; &lt;code&gt;brainless config secret set llm_api_key&lt;/code&gt; stores 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Folders by role, not by name.&lt;/strong&gt; &lt;code&gt;tools/paths.py&lt;/code&gt; resolves inbox, library, thinking, daily, beliefs, decisions and ideas from &lt;code&gt;[folders]&lt;/code&gt;, so a vault can call its notes &lt;code&gt;Notlar&lt;/code&gt;. Compile, digest, dialectic, calibrate, concepts and media import read the roles. Localised names for new vaults live in &lt;code&gt;tools/locale/&amp;lt;lang&amp;gt;/folders.json&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Any model.&lt;/strong&gt; New providers in &lt;code&gt;tools/llm.py&lt;/code&gt;: &lt;code&gt;anthropic&lt;/code&gt; (API key), &lt;code&gt;ollama&lt;/code&gt;, &lt;code&gt;openai&lt;/code&gt;, &lt;code&gt;grok&lt;/code&gt;, &lt;code&gt;gemini&lt;/code&gt;, &lt;code&gt;openrouter&lt;/code&gt; (each with its own key, never another&amp;#x27;s), &lt;code&gt;gemini-cli&lt;/code&gt; and &lt;code&gt;codex-cli&lt;/code&gt; (your own sign-in, run from an empty folder, Codex in its read-only sandbox). One model setting, &lt;code&gt;BRAINLESS_LLM_MODEL&lt;/code&gt;, per lane if needed. &lt;code&gt;llm.py --models &amp;lt;provider&amp;gt;&lt;/code&gt; lists models. Ollama and loopback endpoints count as local, so the no-cloud-fallback rule covers them.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;brainless init&lt;/code&gt;.&lt;/strong&gt; The installer now asks instead of assuming. &lt;code&gt;install.sh&lt;/code&gt; sets up Python and the command, then hands over to &lt;code&gt;brainless init&lt;/code&gt;: 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. &lt;code&gt;--yes&lt;/code&gt; with flags runs it unattended. Your folders go into &lt;code&gt;.git/info/exclude&lt;/code&gt;, so notes never reach git. Python 3.11 is now the minimum. &lt;code&gt;install.sh --profile full&lt;/code&gt; keeps the old setup.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;brainless doctor&lt;/code&gt;.&lt;/strong&gt; One line per check: folders, model, key, Ollama, scheduler, failed jobs, last compile. &lt;code&gt;--probe&lt;/code&gt; sends one tiny prompt.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;One machine, one queue.&lt;/strong&gt; &lt;code&gt;brainless tick&lt;/code&gt; runs 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 in &lt;code&gt;brainless queue&lt;/code&gt;. &lt;code&gt;brainless schedule install&lt;/code&gt; adds the single launchd, systemd or Task Scheduler entry that calls it, on the lite profile only. &lt;code&gt;brainless add&lt;/code&gt; captures a note or a file. On the lite profile a document dropped in the inbox is converted there.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Concept proposals wait without Buzz.&lt;/strong&gt; On a machine with no Buzz identity they stay pending instead of going to an outbox nobody delivers.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Summaries without write access.&lt;/strong&gt; &lt;code&gt;smart_processor.py&lt;/code&gt; no 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The research lane says when it cannot search.&lt;/strong&gt; Without the claude CLI a web lane is skipped with a note instead of failing.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The vault is where the engine is.&lt;/strong&gt; With &lt;code&gt;BRAINLESS_VAULT&lt;/code&gt; unset, tools use the checkout they run from instead of a fixed home path.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.7.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-7-0"/>
    <id>tag:brainless.ezapmar,2026-09-26:v0.7.0</id>
    <updated>2026-09-26T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Take a bad source back out, one document per source, concepts decided in Buzz, and&lt;/p&gt;&lt;p&gt;frontmatter that Obsidian can read.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Retract a source.&lt;/strong&gt; &lt;code&gt;tools/retract_source.py&lt;/code&gt; traces 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 &lt;code&gt;--apply --reason &amp;quot;...&amp;quot;&lt;/code&gt; it goes into &lt;code&gt;_Agent-Context/retracted.md&lt;/code&gt; and 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;One document, one source.&lt;/strong&gt; 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 &lt;code&gt;.wiki/_archive/summaries/&lt;/code&gt; with the reason in &lt;code&gt;LOG.md&lt;/code&gt;, and links move to the copy that stays. Concepts read one summary per document.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Concepts are decided in Buzz.&lt;/strong&gt; &lt;code&gt;tools/concept_review.py&lt;/code&gt; posts each concept proposal to &lt;code&gt;#dreaming&lt;/code&gt;; reply &lt;code&gt;evet&lt;/code&gt;, &lt;code&gt;hayır&lt;/code&gt; or &lt;code&gt;atla&lt;/code&gt;. The Sunday proposal pass reads the whole catalogue and stops while five proposals wait.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Contradiction check.&lt;/strong&gt; &lt;code&gt;tools/contradiction_check.py&lt;/code&gt; reads each night&amp;#x27;s new summaries against their nearest pages and writes real conflicts to &lt;code&gt;_Agent-Context/CONTRADICTIONS.md&lt;/code&gt; and the change brief. No page is edited.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Run log fix.&lt;/strong&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Quoted frontmatter.&lt;/strong&gt; A colon followed by a space in a title or summary made the whole frontmatter block invalid YAML, and Obsidian dropped the page&amp;#x27;s properties. The tools never noticed because they read values by regex. &lt;code&gt;tools/file_query.py&lt;/code&gt; and the idea writer now quote a value when it needs quotes (&lt;code&gt;concepts.yaml_scalar&lt;/code&gt;), and every page the model writes passes through &lt;code&gt;concepts.quote_frontmatter&lt;/code&gt; before 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 &lt;code&gt; #&lt;/code&gt; inside a summary, which YAML reads as a comment and cuts off, is quoted too.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Readers strip the quotes.&lt;/strong&gt; &lt;code&gt;concepts.fm_value&lt;/code&gt; and &lt;code&gt;lint_wiki.parse_fm&lt;/code&gt; return the value without its quotes, so search, the index and the graph export see the same text as before.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Repair existing pages&lt;/strong&gt; once, from the vault root: &lt;code&gt;python3 -c &amp;quot;import sys;sys.path.insert(0,&amp;#x27;tools&amp;#x27;);import concepts as C;from pathlib import Path;[p.write_text(n) for p in Path(&amp;#x27;.wiki&amp;#x27;).rglob(&amp;#x27;*.md&amp;#x27;) if (n:=C.quote_frontmatter(t:=p.read_text()))!=t]&amp;quot;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Test:&lt;/strong&gt; &lt;code&gt;tools/tests/test_file_query.py&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.6.1</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-6-1"/>
    <id>tag:brainless.ezapmar,2026-09-25:v0.6.1</id>
    <updated>2026-09-25T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Health sees the worker&amp;#x27;s LLM login.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Worker LLM row.&lt;/strong&gt; The LLM breadcrumb (&lt;code&gt;.agents/state/llm_status&lt;/code&gt;) is per machine, and the worker does the heavy LLM work. &lt;code&gt;tools/worker_reach.py&lt;/code&gt; now copies the worker&amp;#x27;s breadcrumb over ssh each hour, with the worker&amp;#x27;s own file time, into &lt;code&gt;.agents/state/worker_llm_status.json&lt;/code&gt;. &lt;code&gt;health_check&lt;/code&gt; shows it as a second LLM row, red on an authentication error, so an expired worker login no longer hides behind the main machine&amp;#x27;s green row. &lt;code&gt;BRAINLESS_WORKER_VAULT&lt;/code&gt; sets the worker&amp;#x27;s vault path, relative to its home (default &lt;code&gt;projects/brainless&lt;/code&gt;).&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.6.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-6-0"/>
    <id>tag:brainless.ezapmar,2026-09-25:v0.6.0</id>
    <updated>2026-09-25T00:00:00Z</updated>
    <content type="html">&lt;p&gt;The nightly compile says what it did.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Change brief.&lt;/strong&gt; &lt;code&gt;tools/wiki_changes.py&lt;/code&gt; snapshots &lt;code&gt;.wiki/&lt;/code&gt; before the 23:20 compile and diffs it after: pages added, updated and removed per kind, links gained, and new Contested or Superseded bullets on concept pages. No model. It writes &lt;code&gt;_Agent-Context/WIKI-CHANGES.md&lt;/code&gt;, the morning briefing reads it, and a new contradiction becomes a quick action for the owner. &lt;code&gt;--since &amp;lt;git ref&amp;gt;&lt;/code&gt; shows the change since any commit.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A stuck compiler shows in health.&lt;/strong&gt; The run log gets &lt;code&gt;wiki_changed&lt;/code&gt;; seven nights in a row with no page changed turn HEALTH.md yellow. The dry-run check now counts only runs that report the field, so a field added later does not read older runs as zeros.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dialectic backstage.&lt;/strong&gt; The persona rounds move to &lt;code&gt;#dialectic-lab&lt;/code&gt;; the owner&amp;#x27;s &lt;code&gt;#dialectic&lt;/code&gt; gets one short card per topic. The long context goes to a brief file the personas read, so moderator messages stay a few lines.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Telegram receipt.&lt;/strong&gt; Capture sends one &amp;quot;saved&amp;quot; line back to the whitelisted chat; still no commands or buttons. Buzz deliveries drop the hidden marker, which Buzz rendered verbatim.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Leak scan.&lt;/strong&gt; Common words that are also entity aliases no longer flag every file.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.5.2</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-5-2"/>
    <id>tag:brainless.ezapmar,2026-09-23:v0.5.2</id>
    <updated>2026-09-23T00:00:00Z</updated>
    <content type="html">&lt;p&gt;The README says what it runs on, and the root shows the engine.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;What it runs on.&lt;/strong&gt; A new README section names the three devices behind the reference setup: an iPhone for Telegram capture and Buzz replies, a Mac for writing and commands, and an always-on Arch Linux laptop behind Tailscale that runs the timers, the capture, the Buzz relay and the persona agents. One laptop is still enough to start.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reference deployment is its own doc.&lt;/strong&gt; The real setup (devices, diagram, schedule, units, persona sandbox, placeholder secrets) moved out of &lt;code&gt;docs/how-it-works.md&lt;/code&gt; into &lt;code&gt;docs/reference-deployment.md&lt;/code&gt;, and the wiki page is now generated from it instead of being written by hand. How-it-works keeps a one-paragraph pointer.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The root shows the engine.&lt;/strong&gt; The eleven empty content folders (&lt;code&gt;Work/&lt;/code&gt;, &lt;code&gt;Inbox/&lt;/code&gt;, &lt;code&gt;Thinking/Daily/&lt;/code&gt; and the rest) no longer ship with a &lt;code&gt;.gitkeep&lt;/code&gt; each; &lt;code&gt;install.sh&lt;/code&gt; makes them on the first run. The repo root goes from thirty entries to twenty one.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.5.1</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-5-1"/>
    <id>tag:brainless.ezapmar,2026-09-23:v0.5.1</id>
    <updated>2026-09-23T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Shipped files name nobody real.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Invented names in examples.&lt;/strong&gt; Test fixtures, locale self-tests, comments and one prompt example named real people and companies. They use invented names now; the Turkish suffix cases still test the same thing.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MCP deny list from the profile.&lt;/strong&gt; &lt;code&gt;tools/mcp_server.py&lt;/code&gt; builds its second deny list from fixed parts plus &lt;code&gt;private_segments&lt;/code&gt; in &lt;code&gt;PROFILE.md&lt;/code&gt;, folding case, accents and separators. Put a family member&amp;#x27;s folder name there and the server will not serve it.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Leak scan checks tracked names.&lt;/strong&gt; &lt;code&gt;tools/export_public.py&lt;/code&gt; reads the entity registry, the entity candidates and the &lt;code&gt;Work/*/About People/&lt;/code&gt; file names at scan time and flags any of those names in a shipped file. The names never enter the code; in a checkout without those files the check has nothing to look for.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.5.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-5-0"/>
    <id>tag:brainless.ezapmar,2026-09-23:v0.5.0</id>
    <updated>2026-09-23T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Search by meaning, and a wiki that proposes its own links.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Hybrid search.&lt;/strong&gt; &lt;code&gt;wiki_search.py&lt;/code&gt; fuses BM25 with local embeddings (&lt;code&gt;tools/semantic_index.py&lt;/code&gt;, multilingual-e5-large through fastembed, on the CPU; no vault text reaches an API). On the 34 golden questions MRR rose from 74 to 87 and hit@1 from 62% to 79%, better on every kind of question. An optional addon: &lt;code&gt;pip install -r requirements-search.txt&lt;/code&gt;, then &lt;code&gt;python3 tools/semantic_index.py build&lt;/code&gt;. Without it, search is BM25 as before. A smaller model and a reranker were measured and rejected.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Passage-level sources.&lt;/strong&gt; Every result carries the passage that matched, the line of the match and the last &lt;code&gt;[mm:ss]&lt;/code&gt; marker before it, so an answer cites &lt;code&gt;path:line&lt;/code&gt;. The snippet now folds Turkish letters on both sides; a Turkish query no longer shows the frontmatter.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Retrieval eval by kind.&lt;/strong&gt; The golden set grew from 22 to 34 questions, each tagged name, paraphrase, crosslang or claim, and the eval scores each kind apart and records the mode.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Read-only MCP server.&lt;/strong&gt; &lt;code&gt;tools/mcp_server.py&lt;/code&gt; gives any MCP client &lt;code&gt;search&lt;/code&gt;, &lt;code&gt;read_page&lt;/code&gt; and &lt;code&gt;index&lt;/code&gt;. Standard library only. Over stdio, or over HTTP bound to one address with a bearer token (&lt;code&gt;brainless-mcp.service&lt;/code&gt; for the worker). It never serves a page git ignores, and a hard-coded deny list backs that up. It cannot write.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Link suggestions.&lt;/strong&gt; &lt;code&gt;tools/link_suggest.py&lt;/code&gt; proposes links between pages that mean the same thing but do not link: mutual nearest neighbours in the top 1% of pairs. Homes for orphan pages first, then new links, then near-identical pages for the dedupe procedure. Report only, gitignored and out of the graph.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dreaming.&lt;/strong&gt; &lt;code&gt;tools/dreaming.py&lt;/code&gt; runs at 04:00 on the worker. A model judges each suggested pair (link, duplicate or none, with one sentence why) and posts up to five a night to Buzz &lt;code&gt;#dreaming&lt;/code&gt;. The owner answers yes, no or skip. Approved links live in &lt;code&gt;_Agent-Context/links.md&lt;/code&gt;, and the compiler replays them on every compile, so a rewritten summary keeps them. Duplicates become merge rows; nothing is deleted. A kill rule stops it when under 30% of proposals are approved. Setup: &lt;code&gt;.agents/buzz/install_dreaming_channel.sh&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Documents to the inbox.&lt;/strong&gt; A PDF or office file posted to Buzz &lt;code&gt;#inbox&lt;/code&gt; is converted with markitdown on the worker into &lt;code&gt;Inbox/Documents&lt;/code&gt;; the original never reaches git.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Worker reach.&lt;/strong&gt; &lt;code&gt;tools/worker_reach.py&lt;/code&gt; tells the Mac when it loses the worker (Tailscale down, ssh failing, or no worker commit for hours), with a local notification and a HEALTH.md row. The worker commits its run log twice an hour, not every run.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The wiki compiles every night.&lt;/strong&gt; The compile, lint report, search index, link suggestions and retrieval check moved out of the nightly digest into their own job (&lt;code&gt;tools/nightly_compile.py&lt;/code&gt;, &lt;code&gt;brainless-compile.timer&lt;/code&gt; at 23:20). They used to run only on nights with captures, so a quiet day left edits uncompiled and the index stale.&lt;/li&gt;&lt;li&gt;The installer steps past systemd units already linked in place. The Mac&amp;#x27;s nightly sync refreshes the search index and the link suggestions.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.4.1</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-4-1"/>
    <id>tag:brainless.ezapmar,2026-09-23:v0.4.1</id>
    <updated>2026-09-23T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;&lt;code&gt;_Agent-Context/LEARNINGS.md&lt;/code&gt;: the owner&amp;#x27;s standing preferences and the lessons from correcting an agent, each with the rule, why, and how to apply it. They live in the vault, not in one tool&amp;#x27;s memory. The SessionStart hook loads the file, and the writing and narratives agents and the Buzz reply worker read it. &lt;code&gt;AGENT-RULES.md&lt;/code&gt; Rule 1 names it. The public export ships a stub with one example entry.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.4.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-4-0"/>
    <id>tag:brainless.ezapmar,2026-09-23:v0.4.0</id>
    <updated>2026-09-23T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Concept pages.&lt;/strong&gt; A summary says what one source said; a concept page says what the vault knows about one idea, and every new source updates it in place. - A disagreement keeps both positions with sources and dates. - An outdated claim is struck through, never deleted. - Every claim carries a confidence label. - &lt;code&gt;tools/concepts.py&lt;/code&gt; validates each rewrite. - New concepts are proposed into &lt;code&gt;_Agent-Context/concepts.md&lt;/code&gt; and wait for a yes. - The old articles phase is retired, and &lt;code&gt;--only concept-migrate&lt;/code&gt; moves its pages over.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;A connected graph.&lt;/strong&gt; - A deterministic linker ties summaries to the people, companies and concepts they mention. It holds back when a first name belongs to someone else. - INDEX.md gives one line per page, with topic indexes in &lt;code&gt;.wiki/_index/&lt;/code&gt;. - Aliases in &lt;code&gt;_Agent-Context/aliases.md&lt;/code&gt; catch the words people actually use. - Search folds Turkish letters. - A project mirror that shares a name with an entity becomes &amp;quot;(project)&amp;quot;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Measured.&lt;/strong&gt; - &lt;code&gt;tools/wiki_metrics.py&lt;/code&gt; tracks the orphan rate, links per page, the main component and the bridge pages, week on week, in the scorecard and in HEALTH.md. - &lt;code&gt;tools/retrieval_eval.py&lt;/code&gt; scores golden questions every night. - &lt;code&gt;tools/wiki_dedupe.py&lt;/code&gt; proposes merges and never merges. - &lt;code&gt;brainless graph&lt;/code&gt; writes a Gephi file coloured by page type.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Checks, not requests.&lt;/strong&gt; - Claude Code hooks (&lt;code&gt;tools/hooks/claude_guard.py&lt;/code&gt;) ask before human-area writes and deletions, and refuse secrets and misplaced briefings. - &lt;code&gt;tools/output_guard.py&lt;/code&gt; refuses model chatter and nested pages before they are written. - &lt;code&gt;tools/run_log.py&lt;/code&gt; records every scheduled run with its counts, so a job that ran and did nothing shows up. - The nightly job no longer swallows a failed digest or the compiler&amp;#x27;s exit code.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;New doors.&lt;/strong&gt; - &lt;code&gt;brainless media&lt;/code&gt; turns YouTube and Apple Podcasts episode links into timestamped transcripts, queued and transcribed locally. - &lt;code&gt;brainless chats&lt;/code&gt; brings Claude or ChatGPT history in, triaged and filtered first.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Backups.&lt;/strong&gt; &lt;code&gt;brainless backup&lt;/code&gt; seals the vault and its history with &lt;code&gt;age&lt;/code&gt; once a month, into a folder sync does not reach. &lt;code&gt;verify&lt;/code&gt; is the restore test.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Answer rule.&lt;/strong&gt; Answers from the vault cite a page for every claim, keep outside knowledge under its own heading, and end with what was read and what is not covered.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.3.2</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-3-2"/>
    <id>tag:brainless.ezapmar,2026-09-22:v0.3.2</id>
    <updated>2026-09-22T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;The docs follow the README&amp;#x27;s four lines. Each page opens with the line it serves (gather, think, decide, get shit done) or says it is setup. &lt;code&gt;docs/how-it-works.md&lt;/code&gt; is regrouped under the four lines with a new get-shit-done section, and &lt;code&gt;docs/scripts.md&lt;/code&gt; names its sections the same way.&lt;/li&gt;&lt;li&gt;&amp;quot;Every command proposes and you paste&amp;quot; becomes &amp;quot;the machine proposes and you apply&amp;quot;, and &amp;quot;the same five steps&amp;quot; becomes &amp;quot;the same loop&amp;quot;, wherever they appeared.&lt;/li&gt;&lt;li&gt;Link labels in &lt;code&gt;docs/commands.md&lt;/code&gt;, &lt;code&gt;docs/thinking-clearer.md&lt;/code&gt; and &lt;code&gt;docs/scripts.md&lt;/code&gt; read as page names, and &lt;code&gt;docs/syncing.md&lt;/code&gt; points at the reference setup in &lt;code&gt;docs/how-it-works.md&lt;/code&gt; instead of a README section that no longer exists.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.3.1</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-3-1"/>
    <id>tag:brainless.ezapmar,2026-09-22:v0.3.1</id>
    <updated>2026-09-22T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;The README is rewritten for people, not for the code: the problem, the solution and four lines (gather, think, decide, get shit done), then the install. The long technical half moves to &lt;code&gt;docs/how-it-works.md&lt;/code&gt; and the wiki, where the README links.&lt;/li&gt;&lt;li&gt;&lt;code&gt;docs/references.md&lt;/code&gt;: the books, papers and tools the method, the voices and the engine are built on, each with what was taken and where it shows up. Also a wiki page.&lt;/li&gt;&lt;li&gt;&lt;code&gt;setup.sh&lt;/code&gt; is gone; &lt;code&gt;install.sh&lt;/code&gt; has done its job since 0.1. Unused weekly-question labels are dropped from &lt;code&gt;tools/locale/*/thinking_loop.json&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.3.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-3-0"/>
    <id>tag:brainless.ezapmar,2026-09-21:v0.3.0</id>
    <updated>2026-09-21T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;Writing and narrative agents: &lt;code&gt;.agents/buzz/install_agent_channel.sh &amp;lt;slug&amp;gt;&lt;/code&gt; installs a conversational Buzz agent with its own channel from a card in &lt;code&gt;.agents/buzz/agents/&lt;/code&gt;, pinned to a model and effort level (&lt;code&gt;BUZZ_AGENT_MODEL&lt;/code&gt;, default &lt;code&gt;claude-fable-5-1&lt;/code&gt;). Two cards ship: Writer (&lt;code&gt;#writing&lt;/code&gt;, long-form pieces) and Narrator (&lt;code&gt;#narratives&lt;/code&gt;, children&amp;#x27;s stories). Each writes only inside its drafts folder, loads the editing files first and runs the editor lint before every draft.&lt;/li&gt;&lt;li&gt;&lt;code&gt;tools/writing_index.py&lt;/code&gt; compiles &lt;code&gt;_Agent-Context/WRITING.md&lt;/code&gt;, the map of every long-form asset; &lt;code&gt;tools/writing_ideas.py&lt;/code&gt; posts a pitch round to &lt;code&gt;#writing&lt;/code&gt; every second month. New &lt;code&gt;PROFILE.md&lt;/code&gt; fields: &lt;code&gt;editor_dir&lt;/code&gt;, &lt;code&gt;writings_dir&lt;/code&gt;, &lt;code&gt;drafts_dir&lt;/code&gt;, &lt;code&gt;narratives_dir&lt;/code&gt;, &lt;code&gt;longform_dirs&lt;/code&gt;, &lt;code&gt;corpus_dirs&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;The polling reply worker leaves harness channels alone (&lt;code&gt;HARNESS_CHANNELS&lt;/code&gt;), so an owner message in &lt;code&gt;#writing&lt;/code&gt; gets exactly one reply.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.2.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-2-0"/>
    <id>tag:brainless.ezapmar,2026-09-21:v0.2.0</id>
    <updated>2026-09-21T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;Telegram is capture-only; receipts and errors arrive in Buzz &lt;code&gt;#inbox&lt;/code&gt;. Nothing is sent back over Telegram any more: no replies, no buttons, no &lt;code&gt;/today&lt;/code&gt;. Old Telegram message ids stop authorising writes; pending previews are re-posted to Buzz and must be approved there. This is the reason for the minor version bump.&lt;/li&gt;&lt;li&gt;Today and weekly thinking use owner-only Buzz threads with revision-bound approval, pending-preview migration and recoverable writes.&lt;/li&gt;&lt;li&gt;Notifications use a durable Buzz outbox with relay acknowledgement and lost-ack reconciliation. The interaction timer retries failed delivery and saved replies.&lt;/li&gt;&lt;li&gt;Added delivery, workflow and capture-only regression coverage. See &lt;a href=&quot;https://github.com/ezapmar/brainless-public/blob/main/docs/buzz-interactions.md&quot;&gt;Buzz interactions&lt;/a&gt; for cutover and recovery.&lt;/li&gt;&lt;li&gt;Give the nightly compile a wall-clock budget so a backlog at the front cannot eat the whole window. Summaries, projects and entities check the clock before each file; articles and ideas reserve the seconds their one call needs. The index always runs. The nightly passes most of its timeout to the child as &lt;code&gt;--budget-seconds&lt;/code&gt; and runs it unbuffered, so a killed run still leaves a journal of where it stopped.&lt;/li&gt;&lt;li&gt;&lt;code&gt;health_check.py&lt;/code&gt; notifies with &lt;code&gt;osascript&lt;/code&gt; on macOS and &lt;code&gt;notify-send&lt;/code&gt; on Linux, and skips the call when neither is present, so a RED report on the worker no longer crashes the run after writing the file.&lt;/li&gt;&lt;li&gt;&lt;code&gt;build_dashboard.py&lt;/code&gt; reads last-log dates from the Log section only, and counts both &lt;code&gt;### YYYY-MM-DD&lt;/code&gt; headings and &lt;code&gt;- [YYYY-MM-DD]&lt;/code&gt; list lines. A project that dates its log as a list no longer looks months stale.&lt;/li&gt;&lt;li&gt;The method page now lists the seven Quivy steps with the file each one maps to, and adds the seventh (the pass ends in a seed and, when it settles one, a decision note), which the research command already enforced but the page never said. The dated audit it used to carry moves here: on 2026-09-19 all ten seeds in &lt;code&gt;Thinking/Ideas/&lt;/code&gt; lacked a &lt;code&gt;zk:&lt;/code&gt; address while all six compiled ideas had one, the wrong way round; &lt;code&gt;tools/zk_id.py --apply&lt;/code&gt; is the fix. The page no longer cites a tool that does not ship (&lt;code&gt;editor_lint.py&lt;/code&gt;), names a reading route for Zettelkasten, and the README&amp;#x27;s Install section gains an &amp;quot;Optional inputs&amp;quot; note for voice (ffmpeg + whisper.cpp) and photographs (a backend with vision).&lt;/li&gt;&lt;li&gt;Count the pile, then drain it. &lt;code&gt;tools/wiki_prune.py --count&lt;/code&gt; writes &lt;code&gt;_Agent-Context/PILE-SCORECARD.md&lt;/code&gt; every Sunday with no model: captures per graded decision, filed analyses per decision, Inbox files past fourteen days (the capture belief&amp;#x27;s own falsification line), orphan wiki pages, concept articles that bridge two homes, decisions and challenged beliefs in the window. &lt;code&gt;--archive&lt;/code&gt; applies mechanical rules with a stated reason, dry run by default: an unlinked analysis after 30 days, a summary whose source left the compiled roots after 60, any orphan after 60, and a meeting report that has been summarised and mined after 14 days in Inbox. Nothing is deleted; every move is logged to &lt;code&gt;.wiki/_archive/LOG.md&lt;/code&gt; with its rule and reason, and the archive is out of search, index and lint. &lt;code&gt;health_check.py&lt;/code&gt; carries the Inbox count into the briefing, red above ten. &lt;code&gt;lint_wiki.link_graph()&lt;/code&gt; is now the one definition of &amp;quot;linked&amp;quot; for lint and prune alike.&lt;/li&gt;&lt;li&gt;The nightly digest reads the epic/story/task label before it reads the note: a task contributes its action items and no narrative, a story three lines, an epic is read in full. The digest runs the classifier first so tonight&amp;#x27;s captures are labelled tonight, caps the raw text it reads, and the task ledger applies the same near-duplicate guard the meeting extractor had (&lt;code&gt;tools/task_dedup.py&lt;/code&gt;), so a promise rephrased by the model does not become a second row.&lt;/li&gt;&lt;li&gt;A sixth persona, Methodologist, built on Quivy and Van Campenhoudt&amp;#x27;s research method: it rewrites the thesis as a research question, names the hidden angle, builds concept, dimension and indicator, and writes the falsifiable hypothesis and the cheapest observation plan. Every persona now receives what the moderator received (the topic&amp;#x27;s wiki hits, the owner&amp;#x27;s core beliefs, the decision calendar) and round two must cite a vault file. Six sessions at once strain a single subscription, so personas are mentioned one at a time by default; &lt;code&gt;--parallel&lt;/code&gt; restores the old behaviour.&lt;/li&gt;&lt;li&gt;Each dialectic topic is filed as two pages and a folded transcript. Page one is what a decision needs: a verdict computed from the final votes (Go, Stop or Test first, with the median number), the moderator&amp;#x27;s conclusion and fields, a compact vote table and the proposal. Page two is the method trace: the research question, the hypotheses and tests, one row per persona with its finding and objection. The raw rounds sit under a collapsed callout in the same note. The unanimity warning is a callout, not an HTML span. &lt;code&gt;/dialectic&lt;/code&gt; produces the same layout.&lt;/li&gt;&lt;li&gt;&lt;code&gt;--run night&lt;/code&gt; and &lt;code&gt;brainless-dialectic-night.timer&lt;/code&gt;: a 02:00 experiment that runs the persona lane on the worker&amp;#x27;s local model while the moderator and a new &lt;code&gt;dialectic-judge&lt;/code&gt; lane stay on the cloud and grade each local reply. Replays the day&amp;#x27;s first topic for a like-for-like comparison, scores nothing, and keeps its own section in the status file with a five-night kill rule.&lt;/li&gt;&lt;li&gt;Add epic-triggered weekly research. &lt;code&gt;tools/note_classify.py&lt;/code&gt; tags every capture in the daily and meeting folders as epic, story or task in the Atlassian sense, and &lt;code&gt;tools/weekly_research.py&lt;/code&gt; runs a research cycle only when the week produced an epic. A week of stories and tasks costs nothing: the job exits in seconds without calling a model. The epic gate is deliberately conservative (a score, several independent signals, and either recurrence or breadth), targeting zero or one epic per week, and an epic already researched within eight weeks is not researched again: the recurrence is reported instead, because a topic that keeps returning without closing is waiting for a decision, not for more evidence.&lt;/li&gt;&lt;li&gt;Research follows the vault&amp;#x27;s Quivy method: one opening question, the lens named in one sentence before any hypothesis is written, falsifiable hypotheses, a single salvo of at most five sources each on a different angle, then an interpretation of the deviations. Naming the lens is the book&amp;#x27;s problematique step, and it is what keeps three hypotheses serving one question instead of scattering across three. Every finding must carry &lt;code&gt;Kaynak: &amp;lt;URL&amp;gt;&lt;/code&gt; and one of &lt;code&gt;verified&lt;/code&gt;, &lt;code&gt;claim&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;; unlabelled lines are deleted mechanically before synthesis and &lt;code&gt;unknown&lt;/code&gt; lines may not be used as support. When there is no evidence the report says so, because absence of evidence is not evidence.&lt;/li&gt;&lt;li&gt;Open the research lane in &lt;code&gt;tools/llm.py&lt;/code&gt;: &lt;code&gt;run_prompt(web=True)&lt;/code&gt; grants WebSearch and WebFetch for that one call. The execution tools stay denied even then, and the fetched text reaches the synthesis pass fenced as untrusted data, so the furthest a poisoned page can reach is a wrong sentence in a report.&lt;/li&gt;&lt;li&gt;Add a &lt;code&gt;goose&lt;/code&gt; provider to &lt;code&gt;tools/llm.py&lt;/code&gt; for local inference on the worker, invoked with &lt;code&gt;--no-profile&lt;/code&gt; so it loads no extensions and has no shell. This is the goose-side equivalent of the deny list.&lt;/li&gt;&lt;li&gt;Route the model per lane, not per installation. Every call site now names a lane (&lt;code&gt;python3 tools/llm.py --lanes&lt;/code&gt;), and &lt;code&gt;BRAINLESS_LLM_PROVIDER_&amp;lt;LANE&amp;gt;&lt;/code&gt; points that lane at its own provider, so a note classifier answering with one word out of three can run on hardware you own while a weekly synthesis still goes to a large model. Two reasons, pulling in opposite directions: privacy wants the local model as a lane&amp;#x27;s primary, resilience wants it as a fallback for the cloud lanes (&lt;code&gt;BRAINLESS_LLM_FALLBACK=goose&lt;/code&gt;), and both are the same setting seen from different sides.&lt;/li&gt;&lt;li&gt;The fallback only goes one way. Cloud may degrade to local; local never escalates to cloud, because a lane pinned local was pinned for privacy and a timeout is not consent to send the same text somewhere else. &lt;code&gt;BRAINLESS_LLM_ALLOW_CLOUD_FALLBACK=1&lt;/code&gt; says otherwise, explicitly, per machine.&lt;/li&gt;&lt;li&gt;Log the routing: &lt;code&gt;.agents/state/llm_log&lt;/code&gt; keeps the last 300 calls with lane, provider, outcome and wall time, next to the single latest outcome in &lt;code&gt;llm_status&lt;/code&gt; that the health check reads. &lt;code&gt;tools/llm_bench.py&lt;/code&gt; times the real prompt shapes against a provider, because whether a local model is viable is a measurement, not an opinion.&lt;/li&gt;&lt;li&gt;Guard the task ledger deterministically in &lt;code&gt;spiky_actions.py&lt;/code&gt;. The prompt asked the model not to repeat a task already in the ledger, which is a string comparison wearing a prompt; a duplicate is now dropped after the model, with Turkish suffixes folded, so a weaker local model cannot send the same promise to a person twice.&lt;/li&gt;&lt;li&gt;State the base rate in the epic rubric: an epic is about one note in twenty. Found by measurement, not by taste. Without it a local 4B model promoted four notes out of eight to epic that Opus called stories, always in that direction, which is the expensive one because an epic triggers a research pass. With it the two models agreed on all eight, and both still called an unmistakable multi-month programme an epic, so the sentence tightened calibration without turning the classifier into a constant.&lt;/li&gt;&lt;li&gt;New guide: &lt;code&gt;docs/local-inference.md&lt;/code&gt;, including what the worker hardware can actually do, how to seed a model over a slow link, and the order in which lanes should move.&lt;/li&gt;&lt;li&gt;Add &lt;code&gt;_Agent-Context/SOURCES.json&lt;/code&gt;, a machine-readable source registry. Scripts may only append to &lt;code&gt;candidates&lt;/code&gt;; promoting a candidate is the owner&amp;#x27;s call, at most one new stream per month, and a source that has fed nothing for eight weeks is flagged rather than removed.&lt;/li&gt;&lt;li&gt;Add &lt;code&gt;tools/lang_detect.py&lt;/code&gt; and answer in the language that was used. Research reports follow the triggering note, and the dialectic engine now argues each topic in the language of the notes behind it instead of forcing English.&lt;/li&gt;&lt;li&gt;Reframe both READMEs around connectivity and the three layers (collect, think clearly, decide), including the failure mode the layering guards against, and correct the origin of the name.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.6</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-6"/>
    <id>tag:brainless.ezapmar,2026-09-18:v0.1.6</id>
    <updated>2026-09-18T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;Add &lt;code&gt;docs/scripts.md&lt;/code&gt;: a reference for every Python script in &lt;code&gt;tools/&lt;/code&gt; and &lt;code&gt;.agents/scripts/&lt;/code&gt;, each with a definition, a description and the design philosophy behind it, plus a map of how the scripts relate. Linked from the README.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.5</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-5"/>
    <id>tag:brainless.ezapmar,2026-09-18:v0.1.5</id>
    <updated>2026-09-18T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;Add the Today queue: at most one decision, one commitment, and one evidence review. Telegram supports preview, apply, edit, defer, and dismiss. Repeated deferrals ask for a blocker or smaller step; seven-day completion counts and source links appear in TODAY.md. The existing morning reminder sends the queue.&lt;/li&gt;&lt;li&gt;Record approved decision outcomes in calibration and recover interrupted Today writes without duplicating entries. See &lt;code&gt;docs/today-queue.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Preserve original documents and raw conversions after processing. Failed, missing, or empty AI summaries now trigger retries; generated output is validated before replacing an existing summary.&lt;/li&gt;&lt;li&gt;Apply project privacy checks to every descendant source file.&lt;/li&gt;&lt;li&gt;Rebuild project mirrors when any permitted source changes, is added, renamed, or removed. Existing mirrors rebuild once under the new dependency policy.&lt;/li&gt;&lt;li&gt;Keep kill criteria out of dashboard actions and open loops. Prefer explicit Next Action sections, now included in the project template.&lt;/li&gt;&lt;li&gt;Add offline regression tests for document retention, project privacy, dashboard actions, and the Today queue; run them in public CI.&lt;/li&gt;&lt;li&gt;Rewrite the README around one loop and add &lt;code&gt;docs/capture-flow.md&lt;/code&gt; on the capture flow and the Obsidian network.&lt;/li&gt;&lt;li&gt;Keep private finance tooling out of the export. &lt;code&gt;tools/export_public.py&lt;/code&gt; now excludes the finance folder, because a fixture of real figures passes any word scan. Deployment-specific agent rules move to a private companion file that &lt;code&gt;_Agent-Context/AGENT-RULES.md&lt;/code&gt; points to and the export never lists.&lt;/li&gt;&lt;li&gt;Workers pull with &lt;code&gt;--autostash&lt;/code&gt;, the cron wrapper commits its regenerated context blocks locally so the tree does not sit dirty, and the content engine reads the editing rules alongside the production guide.&lt;/li&gt;&lt;li&gt;&lt;code&gt;VERSION&lt;/code&gt; catches up: 0.1.4 shipped with the file still reading 0.1.3.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.4</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-4"/>
    <id>tag:brainless.ezapmar,2026-09-15:v0.1.4</id>
    <updated>2026-09-15T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;Dialectic scorecard. Round one is isolated (one Buzz root per persona, so nobody reads anyone else before answering); round two is one root that quotes every round one reply. Replies end with &lt;code&gt;Vote:&lt;/code&gt; (YES, NO, CONDITIONAL) and &lt;code&gt;Number:&lt;/code&gt; (NN%), round two also with &lt;code&gt;New evidence:&lt;/code&gt;. &lt;code&gt;score_topic()&lt;/code&gt; turns those lines into a deterministic per-topic scorecard (affirmation rate, who moved and whether they cited evidence, a unanimity warning) that is filed with the note, posted to the channel and fed to the synthesis. Rounds append to &lt;code&gt;.agents/state/dialectic_scores.jsonl&lt;/code&gt;; the worker writes the rolling 30 day view to &lt;code&gt;_Agent-Context/DIALECTIC-SCORECARD.md&lt;/code&gt; with two flags: sycophancy (affirmation above 60 percent) and a persona that never votes NO. &lt;code&gt;brainless dialectic --scorecard&lt;/code&gt; prints it. Persona rules and the &lt;code&gt;/dialectic&lt;/code&gt; command carry the same headings; redeploy the personas after upgrading.&lt;/li&gt;&lt;li&gt;Kill criteria. Every project &lt;code&gt;notes.md&lt;/code&gt; may carry a &lt;code&gt;## Kill Criteria&lt;/code&gt; section of &lt;code&gt;- [ ] YYYY-MM-DD | condition | consequence&lt;/code&gt; lines (the project template has it). &lt;code&gt;tools/kill_criteria.py&lt;/code&gt; scans them deterministically: a past date with an open box is a breach. Breaches turn the new health check row red, are written to &lt;code&gt;_Agent-Context/KILL-CRITERIA.md&lt;/code&gt; for the briefing, lead the dashboard&amp;#x27;s new Kill criteria section and the think surface&amp;#x27;s provocation; PROJECTS-ACTIVE shows each project&amp;#x27;s next criterion, and projects without one are listed.&lt;/li&gt;&lt;li&gt;Vault topic fallback: on a day with no captures the evening dialectic argues one thing the vault is waiting on (a decision past review, a decided note without a prediction, a pending decision near review, a stale belief, a live question), rotated with a 14 day cooldown, instead of idling.&lt;/li&gt;&lt;li&gt;Health check: a &amp;quot;Morning briefing&amp;quot; row goes yellow on weekdays after 08:30 when the day&amp;#x27;s briefing is missing or lacks the health block.&lt;/li&gt;&lt;li&gt;Think surface: the cadence step says how many days it has waited when it exceeds two weeks.&lt;/li&gt;&lt;li&gt;Every thinking command prompt now ends with a Loopback step that files its output through &lt;code&gt;file_query.py&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.3</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-3"/>
    <id>tag:brainless.ezapmar,2026-09-11:v0.1.3</id>
    <updated>2026-09-11T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;The engine is English end to end: every comment, docstring, log line, help string, shell message, prompt and convention document. No Turkish left in code.&lt;/li&gt;&lt;li&gt;Output language is a setting, any language: &lt;code&gt;output_lang&lt;/code&gt; in &lt;code&gt;PROFILE.md&lt;/code&gt; takes any ISO code. LLM prompts carry a language directive; deterministic strings (health labels, bot replies, generated headings, section names) come from &lt;code&gt;tools/locale/&amp;lt;code&amp;gt;/&amp;lt;script&amp;gt;.json&lt;/code&gt; through &lt;code&gt;tools/i18n.py&lt;/code&gt;, English as the fallback. Shipped locales: &lt;code&gt;en&lt;/code&gt;, &lt;code&gt;tr&lt;/code&gt;. Add a directory to add a language. See &lt;code&gt;docs/localization.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Scripts that parse headings they wrote earlier accept both the current language and English, so existing vaults keep working.&lt;/li&gt;&lt;li&gt;Buzz identities renamed to English: &lt;code&gt;briefing&lt;/code&gt;, &lt;code&gt;thinking&lt;/code&gt;, &lt;code&gt;tasks&lt;/code&gt;, &lt;code&gt;content&lt;/code&gt; (key files under &lt;code&gt;~/.config/brainless/buzz/keys/&lt;/code&gt;), and the owner env file is &lt;code&gt;assistant.env&lt;/code&gt;. Existing relays rename the files once.&lt;/li&gt;&lt;li&gt;Installer accepts any two or three letter language code.&lt;/li&gt;&lt;li&gt;Document conversion calls markitdown as a Python library (&lt;code&gt;tools/markitdown_native.py&lt;/code&gt;), not the CLI: one reused converter instance, no PATH discovery, no per file subprocess. &lt;code&gt;smart_processor.py&lt;/code&gt; and &lt;code&gt;batch_markitdown.py&lt;/code&gt; share it.&lt;/li&gt;&lt;li&gt;No em or en dashes anywhere in the tree; the leak scan and CI stay as before.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.2</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-2"/>
    <id>tag:brainless.ezapmar,2026-09-11:v0.1.2</id>
    <updated>2026-09-11T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;CRM snapshot addon: read-only pull from Pipedrive into &lt;code&gt;_Agent-Context/CRM.md&lt;/code&gt; and per-organisation event logs under &lt;code&gt;Inbox/CRM/&lt;/code&gt;. Organisation and deal level only, no person data, no LLM. Provider seam for other CRMs. Systemd timer for the worker, hourly run on the laptop. Documented with a Pipedrive example in &lt;code&gt;docs/addons/crm-pipedrive.md&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Health check row for the CRM snapshot, and an optional Buzz &lt;code&gt;#crm&lt;/code&gt; channel (&lt;code&gt;install_crm_channel.sh&lt;/code&gt;, &lt;code&gt;buzz_crm_sync.sh&lt;/code&gt;) that receives the block when it changes.&lt;/li&gt;&lt;li&gt;&lt;code&gt;buzz_post.sh&lt;/code&gt; no longer needs coreutils &lt;code&gt;timeout&lt;/code&gt; on macOS.&lt;/li&gt;&lt;li&gt;Flag severity: an organisation without an open deal is never red; red is reserved for deals.&lt;/li&gt;&lt;li&gt;&lt;code&gt;VERSION&lt;/code&gt; file and &lt;code&gt;brainless version&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code&gt;docs/&lt;/code&gt; ships with the export.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.1</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-1"/>
    <id>tag:brainless.ezapmar,2026-09-10:v0.1.1</id>
    <updated>2026-09-10T00:00:00Z</updated>
    <content type="html">&lt;p&gt;Not tagged at the time; tagged retroactively on the last commit of the day.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;One-line installer (&lt;code&gt;install.sh&lt;/code&gt;) and the &lt;code&gt;brainless&lt;/code&gt; command.&lt;/li&gt;&lt;li&gt;README rewritten around the decision loop and the five voices, with the real three-device setup as a usage example.&lt;/li&gt;&lt;li&gt;Calibration (&lt;code&gt;brainless calibrate&lt;/code&gt;) and the think-surface command.&lt;/li&gt;&lt;li&gt;Transcript filter, dialectic trigger, failure alerts on the worker.&lt;/li&gt;&lt;li&gt;CI leak-scan gate: every push and pull request runs the export scan.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>brainless 0.1.0</title>
    <link href="https://ezapmar.github.io/brainless-public/whats-new.html#v0-1-0"/>
    <id>tag:brainless.ezapmar,2026-09-09:v0.1.0</id>
    <updated>2026-09-09T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;&lt;li&gt;First public export: engine, commands, personas, installer, MIT license.&lt;/li&gt;&lt;/ul&gt;</content>
  </entry>
</feed>
