Skip to content

Instantly share code, notes, and snippets.

@iamalnewkirk
Last active August 19, 2026 06:43
Show Gist options
  • Select an option

  • Save iamalnewkirk/22ae2d8c8cc1b8790236da9edf2f7b73 to your computer and use it in GitHub Desktop.

Select an option

Save iamalnewkirk/22ae2d8c8cc1b8790236da9edf2f7b73 to your computer and use it in GitHub Desktop.
Facts: Curated Knowledge for Humans and Agents

Facts: Curated Knowledge for Humans and Agents

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 init

The basic unit is a proposition: a statement that can be evaluated as either true or false.

$ fact propose policy.md

That proposition is not automatically a fact.

$ fact list
no propositions

Someone, or something, still has to decide on it:

$ fact pending
01a00-9ef94  pending, update pending  Policy v0  [accept or reject]
$ fact accept 01a00-9ef94

Now 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.


Version-Controlled Knowledge

Think of Facts as applying some of the useful properties of Git to knowledge.

You can propose something:

$ fact propose architecture.md --decision accept

Later, someone learns that it is incomplete:

$ fact revise 019fa-b6e41 architecture-v2.md

The old fact does not disappear just because somebody edited some text.

You can inspect what happened:

$ fact show 019fa-b6e41

You'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-2181f

Now the newer revision can become effective.

The history remains available:

$ fact history 01a00-2181f

Conceptually:

- proposed
- accepted
- revised
- commented
- accepted
- archived
- restored
- revised
- ...

Knowledge changes over time. The history explain how and why.


Information is Accumulated. Knowledge is Curated.

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.md

The system can retain the proposition without treating it as accepted knowledge.

A reviewer sees it, they investigate, and reject it:

$ fact reject 019fb-12a87

The 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."


Actor-agnostic Knowledge Management

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 agent

The agent, codex, can now propose:

$ FACT_HOME=.actors/codex fact propose runbook.md

The human can give themselves a nice name too:

$ fact as "Al Newkirk" --alias alnewkirk --self --type human

Another actor can comment:

$ fact comment 019fb-12a87 \
  --message "This contradicts the production runbook."

Another can reject:

$ fact reject 019fb-12a87

Or 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.


Safer AI Agent Memory

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-6c222

Or 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.


Don't Go Fishing

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 policy

If 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

Normative Use Cases

1. Personal memory

Start a ledger:

$ fact init

Record a preference:

$ fact import my-preferences.md --decision accept

Find it later:

$ fact find "writing style"

Revise it:

$ fact revise 019fb-ce177

Inspect it:

$ fact show 019fb-ce177

The result is more structured than a notes folder without becoming a heavyweight knowledge system.


2. Team decisions

Someone proposes:

$ fact propose deployment-policy.md
$ fact push

The team sees:

$ fact pull
$ fact pending

A 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.md

Then accepted:

$ fact accept 019fc-22d91

Six months later:

$ fact history 019fc-22d91

Now you can answer both: What is the policy, and how did we get here?


3. Engineering knowledge

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.


4. Runbooks and operational knowledge

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-812a1

During 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.


5. Curated Requirements

A product manager proposes:

$ fact propose requirement.md

An 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-12331

Then accepted:

$ fact accept 019fd-12331

Now an implementation agent can query accepted requirements rather than parsing every planning discussion.


6. Curating AI-generated discoveries

Suppose an agent analyzes customer tickets overnight.

It proposes:

$ for file in agent-findings/*.md; do fact import $file; done

The next morning:

$ fact pending

A human accepts three findings and rejects two.

The agent discovered information, decide what to do with the rejected propositions, and continues.


Advanced Topologies

The interesting thing about the Facts system is that the same primitives can support very different systems.

Topology 1: One shared organizational ledger

           +----------------+
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.


Topology 2: Domain ledgers

                +--> 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.


Topology 3: Project memory

Create a dedicated ledger:

$ fact init project-atlas

Capture:

$ 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.


Topology 4: One shared agent mailbox

A ledger can function like an inbox.

Agent A -----+
             |
Agent B -----+--> shared ledger --> Worker Agent
             |
Human -------+

Submit work:

$ fact propose investigate-cache-misses.md

Worker:

$ 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.


Topology 5: One mailbox per agent

               +--> 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.


Topology 6: Reviewer agents

Research Agent
      |
      v
  proposition
      |
      +------> Verification Agent
      |
      +------> Policy Agent
      |
      +------> Human Reviewer
                    |
                    v
                 accepted

For example:

$ fact propose market-observation.md

Invite 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.


Topology 7: Multi-agent consensus

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.


Topology 8: Human-controlled agent memory

An agent has permission to propose but not decide.

Agent:
  propose
  comment

Human:
  accept
  reject
  revise

Agent:

$ fact propose learned-preference.md

Human:

$ fact pending
$ fact open 019ff-872cc
$ fact accept 0119ff-872cc

The agent learns continuously.

The human controls what graduates into durable memory.


Topology 9: Agent-controlled memory with human escalation

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.


Topology 10: Distributed organizational memory

Facts ledgers can move between machines.

Configure a remote:

$ fact remote add origin https://facts.example.com/team

Synchronize:

$ fact pull

Work locally:

$ fact propose architecture-note.md
$ fact accept 019ff-a8211

Publish:

$ fact push

Another 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.


Agents are Replaceable. Organizational Memory Shouldn't Be.

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.


Simple Primitives, Lot of Shapes

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.

Ethic

Information accumulates. Knowledge is curated.

Project Details

  • 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

TL;DR;

Watch the video

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment