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

# Council

The **Council** domain in `@holons/core/council` handles the proposal lifecycle for holonic governance. It implements consent-based decision-making: proposals are created, members signal **agree** or **block**, the result is tallied against a quorum, and the proposal's status is derived from those votes.

Council is how a [Managed Holon](/software/holons-types-flavor/managed-holon.md) makes binding decisions—who joins, how resources are allocated, what the DNA should be, when to federate. It is the operational counterpart to the protocol's [Commitment Registry](/getting-started/glossary.md#commitment-registry).

## Concepts

A **Proposal** has:

* an identity and a title,
* a status drawn from `ProposalStatus` (open, agreed, blocked, withdrawn, expired, …),
* a vote ledger — one `VoteEntry` per voter, with a direction (`agree` / `block` / `abstain`) and timestamp,
* a quorum threshold (`DEFAULT_QUORUM` if not set).

A **VoteTally** is the rolling aggregate over the ledger: counts of agree, block, abstain, and the derived status given the current quorum.

The Council store lives in the `proposals` lens of a holon's HoloSphere namespace (`PROPOSAL_LENS`), which means every interface—web, Telegram bot, CLI, AI agent, MCP client—sees the same proposals.

## Operations

The public functions exported by `@holons/core/council`:

| Function                                           | Purpose                                                    |
| -------------------------------------------------- | ---------------------------------------------------------- |
| `createProposal(input)`                            | Construct a new proposal object (no persistence yet)       |
| `saveProposal(holonId, proposal)`                  | Persist a proposal to HoloSphere                           |
| `createAndSaveProposal(input)`                     | Convenience: build and persist in one call                 |
| `deleteProposal(holonId, id)`                      | Remove a proposal from the holon                           |
| `castVote(holonId, id, voter, direction)`          | Record an explicit `agree` / `block` / `abstain` vote      |
| `agree(...)` / `block(...)`                        | Convenience wrappers around `castVote`                     |
| `applyVote(proposal, vote)`                        | Pure: produce an updated proposal with the new vote merged |
| `tallyVotes(proposal)`                             | Pure: count current agree/block/abstain                    |
| `deriveStatus(proposal, quorum)`                   | Pure: compute status from the current tally                |
| `hasAgreed(proposal, voterId)` / `hasBlocked(...)` | Quick membership checks for a specific voter               |
| `subscribeToProposals(holonId, cb)`                | Live updates as proposals or votes change                  |

The split between **impure** persistence helpers and **pure** tally/derivation helpers is deliberate: the pure functions are reused by every UI to render live tallies without round-tripping through storage.

## Voting model

Consent-based, not majoritarian:

* A proposal can **pass** when it has reached its quorum of agreements and has zero unresolved blocks.
* A **single block** by a member with standing is enough to keep the proposal from passing. The expectation is that the block-holder participates in resolving the underlying concern, not that the proposal needs a majority to override them.
* Abstain is a recorded position—useful for quorum math and for showing "I've seen this and chosen not to weigh in."

Quorum thresholds are configurable per proposal; `DEFAULT_QUORUM` is used when none is specified.

## MCP tool surface

The [MCP server](/software/mcp-server.md) exposes **13 tools** in the `council` domain — full proposal lifecycle plus voting and tally introspection. Any MCP-connected agent can therefore create proposals, cast votes, and check tallies on behalf of its resolved actor.

## See also

* [HolonsBot](/software/holonsbot.md) — the Telegram interface to Council (proposal commands, inline keyboards for voting)
* [DNA](/software/dna.md) — proposals are often used to add or remove chromosomes
* [Glossary: commitment](/getting-started/glossary.md#commitment) — the protocol-level promise type that Council operationalizes


---

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