Changelog¶
All notable changes to Brain Framework (formerly FKF) are documented here. This project follows Semantic Versioning from its first public release.
Unreleased¶
v18.5.0 - 2026-10-14¶
A feature and review release. The brain format (version: 7) is unchanged; bf.yaml gains the optional silent_after and keep settings, which an older bf rejects, the reply schemas only gain optional fields and the search cache rebuilds once. Upgrade with uv tool upgrade brain-framework (or update a brain's pin), run bf skills DIR to update all four skills, and copy the updated example weekly-review routine and gmail-headers sensor into your brain, preserving local adaptations.
Added¶
- A sensor's
silent_after(seconds) reports a scheduled source that keeps succeeding without a new or changed record:bf statusmarks it"silent": true, andattention, the home page andbf status --checklist it. Freshness proves a successful run, not new evidence: a filter or account drift used to look healthy.bf statusand thememoriespage give each source'schanged, the newest time this brain gained a new or changed record of it. keepbounds generated output. An action routine'skeep: Nremoves its actions older than the newest N while they still hold only theACTION.mdthis machine wrote: an edited report, a folder holding another file and an action written beforekeepstay. A prompt'skeep: Nremoves its oldest run records after each run, never another file of its folder, and never fails a recorded run. Replies count them asremoved.bf statusnames each brain'sruntime: theinstalledbf version and, read as data from the brain'suv.lock, thepinnedone. Agents compare their major versions instead of parsing the lock.bf validatereports an enabled prompt file above the 120,000-byte limit, which every run would reject.- A runnable offline prompt example,
examples/prompts/, usescatas a stand-in harness withrefresh: 0: a piped message becomes a record that search finds. The prompt guide starts with it, and troubleshooting covers failed prompts: JSON output withtext, the 120,000-byte limit on standard input too, skipped scheduled runs, harness sign-in and tool permissions. bf-maintaincovers prompts: declare one with an explicitrefresh(an enabled prompt runs every 30 minutes by default, unlike sensors and routines), atimeoutabove the harness's own limit and atextpointer; test it without a model throughcommand: [cat], then run it once withbf run PROMPT --stdin. It treatsmemories/NAME/records as model output and grants the harness only the tools it needs.- Reads return
backlinks_omitted, the number of relation groups beyond the 64 they preview, counted across the selected brains: more than 64 relations used to drop the rest silently.
Changed¶
- A program another process is running, such as a manual
bf collectduringbf watch, isskippedinbf updateinstead of failed: watch no longer alerts a failure that run history never records. bf runsuggests close prompt names too:unknown routine or prompt asistant; … did you mean assistant?.- A scheduled prompt that is not due when it takes its lock, because another process ran it or it waits to retry a failure, says so instead of claiming another run just succeeded.
- The four skills are 30% shorter (17,009 → 11,919 words) without dropping a procedure or safety rule: each shared rule lives once, references link the documentation for exact contracts, and long steps are split. They compare
runtime.pinnedwithruntime.installedinbf statusinstead of reading a brain'suv.lock. bf-actiondefines when an action is done: its Outcome is filled and its TODO has no open box. Discovery resumes only open actions, closing resolves every open task, and later work starts a new action linking the done one.- The documentation gives each rule one owner: timing and failure backoff in Watch and schedule, program names in the file formats, ranges in Limits, dry runs and status fields in Commands, scopes and incomplete answers in Retrieval. The README's Try it installs BF and links Getting started; the guides run copied example scripts as executables.
- The example weekly review lists scheduled programs that failed or are late, says when an empty week or coming week may come from a sensor needing attention, and writes a review when attention is its only content.
- Searches, reads and each MCP call no longer check every record file: the cache keeps each
memories/SOURCEfolder's fingerprint and lists only folders that changed, so on a brain of about 50,000 files a warm search checks its cache in about 16 ms instead of 170 ms (in-process timings on one Linux machine). Collection renames records into place, which always changes their folder; a record file edited in place, which collection never does, waits forbf build. Authored folders,bf buildandbf validatestill list every file. - The home page lists projects needing review first in the space
changedused to take:changednames only other notes, in brief (ref,kind,title,dateortime,modified,review), and the 32 KiB budget is measured on the reply as printed. A brain whosechangedlist repeated its projects used to show only one of the projects due for review. - Deep listing pages stop at their window: with one selected brain the offset is skipped in SQL, so a source page at offset 8,000 answers in about 65 ms instead of 300 ms on the same machine, and later pages of a large exact read no longer rebuild its backlinks.
Fixed¶
bf watchstops a collection whose start a cancellation interrupted, and signals its collection and prompt workers together, once each, so they stop in parallel.bf updatedates its due list once it holds the cycle lock: waiting for another update no longer leaves newly due programs for the next cycle.- A prompt answering a message and a scheduled run of the same prompt no longer overwrite each other's log entries.
- A prompt file above the limit reports
file exceeds 120000 bytesinstead of 120001. bf build --reproject --dry-runcounts changes without holding every reprojected record, and keeps only the failures its reply shows.- Programs no longer inherit
DOTNET_STARTUP_HOOKS,R_PROFILE_USER,LUA_PATHorLUA_CPATH, which load code before the program starts. - The contract check accepts a configuration value that stops listing its allowed values, which widens what files accept, as a minor change.
- Tests give cold interpreter starts the documented 120-second deadline and cap parallel workers at eight, so a loaded machine no longer fails the gate.
guarded-write.pyserializes the check, write and rename of one file among concurrent helpers with an advisory lock belowXDG_STATE_HOME(or~/.local/state), so of two sessions that read the same digest only one succeeds; before, both could report success while one edit was lost. An editor that takes no lock can still save between the helper's last check and its rename.evidence.py readkeeps thestaleandproblemsof every page of a large exact read, so a capture refuses, and a comparison reportsunknown, when a later page was incomplete.- The example Gmail headers sensor no longer misses messages received in the first or last fraction of a second of its window: it widens Gmail's whole-second search outward and filters exactly.
- The prompt guide's Claude Code command allows the read-only
bf readandbf searchcalls its prompt asks for, and the release checklist reads the workflows' mise pin despite its inline comment. - Documentation matches behavior:
--promptandupdate --kindrepeat, prompts get name suggestions, a prompt dry run appends to its own log, program names are unique across sensors, routines and prompts and neverbf,bf initcreates noprompts/folder, and an exportedBF_BRAINtakes precedence over the working directory. - A read of a note ref ending in a bare
#is invalid input (exit 2), like a scope: it read the whole note under a ref no backlink or reminder matched, so the note listed itself as a backlink and lost its tasks and review signals. An offset on the home page or thememoriesoverview exits 2 too. bf validateresolves an alias that a later note declares before checking links, instead of reporting a missing record that exact reads resolve.- Spelling
suggestionsfold Latin accents as promised (equipe, notéquipe), and a paged read without sections inside it omitsoutlineinstead of returningoutline: [].
v18.4.0 - 2026-10-13¶
A feature release. The brain format (version: 7) and the search cache format are unchanged; bf.yaml gains an optional prompts: section, which an older bf rejects, and the reply schemas only gain optional fields. Upgrade with uv tool upgrade brain-framework (or update a brain's pin), run bf skills DIR to update bf-maintain, which now covers prompts, and the retrieval guide, and copy the updated example hooks and weekly-review routine into your brain, preserving local adaptations.
Added¶
- Prompts run your agent harness over the brain, every 30 minutes by default or now with
bf run PROMPT --stdin. Declare one underprompts:with a Markdownpromptfile inprompts/and a direct-argvcommand: BF expands{{brain}},{{home}},{{start}},{{end}}and{{input}}in the file once, then passes it as the command's{{prompt}}argument or, without one, on standard input. BF never runs a model itself. Each successful run becomes a record inmemories/NAME/with the reply as its text (textselects it in JSON output, such as/response), its input, window, duration and the harness's other output, such as token usage, so later runs,bf searchand your agents read it back; those records rank like a low-priority source, so a summary never outranks its evidence. See Run prompts. bf updateruns due prompts after sensors and routines, outside the update lock;bf watchruns them in a second process beside collection, so a long agent run never delays a sensor, and marks them@with their run counts. A direct run never waits for a scheduled one and leaves the schedule's history unchanged, failures included; a scheduled run checks again under its lock that no other process just ran it.bf update --kind sensor|routine|prompt, repeatable, keeps only those kinds of program;update,watchandscheduleaccept--prompt NAMEselectors.- The example session hook names failing or overdue prompts in its attention line, beside sensors and routines.
bf statusreportspromptswith their state, freshness, runs, last run, latest record and failures;attentionand the home page list failing or overdue prompts, andbf validatechecks that each enabled prompt's file exists.
Changed¶
bf runtakes a routine or a prompt: its argument is namedPROGRAM.- A routine's
{{prompt}}placeholder is invalid, as before; only a prompt's command takes it. - CI and security workflows pin
jdx/mise-actionv5.1.1. The explicit mise2026.10.0pin keeps tool-manager upgrades deliberate; the action's 24-hour release-age default applies only without that pin.
Fixed¶
- Cancellation during sensor or routine startup now kills the newly created process group. Markdown complexity tests compare CPU-time growth, and cancellation tests wait for observed process termination, avoiding fixed-speed assumptions on slow CI runners.
- Period pages and search scopes place records without
timebyattributes.observed, including source counts and ordering across brains. Replies keep observation separate from event time; records with neither timestamp remain outside periods, andundatedstill selects every record without event time. - The
weekly-reviewexample lists projects as plain bullets, with overdue reviews first and earliest deadlines first, and separates the open-task preview from its surrounding paragraphs. Generated reviews no longer create duplicate checkbox tasks; complete work in the owning notes. - The session and prompt hooks keep nonempty stale cache results while collection runs, showing “Index refreshing”. They tolerate only the exact stale-cache identity problem; empty generations, malformed metadata and other problems stay silent.
v18.3.0 - 2026-10-07¶
A review and feature release. The brain format (version: 7) and bf.yaml are unchanged; the reply schemas only gain optional fields and the search cache rebuilds once. Upgrade with uv tool upgrade brain-framework (or update a brain's pin). Run bf skills DIR to update bf-use, and copy the updated example hooks, weekly-review routine and any new sensor into your brain.
Added¶
bf searchsuggests close words the brain holds for each misspelled word:"suggestions":{"retension":["retention"]}besideunmatched.- A claim names the note or record that owns its target, when exactly one item of its brain does, as
target_refandtarget_title: follow it without another search. bf collect --dry-runreports theadded,updated,unchangedandremovedcounts a collection would commit, and"removal_refused": truewhen the snapshot guard would refuse it, before you pass--allow-removal.bf watchwarns, likebf schedule, when its interval is at least the shortest selectedrefresh, which runs that program late and makesbf statusreport it overdue.- A mistyped
--brainname suggests close registered, enclosing or referenced brain names:did you mean work?. - The example
gmail-headers.pysensor collects Gmail senders, recipients, subjects, labels and dates throughgws, never message bodies, withperson:email/links, agmail-thread:link per conversation and an RFC 2392mid:alias.
Changed¶
- Writers also lock the brain folder itself: two processes with different
XDG_STATE_HOMEvalues, or two accounts sharing a brain, used to commit at once, and one's recovery could roll back the other's committed records. A filesystem that cannot lock a folder, such as NFS, keeps the state lock alone. - The
weekly-reviewroutine names the projects to review by ref instead of linking them: its links flagged every listed project with newer evidence, so each later review counted the earlier ones. bf initwrites its starter files from the package'sstarter/folder; the generatedAGENTS.mdnow holds one line per paragraph, so the refresh comparison shows every wrapped line once.- A search scoped to an authored folder no longer counts collected sources, and a cache is checked against the layout bf builds in one comparison. Tests run in parallel.
Fixed¶
bf evalranks expected refs among the first 50 results even when they span several reply pages: a search reply stops at its 32 KiB budget, so a ref at rank 46 among long results read as missing and MRR dropped.- An action's
projectsinclude projects itsACTION.mdlinks by entity, alias or BF address, as each project's backlinks already listed the action; only path links counted. - An identity whose BF address percent-encodes a format character, such as
bf://brain/people/bob%E2%80%8B, is invalid like its raw form: it looked like another subject's address. - A footnote-looking line inside a code fence no longer hides the sections after it: its indented lines closed the fence early.
- Period pages and scopes accept a trailing slash, such as
bf read 2026-09/or--scope 7d/, like folder and tag pages. - A file that failed to read for a reason other than permissions, such as an I/O error on a network mount, is read again on the next refresh instead of staying skipped until it changed; the search cache rebuilds once.
- A cache that another program locks, such as an open
sqlite3shell, names the lock instead of advising to check free space. bf statuslists programs nameddate,time,fieldsorattributeslike any other.bf init,bf skillsand other commands reject an argument that is not UTF-8 as invalid input before writing;initandskillsused to create every file, then fail.- Recovery clears an interrupted record transaction that left one temporary file beside a full journal; every later collection used to fail.
bf watchwaits for and stops its update when the terminal closed while it was stopping, instead of leaving it running.- The bf-use
guarded-write.pyhelper refuses a passage that occurs twice in overlapping positions, as it refuses other repeated passages. - The example hooks and the
weekly-reviewroutine escape control and invisible format characters, asbfreplies do: decoding the JSON restored them, so a shared note's title could reach the agent's context or a review action as hidden text. Copy the updated examples into your brain.
v18.2.0 - 2026-10-06¶
A skill release. The brain format (version: 7), bf.yaml, the reply schemas and the search cache are unchanged. Upgrade with uv tool upgrade brain-framework (or update a brain's pin), then run bf skills DIR to install bf-action and update bf-use.
Added¶
- A fourth packaged skill,
bf-action, starts, resumes, hands off and closes a tracked work session. Invoking it with a topic, such as/bf-action website-reviewin Claude Code, is the request to start that action: the agent resumes an open action on that topic or, when none exists, finds the owning project, createsactions/YYYY-MM-DD_website-review/ACTION.mdand fills its Context, TODO and Resume, with no need for wording such as "start an action". The action guide, the working-context and handoff guides,new-action.py,check-handoff.pyand the action template move frombf-usetobf-action;bf-usekeeps retrieval and writing knowledge back.
Upgrade: run bf skills DIR to install bf-action and update bf-use, which removes the moved files. If you edited any bf-use file, the folder reads modified and stays unchanged: back up your edits, then rerun with --force, which keeps edited files the new version no longer ships. A Claude Code SessionStart hook that runs bf-use/scripts/check-handoff.py must point at bf-action/scripts/check-handoff.py. bf init now names both skills in the brain's AGENTS.md; merge that line as Refresh brain instructions shows.
v18.1.5 - 2026-10-06¶
A search fix. The brain format (version: 7), bf.yaml, the reply schemas, the packaged skills and the search cache are unchanged. Upgrade with uv tool upgrade brain-framework (or update a brain's pin); a copied prompt-context.py hook can take the example's new word list.
Fixed¶
- Search drops
other,othersandanother, and the Frenchautre,autres,maandta, like other function words. In a mostly English brain,Pourquoi Kotlin plutôt qu’un autre langage ?ranked first a short French note that only sharedautreswith the question, a rare word that outweighed the subject; the note about Kotlin now ranks first. A query made only of such words still searches them literally. The exampleprompt-context.pyhook mirrors the list.
v18.1.4 - 2026-10-04¶
A review release of fixes. The brain format (version: 7), bf.yaml, the reply schemas and the packaged skills are unchanged; the search cache rebuilds once. Upgrade with uv tool upgrade brain-framework (or update a brain's pin); no other step is needed.
Fixed¶
- Search no longer lands on a section without the matching text: in a copied document with several H1s, text under a later H1 ranked as the H2 above it, whose exact read stops at that H1. An H1 after the first section is now a section of its own. The search cache rebuilds once.
- A record's fields other than
textare bounded by their encoded size, as the reply limit counts bytes: a record of long non-ASCII links or aliases passed the 2 MiB check, then every exact read of it failed withresponse exceeds its byte limit. Collection now rejects it withfields other than text exceed 2 MiB. - A registered brain whose folder exists but cannot be reached, such as a locked folder, is reported as
registered brain directory exists but cannot be reached; restore access to itby search, read andbf statusinstead of as absent, whose advice to register it againbf registerthen refused. A registered path that became a regular file is absent everywhere, sobf registertakes over its name. - An empty value, as an unset variable gives, is invalid input for
bf collect "",bf run "",--sensor "",--routine "",bf collect SENSOR --since ""andbf build --reproject "": they used to name an unknown program, collect the default window or rebuild the whole cache instead of reprojecting. - A zero-length window such as
0dis an invalid period forbf readand--scopealike; the read used to return an empty page while the scope failed withsince must be earlier than until.bf validatereports a link to such a page as an unresolved BF target. bf mcpno longer writes the MCP SDK's log line for each rejected or failed tool call to stderr; the reply carries the error.- Excerpts of a large passage holding a few characters that folding changes, such as
²or a no-break space, are computed faster.
Documentation¶
- The four-tool guide and the watch example give the working checkout command,
uv run --project CHECKOUT bfinside a copied brain; the README's four-tool reply names what it trims.
Added¶
scripts/verify-release.sh X.Y.Zverifies a published release in one command: the annotated tag on origin, a non-draft GitHub release holding exactly the wheel and source archive, PyPI digests matching them, their build attestations and a clean install of that wheel that initializes, validates, searches and reads a brain. The release checklist now gives the commands for the release worktree, checking tasks with the pinned mise, waiting for CD and syncing the primary checkout, runs the gate withGITHUB_ACTIONS=trueand asks for an independent review before committing. Tests coverscripts/verify-release-tag.sh, the guard CD runs before publishing.
Changed¶
- Development tools: Python 3.14.8, uv 0.12.23, dprint 0.60.1, lefthook 2.1.16, trivy 0.75.0 and mise 2026.10.0 in the workflows. The package smoke test builds its environments in the disk cache instead of
/tmp, and every test subprocess has a timeout.
v18.1.3 - 2026-10-04¶
A documentation release. The package behavior, the brain format (version: 7), bf.yaml, the reply schemas and the search cache are unchanged; no upgrade step is needed.
Documentation¶
- The loop diagram names its five steps (gather, normalize, connect, act and learn), labels the agents' search and read and starts the act arrow from the agents rather than from
bf. - The brain session diagram shows the agent noting its conclusion in the project note, as its "writes the outcome back" claim says, and the review diagram shows the full
bf read project:new-websitecommand. - The watch screenshot shows the log path the dashboard prints,
logs/unavailable.log, instead of an outdated state-directory path, and the README shows it at the same width as the other diagrams. - The logo's title and description describe the picture instead of design notes.
v18.1.2 - 2026-10-04¶
A documentation release. The brain format (version: 7), bf.yaml, the reply schemas and the search cache are unchanged. The packaged bf-setup skill only changes its Claude Code guidance: run bf skills DIR to refresh installed copies.
Documentation¶
- The README presents BF as a second brain on your own computer: agents opened in a brain start from your projects and evidence instead of a blank session. Four diagrams show the gather-to-learn loop, a blank session beside a brain session, how field mappings turn four tools' names into one knowledge graph and how a project is flagged for review when its linked evidence changes. New sections cover the questions a brain answers and the tools behind them, the sources one brain can gather,
bf.yamlas the coordination hub, personal and team brains shared through Git and the trade-offs: local execution, provider setup and the agent harness's data terms. It also points agents tollms.txt. - Claude Code 2.1.277+ loads a brain's
AGENTS.mdon its own, so the guides no longer ask for aCLAUDE.mdholding@AGENTS.md; the agent guide keeps that import as the fallback for older versions, and an existing brain may keep itsCLAUDE.md.
Changed¶
- The release scripts carry a
.shextension:scripts/push-and-tag.sh,scripts/release-notes.shandscripts/verify-release-tag.sh.
v18.1.1 - 2026-10-03¶
A documentation release. The package, the brain format (version: 7), bf.yaml, the reply schemas and the search cache are unchanged; no upgrade step is needed.
Documentation¶
- The documentation site gains offline search (Ctrl+K or
/), header tabs for Start here, Guides, Reference and Privacy and legal, page icons, a light, dark and system color toggle, GitHub repository and edit links, and a footer with privacy, notices and license links. The changelog and license are site pages, so every navigation entry stays on the site. Search keeps the site free of accessibility violations in an axe-core audit: the closed dialog leaves the tab order, its controls are named and its result paths meet contrast. - Agents can read the guides as Markdown through
llms.txt, which summarizes each guide,llms-full.txtorindex.mdbeside each page, which each guide's HTML advertises as its Markdown alternate. The overview now links every guide.
v18.1.0 - 2026-10-03¶
A review release of fixes. The brain format (version: 7), bf.yaml and the reply schemas are unchanged; listed fields are bounded, and the search cache rebuilds once. Upgrade with uv tool upgrade brain-framework (or update a brain's pin), then run bf skills DIR.
Fixed¶
bf skills --forcekeeps a file you edited that the new version no longer ships, as it keeps every other file BF does not ship, instead of deleting it.- A record commit whose completion marker landed before a final directory sync failed reports success instead of "nothing was written".
- A registered brain whose folder exists but cannot be reached fails with
cannot reach the brain registered as NAMEinstead of advice to register it again, whichbf registerthen refused. bf run --hook "", as an unset variable gives it, is invalid input instead of running the first argument as a routine;bf status --check --watchnames--watchin its invalid-input line.bf eval --baseline=~/eval.jsonexpands~, like every other path option. Without a home directory, commands fail with onebf:line namingHOMEinstead of a traceback.bf scheduleinstalls systemd units belowXDG_CONFIG_HOMEwhen it is set, where the user manager reads them.bf watchruns updates for apip install --userinstallation, andbf watch --jsonreports unavailable desktop alerts with abf:line on stderr instead of a JSON object.- A claim footnote's label can no longer change a note's structure:
[^```]or[^<pre>]used to open a block that hid the sections and links after it. Links in a footnote's continuation paragraph, indented by four spaces or a tab, now support the section that cites it, and labels match regardless of case, as on GitHub. - A copied document whose headings repeat an explicit anchor, or whose title's slug another heading anchors, stays searchable: the later heading takes a generated slug. OKF notes still fail
bf validate. - An OKF
sourcesentry whose?rel=names an undeclared relation still cites its target in reads;bf validatestill reports the relation. - Validation messages count only the distinct problems they do not name.
- The example sensor, routine and hook guides make a downloaded script executable with
chmod +xbefore configuring it as a command, since a download drops the executable bit andbf validatethen rejects the program;github-history.mdcopies from the release tag matchingbf --versionand says when to raisetimeoutfor a large backfill. - Programs no longer inherit
ZDOTDIR,PHPRCorPHP_INI_SCAN_DIR, which make zsh or PHP run code before the program starts. - The guarded-write helper follows a linked brain folder and links above it, such as
/homeon Fedora Atomic or/tmpon macOS, as bf does, instead of refusing every absolute path through them; links inside the brain are still refused. bf-useasks before updating the skills for a newerbf, and names the folder to pass tobf skills.- Quitting
bf watchwhile an update is still stopping printsbf: stopping the active update; this can take up to 60 secondsinstead of leaving a silent terminal. - An exact read across several brains returns the brain that holds the ref with a
problemsentry for another brain that fails, such as on a malformed record of a shared source or a busy writer, instead of failing; when no brain holds it, the failure stands. - A page's address as
--scope, such asbf://brain/projects,bf://brain/7dorbf://brain/memories/gmail, is invalid input instead of silently matching nothing; use its brain-relative form. - Listed
fieldsstop at 2 KiB of JSON per item, in field-name order, so a shared brain declaring hundreds of fields cannot push home, a listing or a note's backlinks past the reply limit; exact reads keep every field. - The retrieval reference states that a relation page's
totalincludes the claims of its narrower relations.
v18.0.0 - 2026-10-03¶
A review release. Review signals now follow upstream changes and the evidence a note cites, the home page and exact reads summarize what needs attention, and every interface reports invalid input the same way. The brain format (version: 7) and bf.yaml are unchanged apart from accepting empty sections; stricter identity rules and bounds are listed below. Reply schemas only gain optional fields, and the search cache rebuilds once.
Breaking changes¶
- Invalid input. A usage error prints one stderr line,
bf: invalid input: ARGUMENT: reason (see bf COMMAND -h), with exit 2, instead of Typer's usage text and boxed panel; help is unchanged. MCP clients receive the same rejections asinvalid input: ARGUMENT: reasonnaming the tool argument (query,scope,reforrel), including malformed refs, periods, addresses, scopes and relations that used to return bare messages. - Exit codes. These are invalid input (exit 2) instead of failures (exit 1):
--relon a page written with a trailing slash (projects/) or on an existing folder page,--relwith a#section, a section of a page (bf read tasks#x,bf read bf://NAME/7d#x), an invalid period belowmemories/SOURCE/, a ref that is not UTF-8 andbf watch --poll-interval nan. - Empty values. An explicit empty
--brainis invalid input instead of falling back toBF_BRAIN, the enclosing brain or every registered brain, and so are an emptyPATHforinitandregister,DIRforskillsandschedule --output. - Scopes and retrieval cases. A note or page section as
--scope, such asprojects/atlas.md#next-actions, is invalid input instead of silently matching nothing.bf evalchecksexpectandforbidrefs asbf readchecks a ref, so a malformed or unnormalized ref fails the suite instead of aforbidthat always passed, and a malformed identity query fails when the suite loads. - Identities. An identity holding a Unicode format character (category Cf, such as U+200B, U+200C, U+200D, U+202E, U+FEFF or a soft hyphen) is rejected: two identities that look alike would silently differ. A BF entity, alias or resource must reach its note or record: another brain's namespace, a
#section, a note file path, a page address or aSOURCE:IDaddress failsbf validate, and the note or record leaves the search cache like one with a foreign alias. A malformed BFresourcemakes its note invalid, like a malformed alias. - Bounds. Note frontmatter
aliasesandlinkshold at most 1,000 items, like tags and records, and a record'sfieldsat most 1,000 names. - Routine replies.
bf runrejects a disabled routine before running anything, with a stderr diagnostic and no JSON reply, as it rejects an unknown one. A--dry-runreply no longer names anactionpath, which the real run picks anew, and reportsskippedwhen the real run would skip. - Skills.
bf skillsreportsnewer, exits 1 and leaves the folder when a newerbfinstalled a different copy of a skill, such as a brain's pinned runtime sharing the skills directory;--forceinstalls this version's copy. The packaged skills search, read and check every brain with the installedbf, never through a brain's pinned runtime, which installs and runs code the brain supplies. - Heading slugs. A heading whose title spans several lines, or whose
{#id}sits inside emphasis, a code span, link text or an escape, gets a new slug, such as#title-line-one-line-two;bf validatereports links to the old one.
Upgrade: run uv tool upgrade brain-framework (or update a brain's pin), then bf skills DIR; the skills now require Brain Framework 18. Drop empty --brain "" arguments from scripts and host configurations, and match the new bf: invalid input: line where a script parsed usage errors. Run bf validate: retype the identities it names for invisible characters or unreachable declarations, point links at renamed heading slugs, and fix a sensor whose records it reports, then collect again, since collection replaces its own records. Re-copy the example git-history.py, github-history.py, local-documents.py, prompt-context.py, session-context.py or weekly-review.py if your brain uses one; remove timeout: 3600 from a github-history.py sensor, and note that git-history.py --skip with any worktree's path now skips its whole repository.
Added¶
- Review signals follow evidence that changed: a project linked from a record whose upstream
updatedis after the note's last edit, such as an issue closed or a pull request merged, needs review, and so does a note citing a record that happened or changed since. The optionalnewerfield names up to five of those items, newest first. A future event counts once it happens, and an edit always clears the flag. - Exact reads summarize their note: a section read states the note's
title,type,statusanddate, and a whole read of a project, or of a note withstale_after, carriestasks,nextand its review signals. - The home page reviews every current project, lists those needing review first, ends near the 32 KiB page budget and reports
projects_total. Its actions, changed and upcoming items carry the same review signals, so an action or concept paststale_aftershows there, and deprecated notes leave every home section. bf validatewarns, without failing, about recordlinksthat are neither identities nor URLs and about a temporary file an interrupted write left behind, and checks programs launched through a command, such as[uv, run, ..., sensors/brief.py].bf schedulewarns when its interval is at or above the shortest selectedrefresh;bf statususage windows gainsincewhen heavy use cut them.bf registerat a moved brain's new place replaces the entry whose folder no longer exists, or which reaches the same brain through another path, and reportsreplaced.- A Python whose SQLite is older than 3.35 or lacks FTS5 or JSON functions fails with a message naming the requirement and the fix, instead of a misleading cache error.
Fixed¶
- Search keeps the English word
comment, and a quoted word is always a search term.one,ones,doing,having,ours,yours,theirsandhersdrop like other function words: stemming made them match nearly every passage. - Note leads and task text keep identifiers such as
MAX_FILE_SIZE,deploy_all.sh,2*3and link refs such as_drafts/. - Reading a record, and its relation page, lists links to its
SOURCE:IDfrom other selected brains, as search did; review signals skip names that several items claim, as backlinks do. - A large read's
outlinelists only the headings inside it, so an H1-only note or a section without subsections fills its first page instead of pointing back to itself. With several brains, pages fit their items within the 32 KiB budget once refs are named by address. - A refresh loads
bf.yamlonce: abf.yamlbriefly invalid during an editor save no longer leaves the files indexed meanwhile skipped untilbf build. A killed build's.bf/index.sqlite.newis removed, and each skipped file's error is cut to 1 KiB so a few hostile files cannot push replies past their limit. - Parsing a note with many repeated headings, or a long run of
[^, takes linear time instead of stalling search, validation and section reads. - A heading anchor is read from the heading's source, and generated
-Nslugs skip explicit anchors. An indented OKF footnote definition keeps its link, which supports the section that first cites it. - A link Python cannot parse, such as
http://[your-host]/, or a relative link holding a backslash no longer makes a copied document unsearchable; link errors name the line or frontmatter key. bf validatereports each problem of a note once, names where a link problem first occurs, no longer turns links to a note's entity into false "unresolved BF target" problems, and reports a record link whose scheme case differs from its source, such asMail:m1.- A huge hex or octal YAML integer is invalid YAML instead of a crash of every search over the brain and its references. Validation messages name at most five problems, then how many more, and sensor output is checked record by record, so malformed output or frontmatter cannot build megabytes of error text.
- An unreadable top-level folder is skipped and reported while the rest of the brain answers, Unix sockets are reported as special files, and empty
brains:,fields:,sensors:,routines:orwatch:sections read as empty. - A
--brainpath withoutbf.yamlfails naming the selection before anything runs, a registered brain whose folder is absent fails with the registry's message, andbf registerkeeps a name whose folder exists but cannot be reached. - A window collection that ends before it runs, such as a backfill chunk, extends coverage without counting as a fresh collection. A
logroutine is no longer killed pastmax_bytes; its log keeps the last 256 KiB. - A program ended by a signal fails with
program was killed by SIGKILLinstead ofexited with status -9. An action folder left with only a killed write's temporary file no longer makes the routine skip for the day. - Collection checks projected records against the record bounds and validates each record once.
bf schedulepreviews copy from~/.config/bf-schedules, where its warning suggests writing, and--output DIRno longer fails when DIR holds the state directory.- A disabled program fails with
sensor NAME is disabled in bf.yaml; set enabled: true to run itinstead of suggesting its own name.bf run --hook EVENTreads standard input only when a routine lists the hook, so an unlisted hook succeeds at once in agent shells. - Diagnostics and MCP error text escape control and format characters from file names and keys, and replies escape every Unicode format character, so a shared brain can neither send terminal escape sequences nor hide text. MCP error text hides brain roots, the registry and the home directory.
- A closed or full standard output fails with one line and exit 1 instead of a traceback or exit 120; closing the terminal under
bf watchexits 130. bf watchshows bf's own diagnostic whenbf.yamlbecomes invalid or drops a selected program,notifications: successandallalert while another program keeps failing, and the details panel shows local time.bf skillsfinishes an interrupted install or update instead of reporting its own partial copy asunmanagedor as your edits.- MCP integer arguments accept integral floats such as
5.0;tags/LABEL/andbf eval --path evals/accept a trailing slash; default brain names fold accents (Équipe produitbecomesequipe-produit). - The example
git-history.pycollects repositories whose scanned checkouts are only worktrees, once each;github-history.pypages by modification time and reads merge state from the issue listing, one request per 100 items instead of one more per pull request;local-documents.pyskips Office owner files; the example hooks and weekly review name items bybf://address across brains. - The skills run helpers with an installed Python 3.14 when
python3is older (uv python find --system --no-config --no-project 3.14), never throughuv run, which adopts a.venvabove the working directory, and they review a brain's.venv/,uv.tomland.python-versionbefore running its pin. The guarded-write helper names its temporary file like bf's own writes.
Changed¶
bf mcpvalidates its brain selection at startup, then resolves it again for each call, so registry changes need no restart.- Faster: a full build creates its schema in one transaction, a search after an edit scans the brain once, problem checks use an index, record commits count files without a stat each, home computes review signals in one query, and validation parses each note once.
- Identity search no longer repeats an untyped link beside a typed one from the same origin; usage history keeps 30 days; help and errors name arguments
QUERY,REF,SENSOR,PATHandDIR. - The contract gate checks configuration schemas for narrowing and reply schemas from the reader's side;
mise run checkvalidates the changelog, and a hung test ends the run after 300 seconds. - The documentation, skills and examples describe this release: identity rules, review signals, invalid-input lines, the pinned-runtime review and the new limits. Reference pages own each contract and guides link to them.
v17.0.0 - 2026-10-02¶
A review release. The brain format (version: 7), bf.yaml and the search and read reply schemas are unchanged. The command line is stricter, so input that was silently misread now fails, and failures that took down a whole brain are now contained.
Breaking changes¶
- Routine input.
bf run ROUTINEpasses piped input only with--stdin. It used to read any open standard input and failed after 10 seconds in agent shells that hold it open.bf run --hook EVENTstill passes what Git pipes, such as the refs of a push. - Repeated options. An option that takes one value may appear once:
bf search launch --scope projects --scope concepts, a second--brain,--relor--hookexits 2 naming it. The last value used to win, so the answer silently ignored the others.--sensorand--routinestill repeat to select several programs. - Routine arguments.
bf runrejects an unknown option before--, such as--dryrun, with exit 2. It used to pass it to the routine, which then ran for real. - Read relations.
bf read PAGE --rel RELATIONis invalid input (exit 2), as a page is recognizable before any brain is read. - MCP arguments. Tool arguments are validated strictly: a
limitoftrueor"5"is an error instead of a coerced value. - Retrieval cases. A plain
expectorforbidref inbf evalnames a file of the evaluated brain. A related brain's note at the same path used to satisfy it; name that note by itsbf://NAME/...address.
Upgrade: run uv tool upgrade brain-framework (or update a brain's pin), then bf skills DIR; the skills now require Brain Framework 17. Add --stdin where a script pipes input into a direct bf run ROUTINE, and put -- before routine arguments that start with a dash. Re-copy the example git-history.py, prompt-context.py, session-context.py or weekly-review.py if your brain uses one. Then run bf validate and bf eval.
Added¶
bf statuslists each brain'sattention: the scheduled programs that failed or areoverdueorneversucceeded, as the home page does. A brain reported"healthy": falsewith"problems": []and left the reason to a scan of every source and routine.
Fixed¶
- Search keeps a function word written as an acronym.
EU AI Actsearched onlyact, andAI,ITorUSdropped from any query, because they spell French or English function words. Lowercase function words and the habitualANDandORstill drop. The exampleprompt-context.pyhook mirrors the rule. - Searching a note's title finds the note before a section that mentions it: a section's note title and parents rank below a heading.
Atlas next actionsstill finds that section. - One unreadable folder, such as a source restored with another owner, no longer fails every search, status, validation and build of the brain: it is skipped and reported, and
bf validatenames it as an unreadable folder. - Collection stops below the 100,000-entry scan limit of its source and fails like any other collection, so a growing window source can no longer make every search and read of the brain fail. A commit changing exactly as many records as the limit no longer leaves a pending transaction behind.
- An action routine's relative links and headings are checked before writing, like its metadata and relations: an action that
bf validaterejects, such as one linkingprojects/x.mdinstead of../../projects/x.md, is never written. bf validatereports every problem of a note, and links to a note it cannot parse are no longer reported as unresolved: one invalid date or undeclared relation hid the note's other problems and broke the links of other notes.- A far-future
stale_after, such as9999-12-31T23:00:00Z, no longer crashes the home and projects pages in timezones east of UTC. bf mcpstops at once on SIGTERM or Ctrl-C with exit 130, instead of waiting for another input line.- Reading a note alias named like a source, such as
jira:ATLbeside ajirasource, no longer fails on another malformed record of that source or while a writer holds the brain. - Filesystems reporting 64-bit hashed inode numbers, such as mergerfs, no longer fail every cache refresh with a traceback.
- A query starting with
bf:, such asbf: how to configure sensors, searches its words instead of failing as an invalid address. - The example
git-history.pyskips linked worktrees, which collected their repository's whole history again; records already collected stay. The example routine and session hook read a task's Markdown link as its label. - The meeting-notes recipe has the agent draft GitHub issues for review instead of creating them from calendar text that anyone who invites you can write.
Changed¶
- Packaged skills no longer carry
metadata.version, so a release changes a skill's files only when its content changes;.bf-skill.jsonstill records the installing version. - Adding
broaderortargetsto a relation no longer rebuilds the search cache: relation pages readbroaderat query time, and collection and validation checktargets. - The schedule preview suggests
--output ~/.config/bf-schedules, outside the brain, like the documentation: the generated files hold this machine's paths. - The documentation states exact reads across brains as they behave: while a brain is unavailable, a found ref returns with a
problemsentry and a missing one fails as incomplete.
v16.1.1 - 2026-09-29¶
A patch release from a review of 16.1.0: no format or reply change. Upgrade with uv tool upgrade brain-framework, then bf skills DIR to update unedited skills.
Fixed¶
- A declared
numberfield set to.nanor.infin a note's frontmatter passedbf validateand then failed every search or read reply listing the note with a traceback.bf validatenow reports the frontmatter as invalid, and retrieval skips the note with a problem like any other invalid note. - A path starting with an unknown
~user, such asbf search --brain ~typo/brain,bf init,bf register,bf skillsorbf schedule --output, fails withbf: a path's ~ or ~user home directory cannot be resolvedinstead of a traceback. - An exact read of two records that name each other as aliases no longer recurses when both files disappear between the cache check and the read.
bf skillstreats a file you added at a path a newer version starts shipping asmodifiedand keeps it, instead of overwriting it.- A routine whose action was written but whose run history could not be saved reports
wrote PATH but local run history could not be savedinstead of claiming no action was written.
v16.1.0 - 2026-09-29¶
A review release: no format or reply change is required. It fixes the published reply schemas, which rejected some valid replies, and several failure paths; the skills, examples and documentation are clearer and match the code.
Upgrade: uv tool upgrade brain-framework, then bf skills DIR to update unedited skills. Re-copy the example weekly-review.py, github-history.py, git-history.py or local-documents.py if your brain uses one, and merge the new AGENTS.md guidance as Refresh brain instructions shows. From 15.x, apply the 16.0.1 steps first: bf skills reports skill copies made before 16.0 as unmanaged and leaves them; back up any edits and rerun it with --force.
Fixed¶
- The published reply schemas (
bf schema --kind read-reply, MCPoutputSchema) accept every valid reply: an empty period page, such asbf read 7din a new brain, matched two page shapes, so MCP clients that validate structured output failed the read. Reply shapes are now alternatives (anyOf), and tests validate every reply against the published schemas too. - A record's
attributesandfieldsare returned exactly as stored: replies no longer convert instants inside them to local time or drop an attribute namedtimebesidedate. - A collection that would change more than 100,000 records fails like any other collection error, recorded in history with its backoff, instead of exiting as invalid input and stopping
bf update. - An unrecoverable cache error prints
the search cache is unavailable; run bf buildin the CLI and MCP instead of a traceback. - A read waiting for another writer to build a missing cache fails after one wait, naming the writer, instead of retrying for up to six minutes.
- A program that cannot start is reported as such even when its log cannot be written.
- YAML files other than UTF-8, such as UTF-16 with a byte-order mark, are rejected naming the file.
bf skills --checkreported a skill with a deleted file ascurrent: it is nowmodifiedand lists the file underedited;--forcerestores it.- A reply names an unavailable brain once, worded as its pages report it.
bf searchandbf readreject--offsetabove 2^53−1 as invalid input (exit 2), like the MCP tools.
Changed¶
bf update --sensorand--routinesuggest close names for an unknown program.bf initwrites the sameAGENTS.mdfor every brain (bf://NAME/...), so comparing it with a scratch brain shows only template changes. It asks agents to update notes when the user asks or the task authorizes it, and never to editmemories/.- Help text states that
watchoptions overridebf.yaml, thatstatus --checkalso fails on programs that never succeeded and which itemsexport --kind identitieslists. - Skills: helpers run from any directory as
python3 "$SKILL_DIR/scripts/NAME.py", and throughuv run --project PATH --lockedin a brain that pins its runtime. Version checks follow each skill'scompatibilityinstead of a written version.guarded-write.pyrefuses a symbolic link anywhere in the note's path; run it from inside the brain with a relative path.new-action.pyremoves what it created when its write fails.bf-maintainexplains eachbf statusfield, and duplicated rules now live in one guide each. - Examples:
weekly-review.pyshows times with their offset instead of labelling local times as UTC.github-history.pyskips a pull request updated during its run, which the next window collects.git-history.pyrequires Git 2.37 and says so.local-documents.pykeeps the text read before an Office part's element or nesting limit and marks the recordpartialinstead of failing the snapshot. The sensors README adds a Calendar agenda configuration, and example brains ignorelogs/. - Documentation: Install and update and the four-tool walkthrough move to Start here, Troubleshooting to Reference. The upgrade steps separate the version upgrade from the manual steps of a major release and explain
modifiedandunmanagedskills. The docs now say thatoverduemeans no success within twice the refresh, that a statuscacheofstaleormissingawaits recovery, and that an exact read across brains fails while one of them is unavailable. They also document the state-directory symlink error and the corrected page sizes, log limits and missed-schedule behavior.
Development¶
scripts/push-and-tag X.Y.Zpushesmain, waits for CI on that commit and tags it only after success, whatever shell runs it;tests/test_release.pycovers the release scripts, and CI validates the release notes on every push.- The weekly security workflow also installs the package on the next Python release, and scans through the gate's tasks without caches.
- Dependency updates: uv 0.12.20, zensical 0.0.66, sse-starlette 3.5.0, pyjwt 2.15.1.
v16.0.1 - 2026-09-29¶
First published 16.0 release. The v16.0.0 tag stopped at verification before publication and remains unchanged: two cache-recovery tests expected a rebuilt cache to get a new inode number, which Linux CI filesystems reuse; they now check the rebuilt cache's integrity instead.
Brain Framework 16 settles the contract so that later releases only add to it. One brain format number covers bf.yaml and evaluation suites, one word names each concept, dates and datetimes are separate, routines become general brain programs with hooks and logs, the agent skills ship with the package, and published reply schemas accept added fields while a release gate rejects anything else. Search, the graph, validation and interrupted writes are also more robust.
Breaking changes¶
- Brain format 7.
bf.yamland everyevals/*.yamldeclareversion: 7. Theschema:key ofbf.yamlis nowfields::fields:declares shared fields and relations, a sensor'sfields:maps them, a record stores them and a note sets them. - Dates and datetimes. A note states its
updatedday asdate(2026-09-29), never as the UTC instant of its local midnight; claims, exports and backlinks asserted by notes carrydatetoo, andreview_dueis a date. - OKF review deadline. Note frontmatter
review_dueandreview_afterare replaced by OKF'sstale_after, an instant with its timezone: a note is due for review once it is stale. Without it, projects fall due 14 days after their last edit, as before; replies name the deadline's origin asreview_source: stale_afterormodified. An OKF note'sresourceURI is one of its identities, like an alias. Every datetime in a reply shows the local offset, to the second (2026-09-29T09:00:00+02:00); files, run history and the cache keep UTC. - Routines. A routine is any deterministic brain program declared under
routines:.output: log(the default) keeps its stdout in its log;output: actionturns its Markdown into a dated action as before.hooks: [pre-push]letsbf run --hook pre-pushrun it, andbf run ROUTINE [ARGS]...runs one now; both pass arguments and piped input through. Action folders written by routines end in an 8-character suffix. - Logs. Sensors and routines log each run to
logs/NAME.login the brain, newest last and bounded to 1 MiB;bf initignores/logs/in Git and retrieval never reads it. Status and errors name these brain-relative logs. - Freshness. A scheduled program late by more than twice its refresh is
overdue(wasstale); status no longer repeats it as astaleboolean.stalenow only marks results served from a cache a writer is updating. Status reports that cache asbusy, and an interrupted transaction aspending_transactionwith its recovery command, instead of failing. - Search. Quoted phrases and
word*prefixes are honored; results matching more of the query rank higher; tags rank like headings; a nested section's title readsNote — Parent — Child; equal scores list the newest first. Replies addunmatched(words found nowhere) andsections(other matching sections of a note). Periods accept2026-09-21..2026-09-25as a scope and a page. The search cache rebuilds itself once. - Reads. A note above 32 KiB opens with its outline, graph context and first 4 KiB; read its sections by ref or follow
next_offset. Task text keeps its links as[label](ref)with brain-relative refs. Listed items and backlink previews show declared single-valuefields, such as a status, and backlink previews add anexcerptof at most 160 characters. Outgoing claims keep up to 20 per relation and 50 in all, so a crowded relation never hides another. - Export.
bf exportprints edges;bf export --kind identitieslists each note or record that declares names beyond its own address, with every name it answers to. Theedgespositional argument is gone. - Skills. Seven skills become three and ship inside the package:
bf-use(find, write and track work),bf-setup(onboarding, discovery and imports) andbf-maintain(integrations and operations).bf skills DIRinstalls or updates them without overwriting edited copies;--checkreports drift. Helper scripts use paths relative to their skill. - Initialization.
bf initno longer createstests/,--fullno longer createssettings/, and the generatedAGENTS.mdteaches the new search syntax,date/timeandbf run. - Limits. Continuation offsets stop at 2^53−1, the largest integer every JSON client represents exactly.
Upgrade: stop the watcher, rename schema: to fields: and set version: 7 in bf.yaml and each evals/*.yaml, replace note review_due/review_after with stale_after, add output: action to routines that write actions, add /logs/ to .gitignore, replace bf export edges with bf export, read freshness: overdue and a note's date in scripts, reinstall skills with bf skills DIR after removing bf-learn, bf-action, bf-scan and bf-import, regenerate native schedules with bf schedule, then run bf validate and bf eval.
Added¶
bf runand routinehooksfor Git and other event hooks;bf updatenames the manual programs it skipped.- Typed note claims: an OKF note's
fields:sets declared fields, such asowner: [person:email/bob@example.test], validated like a record's. bf skills DIR [--check] [--force].bf export --kind identities.- Published reply schemas accept added fields, and
tests/contract/keeps each schema of the major release: any other change fails the gate. - MCP tools publish their reply schemas as
outputSchema; errors name thesearchandreadtools. bf validatechecks that each enabled program insensors/orroutines/is an executable file, that declared relations are not written at the top level of frontmatter, and that?rel=appears only onbf://links.- Lookup errors name what exists: a missing section lists the note's sections, and a mistyped page, note, sensor or routine suggests close names.
- Status reports each source's
bytes.
Changed¶
- A link naming an undeclared relation keeps its note or record searchable as an untyped link;
bf validatenames the relation. bf validateaccepts a record's provider alias as a link target, checks a relation'stargetsagainst every identity the target's owner declares, and accepts OKFsourceswhoseresourcedescribes a population.- Record commits back up replaced files with hard links and roll back only the files they changed, so an interrupted commit recovers in about a second; commits need about half the fsyncs.
- Exact reads during a commit return within about 3 seconds, marked
stale, instead of waiting up to 2 minutes; a waiting cache rebuild is no longer starved by readers; a damaged cache is discarded and rebuilt; watch and generated schedules allow 60 seconds to stop. bf evalranks each case among the first 50 results, even below its limit.bf --helplists commands from setup to repair.
Fixed¶
- A note dated in a timezone east of UTC no longer shows the previous day.
- An unwritable state directory is named, with
XDG_STATE_HOME, instead of blaming the brain. - A completed commit whose cleanup was interrupted no longer blocks reads.
v15.0.0 - 2026-09-29¶
Brain Framework 15 reshapes replies for agents: smaller, bounded, described by published JSON Schemas and easier to continue. It ranks sections by their note, collapses duplicate records across sources, pages relationships, adds graph settings and exports, and hardens collection and cache rebuilds. The brain storage format remains version: 6; the search cache rebuilds once after the upgrade.
Breaking changes¶
- Watch preferences now live in the optional
watchmapping inbf.yaml.settings/watch.yamlis no longer read, andbf schema --kind watchandwatch.schema.jsonare removed;bf schemaincludes watch preferences. Defaults and CLI precedence are unchanged. All commands loadingbf.yamlvalidate the section, even when CLI options override it. - Exact reads above 32 KiB return their note or record text in pages (
textorrecord.text, withoffset,next_offsetandtotal_characters; the first page adds the sectionoutlineand the graph context) instead of JSONchunkstrings. Every exact read addssha256(of the whole file) andmodified. - Backlink groups always name their
relation(linksfor untyped links) and preview their 5 newest items withref,title,time,kindandsource,statusortypeonly.bf read REF --rel ROLElists a whole group. - OKF
sourcesentries now claim the built-incitesrelationship instead of an untyped link: backlinks list them undercites.linksandcitesjointagged-withas reserved schema names. - With one selected brain, result and listing entries omit
brainanduri; records omittype, whichkindalready states. - Search
sourceslists the sources of returned records and those needing attention (failed,staleornever), withsources_omittedcounting the rest; replies without items andmemoriesscopes keep the full list. - Search shows one result per URL when several sources hold it, such as a Drive file and its catalog entry; the result's
alsolists up to five other refs, asbf://addresses when several brains are selected. One source's records, such as highlights of one document, stay separate. - Pages and searches end early near 32 KiB instead of 2 MiB, counting a page's summaries such as
changed; follownext_offset. Result and listing titles are previews of at most 200 characters ending in…, and homechangedandupcomingpreviews omit excerpts. - Period pages (
today,7d, dates) and homeupcomingomit records ofpriority: lowsources;sourcesandactivitykeep their counts, marked"priority":"low", with the page listing them. - Collection rejects a record whose fields other than
textexceed 2 MiB serialized, andbf validatereports such stored files, so every record reads back; keep bulky content intext. bf initwrites a much shorterAGENTS.md(about 280 words instead of about 960); authoring rules live in thebf-learnskill.- The
bf-actionhandoff check reportscharactersinstead ofreply_characters.
Manual upgrade:
- Stop the watcher, move the keys from
settings/watch.yamlbeneathwatch:in your existingbf.yaml(indent them two spaces), remove the old file, runbf validateand restart the watcher. Remove the emptysettings/directory only if nothing else uses it. Brains without custom watch preferences need no change. - Rename any
schemafield namedlinksorcites, then runbf validate. - Update scripts that parse replies: concatenate exact-read text pages while
next_offsetis present and require an unchangedsha256; list a backlink group withbf read REF --rel ROLEand explain a link withbf search 'IDENTITY'; read OKF sources undercites; buildbf://NAME/REFfrom the reply's brain when you need an address with one brain selected; followalsowhere you expected every copy of a URL; readmemories/SOURCE/PERIODto list a low-priority source's records. Validate parsed replies withbf schema --kind search-replyandbf schema --kind read-reply. - Re-copy the upstream
bf-use,bf-learnandbf-actionskills and any copied hook (examples/hooks/session-context.py), which read the new replies. - Optionally compare your brain's
AGENTS.mdwith a scratchbf initand keep what your brain still needs.
# https://fmind.github.io/brain-framework/docs/schedule/#watch-preferences
watch:
interval: 300
notifications: off
Added¶
- Role pages:
bf read REF --rel ROLE [--offset N]and MCPread(ref, rel, offset)list every item linking to a note, record or identity through one relationship, 50 per page; an undeclared role exits 2 naming the declared ones, and abf://address with an undeclared?rel=reports a problem. broader: ROLEon a relation field: the parent's role page also lists its narrower roles' items, each keeping its ownrelation.targets: [PREFIX, …]on a relation field: collection rejects mapped values and typed record links outside them without changing evidence, andbf validatereports stored records and note links outside them.bf validatelists non-failingwarningsfor identities that differ only by letter case;bf statuslistswarningsfor a record source or authored folder above 80% of the scan limit. Neither changes the exit code.bf build --reproject SENSOR [--dry-run]re-applies a sensor's current mappings to its stored records without running it or removing records.bf export edgesprints every claim of the selected brains as JSON Lines, offline, for DuckDB or networkx.sensors.NAME.priority: normal|lowinbf.yaml: low ranks a source at half weight in search and keeps its records out of period and home lists; applied at query time withoutbf build.bf evalreports each search case'srankand the run'smrr;bf eval --baseline FILElistsregressionsandimprovementsagainst a saved reply.- Published JSON Schemas for
bf searchandbf readreplies:bf schema --kind search-reply|read-reply,docs/search-reply.schema.jsonanddocs/read-reply.schema.json. The test suite validates every reply against them. - Typed claims carry the asserting item's
time. - MCP tools gain titles, and the server sends a title and instructions with the orient, find, verify and answer loop, role pages and completeness checks.
- Opt-in
examples/hooks/prompt-context.pyfor Claude Code and Codex lists up to three matching note refs per prompt, counts records without quoting them, and stays silent after 2 seconds or on incomplete retrieval. - The
bf-learnscripts/guarded-write.pyhelper replaces a note from stdin only while it still has thesha256of the agent's read. - Add an explicit
frefresh shortcut tobf watch(uremains an alias): reload configured sources and check due work now, retaining one follow-up request during an active update while respecting pause, selectors and retry timing. - Add a reviewed GitHub history sensor and backfill walkthrough: selected-branch commits (one year of
mainby example), all-age issues and pull requests, incremental refresh and bounded pagination that preserves evidence on failure.
Changed¶
- The 100,000-entry scan limit applies per source directory under
memories/and per authored folder, and its error names the crowded directory with a remedy. bf buildand automatic rebuilds fill.bf/index.sqlite.newbeside the live cache and replace it atomically: searches and collections continue meanwhile, and an interrupted build leaves the live cache intact. Readers hold a brief cache lock while connected, so a replaced cache never attaches the new one's write-ahead log.bf updateandbf watchrecover an interrupted record transaction before refreshing the cache; reads still refuse and namebf buildorbf update.- Rewording a schema field's
descriptionorexamplesno longer rebuilds the cache; addingbroaderortargetsdoes. - Rolling back an interrupted transaction syncs the source directory once instead of once per record.
- Mapping errors at collection name the record's zero-based position.
- The skills describe the new replies, role pages, low-priority sources, rank-aware evaluations, scan warnings and graph settings.
- Synchronize the project description across the README, documentation, package metadata, CLI help and GitHub About to “🧠 Brain Framework: from information to informed actions.”
Fixed¶
- A section now ranks under its note's title as well as its heading, so "Atlas next actions" finds Atlas's own Next actions before other notes that mention Atlas; a query matching only a note's title still returns the whole note.
- The snapshot shrink guard counted the catalog left by an interrupted commit, letting a truncated listing remove most records; recovery now runs first.
- A routine retried after its run history failed to save no longer writes a second action for the same day.
- Temporary
.write-*files left by killed writes are removed by the next transaction or recovery of their source. - Reject ambiguous GitHub pagination and PR details that move outside the requested window, preserving saved evidence instead of accepting an incomplete or out-of-scope collection.
v14.0.0 - 2026-09-28¶
Brain Framework 14 is the first stable release. It settles the brain format, the CLI and MCP reply contracts and the execution boundaries so that later releases can extend them without breaking them. Collection only runs in one explicitly selected brain, stored evidence resists partial provider failures, retrieval replies share one shape, and the guides, skills and examples are tested against the release they document.
Breaking changes¶
- Formats:
bf.yaml(format 6) and evaluation suites (format 5) requireversion. YAML follows the 1.2 core schema:yes,no,onandoffare strings,017is decimal and1:30is text. - Notes: in projects, concepts and
ACTION.mdnotes, onlydeprecatedcloses a note: it ranks last and leaves home, tasks and review reminders. Aliases must be namespaced identities such asrepo:github.com/owner/name, titles are limited to 4,096 characters, and page paths (home, folder roots,tasks, periods,tags/*,memories/*) cannot be entities or aliases. Other Markdown, such as action inputs and outputs, is ordinary: only validtitle,type,status,updated,summaryanddescriptionapply, and it declares no entity, alias, tag, frontmatter link or review date. - Links and identities: body links keep their written form, so BF links must percent-encode spaces and
%. A note alias equal to a record ref is an ambiguous identity, an entity or alias whose first path segment contains:is invalid,tagged-withis reserved for tag membership, and periods accept ASCII digits only.bf://NAME/source:idalways names a record. - Records: aliases must be namespaced identities, ids must fit a BF address (7,988 characters once percent-encoded), URLs are limited to 8,192 characters without control characters, and lone surrogates are rejected.
bf validatereports stray files and hidden.jsonfiles undermemories/. - Selection and execution: a bare
--brain NAMEorBF_BRAIN=NAMEresolves through your registry first and fails when the enclosing brain or its references claim that name for another directory.update,collect,watchandscheduleact on exactly one brain (--brain,BF_BRAINor the enclosing brain) and never fall back to all registered brains; outside a brain they fail. For them, a name must be registered or be the enclosing brain's own: a referenced brain or a directory below the working directory fails withneither registered nor the enclosing brain. An enclosingbf.yamlmust be a regular file owned by you, and the user registry~/.config/bf/config.yamlmust be a regular file. Program executables must be bare command names or normalizedsensors/orroutines/paths. - Collection: a snapshot that would remove more than half of an existing catalog and more than 10 records fails without changing evidence, like an empty snapshot;
bf collect SENSOR --allow-removalaccepts one such run. Failed sensors and routines retry after 1, 2, 4… minutes, capped at theirrefresh, instead of every cycle;bf collectretries a sensor at once. A concurrentbf updateof the same brain waits up to 10 minutes before failing, and a program whose background process keeps its stdout open fails one second after it exits. - Replies:
problemsis always a list of objects witherrorand optionalbrainandfile.bf buildandbf updatereport skipped files asskippedand exit 1 when files were skipped;bf statusreports its cache ascache, and its source and routine entries usestate,last_collected,window,last_run,last_success,failed,failuresandloginstead of the removedenabled,configured,run,success,startandendkeys.bf updatereplies with one brain object whosesensorsandroutineslists are always present. Search no longer returnsmore;next_offsetalone signals continuation. All instants are canonical UTC ending inZ; absent ones are omitted, except inbf watch --jsonrows, wheresuccessandnext_dueare then empty strings. A source without dated records has nolatest.bf watch --jsonno longer emitsobserving. - Reads and searches: exact replies longer than 65,536 characters are JSON chunks from offset 0, and a non-zero offset on a smaller reply fails. The MCP
readtool has nobrainargument; use abf://NAME/...address. Both MCP tools reject unknown arguments, such as thatbrainor a misspelledscope, instead of ignoring them. Identity scopes include the identity's owning note. An unknownmemories/SOURCEscope is not found, and a segment below it other than a period,undatedor a record file is invalid. Malformed refs,bf://NAMEwithout its trailing slash and queries without any word exit 2, including a search query shaped like a malformed BF address. Retrieval needs write access to.bfand rejects a.bfthat is a symlink, not a directory or owned by someone else. - Evaluation:
bf evalvalidates every case while loading, including scopes (a0dwindow is invalid), read refs,bf://addresses and query words, and fails the whole run on an invalid suite. - Scheduling: a relative
bf schedule --outputresolves against the brain, and generated systemd units no longer cap the whole update at 45 minutes. - Removed legacy: JSON Lines record storage handling, the
active,paused,blocked,doneandarchivedstatuses, the/logs/entry in new brains'.gitignoreand the hand-written systemd example.
Added¶
- Sort
bf watchandbf status --watchby name, last success, returned items, state, next due time, changes, duration, output bytes, refresh interval or kind, with reverse order, first/last navigation, an item-count column and a keyboard guide. JSON watch rows exposerecords, the last successful sensor run's returned count. bf schema --kindexports offline editor schemas for brain, watch, registry and evaluation files, generated and checked from the runtime models.bf evalassembles chunked exact reads and verifies their digest before checking read cases.bf validatenames the file of every problem, flags capped lists withproblems_truncatedandunresolved_truncated, checks embedded images and accepts page addresses (home, folders, periods, tags, sources and record files) as link targets. Project notes resolve a leading/fromprojects/, as concepts already did.- Registered brains that are absent on this machine appear in search and read
problems, andbf status --checkfails on them and onbrains:references that retrieval cannot include. memories/SOURCE/undatedis a search scope, like the page of that source's undated records.- The bf-learn evidence helper reads and assembles chunked exact replies with
read REF --brain BRAIN. - Documentation for shell completion, refreshing a brain's
AGENTS.mdfrom the installed template, and every enforced limit. - The package declares
Development Status :: 5 - Production/Stable.
Changed¶
- Search matches words in one Unicode compatibility form, so
ß, ligatures, full-width letters and decomposed accents are found, while excerpts keep the source's characters. The search cache rebuilds itself. - Collection parses only the record files it replaces or removes and syncs each directory once per transaction, and exact reads of absent records reuse a ready cache.
- Every lock follows the physical brain directory, so different paths to one brain share update, watch and program locks, and a busy program names itself.
- Sensors and routines receive
BF_BRAINset to the executing brain, so nestedbfcalls read that brain. - For scheduled window sensors, a manual
bf collectafter a pause no longer moves the resume point past the uncollected gap. - The
AGENTS.mdwritten bybf initstates execution authority, one-brain selection, incomplete-result boundaries,deprecated-only closing, chunked reads and multi-brainurireads. New brains' starter evaluation readsbf://NAME/concepts/welcome.md, and newbf.yamlfiles omit redundant defaults. - The watch dashboard keeps the selected row, program states and failure details visible from 80 columns, shows the sort field and direction in the panel title, applies batched keys in order and redraws only on change or once a second.
- Documentation is organized around first use, everyday tasks, collection and reference. Guides install with
uv tool install --python 3.14 brain-framework, copy examples from the release tag matchingbf --version, and name action foldersYYYY-MM-DD_topic-SUFFIX;tests/test_guides.pyruns the getting-started guide and checks every reply it shows. - Skills describe the 14 contracts, use
## Decision {#decision}in project and action templates, and are tested for the commands, options, anchors and Python 3.11 standard library they rely on. - Example sensors stay within the record limits, map provider fields explicitly and print content-free reasons for their failures. The Calendar sensor keeps cancelled events as
Cancelled: SUMMARYat their original time, the Git history sensor reads branches, tags, remotes andHEADand skips unreadable folders, and the team example is abfandgitwalkthrough. - Ordinary Markdown whose foreign frontmatter is not valid YAML stays searchable without it, a block that never closes is searched as text, and Emacs
.#NAMElock files beside authored files are ignored, so none of them failsbf build,bf updateorbf validate. A routine that already wrote today's action skips its rerun while that folder holds any file, even an editor lock. - Collection replaces, or a snapshot removes, a stored record file that holds its own id but breaks the current record rules, such as a display-name alias or an over-long title; misnamed files still fail it.
- Diagnostics name what to fix: duplicate YAML keys give their position, unknown watch settings and undeclared field mappings name their key, search errors name
QUERYor--scope,bf registernames a missing directory orbf.yaml, unavailable or unloadable brains are named once by their registered orbrains:name, andbf initasks for--namewhen the directory name cannot form one. bf schedulewithout--outputwarns that its install commands name files it did not write. When an update fails only because the search cache skipped files,bf watchsays so and sends no collection-failure alert. JSON watch rows are documented key by key.- The bf-action helper accepts a symlinked brain root, the bookmark inventory helper distinguishes a reached limit from an unsupported export, and example sensors name the repository, folder or limit behind a failure; the Calendar sensor keeps very large events within the 1,000-link record bound. Guides write GitHub identities in lowercase and install skills and the watch demo from the release tag.
- Development uses
uv run --locked, hermetic UTC tests under pytest 9 strict mode, a 95% branch-coverage floor, generated third-party notices (mise run generate:notices) and a dashboard screenshot rendered from the fictional demo (mise run generate:screenshot), each checked by the gate. CI runs shared checks once and tests on all four platforms; the weekly security workflow also installs the package with the newest allowed dependencies, and the package check completes an MCP stdio handshake with the installed package.
Fixed¶
- Body links to identities or records with accents, spaces or
%now match their frontmatter form in backlinks, reads, scopes and validation. - Removing or retyping a schema field no longer hides the stored records that carry it.
- A note whose H1 is followed by a
---rule, or that starts with a byte order mark, keeps its frontmatter; link validation compares exact file names on case-insensitive disks; lead and anchor parsing is linear on adversarial notes. - Period and source pages report each problem once; previews order ties like their continuations; deep search offsets no longer compute skipped excerpts; reading a typed link to an unowned identity works.
bf evalnames the suite and case of an invalid case before any retrieval; JSON replies are UTF-8 whatever the locale; a non-UTF-8 note is reported as such.- Collection survives files that vanish during a scan, names linked intermediate folders and the directory that exceeds the depth limit, and ignores empty or relative
XDG_*values. - A successful sensor whose background helper inherits stderr no longer times out; clock corrections no longer delay scheduled programs; malformed usage events no longer interrupt status.
- The watch dashboard no longer hides the selected row when programs outnumber the screen or truncates states and counts on 80–128 column terminals.
- The example hook, routine and sensors run on Python 3.11 again; example Calendar and Drive sensors reject malformed continuation tokens; the local documents sensor names unreadable, damaged or encrypted files.
- A file or folder name that is not valid UTF-8, such as a Latin-1 name from an old archive, or that holds a backslash, is reported as
file name is not valid UTF-8 or contains a backslash; rename itinstead of failing search, read, status, build and validate for the whole brain. - Documentation navigation and wide tables are keyboard accessible, and release notes reject empty or duplicate sections.
- Remove a breaking-change bullet copied by mistake into historical release sections.
Security¶
- Brain names resolve through the owner's registry before the working directory, an enclosing
bf.yamlis trusted only when you own it, and registered brains are selected for retrieval only, so an untrusted checkout cannot run its programs under your name. - Program environments also drop
SHELLOPTS,BASHOPTSandPS4. - The private state root is created with mode 0700; the search cache is opened through one no-follow descriptor, created with mode 0600 and read with SQLite's defensive settings.
- The example session-context hook never prints collected record refs, and a non-interactive
bf status --watchno longer suggests the program-executingbf watch --json. - A search cache that bf did not create in place, such as one copied, cloned or extracted with a brain, or one holding triggers or views, is rebuilt from the brain's files, so rows no file supports never reach retrieval. The cache is bound to its file's inode number, which a remount keeps.
- CLI JSON replies, MCP tool text and
bf watch --jsonrows write DEL and C1 control characters from collected text as JSON escapes, so a terminal cannot act on them; the decoded values are unchanged. - Collection errors, run history and
bf statusno longer quote an undeclared link relation from sensor output.
v13.0.2 - 2026-09-27¶
First published 13.0.x release. The v13.0.0 and v13.0.1 tags stopped at verification before publication and remain unchanged. CI and scheduled security checks now pin mise 2026.9.15. Terminal-restoration checks exercise line input before comparing all settings, accounting for macOS kernel state while retaining cancellation and restoration assertions.
Brain Framework 13 adds continuous collection, independent record files, complete retrieval and practical workflows from evidence to decisions. Before upgrading from 12, follow the manual steps below on a backed-up copy with collection stopped.
Changed¶
-
Use the same product description in package metadata, CLI help, the README and documentation: 🧠 AI Brain Factory: from information to informed action. Not for 🐙 mindflayers or 🧟 zombies.
-
Breaking storage change:
bf.yamluses format 6. Each source record lives atmemories/SOURCE/SHA256_ID.json, replacing monthly JSONL catalogs. Record IDs andsource:idrefs stay stable; source pages replace thepartitionsinventory with paginated records. Retrieval evaluation files remain format 5. - Breaking execution change: remove machine collection permissions and sensor content-trust settings. Registration stores names and paths only; explicit collection/update/watch commands run enabled programs in selected roots, never referenced brains. Remove obsolete registry
collectfields, sensortrustfields and--collectoptions. Retrieved content remains untrusted evidence. - Breaking note contract: projects, concepts and canonical action
ACTION.mdnotes require OKF structure, a nonemptytype, anddraft/stable/deprecatedlifecycle statuses. Work progress belongs in the body and checkboxes; attachments may remain ordinary Markdown. Routine output is validated before an action is created. - Breaking reply contract: remove
collectfrom init, registration and status replies,trustfrom source metadata, andexternalfrom retrieval and evidence-helper replies. Pages include record excerpts consistently; hooks and routines reference collected records without copying their text into authored context. - Review reminders use local file modification time, optional
review_afterdays or areview_duedate. Replies explain deadlines and newer evidence without claiming a review occurred. File copies/checkouts can reset modification times; explicit deadlines remain portable. - Routine actions use unique session suffixes, with daily suppression local to each collecting clone. Shared brains can merge independent records and actions independently; conflicting evidence still requires review.
- Rewrite guides around a runnable decision example, first sensors, schema mappings, team setup and expected results. Keep the README concise and expand advanced reference pages, privacy boundaries and recovery instructions.
- Refresh compatible Python dependencies and keep task output concise while retaining diagnostics, security findings, test counts and coverage totals.
Added¶
bf watchfollows collection in a full-screen terminal dashboard with keyboard navigation, pause/cancellation and last-run changes.bf status --watchobserves without execution;watch --jsonstreams snapshots. A second interactive watcher observes the active collector.- Brain-owned
settings/watch.yamlcontrols check/display periods and generic desktop failure/recovery alerts, with optional success notifications and cooldowns. bf schedulegenerates inspectable systemd, launchd or cron definitions and installation/removal commands without activating them. Repeatable--sensorand--routineoptions select programs for update, watch and schedule while retaining enabled/refresh rules.- Window sensors can use a separate
reconcilecadence to revisit older evidence. Collection/status replies report requested windows, reconciliation, elapsed seconds, output bytes and record change counts. bf read taskslists open checkboxes with source sections, line locations, complete counts and pagination. Weekly reviews summarize tasks without duplicating the original checkboxes.bf://NAME/tasksis reserved for this computed page.- Browse tags, follow brain-qualified tag pages and search explicit tag membership with
--scope bf://NAME/tags/LABEL. Tags retain their originating notes and use bounded, validated labels. bf-setup,bf-scanandbf-importguide onboarding, explicitly scoped discovery and selected imports. New brains include technical-test and retrieval-evaluation folders with immediately runnable starter cases.- Action helpers create independent sessions and check Context/Resume budgets before handoff. Learning guides cover reviews, evidence retention, sharing and conflict resolution.
- Runnable fictional context-hub, watch and two-contributor examples demonstrate integrations and collaboration. A highlights sensor imports selected passages with URLs, locators and annotations kept separate from source text.
- Deterministic retrieval evaluations under
evals/join the full gate without models or providers. Package checks exercise wheel and source archives outside the checkout; the manual benchmark validates every measured result.
Fixed¶
- Search/listing continuations expose remaining results. Oversized exact replies return lossless JSON chunks with SHA-256 verification; outgoing graph previews mark omitted claims. Empty searches retain failed/never-collected source coverage.
- Symlinks and special files are skipped and reported without following their targets or hiding other evidence. Incomplete exact reads fail visibly; pending recovery journals still block retrieval until repaired.
- Invalid YAML identifies the file, line and column without quoting private content. Persisted-record diagnostics redact provider-controlled keys. Status reports a broken brain while retaining reports for other selected roots.
- Reject unresolved Markdown merge markers and foreign-namespace note aliases during validation/indexing. Preserve source links on every canonical note type and resolve typed links to tag pages correctly.
- Preserve existing evidence-capture destinations, including dangling symlinks. Session hooks constrain metadata to its owning brain; weekly reviews follow all project continuations and reject incomplete retrieval.
- Keep Git history collection within selected directories and half-open time windows, including in-window commits with out-of-order dates.
- Keep starter absent-evidence evaluations stable as notes grow. A malformed optional registry no longer prevents operations on an explicitly selected brain path.
- Retry failed scheduled programs on the next cycle even when an earlier success is still within its refresh interval. The watch display shows these retries as immediately due.
- Remove empty code-line links from the documentation's keyboard navigation and accessibility tree.
Manual upgrade from 12¶
- Stop all writers. With version 12, run
bf buildandbf validate, then back up the whole brain, including ignored memories and attachments. Git alone is not a full backup. Work on a separate copy with version 13 installed in a separate environment. - Convert each nonblank line of
memories/SOURCE/*.jsonlintomemories/SOURCE/SHA256_ID.json, using the lowercase SHA-256 of the UTF-8 record ID. Preserve every field and reject duplicate IDs, duplicate JSON keys, symlinks and unexpected files. Write to a fresh directory, verify counts, then replace only the copy'smemories/; never install partial output. Brains without collected records skip this step. - Set
version: 6in the copiedbf.yaml; retrieval suites stay at format 5. Remove sensortrustfields. Explicit collection/update/watch commands now run enabled programs in selected roots; review their configured argv before execution. - Give projects, concepts and canonical action notes a nonempty
typeanddraft,stableordeprecatedstatus. Move work states into the body/task list; preserve OKF sources and verification metadata. Replace aliases claiming another brain's namespace with explicit links. - Back up the user registry, then remove registration
collectfields and obsolete--collecthost flags. Update installed skills and restart hosts. Reply consumers must follownext_offset, verify/reassemble exact-read chunks and stop expecting removedexternal,trust,collector sourcepartitionsfields. Routine action paths now include a UUID suffix. - On the copy, run
bf build,bf validate,bf evaland technical tests. Compare record counts, search a known decision and read its reason and supporting record. Resolveproblems/staleand check source freshness separately before switching collectors/hosts and resuming the authorized schedule. If checks fail, retain the original version-12 runtime and backup together; do not open format-6 data with version 12.
v13.0.1 - 2026-09-27¶
Unpublished tag. The macOS terminal tests compared a transient kernel flag before processing the next input. See v13.0.2 for the full release notes and portable terminal checks.
v13.0.0 - 2026-09-27¶
Unpublished tag. See v13.0.2 for the full release notes and corrected CI toolchain.
v12.0.2 - 2026-09-25¶
First published 12.0.x maintenance release. The v12.0.1 tag stopped at the CI gate before publication and remains unchanged.
A maintenance release for reliable absence checks, documentation and release verification. Brain configuration and retrieval suites remain at version 5; no manual upgrade is needed.
Fixed¶
- Schema checks use their own scratch directory, so a concurrent clean documentation build cannot delete their intermediate files.
- Collection bounds saved coverage by its successful run and the current observation time. A future window left in run history no longer keeps successful scheduled collection permanently stale.
- A missing read no longer proves absence when a directly referenced brain is unavailable or identity lookup skipped invalid evidence. Retrieval evaluations expecting an empty answer fail visibly until the incomplete scope is repaired.
- Future-dated notes appear in the home page's upcoming items without displacing recent changes.
- PDF converter process tests allow interpreter startup on busy machines while still asserting output limits, timeouts and process cleanup.
Changed¶
- CI and release publication share the four-platform verification workflow. PyPI and GitHub receive the exact distributions that passed isolated installation tests, with hash comparisons before and after publication.
- Wheel and source-distribution checks install locked runtime dependencies outside the checkout and exercise initialization, validation, search, exact reads, status and retrieval evaluation.
- Development tasks and hooks use native tools with separate import sorting and formatting, a configured coverage floor, strict rendered documentation links and disposable schema generation.
- Refresh the README, documentation overview and branding; clarify which sensor integrations ship as reviewed examples and how to create others.
v12.0.0 - 2026-09-25¶
Brain Framework 12 ranks notes and records in one search query and answers several times faster; BF links carry only a relationship. On a personal brain of 52,000 records, full cache builds take 13 s instead of 69 s, searches and reads 0.3–0.4 s instead of up to 1.8 s, and the cache shrinks from 357 MB to 239 MB. The bf.yaml and retrieval suite formats stay at version 5, but notes that use removed link attributes or frontmatter fields need the manual upgrade below. The search cache rebuilds automatically.
Changed¶
- Breaking: search ranks every item containing any of the words in one BM25 query. The former all-words pass let long records that happened to contain every word fill the results before a note matching most of them; BM25 already ranks fuller matches higher.
- Only projects, concepts and each action's
ACTION.mdreceive the note ranking boost.concepts/index.md,concepts/log.mdand an action'sinputs/andoutputs/rank like evidence. - A query shaped like an identity (
re:invent,python:3.14) that no item is, names or links to ranks its words instead of returning a silent empty answer; the reply carries"identity": "unknown". - Record field values are searchable words without their JSON keys, so a word such as
authororkindno longer matches every record with that field. - Breaking: a BF link accepts only
?rel=ROLE. Thesubject,evidenceandasserted-byquery keys and typed link attributes are removed; a link's subject is its note'sentity, otherwise its file, or the collected record. Claims inrelationsandclaimsaresubject,relation,targetandorigin: theevidence,asserted_byandattributesmembers are gone. - Breaking: note frontmatter
fieldsno longer declares relationships; it is ordinary frontmatter data.
Fixed¶
- Searches no longer compute an excerpt for every matching passage before ranking: only returned passages get one. A four-word query over 50,000 records took 1.9 s in excerpts alone.
bf.yamlis parsed once per content within a command, with libyaml when available, instead of several times per search and once per indexed file during a rebuild.- The relationship cache no longer copies an eight-column key into each of its indexes.
- Backlinks, identity searches and project review signals look up links and relationships through indexes instead of scanning every link of the brain for each relationship group.
Upgrade¶
- Find removed link attributes:
grep -rnoE 'bf://[^) ]*\?[^) ]*' projects concepts actions | grep -vE '\?rel=[a-z0-9-]+(#[^) ]*)?$'. Keep?rel=ROLE; move a relationship of another entity into that entity's note, and keep supporting references as ordinary links in the same section. - Find frontmatter relationships:
grep -rln '^fields:' projects concepts actions. Replace each identity value with a[label](bf://NAME/path?rel=FIELD)link in the note body. - Consumers of
relations[].evidence,asserted_byorattributesreadrelations[].origininstead. - Run
bf validate: remaining removed attributes are reported as invalid BF links.
v11.1.1 - 2026-09-25¶
First published 11.1 release. The v11.1.0 candidate stopped at the release test gate before publication; its tag remains unchanged.
Brain Framework 11.1 adds optional decision workflows to the agent skills and hardens collection, retrieval and validation after a full review. The brain format is unchanged: bf.yaml and retrieval suites stay at version 5.
Added¶
- Decision workflows in the
bf-actionandbf-learnskills, loaded on demand: a small working context in each action (## Context {#context}of at most 300 words, six refs and 4 KiB, and## Resume {#resume}), decisions with alternatives and expected outcomes, conditional intentions, explicit unknowns, belief revision with a declaredsupersedesrole, dependency review bounded to two hops and ten dependents, procedures learned from outcomes and reviewed transfer to another brain. skills/bf-learn/scripts/evidence.py, a standard-library helper for Python 3.11 or later:captureretains one exactbf readwith its digest and limitations, andcomparereturns a compactchanged,unchangedorunknownverdict for a new read. It reads stdin only and never opens a brain, runs a provider or uses a model.- An agent workflows page covers the skills, the everyday loop, resuming actions, decision workflows and evidence captures.
- The example brain demonstrates a decision review: a fictional policy, a superseded decision, an intention, an unknown, a draft procedure, a prepared transfer and retrieval cases for each.
Changed¶
- Search excerpts are one line and start below a section's heading, which the result title already names. The search cache rebuilds automatically.
- Exact record reads and search coverage report the same freshness as
bf statusand source pages: a trusted scheduled sensor that never succeeded isnever. An unreadable registry grants no trust and leaves freshnessunknown. - An invalid
--scope,--sinceor--untilexits 2 as invalid input, like other command-line errors. A closed terminal (SIGHUP) cancels like SIGTERM and kills running providers;nohupkeeps it ignored. bf status --checkfails only for scheduled sensors this machine runs, as documented; a failed manual collection is still reported with its log.- Registered brains win over a same-named directory below the working directory for
--brain NAME.
Fixed¶
- The brain writer lock follows the brain directory's device and inode, so bind mounts and differently spelled paths of one brain no longer commit concurrently. Writers must share one private state directory.
- A state directory below a linked ancestor, such as
/homelinked to/var/home, no longer breaks every command; the state root itself still may not be a link. - A registry entry with a relative path is rejected instead of granting collection trust to whatever that path means in the working directory.
- Relative
PATHentries no longer let a bare command resolve inside the brain, and everyPYTHON*variable plus Java, Lua andGCONV_PATHstartup variables are removed before a sensor or routine starts. Brain executables may exceed 1 MiB. - Invalid sensor output is reported by record position and field name only: keys the provider printed no longer reach errors, logs or run history.
- An empty snapshot no longer erases a non-empty catalog; the run fails and keeps the records. Delete
memories/SOURCE/to clear a source deliberately. - A backfill whose
--untillies in the future no longer blocks later scheduled successes: coverage never extends past the run. - A routine run skipped because today's action exists no longer loses its window; the next written action covers it.
- A stored revision claiming a modification after it was first observed, such as a file with a future mtime, no longer freezes a record against newer collections.
- A note dated
0001-01-01or9999-12-31is invalid instead of crashing searches and pages; a damaged cache reports "run bf build" instead of a traceback. readkeeps answering from the other brains when one selected brain has an invalidbf.yaml, and reports it underproblems.- An alias claimed by several notes no longer merges their backlinks in scoped searches and identity pages.
- Identity searches include links to a note's sections, like scoped searches and backlinks.
- Period pages order
changeditems by modification time across brains. memories/SOURCE/PERIODfor an unknown source is a missing page instead of an empty answer.- Reading an identity or an absent source no longer waits for a running writer.
- A record id too long for a BF address still reads, with its backlinks reported as unavailable.
- Headings without word characters get an addressable
sectionslug; explicit anchors cannot end in.md; a link to a non-Markdown file whose name contains#validates. - The session hook and the weekly review show local dates, and the weekly review writes one paragraph per line and fences record ids so that none can become a link.
- The exit-code test accepts colored usage errors, as CI terminals print them.
v11.0.0 - 2026-09-25¶
Brain Framework 11 turns listings into pages, gives actions a resumable page and schedules deterministic routines next to sensors. Search takes words and one scope; everything else is a page that read resolves. The brain format changes: bf.yaml and retrieval suites move to version 5.
Changed¶
bf readwithout a ref returns the home page: active and blocked projects, the latest actions, notes changed in 7 days, record activity per source in 24 hours, items in the coming 7 days, and scheduled sensors or routines that needattention. Projects are marked forreviewwhen their note is older than 14 days or items dated after it link to them (new_links), and show opentaskswith thenextone.readresolves pages: folders (projects,concepts,actionsand subfolders), periods (today,yesterday,YYYY-MM-DD,YYYY-MM,12h,7d,2w) with items modified in the period and each source's share,memories,memories/SOURCEwith its partitions, andmemories/SOURCE/PERIOD,snapshotorundated. Pages combine the selected brains, stay bounded (50 period or source items, 200 notes per folder, 20 per section) and report totals;bf://NAME/andbf://NAME/PAGEselect one brain.- Whole note and record reads include
backlinksacross the selected brains, grouped by explicit relationship with claim explanations, andclaimswhose explicit subject is the item. An identity without an owning note reads as a page of what links to it.bf read actions/FOLDERreturns ACTION.md with the action's files and the projects it links to. - Breaking:
bf search QUERY [--scope SCOPE] [--limit N]requires words or an identity. A scope is a folder or file, a period or an identity.--since,--until,--source,--type,--status,--recent,--changed-since,--current,--relation,--targetand--subjectare removed. MCPsearchtakesquery,scopeandlimit; MCPreadaccepts an empty ref for the home page. - Breaking:
bf.yamlversion 5 declaresroutines:, deterministic programs thatbf updateruns after the sensors with the same trust, process boundary, timeout, output bound and private log. A routine's Markdown is validated and written asactions/YYYY-MM-DD_NAME/ACTION.md; an existing action is never replaced, empty output writes nothing, and a failure writes nothing and keeps it due. Routine names are action slugs distinct from sensor names.bf statusreports routines, and--checkfails on stale or failed ones. - Breaking: retrieval suites use version 5. A case is a search (
query, optionalscopeandlimit) or a read (read: a page, note, record or identity), checked withexpect,forbid,textandempty; a read that finds nothing is empty. - Sensors declare
trust:ownerfor text the brain's owner writes,external(the default) for mail, chat, invitations, issues, feeds and other third-party text. Pages show external records by title and ref without excerpts; searches, exact reads and backlinks label themexternal; source coverage reports each source's trust, and undeclared historical sources are external. bf statusno longer listsreview; project review moved to pages. Process errors name the program rather than a collector, since sensors and routines share the runner. The search cache rebuilds automatically.
Added¶
- The
bf-actionskill starts, resumes and closes one action, a single session of work, when the user asks for it; the action template moves there frombf-learn. examples/routines/weekly-review.pyrenders a weekly review action frombf readpages, with a fake-bftest and a README contract. It names external items by ref only.examples/hooks/session-context.pyprints a short context for the current repository at agent session start (project, review signal, next task, linked evidence), and nothing when unavailable.
Fixed¶
- A manual backfill that ends before a sensor's recorded coverage no longer replaces that coverage, moves its resume point or marks the sensor fresh; a contiguous backfill extends coverage backwards without counting as a fresh success.
Manual upgrade from 10¶
- Pause scheduled writers. Install the same Brain Framework 11 build for every CLI, MCP host, project environment and scheduled writer, and restart long-running MCP readers.
- Change
bf.yamltoversion: 5. Every sensor is nowexternalby default: addtrust: ownerto the sensors whose text you write yourself, such as local Git history or your own documents. - Change every suite under
evals/toversion: 5. Rewrite cases that used removed fields: a time window or filter becomes areadof a page (7d,2026-09,projects,memories/SOURCE) or a searchscope; arelation,targetorsubjectcase becomesread: IDENTITYwithexpect, andtextnaming the role when it matters. - Replace scripts, routines, skills and agent instructions that call removed search options: pages for listings and timelines,
bf read IDENTITYfor backlinks and claims,--scopefor bounded searches. Update theAGENTS.mdthat earlierbf initgenerated, and reinstallbf-use,bf-learn,bf-maintainand the newbf-action. - Optionally move scheduled review scripts into
routines/and declare them underroutines:. Review them like sensors before a trusted machine runs them. - Run
bf build,bf validateandbf eval; compare the home,projectsand period pages with your previous listings, then resume the scheduled writer.
No migration tooling or legacy command surface is included. Runtime dependencies are unchanged.
v10.0.0 - 2026-09-25¶
Changed¶
- Declare directly related brains in
bf.yamlwith stable names and relative, absolute or home-relative paths. Search, read, MCP and evaluations include direct references without recursive discovery or required global configuration. Missing references report incomplete scope; conflicting names are excluded. bf initdefaults to no global registration or collection trust; explicit--collectopts in. Maintenance commands do not expand references, and references never authorize sensors. Retrieval suites accept qualified BF addresses to distinguish same-named files across brains.- Add portable
bf://brain/path#sectionaddresses, explicit noteentityidentities and typed notefields. BF link queries encode declared relationships and attributes, with explicit subject/evidence/attribution and an immutable origin in the derived SQLite projection. - Add selected-brain alias federation, incoming
targetand outgoingsubjectfilters, and relationship explanations through CLI, MCP and retrieval suites. Ambiguous aliases do not merge, external URL queries stay opaque, and foreign links never broaden brain selection. -
Headings support stable
{#anchor}identifiers. Validation checks local BF addresses and reports foreign unresolved targets. New brains include a small relationship vocabulary and agent instructions for links. -
Brain format 4 restores explicit
schemafields inbf.yaml: descriptions, strict types, cardinality, validated examples and typed relationships. Sensors map their record output with JSON Pointers or constants; normalized values are stored in recordfieldsand included in offline search. - Typed relationships form a disposable, evidence-backed SQLite graph. CLI, MCP search and retrieval cases accept
relationandtargettogether, with exact identities and explicit owner aliases. Schema changes invalidate the cache; record replacement and snapshot deletion remove obsolete edges. bf evaldiscovers YAML suites recursively underevals/;--pathselects a suite or directory. Technical tests remain intests/.bf init --fullcreates both folders.- Git and Calendar example sensors preserve author/repository and organizer/attendee roles for explicit mapping.
Manual upgrade from 9¶
- Preserve the brain files, configuration, machine state and previous runtime; pause all collection writers and finish or recover pending transactions.
- Install the same Brain Framework 10 build for every CLI, MCP host, project environment and scheduled writer. Restart long-running readers after the switch.
- Change
bf.yamltoversion: 4. Declare shared fields underschemaand each sensor'sfieldsmapping. Keep provider transformations in sensors; do not infer missing relationships from names or flattened links. - Create
evals/, movequeries.yamltoevals/retrieval.yaml, change suiteversionto 4, and update paths in tasks, docs and skills. Multiple named suites may share the directory. - Existing records without normalized fields remain readable. Preserve originals before explicitly backfilling fields from retained structured evidence; unavailable historical roles remain unknown. Mapping changes alone do not rewrite history or contact providers.
- Add directly related brains under
brains: {team: {path: ../team}}inbf.yaml; ensure target names match. Readers now include these direct references, so review the intended audience. Use paths or local names for discovery. Existing optional registrations remain usable; newly initialized brains need explicit--collectbefore collection. - Keep the brain
namestable across clones; use it as the BF URI authority. Declare roles before adding BF link queries. Give entity notes explicitentityidentities and reviewed aliases; do not reinterpret external URL queries or fabricate historical relationships. Refresh separately installed skills and brain agent instructions. - Run
bf build,bf validate, technical tests andbf eval; check role-specific queries and exact reads, then resume the scheduled writer. Keep originals until recovery is verified. Rollback requires the prior runtime and original configuration and records, not only a cache rebuild.
No migration tooling or legacy command surface is included. Runtime dependencies are unchanged.
v9.2.0 - 2026-09-24¶
Brain Framework 9.2 starts new brains smaller, checks action folders and repairs the PyPI project page. The brain format is unchanged: existing version 3 brains need no conversion.
Added¶
bf init --fullalso creates the optional versioned folders:memories/,assets/,sensors/,routines/,settings/,skills/andtests/.bf validatereports action folders that are not namedYYYY-MM-DD_slugor lackACTION.md. Rename such folders withgit mv; validation then reports any links to update.- Document the optional brain folders: versioned
assets/for media that notes link to, and the unversionedinputs/,originals/andlogs/that new brains already ignore.
Changed¶
bf initcreates onlyprojects/,concepts/andactions/; other folders appear when first needed.bf registerkeeps the registry's leading comment lines when it rewrites the file.- Search, MCP and retrieval cases resolve relative times in one place. An invalid search time exits 2 as invalid input, and an invalid retrieval case names the case.
bf statusbuilds its report in the health service; the CLI stays a thin adapter.- PyPI publication accepts deployments only from
v*tags.
Fixed¶
- README links are absolute, so the PyPI project page reaches the documentation, skills and examples; a test keeps every link resolvable offline.
bf evalnames a missingqueries.yamlinstead of reporting an inaccessible file.- Claude Code discovers the repository's
bf-contributeskill through.claude/skills.
v9.1.0 - 2026-09-24¶
Brain Framework 9.1 prepares team deployments. The brain format is unchanged: existing version 3 brains need no conversion.
Added¶
bf init --no-collectregisters a shared brain for search without collection trust, andinitaccepts a fresh clone of an empty repository.- A team brains guide: distinctive names, joining, CI collection with preserved run state, allowlisted
memories/publication, required review of sensor code, and data retention. - A documented compatibility policy: the brain,
bf.yamlandqueries.yamlformats change only in a major release, with manual upgrade steps.
Fixed¶
bf initanchors.gitignorepatterns to the brain root, soactions/*/inputs/stay versioned and a teammate's clone validates like the author's copy. Existing brains that copied the old patterns should prefixinputs/,logs/,memories/,originals/and.bf/with/.bf initnames a brain after its directory instead ofknowledge, avoiding registry name collisions between personal and team brains, and explains how to resolve a taken name.- Unsupported platforms fail with a clear message instead of an import traceback.
Changed¶
- Call executable collectors sensors in command help, documentation and the
bf-maintainskill; record refs,--source, healthsourcesand OKFsourceskeep their provenance names.search --sourcenow has help text.
v9.0.1 - 2026-09-24¶
First published Brain Framework release. The v9.0.0 candidate stopped at the macOS ARM64 concurrent-registration check before publication; its tag remains unchanged. This release includes the complete identity and format transition described below.
Fixed¶
- Recover when a competing process creates the shared lock during its initial open, while retaining the same confined parent and no-follow checks. A missing or unsafe lock still fails explicitly.
- Cover initial lock creation races, persistent missing locks and unsafe contenders without relaxing writer serialization.
Breaking changes¶
- Rename FKF to Brain Framework: install
brain-framework, importbf, and runbf. The repository and documentation move tofmind/brain-framework. - Use format 3 for
bf.yamlandqueries.yaml, withsensors:,{{brain}},--brain,BF_BRAIN, and abrains:registry under~/.config/bf/. Private runtime state lives under~/.local/state/bf/. - Organize authored knowledge in
projects/,concepts/, andactions/withACTION.md; collected records inmemories/; collection code insensors/; maintenance inroutines/andsettings/; disposable search in.bf/. - Rename workflows to
bf-use,bf-learn,bf-maintain, andbf-contribute. CLI and MCP results identify their brain; collection reports identify sensors while record provenance retainssource:idand OKFsources. - Keep one current format without legacy aliases. Preserve original evidence and per-machine collection trust during any one-time transition, and rebuild caches from the migrated files.
Preserved¶
- Offline search and exact reads, two read-only MCP tools, plain-file evidence, bounded trusted collection, atomic recovery and external scheduling.
- Stable record IDs, provider provenance, explicit concept types, and searchable Markdown in action inputs and outputs.
v9.0.0 - 2026-09-24¶
Unpublished transition candidate. Publication stopped at the macOS ARM64 concurrent-registration gate; the tag remains unchanged. The corrected transition is released in v9.0.1.
v8.2.2 - 2026-09-24¶
Fixed¶
- Refuse collection into a source with duplicate stored IDs before changing evidence, including snapshot replacement.
- Serialize concurrent base registrations and write the registry durably with owner-only permissions.
- Preserve
#and percent escapes in note filenames and local links; require exact record IDs in retrieval cases.
Changed¶
- Explain the value of shared, file-based knowledge through concrete questions and the search, read, work and update loop.
- Add runnable team-pilot retrieval cases, routine upgrade instructions and host connection checks.
- Align documentation and skills on base selection, skill discovery, collection trust, recovery and native scheduling.
v8.2.1 - 2026-09-23¶
First published 8.2 release. The v8.2.0 candidate stopped at the Intel macOS test gate before publication; its tag remains unchanged.
FKF 8.2 makes incomplete results visible, preserves evidence through interrupted writes, and helps distinguish recently edited knowledge from historical records. Existing version 2 bases need no conversion; disposable search caches rebuild automatically.
Added¶
search --changed-sinceand--currentin the CLI, MCP and retrieval cases, with active, disabled and historical source coverage, freshness and change counts.- Reserved record attributes
updated,observedandpartialdistinguish upstream revision, collection time and incomplete content from event time. - Scoped local document extraction and optional Calendar agenda snapshots in the standalone collector examples.
Fixed¶
- Select test timezones before Python starts, preserving all DST and shared-cache checks on builds without
time.tzset(), including Intel macOS. - Recover interrupted multi-partition commits from durable originals through explicit
build, collection or backup. Serialize source runs and state updates, preserve directory entries before journal writes, and bound partitions before writing. - Preserve newer upstream revisions during backfills, repair duplicates and corrupt caches, and retry concurrent cache replacement.
- Report skipped files and unavailable bases in search; reject incomplete retrieval-case answers. Fail stale-cache health checks and skipped-file updates, reject malformed partition paths, confine link validation, and distinguish unreadable record sources from missing records.
- Correct recent and identity ordering, per-item passage selection, local-date and DST handling, and malformed-note isolation. Expose identity ambiguity and OKF provenance links.
- Validate Drive snapshot response identity before accepting empty catalogs, bound provider output while subprocesses run, and cancel collector descendants on SIGTERM.
Changed¶
- Rewrite onboarding around a runnable first decision and a small team pilot. Clarify offline and security limits, scheduler cadence and example isolation.
- Expand failure tests, French retrieval cases and the benchmark's changed and unchanged record paths. No runtime dependencies or services added.
v8.1.0 - 2026-09-23¶
Added¶
fkf statuslists active or blocked project notes whoseupdateddate is more than 14 days old underreview, as a reminder rather than a failure.searchandreadkeep local usage counts in the private state directory (time, operation and result count, never the query), summarized byfkf statusover 7 and 30 days so an owner can see whether agents use a base. Retrieval cases are not counted.
Changed¶
- The example Git collector skips hidden repositories, repositories named with
--skip, and bot or reserved-test-domain authors.
v8.0.1 - 2026-09-23¶
Changed¶
- Match English word forms with the FTS5 Porter stemmer, so
meetingsfindsmeetinganddecidedfindsdecide. Existing caches rebuild on the next search.
v8.0.0 - 2026-09-22¶
FKF 8 focuses on the loop that makes a knowledge base useful: collect on a schedule, search from anywhere, read the exact source, keep notes current. It removes machinery that made bases hard to run and notes hard to read.
Breaking changes¶
- Store records as monthly JSON Lines,
records/<source>/<YYYY-MM>.jsonl, with one line per source item upserted by id; snapshot sources keep onesnapshot.jsonl. Immutable per-run capture files, capture hashes, latest/historical snapshots and--historyare removed; Git or backups keep history. This also removes the 20,000-file ceiling that hourly collection reached within two months. - Replace
findandcontextwith onesearch [QUERY] [--since] [--until] [--source] [--type] [--status] [--limit] [--recent]. An empty query lists a time window newest first. Byte budgets are removed;--limitbounds results. - Use readable refs everywhere:
path,path#sectionandsource:id. Base ids,fkf://qualified references andrecord:<hash>URIs are removed. fkf.yamlisversion: 2with anameand noid;fkf.local.yamlis removed. Bases are registered per user in~/.config/fkf/config.yaml, which also grants collection trust per machine.collect SOURCE [--since] [--until] [--dry-run]replaces positional windows and--preview.buildalways rebuilds from scratch;--checkand--if-staleare removed.- Remove containers,
parents,--withinandindexes/structures.json; link folders and labels with ordinarylinks. Remove note supersession, the special## Historyheading, trust-signal computation,reviewedandeffective; note status is one of draft, active, paused, blocked, done, stable, deprecated or archived, andupdateddates a note. - MCP exposes
searchandread. - Convert a v7 base with a one-off script in that base; see the upgrade notes in the documentation.
Added¶
- Search every registered base from any directory, or only the enclosing base; results name their base.
fkf register PATH [--collect]adds a cloned team base; a base never runs collectors on a machine that has not trusted it.- The search cache refreshes itself incrementally before each query, skips and reports unparsable files, and keeps answering, marked
stale, while another writer holds the base. - Relative times:
now,today,yesterday,12h,7d,2wand localYYYY-MM-DDdates. fkf status [--check]reports each source's last run, success, error and private stderr log, and fails when a trusted scheduled source is stale.fkf updatecovers every trusted base, resumes each window source from its last success with overlap, catches up at most 30 days, and keeps run state outside the base.fkf validatereports every problem at once, including broken links, missing headings, cited records that do not exist and misplaced or duplicate records.
Changed¶
- Rank exact identities first, then items matching all words, then any word; notes above records; deprecated and archived notes last; one result per note through its best section.
- Collectors run from the base root with the user's environment minus loader-injection variables, and write stderr to a bounded private log.
- Retrieval cases use
version: 2withexpect,forbid,text,emptyand time filters.
v7.0.1 - 2026-09-21¶
First published v7 release. The v7.0.0 candidate stopped at the macOS package gate before publication; its tag remains unchanged.
Fixed¶
- Resolve temporary smoke environments to physical paths, including macOS
/var, so strict private-state symlink protection remains enabled during distribution checks. Copy packages explicitly when temporary environments and the cache use different filesystems.
Breaking changes¶
- Replace the Go implementation with one typed Python package and the
fkfcommand. Python 3.14 or newer on Linux or macOS is required; install withuv tool install --python 3.14 'fkf==7.0.1'. - Use one current base format:
fkf.yaml, authoredprojects/,wiki/andtasks/, immutable normalizedrecords/, and disposable.fkf/andindexes/. Preserve a v6 base and executable separately; there is no in-place migration or compatibility command. - Remove bundled provider integrations, presets, harness installation, execution approval registries and learning proposal machinery. Bases own collectors, schedules and knowledge editing. Reusable Markdown skills and three source examples are maintained separately from the Python distribution.
- Require an explicitly built, ready cache for indexed retrieval. Missing, stale or corrupt caches name the
fkf buildrecovery command; direct authored and capture-file reads remain available.
Added¶
- Explicit
updatewith a side-effect-free dry-run, per-source refresh policy and durable successful automatic checkpoints. Failed windows stay due, manual collections do not move automatic progress, andbuild --if-staleskips a ready index. - Base-qualified exact evidence references, explicit source structure and membership filters, current versus historical capture retrieval, and authored section references.
- OKF v0.2 wiki structure validation, provenance and asserted verification signals, lifecycle filters, and resumable task folders with inputs and outputs.
- A runnable fictional base with a credential-free collector and retrieval acceptance cases; focused
fkf-use,fkf-learn,fkf-maintainand repository-localfkf-contributeskills.
Changed¶
- Keep CLI and the three read-only MCP tools on shared services. Context includes the complete JSON and final newline within four UTF-8 bytes per budget unit; MCP also counts its response wrapper.
- Match literal lexical terms with case and diacritic folding, explicit identities and authored-note preference. Keep event-time filtering separate from capture recency and decision validity.
- Confine filesystem access, bound subprocess output and runtime, sanitize collection environments, and preserve atomic immutable evidence and a tested rebuild/recovery path.
- Publish a documented installation and upgrade path, complete command reference, skill setup example, and contributor release checklist. Remove obsolete implementation proposals from the current tree.
v6.0.2 - 2026-09-09¶
Fixed¶
- Share a fifteen-second deadline across passive-hook children while allowing individual context calls up to ten seconds. Expired budgets prevent new children, and timed-out process groups are terminated.
- Create every missing parent directory with owner-only permissions during atomic writes, without changing existing directory modes.
- Isolate the security-rule checkout from Git environment variables inherited by linked-worktree hooks, while retaining rejection of local rule edits.
v6.0.1 - 2026-09-09¶
Fixed¶
- Keep passive hooks compatible with system Python 3.9 and newer, independently of the FKF package’s Python 3.14 environment. The formatter now preserves that syntax boundary and a regression test checks it.
- Consolidate the hook’s validated direct-argv dispatch through the fixed system
envexecutable.
v6.0.0 - 2026-09-09¶
Breaking changes¶
- Consolidate source execution and improve offline retrieval. Base-owned helpers now live in
sources/, retrieval evaluations inchecks/queries.yaml, and optional app scripts inclients/. Update declarations and reinstall managed harness hooks, review the resulting execution plan, and renew trust before collecting. Stored evidence remains readable without re-collection.
Changed¶
- Select a persistent launcher explicitly with
harness print/install --executablewhen package-manager PATH entries disagree. - Reuse status narrative pages for briefing commitments instead of reading and parsing task/project files again.
- Rename base collection helpers from
bin/tosources/and retrieval acceptance tochecks/queries.yaml. - Declare single-script uv app clients under
clients:; hash and disclose their separate execution tree. - Make CLI context receipt persistence opt-in with
--save-receipt, keeping ordinary context reads lock-free. - Surface explicit project next actions, review dates, deadlines, and blockers in the offline brief.
- Improve multi-term lexical ranking and excerpts, reuse Unicode-preserving text analysis, and reduce exact-budget packing work.
- Let retrieval evaluations require answer-bearing excerpts and verified offline reads, beyond URI recall.
- Describe harvested lessons as trace citations rather than a knowledge-quality measure.
Fixed¶
- Report exact missing completed dates per enabled event source using the configured collection window, including in briefing attention.
- Reuse task pages for fallback selection and the global learned backlog, and skip a second Markdown parse when rendered headings contain no Learned section.
- Keep conjunctions out of question scoring and select commitment and body excerpts independently so metadata cannot displace the answer.
- Give body-cache manifests an independent 8 MiB bound, retaining the 4,096-entry and 512 MiB content limits.
- Select prompt transcripts through bounded archive metadata and resolve bodies from stored lineage, generation, and turn provenance without changing evidence IDs or deleting history.
- Search project commitments and preserve active handoffs in compact identity context; unify indexed and fallback lesson backlog semantics.
- Compile canonical fragment validation once per process and report hook timeouts without exposing child output.
-
Compare GitHub commit bounds as instants, project safe fallback titles for untitled browser visits, and discard RSS stylesheet metadata without fetching it.
-
Open Chromium-family browser roots and profile directories through retained no-follow descriptors so linked path components cannot redirect local history or bookmark collection.
v5.0.1 - 2026-09-07¶
Fixed¶
- Prevent long-lived MCP stdio servers on Python 3.14 from accumulating timeout callbacks during cancellation polling, eliminating age-correlated CPU and memory growth.
- Let local release verification ignore only uv's exact one-byte
dist/.gitignoremarker while continuing to reject every other unexpected asset. - Parse RSS, Atom, and OPML with a DTD-rejecting XML parser so valid CDATA and predefined or numeric references retain their text without enabling entity expansion.
- Preserve provider-formatted Gmail recipient names while continuing to derive normalized participant identities from mailbox addresses.
- Keep agent session hooks non-blocking when invoked with terminal standard input.
v5.0.0 - 2026-09-07¶
Highlights¶
- Reimplement FKF as one typed Python 3.14 package while preserving the
fkfcommand,fkf: 1configuration and evidence envelopes, trust digests, rebuildable graph and lexical cache contracts, ranking version 7, offline reads, and bounded read-only MCP surface. - Publish a wheel and source distribution for
uv tool install fkfand one-shotuvx fkfuse, with locked uv development, strict Ruff and ty checks, hermetic branch-coverage tests, PyPI trusted publishing, and GitHub build-provenance attestations. - Consolidate provider execution behind one direct-argv boundary, package presets and skills as runtime resources, and retain deterministic differential coverage against the final Go implementation.
- Load the MCP SDK only for MCP commands so ordinary CLI startup does not pay for its server and transport stack.
- Replace the Hugo module with a locked, self-contained Zensical documentation build while preserving the published Pages routes.
Breaking changes¶
- Replace native release archives,
install.sh, and the self-replacingfkf upgradecommand with standard Python packaging. Useuv tool upgrade fkffor a persistent uv installation. - Narrow the existing
?jq=and--whereselector spelling to the safe field-path grammar plus optional terminal| length; arbitrary jq programs are rejected instead of running an embedded evaluator.
Upgrade notes¶
- Existing bases and collected evidence need no migration or re-collection. After installing v5, refresh official helpers, review and renew execution trust, then rebuild derived caches:
fkf config helpers --refresh,fkf trust --all, andfkf build all. - Use a persistent
uv tool install fkflauncher for harness and schedule integrations. Reserveuvxfor one-shot commands.
v4.0.1 - 2026-09-04¶
Fixed¶
- Make Ruff linting independent of contributor-level configuration and use the correct exception types in the Gmail body helper, restoring the clean four-platform release gate.
- Keep historical agent-session collection available as the append-only store grows by bounding in-window identities before selecting their newest complete generation, while rejecting a partial manifest scan.
v4.0.0 - 2026-09-04¶
Highlights¶
- Make every derived-cache check read-only with
build [graph|index|wiki|all] --check, add selective body-cache pruning by source and age, and report lexical-index integrity alongside graph health. - Add reviewed Gmail and Calendar body helpers plus four disabled Google Workspace metadata presets, while keeping provider diagnostics private and bounding provider output before it can fill memory or temporary storage.
- Keep append-only agent-session stores collectible without a lifetime generation ceiling, normalize Git commit titles without discarding raw messages, and refresh the compact embedded usage skill.
- Harden installation, upgrade, and release delivery with exact dirty-build version handling, portable macOS installation, a four-platform CI gate, draft-before-attestation publication, and exact-head Pages deployment.
- Rewrite the README around the concrete benefit—owned, inspectable memory shared across coding agents—and tighten the command, source, graph, privacy, and contributor guides.
Breaking changes¶
- Remove the documented but ineffective
fkf status --allflag; barestatusalready performs the complete offline check. - Emit one
{wiki, projects, records, lint?, ok}document from bare structuredfkf validateinstead of concatenating several top-level JSON reports. - Bound
receipt.consulted_bodiesunder the requested pack budget and expose the complete count asconsulted_bodies_total. - Aggregate text
find --countoutput across the selected window, bound textwhoneighbours per relation kind, and make body-prune text output explicit. - Treat a corrupt lexical cache as a status error. A missing or stale rebuildable cache remains a warning.
- Remove the unused exported
services.StatusRequest.Allfield and add build/prune request types plus cache-health and receipt fields. Go source consumers using unkeyed literals or strict JSON decoders must update.
Fixed¶
- Preserve body-cache crash consistency and confinement across selective pruning, corrupt or missing cache entries, malformed timestamps, symlinked roots, source/age no-ops, and newest-event restore markers.
- Keep command output inside exact byte budgets, make graph-generation state a published confined URI, and prevent stale or corrupt derived caches from masquerading as current.
- Refuse unsafe response-file-style body arguments, disclose the real body execution policy during trust review, and retain one finite shutdown path for oversized or uncooperative body providers.
- Prevent an equal or newer Git-describe development build from being replaced by an older release, and ensure all release archives carry the README, license, notices, checksums, and build-provenance attestations.
Upgrade notes¶
- Existing
fkf: 1configuration and evidence remain valid; no re-collection or data migration is required. - Refresh any installed official helpers, review and renew execution trust, then rebuild derived caches:
fkf config helpers --refresh,fkf trust --all, andfkf build all. - Update consumers of bare structured
validateand the removedstatus --allflag before upgrading automation.
v3.0.2 - 2026-09-03¶
Fixed¶
- Keep the cross-process writer-lock test helper alive without triggering Go's deadlock detector, removing a timing-dependent macOS CI failure without changing runtime behavior.
v3.0.1 - 2026-09-03¶
Fixed¶
- Make schedule CLI tests select the native fake scheduler and managed-file layout, restoring the hermetic CI contract on macOS without changing runtime behavior.
v3.0.0 - 2026-09-03¶
Highlights¶
- Add deterministic
brief,day,timeline,who, andevalworkflows, temporal query grammar, declared identity aliases, and compact text and structured retrieval receipts. - Add digest-bound lexical and constant-time graph caches while keeping durable evidence authoritative, offline reads reproducible, and indexed and fallback retrieval semantically identical.
- Add login-aware opportunistic sync, hourly systemd and launchd scheduling, and idempotent harness integration for Claude Code, Codex, Gemini CLI, Copilot CLI, Antigravity, OpenCode, Grok, Cursor, Kiro, and Cline.
- Add bounded, ignored, manifest-verified body caching with per-source
none,cache, andsyncpolicies; first-class meeting-note and local agent-memory sources can prefetch searchable text without copying it into durable evidence. - Expand and harden the reviewed personal presets, session traces, staged learning workflow, MCP surface, provider pagination, process isolation, trust revalidation, and graph generation consistency.
Breaking changes¶
- Every collected record must now project one meaningful, control-free
title; update custom source schemas and field mappings before the next sync. - Structured
findandcontextresults omit raw provider records and internal day selections by default; pass--rawonly when those diagnostic fields are required.
Upgrade notes¶
- Existing evidence remains valid and requires no re-collection. Run
fkf build all --base <base>to create the new derived graph and lexical caches. - Refresh FKF-owned helpers and harness integrations, review the resulting execution plan, and renew trust before running changed collectors:
fkf config helpers --refresh,fkf harness install --all, thenfkf trust --all. - Body caching stays opt-in per source. The default
bodies: nonefetches only on an explicitread --body;cacheretains an explicitly fetched body andsyncprefetches it after evidence is written.
v2.1.0 - 2026-08-30¶
Highlights¶
- Add a dedicated base
tests/execution tree for source verification hooks, recursively covered by trust and prepended toPATHonly forfkf test; collection and body commands cannot see test fixtures or shadows. - Report source-hook readiness separately from ordinary
requires:, disclosebin/andtests/as distinct trust items, and carry the new layout through init, permissions, schemas, documentation, and bundled skills. - Preserve v2 compatibility: bases without
tests/keep their existing trust digest, hooks can still resolve frombin/, and an empty optional selection remains a successful 0/0 report. Completion gates should name mandatory sources.
Fixed¶
- Restrict repository metadata projected by bundled session, Git, and agent-hook helpers to GitHub remotes, while continuing to strip credentials and reject malformed paths.
- Open Atuin history read-only in batch mode, omit deleted rows and command text, and declare the Git dependency used by the agent-sessions preset.
Upgrade notes¶
- A pre-existing base
tests/directory is now reserved, recursively trust-covered execution material and must contain no symlinks. Move source hooks and their support files there, keep generic repository tests elsewhere, then review and renew trust.
v2.0.1 - 2026-08-29¶
Fixed¶
- Make verified release archives the documented v2 installation path and explain that Go's major-version import rules keep the unchanged module path's
go install ...@latestresolution on v1.
v2.0.0 - 2026-08-29¶
Highlights¶
- Add optional, trust-covered source
test:argv andfkf test, with enabled-source defaults, explicit disabled-source selection, bounded timeouts, stable reports, and provider-stderr privacy. - Publish
graph.meta.jsonschema version 2 with separate SHA-256 inputs for events, index, projects, tasks, wiki, and edge-relevant schema semantics, plus a framed aggregate and exactgraph.tsvoutput digest. - Give every bundled shell helper an explicit
.shextension and require.shor.pywhen scaffolding a helper, including the interpreter in the generated readiness contract when needed.
Breaking changes¶
- Existing derived graph metadata must be rebuilt with
fkf build graph; collected evidence remains readable and requires no re-collection. - Base configurations and harness integrations using bundled extensionless helper names must move to the corresponding
.shnames before refreshing helpers.
v1.1.2 - 2026-08-27¶
Highlights¶
- Flatten the documentation sidebar on desktop and mobile so Overview and every guide are peers, while preserving all published routes and enforcing the rendered navigation contract in tests.
v1.1.1 - 2026-08-27¶
Highlights¶
- Make failed collection diagnostics actionable with the source, date or window, safe substituted command, neutral working directory, timeout, and exit class while keeping provider stderr and body-derived arguments private.
- Stage release installation beside the destination before an atomic replacement, preserving an existing binary if staging fails; cover every published Linux and macOS architecture tuple hermetically.
- Add a dedicated configuration-schema guide, present every documented agent harness at the same level, refresh vendor hook contracts, simplify root help and contributor instructions, and keep the Overview first in the documentation tree.
- Scope toolchain drift checks to project pins, refresh the embedded usage skill and supported-version policy, and retain a strict, generated, link-checked documentation contract.
v1.1.0 - 2026-08-27¶
Highlights¶
- Add
fkf upgrade, which selects the current platform archive, verifies its published SHA-256 checksum and reported version, and atomically replaces the running executable. - Send the documentation root directly to the Overview, expose Overview in the navigation, and remove the intermediate "Read the docs" landing page.
- Explain repeated
fkf syncsafety and how coding agents learn from project and wiki content through the read-only MCP server and embedded skills.
v1.0.0 - 2026-08-26¶
The initial Fmind Knowledge Framework release: one Go binary that collects developer activity into an owned, inspectable base of JSON and Markdown, links it as a graph of relative URIs, and gives coding agents a deterministic context pack under a token budget.
Highlights¶
- Collect complete daily events and point-in-time indexes from local tools, GitHub, Google Workspace, and Google Cloud presets, plus arbitrary reviewed provider commands.
- Compose each source from direct argv or a trust-digested helper whose shebang selects its interpreter, with curated preset helpers for provider boundaries that need shared pagination, completeness, or privacy handling.
- Declare one root semantic
schema:with descriptions, cardinality, examples, and relation roles; sources associate those shared fields with provider paths, and stored documents retain the exact schema subset they used. - Build an open, transcription-only graph: any non-reserved lowercase entity scheme is valid, relation field names are base-defined, and edges come only from declared fields, authored links, tags, and explicit
relations:frontmatter. - Read, find, rank, and graph stored knowledge entirely offline; the read-only MCP server cannot collect, write, shell, or fetch bodies.
- Share one base across Claude Code, Codex, Gemini CLI, OpenCode, Copilot CLI, Antigravity, Cursor, Kiro, Cline, and other harnesses through portable Agent Skills and documented hooks.
- Keep execution explicit with a canonical-plan trust digest covering enabled commands, body-bound paths, helper scripts, executable bits, executable search directories, retry, pacing, and collection policy without re-arming on YAML presentation, inherited environment, or retrieval-only metadata.
- Use one explicit
fkf: 1marker value for strict base configuration and the separate additive evidence envelope. - Store plain JSON and Markdown in five typed layers, with rebuildable
graph.tsvandgraph.meta.jsonat the base root, strict schemas, bounded and atomic I/O, path confinement, owner-only permissions, and untrusted-content framing. - Reproduce lexical retrieval under a hard whole-pack budget with a selection receipt that records scores, reasons, counted exclusions, rejected pins, evaluation day, ranking version, and semantic-input digest.
- Ship synthetic demos, personal and team presets, a strict Hugo documentation site, hermetic race-tested Go suites, security scans, reproducible archives, checksums, and build-provenance attestations.
Supported platforms¶
Release archives are provided for Linux and macOS on amd64 and arm64. Native Windows is intentionally out of scope; WSL2 uses the Linux archive.