hence |~ multi-agent planning with defeasible logic

15 January 2026 - Hugo O'Connor

An abstract image representing multi-agent coordination

Classical logic is monotonic, as premises are added the set of conclusions can only increase.

In the real-world we rarely operate from complete knowledge of the facts. We might be wrong!

Therefore, we cannot rely on partial knowledge to draw permanent conclusions. We must learn as we move through the world and acquire new knowledge that may contradict earlier conclusions.

Things I once thought
Unbelievable
In my life
Have all taken place

PJ Harvey, Good Fortune

John McCarthy identified the need for non-monotonic reasoning in the late 1970s to address how intelligent agents would solve problems with incomplete information.

It was the following video that captured my interest in the subject many years ago;

John McCarthy explains the motivation for non-monotonic reasoning (1986).

Defeasible logic, one of several formalisms that emerged from this line of inquiry, handles non-monotonicity in linear time through facts, rules, and relations:

  • Facts (given, >>) assert what is true
  • Strict rules (always, =>) can't be defeated: invariants, hard constraints
  • Defeasible rules (normally, ->) hold by default but can be overridden
  • Defeater rules (except, ~>) block conclusions without asserting alternatives
  • Superiority relations (prefer, >) resolve conflicts when multiple rules fire

I created hence, a command line tool that gives defeasible reasoning capabilities to LLM agents, to plan, coordinate and learn as they pursue a set of goals.

hence builds on Spindle, a defeasible reasoning engine created by Ho-Pun Lam and Guido Governatori at NICTA, and Maher's proof that propositional defeasible logic has linear complexity.

Our fork, Spindle-Racket, adds abduction, semantic annotations, reasoning traces, process mining, temporal logic based on Allen's interval calculus and a novel approach to auto-epistemic reasoning whereby agents can create a spindle theory to reason about their confidence in claims made by their peers. A new DSL (Spindle Lisp) allows for future extensibility.

Download it and try the demo:

curl -fsSL anuna.io/h | bash

Why agents need this

The default planner for LLM agents is a TODO list, an unordered set with no transition semantics. The reader is the state machine, interpreting dependencies and priorities on each read. Interpretation errors waste tokens or cause error loops. Semantic drift between reads or readers can lead to further divergence.

In Hence, the derivation logic is in the file, not in the mind of the reader.

How it works

A plan file defines tasks, dependencies, and assignments. Consider two agents building an API:

;; Tasks
(given task-design)
(given task-impl)
(given task-tests)
(given task-review)
(given no-deps-design)

;; Agents
(given agent-coder)
(given agent-security)

;; Design is ready immediately (no dependencies)
(normally r1 (and task-design no-deps-design) ready-design)

;; Implementation waits for design completion
(normally r2 (and task-impl completed-design) ready-impl)

;; Tests and review wait for impl completion
(normally r3 (and task-tests completed-impl) ready-tests)
(normally r4 (and task-review completed-impl) ready-review)

;; Assignments
(normally r10 (and ready-tests agent-coder) assign-tests-coder)
(normally r11 (and ready-review agent-security) assign-review-security)

;; Defeater: blocked review defeats ready-review
(except d1 blocked-review (not ready-review))

The inference graph looks like this;

  task-design        task-impl          task-tests       task-review
       │                  │                  │                 │
       │ r1               │                  │                 │
       ▼                  │                  │                 │
  ready-design            │                  │                 │
       │                  │                  │                 │
       + completed ──────►│                  │                 │
                          │ r2               │                 │
                          ▼                  │                 │
                     ready-impl              │                 │
                          │                  │                 │
                          + completed ──────►├────────────────►│
                                             │ r3              │ r4
                                             ▼                 ▼
                                        ready-tests       ready-review ◄══ blocked-review
                                             │                 │              d1 (except)
                                        + agent-coder     + agent-security
                                             │                 │
                                             ▼                 ▼
                                      +∂ assign-tests    -∂ assign-review
                                           -coder           -security

Agents interact with the plan through shell commands:

$ hence next plan.spl
Next actions:
  1. ready-design

$ hence complete plan.spl design
Added: (given completed-design)

Next actions:
  1. ready-impl

$ hence complete plan.spl impl
Added: (given completed-impl)

Next actions:
  1. assign-tests-coder
  2. assign-review-security

When something blocks, agents can see why:

$ hence why-not plan.spl assign-review-security
Why not: assign-review-security

Missing prerequisite: ready-review
  Defeated by: d1
    blocked-review ~> (not ready-review)

When agents discover something, they assert it:

$ hence assert plan.spl '(given discovered-vulnerability)' --agent security
Added: (given discovered-vulnerability)

$ hence next plan.spl
Next actions:
  1. needs-fix

Blocked:
  - ready-deploy (defeated by d-block-deploy)

The fact is appended to the plan. Conclusions are redrawn on the next query. No central coordinator needed.

Design choices

Single file, no external state. The plan is plain text. Version control it, diff it. Writes under 4096 bytes are atomic on POSIX, so concurrent agents don't need coordination.

Explanations built in. hence explain shows derivation chains. hence why-not shows blockers. hence require reasons backwards: given a goal, what facts would make it true? Use --assume to see what's needed after certain facts are established.

Hypothetical reasoning. hence what-if shows what conclusions would become derivable if specified facts were added, without modifying the plan.

Task lifecycle. hence claim marks tasks in-progress, preventing other agents from taking them. hence block adds a defeater with a reason. hence unblock removes the block. All mutations are timestamped for audit trails.

Kanban view. hence board shows a visual overview of task states: backlog, ready, in-progress, blocked, done. --tree for another view.

Belief revision. hence assert lets agents record discoveries with full DSL power: facts, rules, defeaters, and superiority relations. Write rules that trigger on certain facts, and when those facts appear, conclusions update automatically.

Process mining. hence learn mines patterns from completed plans, extracting institutional knowledge from execution history. hence extract-log converts plans into structured event logs.

Semantic annotations. Metadata on rules, facts and conclusions such as descriptions, confidence, provenance, loosely coupled from reasoning. Trace conclusions back to source documents or code.

Getting started

# Install
$ curl -f https://files.anuna.io/hence/latest/install.sh | bash

# Validate a plan
$ hence validate plan.spl

# See what's actionable
$ hence next plan.spl

# Kanban board view
$ hence board plan.spl

# Filter by agent
$ hence next plan.spl --agent coder

# SPL format reference for LLMs
$ hence llm

The repository has example plans for different coordination patterns.

Why hence?

If coordination logic can live outside the model, it should. Hence puts the reasoning in a plain text file that agents query, update, and learn from, not in context windows they burn through.

Plans that can't change are brittle. Plans that change without structure are chaos.

Defeasible logic gives us plans that be revised in response to new information while preserving the reasoning that led to each revision.

Plans need the capacity to change, because the future is unwritten.

--

hence is open source under AGPL-3.0.

Go back