> 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/core.md).

# The Shared Core

**`@holons/core`** is the heart of the Holons codebase. It owns every piece of domain logic—scoring, tasks, council, DNA, federation, expenses, calendar, users, library, checklists, REA, settings, categories, commands—and exposes them as independently-callable modules. Every interface in [Harvest](/software/harvest-dashboard.md) (web, Telegram, CLI, AI, MCP) calls these modules. They do not duplicate the logic; they consume it.

This page is the architectural overview. For domain detail, jump to the individual pages.

## What "shared core" means in practice

> One source of truth for Holons domain logic, several UIs sharing it.

A user creating a task in Telegram and a Claude agent calling the MCP `task_create` tool reach the **same function**: `createDefaultTask` in `packages/core/src/tasks/creation.ts`. The Quest they produce lives in the **same lens** in HoloSphere. Scoring sees the **same event** when the Quest completes. Federation propagates the **same data**.

This is why "compute user score" means the same thing in every UI: there is only one implementation of it.

## Domain catalog

Each domain lives at `packages/core/src/<domain>/`, exposes its public API via `index.ts`, and is reachable from any consumer with a subpath import.

| Domain         | What it owns                                                                                                                        | Page                                          |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| **tasks**      | Unified Quest model — tasks, proposals, events, offers, requests                                                                    | [Tasks](/software/tasks.md)                   |
| **council**    | Proposal lifecycle and consent-based voting                                                                                         | [Council](/software/council.md)               |
| **scoring**    | Value-equation evaluation; per-user / per-action / full-holon scores                                                                | [Scoring](/software/scoring.md)               |
| **rea**        | Resource-Event-Agent event ledger and factory                                                                                       | [REA Accounting](/software/rea-accounting.md) |
| **dna**        | Holon chromosomes (value / tool / practice) and DNA sequences                                                                       | [DNA](/software/dna.md)                       |
| **library**    | Shared community library — borrow / lend / deposit                                                                                  | [Library](/software/library.md)               |
| **federation** | Cross-holon publishing via HoloSphere + Nostr                                                                                       | *(no page yet)*                               |
| **holosphere** | Identity-aware reads/writes against the substrate                                                                                   | [HoloSphere](/software/holosphere.md)         |
| **expenses**   | Shared cost logging and splitting                                                                                                   | *(no page yet)*                               |
| **calendar**   | Events, recurring events, scheduling                                                                                                | *(no page yet)*                               |
| **users**      | Multi-holon membership and appreciation tracking                                                                                    | *(no page yet)*                               |
| **checklists** | Recurring and role-based task lists                                                                                                 | *(no page yet)*                               |
| **shopping**   | Shared shopping lists                                                                                                               | *(no page yet)*                               |
| **settings**   | Per-holon configuration with hex-grid integration                                                                                   | *(no page yet)*                               |
| **categories** | Taxonomies for items and contributions                                                                                              | *(no page yet)*                               |
| **commands**   | Shared command registry used by [Text UI](/software/text-ui.md), [AI UI](/software/ai-ui.md), [MCP Server](/software/mcp-server.md) | *(see UI pages)*                              |

The "no page yet" entries are real, working domains; they just don't yet have dedicated docs. The MCP server exposes tools for every one of them.

## Conventions

A small set of rules keeps the core stable as it grows.

### Subpath imports — no central barrel

```ts
import { calculateUserScore } from '@holons/core/scoring';
import { createDefaultTask }  from '@holons/core/tasks';
import { saveProposal }       from '@holons/core/council';
```

There is **no** `import { everything } from '@holons/core'` barrel that re-exports every domain. The subpath form is mandatory because:

* It makes domain dependencies explicit in import lines.
* Tree-shaking works without any bundler magic.
* New domains land without touching a central re-export file.
* Two domains can have a function of the same name without colliding.

Subpath exports are configured via a wildcard in `packages/core/package.json`:

```json
"exports": {
  ".": "./src/index.ts",
  "./*": {
    "types": "./src/*/index.ts",
    "import": "./dist/*/index.js",
    "default": "./src/*/index.ts"
  }
}
```

Creating `packages/core/src/<new-domain>/index.ts` instantly makes `@holons/core/<new-domain>` importable—no configuration change needed.

### TypeScript everywhere

Core is TypeScript. New UIs are TypeScript. The Telegram bot is in a mixed JS+TS state (bootstrap and several modules migrated; the rest still JS, allowed via `allowJs`). Types are exported alongside functions:

```ts
import type { Quest, QuestParticipant } from '@holons/core/tasks';
```

### UI-agnostic

Core never imports `svelte`, `telegraf`, or any framework. Only `import type` for shared interface shapes when truly necessary. The list of allowed runtime dependencies is intentionally tiny: `holosphere`, `ical.js`. That's it.

### Pure vs. impure split

Every domain has the same internal structure:

* **Pure helpers** — functions that take data and return data. No I/O, no side effects. Used by every UI for live rendering (live tallies, live scores, live previews).
* **Impure helpers** — functions that read from or write to HoloSphere. Called when the action is committed.

This split is what lets the web dashboard show "if you complete this task, you and Laura each get 2 points" without round-tripping to storage: the same pure function runs in the browser.

### One HoloSphere factory

There is exactly one place that instantiates HoloSphere: `@holons/core/holosphere`. Every UI calls into it for identity-aware writes (`writeWithIdentity`, `canWriteToHolon`). This keeps actor resolution, write permissions, and audit attribution consistent regardless of where a call originates.

### Tests live next to the code

Every domain ships a vitest spec at `packages/core/src/<domain>/<domain>.test.ts`. Tests are not in a separate `tests/` tree. This keeps each domain self-contained and makes it obvious which test exercises which file.

## How a new domain lands

1. Create `packages/core/src/<domain>/{index.ts, types.ts, …}`.
2. Export the public surface from `index.ts`.
3. Write a vitest spec: `<domain>/<domain>.test.ts`.
4. If the domain has its own MCP tool wrappers, add `packages/mcp-ui/src/tools/<domain>.ts` and append the domain name to the `DOMAINS` array in `packages/mcp-ui/src/tools/index.ts`.

That's it. No central registration, no manifest, no per-UI plumbing. Every UI that imports from the new path automatically gets the new capability.

## How a new UI lands

1. `mkdir packages/<my-ui>/src`.
2. Copy `packages/text-ui/{package.json,tsconfig.json}` as a starting point.
3. Depend on `@holons/core` via `"@holons/core": "workspace:*"`.
4. `pnpm install` from the repo root.
5. Implement the renderer / parser / input mode against `@holons/core/commands` so the new UI invokes the same actions as the others.

The shared command registry is the single integration point a new UI needs to touch. Every existing command becomes available to the new UI for free.

## What this architecture buys

* **Consistency.** Every interface produces the same data, scores it the same way, federates the same events.
* **Speed.** A new feature is one PR, not five.
* **Independence.** Each UI can iterate on its presentation without coordinating with the others.
* **Testability.** Domain logic is exercised by vitest specs that run in milliseconds, with no UI launched.
* **AI-readiness.** Because every operation is a `CoreCommand` with declared params, exposing it as an [MCP tool](/software/mcp-server.md) or [Claude tool](/software/ai-ui.md) is a one-line wrapper.

## See also

* [Harvest](/software/harvest-dashboard.md) — the monorepo that contains `@holons/core` and its UIs
* [MCP Server](/software/mcp-server.md) — the auto-registered tool surface over the core
* Domain pages: [Tasks](/software/tasks.md), [Council](/software/council.md), [Scoring](/software/scoring.md), [REA Accounting](/software/rea-accounting.md), [DNA](/software/dna.md), [Library](/software/library.md)


---

# 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/core.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.
