Most knowledge and/or memory management systems are primarily concerned with
storing, maybe even organizing, information.
Facts is primarily concerned with deciding
what information should become knowledge, and when, and how. It's as much
about multi-player consensus as it is about fast capture and recall. The
CLI is a zero-config, fast, malleable
substrate for managing trusted knowledge. You start by initializing the system.
$ fact initThe basic unit is a proposition: a statement that can be evaluated as either true or false.
$ fact propose policy.mdThat proposition is not automatically a fact.
$ fact list``no propositionsSomeone, or something, still has to decide on it:
$ fact pending``01a00-9ef94 pending, update pending Policy v0 [accept or reject]``$ fact accept 01a00-9ef94Now it can participate in the ledger's accepted knowledge.
That small distinction is very powerful and enables multi-player curation.
A wiki says:
Someone wrote this.
Facts can say:
1. Someone proposed this.
2. These actors considered it.
3. This revision was accepted.
4. This is the version currently treated as fact.
That distinction matters for humans. It matters even more for AI agents. It enables transparency, tracing, and accountability.
Think of Facts as applying some of the useful properties of Git to knowledge.
You can propose something:
$ fact propose architecture.md --decision acceptLater, someone learns that it is incomplete:
$ fact revise 019fa-b6e41 architecture-v2.mdThe old fact does not disappear just because somebody edited some text.
You can inspect what happened:
$ fact show 019fa-b6e41You'll see something like:
...
Revisions
01a00-2181f pending 2026-08-17T06:18:33.162Z ...
019fa-b6e41 accepted 2026-08-17T06:15:49.427Z ...
That's an important distinction.
This knowledge/memory system still has an accepted fact:
Revision 019fa-b6e41
It also has a proposed replacement:
Revision 01a00-2181f
The replacement does not become effective merely because it is newer.
It has to earn that status.
$ fact accept 01a00-2181fNow the newer revision can become effective.
The history remains available:
$ fact history 01a00-2181fConceptually:
- proposed
- accepted
- revised
- commented
- accepted
- archived
- restored
- revised
- ...
Knowledge changes over time. The history explain how and why.
Consider a company wiki.
Someone adds: "Customers on the Enterprise plan receive 24-hour support."
It is immediately searchable.
That is useful if the statement is correct.
It's less useful if someone misunderstood the policy.
With Facts:
$ fact import wiki/enterprise-support-research.mdThe system can retain the proposition without treating it as accepted knowledge.
A reviewer sees it, they investigate, and reject it:
$ fact reject 019fb-12a87The proposition remains part of history. It simply never became a fact. Which
gives you a useful distinction, i.e., "We considered this" is not the same
thing as "We believe this is true."
Facts does not fundamentally care whether the actor is a human, an agent, a service, or an organization.
The following creates an operating environment for a registered actor with public/private signing key pair and permissions to participate.
$ fact as "Codex" --alias codex --home .actors/codex --participate --type agentThe agent, codex, can now propose:
$ FACT_HOME=.actors/codex fact propose runbook.mdThe human can give themselves a nice name too:
$ fact as "Al Newkirk" --alias alnewkirk --self --type humanAnother actor can comment:
$ fact comment 019fb-12a87 \
--message "This contradicts the production runbook."
Another can reject:
$ fact reject 019fb-12a87Or several participants can be involved:
$ fact invite 019fb-12a87 alice
$ fact invite 019fb-12a87 reviewer-agent
$ fact invite 019fb-12a87 security-agent
The important concept is not "human approval."
It is controlled knowledge formation.
Humans can supervise agents.
Agents can supervise agents.
Humans and agents can participate together.
A common agent-memory loop looks roughly like this:
Agent observes something
|
v
Write to memory
|
v
Retrieve it later
|
v
Treat it as context
The danger is obvious once you look at it this way.
An agent makes one bad inference:
Customer X never wants an email notifications.
The agent stores it.
A future agent retrieves it.
Now a mistake gets committed to memory as truth. This problem can be compounded if that memory is shared causing a catastrophic failure.
Facts lets you put a decision boundary in the middle.
An agent can propose:
$ fact propose --message "Customer notification preference ..."But a future agent querying accepted knowledge does not have to see it yet.
And human could approve it:
$ fact accept 019fb-6c222Or another agent could review it first.
Or multiple participants could be required.
The workflow becomes:
observe
|
v
propose
|
v
review / deliberate
|
v
accept
|
v
recall as trusted knowledge
The agent is still free to learn and propose new information and revisions.
Consider This: Two agents using a shared ledger to check each other's work
you now have a dynamic autonomous in-flight CI process.
A common AI architecture looks like this:
Slack
Drive
Wiki
Tickets
Email
Databases
Meeting transcripts
Documentation
|
v
"Agent, go figure it out."
The agent repeatedly has to determine:
- Which document is current?
- Which statement was superseded?
- Was this proposal ever approved?
- Was this just somebody's opinion?
- Which of these three policies is authoritative?
Facts gives you another layer.
Raw information can stay where it is.
Curated knowledge can live here:
$ fact find "production database access"You might get:
019f91-a2f91 Production database access requires VPN
019fa8-3cfa8 Production credentials rotate every 30 days
019fa9-92fa9 Production writes require an approved change
Now the agent starts with three accepted facts instead of 4,000 search results.
Tagging helps actors organize and narrow vector search results even further.
$ fact find "production database access" --tag network --tag policyIf it needs supporting information, it can go fishing afterward.
The default workflow becomes:
1. facts first
2. raw information second
Instead of:
1. search everything
2. hope retrieval found the right answer
Start a ledger:
$ fact initRecord a preference:
$ fact import my-preferences.md --decision acceptFind it later:
$ fact find "writing style"Revise it:
$ fact revise 019fb-ce177Inspect it:
$ fact show 019fb-ce177The result is more structured than a notes folder without becoming a heavyweight knowledge system.
Someone proposes:
$ fact propose deployment-policy.md``$ fact pushThe team sees:
$ fact pull``$ fact pendingA participant comments:
$ fact comment 019fc-22d91 \
--message "Can we clarify whether emergency deploys are exempt?"
The proposition is revised:
$ fact revise 019fc-22d91 deployment-policy-v2.mdThen accepted:
$ fact accept 019fc-22d91Six months later:
$ fact history 019fc-22d91Now you can answer both: What is the policy, and how did we get here?
Small engineering conclusions frequently disappear into chat.
Facts can turn them into reusable knowledge.
```
$ cat <<'EOF' | fact propose - --decision accept
Invoice numbering
The billing service is the sole authority for invoice numbers.
EOF
```
Later:
$ fact find "invoice number ownership"Another:
```
$ cat <<'EOF' | fact propose - --decision accept
Public identifiers
Public API identifiers must not expose internal database IDs.
EOF
```
An engineering agent working on billing can retrieve both.
It does not need the entire architecture wiki.
An incident produces a lesson:
```
$ cat <<'EOF' | fact propose -
Restarting the queue workers
Queue workers must be drained before restarting the scheduler.
EOF
```
An operations engineer reviews it:
$ fact accept 019fc-812a1During the next incident:
$ fact find "restart queue scheduler"The incident gets resolved much quicker and could possibly be automated with AI agents with access to the same incident response ledger.
The reusable lesson becomes knowledge.
A product manager proposes:
$ fact propose requirement.mdAn engineer comments:
$ fact comment 019fd-1233 \
--message "This requires the billing API changes first."
A designer comments:
$ fact comment 019fd-12331 \
--message "The empty state is unspecified."
The requirement is revised:
$ fact revise 019fd-12331Then accepted:
$ fact accept 019fd-12331Now an implementation agent can query accepted requirements rather than parsing every planning discussion.
Suppose an agent analyzes customer tickets overnight.
It proposes:
$ for file in agent-findings/*.md; do fact import $file; doneThe next morning:
$ fact pendingA human accepts three findings and rejects two.
The agent discovered information, decide what to do with the rejected propositions, and continues.
The interesting thing about the Facts system is that the same primitives can support very different systems.
+----------------+
Human A -->| |
Human B -->| Single |
Agent A -->| Ledger |
Agent B -->| |
+----------------+
Everybody works from one shared knowledge domain.
Typical commands:
$ fact pull
$ fact pending
$ fact propose discovery.md
$ fact push
Useful for a small team with broadly shared knowledge.
+--> engineering
|
Agents/Humans --+--> product
|
+--> operations
|
+--> security
Switch domains:
$ fact use engineering
$ fact find "authentication"
$ fact use security
$ fact find "authentication"
Same query.
Different curated knowledge boundary.
An agent can be granted only the knowledge domains it needs.
Create a dedicated ledger:
$ fact init project-atlasCapture:
$ fact propose requirements.md --decision accept
$ fact propose constraints.md --decision accept
$ fact propose architecture.md
During development:
$ fact find "database"
$ fact pending
$ fact revisions 019fe-22311
When the project ends, the ledger remains as durable project memory.
The next team does not have to reconstruct the project from Slack history.
A ledger can function like an inbox.
Agent A -----+
|
Agent B -----+--> shared ledger --> Worker Agent
|
Human -------+
Submit work:
$ fact propose investigate-cache-misses.mdWorker:
$ fact pending
$ fact echo 019fe-8bb91
The worker acts, then records an outcome:
$ fact revise 019fe-8bb91 result.md
$ fact accept 019fe-8bb91
A proposition becomes both communication and durable record.
+--> researcher ledger
Human/Agents --+--> security ledger
+--> coding-agent ledger
+--> planner ledger
An orchestrator switches context:
$ fact use researcher
$ fact propose research-request.md
$ fact use security
$ fact propose review-request.md
$ fact use coding-agent
$ fact propose implementation-request.md
Each agent sees only its own work and memory.
The ledger becomes:
inbox + memory + history
without Facts needing to define an agent framework.
Research Agent
|
v
proposition
|
+------> Verification Agent
|
+------> Policy Agent
|
+------> Human Reviewer
|
v
accepted
For example:
$ fact propose market-observation.mdInvite reviewers:
$ fact invite 019ff129-a71 verification-agent
$ fact invite 019ff129-a71 policy-agent
$ fact invite 019ff129-a71 alice
Their decisions determine whether the observation graduates into shared memory.
Suppose no single AI should be trusted to update critical memory.
Agent A: accept
/
Proposal ----- Agent B: accept
\
Agent C: reject
The ledger records each position.
Consensus policy determines whether the proposition becomes effective.
That is very different from:
Agent A wrote something to memory, therefore it is memory.
You can deliberately combine different models or agents with different tools so that their failure modes are less correlated.
An agent has permission to propose but not decide.
Agent:
propose
comment
Human:
accept
reject
revise
Agent:
$ fact propose learned-preference.mdHuman:
$ fact pending
$ fact open 019ff-872cc
$ fact accept 0119ff-872cc
The agent learns continuously.
The human controls what graduates into durable memory.
Invert the previous model.
Routine facts are handled by agents.
Humans appear only when something is contested.
Proposal
|
+--> Reviewer Agent A
|
+--> Reviewer Agent B
|
disagreement?
/ \
no yes
| |
settle human
The human's inbox can effectively become:
$ fact conflicts
$ fact pending
Humans manage exceptions instead of reviewing every memory update.
Facts ledgers can move between machines.
Configure a remote:
$ fact remote add origin https://facts.example.com/teamSynchronize:
$ fact pullWork locally:
$ fact propose architecture-note.md
$ fact accept 019ff-a8211
Publish:
$ fact pushAnother participant:
$ fact pull
$ fact find "architecture"
The useful property is not simply synchronization.
It is that the knowledge is not trapped inside the application that currently consumes it.
Suppose today you use:
Agent A
Six months later:
Agent A is retired.
Agent B replaces it.
If Agent A owns its memory, you have a migration project.
If the organization owns a Facts ledger:
Agent A --> Facts <-- Agent B
the replacement starts with the same accepted organizational knowledge.
Models change.
Frameworks change.
Vendors change.
Agents come and go.
The ledger remains.
At first glance, Facts is intentionally small.
You can:
- fact propose
- fact revise
- fact comment
- fact accept
- fact reject
- fact find
- fact pull
- fact push
But those primitives compose into:
- Personal memory
- Team knowledge
- Engineering decisions
- Agent memory
- Shared agent mailboxes
- Per-agent mailboxes
- Human review systems
- Multi-agent consensus
- Project memory
- Domain-specific knowledge stores
- Distributed organizational memory
That is the point.
Facts does not try to predict the application.
It provides the substrate.
And underneath all of those topologies is the same simple distinction:
Someone said it.
is information.
We accepted it.
is a fact.
Information accumulates. Knowledge is curated.
- CLI – The Facts protocol reference CLI written in Rust.
- SDK – The Facts protocol reference SDK written in Rust.
- Spec – The Facts open protocol for shared knowledge management.
- Architecture – An explanation of the Facts protocol, the Fact CLI, and their underlying architectures.
- Founder – Al Newkirk