> ## Documentation Index
> Fetch the complete documentation index at: https://docs.equa.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# SPEC 005: Agreements

> Governing documents, operating agreements, and authorization management

# SPEC 005: Agreements

> **Status:** DRAFT
> **Priority:** P0
> **Created:** 2026-02-21
> **Approved:** pending
> **Repo(s):** equa-web, equa-server

***

## 1. Feature Purpose

The Agreements module manages an organization's governing documents — primarily operating agreements and board authorizations. An operating agreement represents a **point-in-time snapshot** of the organization's equity structure, capturing shareholdings, security types, plans, and transactions as immutable, content-addressed records. Authorizations track board-level approvals attached to specific documents. Together, these provide a legally auditable chain of the company's equity history.

## 2. Current State (Verified)

**Frontend module:**

```
equa-web/src/modules/agreements/
├── components/   # Agreement list, detail, authorization management
├── services/     # API client for agreements and authorizations
├── store/        # State management for agreements
└── index.tsx
```

**Backend modules:**

Agreement entities span the `organization` and `captable` server modules. Operating agreements reference cap-table entities (shareholdings, securities, plans, transactions) via content-addressed hashes. Authorizations are managed alongside organization-level data.

```
equa-server/modules/captable/      # OperatingAgreement and related join entities
equa-server/modules/persistence/   # Entity definitions
```

## 3. Data Model

### Entities

| Entity                           | Description                                                            | File                                                                             |
| -------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| OperatingAgreements              | Point-in-time snapshot of equity structure                             | `equa-server/modules/persistence/src/entity/OperatingAgreements.ts`              |
| OperatingAgreementsShareholdings | Join: operating agreement ↔ shareholdings (composite PK)               | `equa-server/modules/persistence/src/entity/OperatingAgreementsShareholdings.ts` |
| OperatingAgreementsTransactions  | View entity: recursive CTE joining operating agreements and hash lists | `equa-server/modules/persistence/src/entity/OperatingAgreementsTransactions.ts`  |
| Authorizations                   | Board-level approvals attached to documents                            | `equa-server/modules/persistence/src/entity/Authorizations.ts`                   |

### Key Fields — OperatingAgreements

| Field                    | Type   | Nullable | Description                                   |
| ------------------------ | ------ | -------- | --------------------------------------------- |
| `organization`           | `uuid` | No       | Owning organization                           |
| `timestamp`              | `Date` | No       | Point-in-time this agreement represents       |
| `organizationDetails`    | `Hash` | No       | Snapshot of org details at this point         |
| `plans`                  | `Hash` | Yes      | Snapshot of equity incentive plans            |
| `shareholdings`          | `Hash` | Yes      | Snapshot of all shareholdings                 |
| `securityTypesSeniority` | `Hash` | Yes      | Security type seniority ordering              |
| `securityTypesShares`    | `Hash` | Yes      | Share counts by security type                 |
| `transactions`           | `Hash` | Yes      | Snapshot of transactions                      |
| `previous`               | `Hash` | Yes      | Link to the prior operating agreement (chain) |

### Key Fields — OperatingAgreementsShareholdings

| Field                | Type   | Nullable | Description          |
| -------------------- | ------ | -------- | -------------------- |
| `operatingAgreement` | `Hash` | No       | Part of composite PK |
| `shareholding`       | `Hash` | No       | Part of composite PK |

### Key Fields — OperatingAgreementsTransactions

This is a **ViewEntity** backed by a recursive CTE that joins `operating_agreements` with `hash_lists` to materialize the full transaction chain for a given agreement.

### Key Fields — Authorizations

| Field               | Type      | Nullable | Description                                       |
| ------------------- | --------- | -------- | ------------------------------------------------- |
| `organization`      | `uuid`    | No       | Owning organization                               |
| `target`            | `string`  | No       | What is being authorized (e.g. plan, transaction) |
| `authorizationDate` | `Date`    | No       | Date of board authorization                       |
| `document`          | `Hash`    | Yes      | Reference to the authorization document           |
| `note`              | `text`    | Yes      | Free-text note                                    |
| `reason`            | `uuid`    | Yes      | Reference to the reason / triggering event        |
| `documentTypeName`  | `string`  | Yes      | Type label for the attached document              |
| `deleted`           | `boolean` | No       | Soft-delete flag                                  |

### Relationships

```mermaid theme={null}
erDiagram
    OPERATING_AGREEMENTS ||--o{ OA_SHAREHOLDINGS : "captures"
    OPERATING_AGREEMENTS ||--o{ OA_TRANSACTIONS : "includes"
    OPERATING_AGREEMENTS ||--o| OPERATING_AGREEMENTS : "previous (chain)"
    AUTHORIZATIONS }o--|| ORGANIZATIONS : "belongs to"
    OPERATING_AGREEMENTS }o--|| ORGANIZATIONS : "belongs to"
```

### Content-Addressed Hashing

All `Hash`-typed fields are content-addressed identifiers. This guarantees:

* **Immutability**: once an agreement snapshot is created, its referenced data cannot be altered without producing a different hash.
* **Auditability**: the `previous` chain forms a tamper-evident linked list of every equity-structure change.
* **Deduplication**: identical data produces identical hashes, preventing redundant storage.

## 4. API Endpoints

| Method | Path                                                      | Auth    | Description                               |
| ------ | --------------------------------------------------------- | ------- | ----------------------------------------- |
| GET    | `/v1/organizations/:orgId/agreements`                     | Session | List operating agreements                 |
| POST   | `/v1/organizations/:orgId/agreements`                     | Session | Create a new operating agreement snapshot |
| GET    | `/v1/organizations/:orgId/agreements/:hash`               | Session | Get agreement details                     |
| GET    | `/v1/organizations/:orgId/agreements/:hash/shareholdings` | Session | List shareholdings in this agreement      |
| GET    | `/v1/organizations/:orgId/agreements/:hash/transactions`  | Session | List transactions in this agreement       |
| GET    | `/v1/organizations/:orgId/agreements/latest`              | Session | Get the most recent agreement             |
| GET    | `/v1/organizations/:orgId/authorizations`                 | Session | List authorizations                       |
| POST   | `/v1/organizations/:orgId/authorizations`                 | Session | Create a new authorization                |
| GET    | `/v1/organizations/:orgId/authorizations/:id`             | Session | Get authorization details                 |
| PUT    | `/v1/organizations/:orgId/authorizations/:id`             | Session | Update an authorization                   |
| DELETE | `/v1/organizations/:orgId/authorizations/:id`             | Session | Soft-delete an authorization              |

## 5. Frontend Components

| Component          | File                                                                | Purpose                                   |
| ------------------ | ------------------------------------------------------------------- | ----------------------------------------- |
| AgreementsPage     | `equa-web/src/modules/agreements/components/AgreementsPage.tsx`     | List operating agreements chronologically |
| AgreementDetail    | `equa-web/src/modules/agreements/components/AgreementDetail.tsx`    | View a single agreement snapshot          |
| AgreementDiff      | `equa-web/src/modules/agreements/components/AgreementDiff.tsx`      | Compare two agreement snapshots           |
| AuthorizationsList | `equa-web/src/modules/agreements/components/AuthorizationsList.tsx` | List board authorizations                 |
| AuthorizationForm  | `equa-web/src/modules/agreements/components/AuthorizationForm.tsx`  | Create/edit an authorization              |

### Routes

| Route                                    | Component          | Description             |
| ---------------------------------------- | ------------------ | ----------------------- |
| `/organizations/:orgId/agreements`       | AgreementsPage     | Agreement listing       |
| `/organizations/:orgId/agreements/:hash` | AgreementDetail    | Single agreement detail |
| `/organizations/:orgId/authorizations`   | AuthorizationsList | Authorization listing   |

### State Management

Agreements state is managed within the `agreements` module store. The operating-agreement chain is loaded lazily — the latest agreement is fetched first, with prior snapshots loaded on demand for diff views.

## 6. Business Rules and Validation

| Rule    | Description                                                                                               | Enforcement |
| ------- | --------------------------------------------------------------------------------------------------------- | ----------- |
| AGR-001 | A new operating agreement must reference the current latest agreement as `previous`                       | Backend     |
| AGR-002 | Operating agreements are append-only; existing snapshots cannot be modified                               | Backend     |
| AGR-003 | The `previous` chain must be acyclic (no circular references)                                             | Backend     |
| AGR-004 | Authorization `document` hash must reference a valid uploaded document                                    | Backend     |
| AGR-005 | Soft-deleted authorizations are excluded from active queries but retained for audit                       | Backend     |
| AGR-006 | Only organization admins can create operating agreements or authorizations                                | Both        |
| AGR-007 | Each operating agreement must have a `timestamp` that is on or after its `previous` agreement's timestamp | Backend     |

## 7. Acceptance Criteria

* [ ] AC-1: Admin can create a new operating agreement that snapshots current shareholdings, plans, securities, and transactions
* [ ] AC-2: New agreement automatically links to the previous agreement via `previous` hash
* [ ] AC-3: Agreement detail view displays all captured shareholdings and transactions
* [ ] AC-4: User can compare two agreement snapshots to see equity structure changes
* [ ] AC-5: Admin can create a board authorization with date, document, and notes
* [ ] AC-6: Soft-deleting an authorization hides it from active views but preserves audit trail
* [ ] AC-7: Recursive CTE correctly materializes the full transaction list for OperatingAgreementsTransactions
* [ ] AC-8: Content-addressed hashes are correctly computed and verified on read
* [ ] AC-9: Agreement chain is displayed chronologically with linked-list navigation

## 8. Risks and Edge Cases

| Risk                                                       | Likelihood | Impact   | Mitigation                                                                   |
| ---------------------------------------------------------- | ---------- | -------- | ---------------------------------------------------------------------------- |
| Hash collision in content-addressed data                   | Very Low   | Critical | Use cryptographic hash function (SHA-256+); collision probability negligible |
| Broken `previous` chain (orphaned agreements)              | Low        | High     | Foreign-key-like constraint; validate chain integrity on creation            |
| Recursive CTE performance on long histories                | Med        | Med      | Limit recursion depth in query; paginate transaction results                 |
| Stale snapshot if cap table changes between creation steps | Low        | Med      | Capture agreement atomically within a single transaction                     |
| Authorization document references invalid hash             | Low        | Med      | Validate document hash exists before persisting authorization                |

## 9. Dependencies

| Dependency                       | Type            | Status |
| -------------------------------- | --------------- | ------ |
| SPEC 003: Cap Table              | Required before | DRAFT  |
| SPEC 004: ESOP                   | Integrates with | DRAFT  |
| SPEC 007: Documents and DocGen   | Integrates with | DRAFT  |
| SPEC 012: Team Members and Roles | Required before | DRAFT  |
