> For the complete documentation index, see [llms.txt](https://docs.holons.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.holons.io/software/rea-accounting.md).

# REA Accounting

**REA** stands for **Resource–Event–Agent**, a well-known accounting model from the work of William E. McCarthy: every economic phenomenon is captured as an *event* that moves *resources* between *agents*. The `@holons/core/rea` domain is the Holons ecosystem's implementation of that model.

Every action that should "count"—a task being completed, an appreciation being given, an expense being logged, a library item being borrowed, an offer being made—produces an REA event. Those events are what the [scoring](/software/harvest-dashboard.md) system reads when computing contribution equity, and what federated holons exchange when sharing recognition across membrane boundaries.

REA is the **substrate** layer of the contribution stack. Most users never interact with it directly; they create tasks, give appreciations, log expenses—and the corresponding REA events are recorded as a side effect.

## Why REA

The alternative to REA is to keep separate, ad-hoc records for tasks, appreciations, expenses, and so on, and then re-aggregate them for scoring. That works briefly but breaks down as soon as a holon wants to:

* recognize a new kind of contribution without rewriting the scoring pipeline,
* federate recognition data across holons that track different things,
* audit "what happened in this holon last month" as a single ordered stream.

REA solves these by making the **event** the unit of record, with a loose enough shape that new event types don't require schema migrations.

## The event shape

```ts
interface REAEvent {
  id: string;
  timestamp: number;
  resource?: {
    type?: string;
    quantity?: number;
    unit?: string;
    resourceId?: string | number;
    [key: string]: any;
  };
  provider?: { id?: string | number; type?: string; name?: string; [key: string]: any };
  receiver?: { id?: string | number; type?: string; name?: string; [key: string]: any };
  context?: {
    holonId?: string;
    questId?: string | null;
    itemId?: string | number;
    expenseId?: string;
    note?: string | null;
    [key: string]: any;
  };
  eventType?: string;
  status?: string;
  [key: string]: any;
}
```

The shape is deliberately loose. The required fields are `id` and `timestamp`; everything else is optional. Each domain that emits events adds the fields it cares about under `resource`, `context`, etc. Forward compatibility comes for free.

## Storage

Events are persisted in the `rea_events` lens of the holon they belong to:

```
HoloSphere.put(holonId, 'rea_events', event)
```

Querying is an in-memory filter pass over the lens contents, supporting:

```ts
interface EventQueryFilters {
  resourceType?: string;
  eventType?: string;
  agentId?: string | number;
  fromDate?: number;
  toDate?: number;
  status?: string;
}
```

This keeps the storage layer simple and the query layer flexible—the same semantics as the original Telegram-bot implementation, now lifted into shared core.

## The Event Factory

`REAEventFactory` is a static class with one method per kind of action that should produce an event. Callers don't construct raw REA events; they call factory methods like:

* `questCreated(...)` / `questCompleted(...)`
* `appreciationGiven(...)`
* `expenseEvents(expense)` — produces both the paid-event and the per-participant share-events
* `timeLogged(...)`
* `itemBorrowed(item, borrower)` / `itemReturned(item, returner)`
* `offerMade(...)` / `wantMade(...)`
* `creditIssued(...)`

The factory ensures every event has:

* a unique ID (`generateId(holonId)` produces `${holonId}_${timestamp}_${rand}`),
* properly shaped `provider` / `receiver` agents (`createUserAgent`, `createHolonAgent`, `createExternalAgent`),
* the correct `eventType` discriminator for downstream aggregators to dispatch on.

Output matches the original JavaScript factory exactly, so existing stored events keep aggregating correctly after the TS migration.

## Where it plugs in

REA is the integration point between several otherwise-independent domains:

* [**Council**](/software/council.md) emits events when proposals reach agreement (recognition for participation).
* [**Library**](/software/library.md) emits `itemBorrowed` and `itemReturned` events, with optional deposit accounting.
* **Expenses** emits a `expense:paid` event plus one share-event per participant.
* **Tasks** emits quest lifecycle events.
* **Scoring** consumes all of them through the `REAEventStoreLike` interface to compute contribution points.

This is why a "value equation" in the protocol sense can be reconfigured purely by changing weights: the underlying event stream is the same regardless of what you choose to value.

## MCP tool surface

REA itself is not heavily exposed as MCP tools—the goal is for events to be a **byproduct** of domain operations, not something agents have to manage directly. When a Claude agent calls `task_complete` or `appreciation_give` via the [MCP server](/software/mcp-server.md), the corresponding REA events are emitted automatically.

The `holosphere` MCP domain provides escape-hatch reads against the `rea_events` lens for tooling that wants to inspect the event stream directly.

## See also

* [Harvest](/software/harvest-dashboard.md) — the monorepo that contains `@holons/core/rea`
* [Glossary: value equation](/getting-started/glossary.md#value-equation) — what the event stream ultimately feeds
* [Glossary: epoch](/getting-started/glossary.md#epoch) — the time windows over which the events are aggregated
* [Funding Flow](/getting-started/funding-flow.md) — the protocol-level distribution mechanisms REA enables


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.holons.io/software/rea-accounting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
