The equity.* family (64 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.
Setequity.authorisedCapital.set
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Sets a share class’s authorised capital. If classId is given it RAISES that class (refusing any
value BELOW the current Σ-issued - the authorised≥issued floor); otherwise it CREATES the class with
the given authorised. authorised can only ever be ≥ issued (you cannot un-issue by lowering the
ceiling below what is already out).
Input { issuerPartyId, name, authorised, grain?, classId?, parValueMinor?, currency? } (fields ending in ? are optional)
Call POST /v/equity.authorisedCapital.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.authorisedCapital.set.
Getequity.captable.get
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
The cap-table projection: per class - authorised + issued (Σ ledger); per holder - outstanding shares (Σ ledger by holder); plus the fully-diluted total (issued + the unallocated option-pool remainder). NEVER reads a stored balance - every number is a ledger replay (INV-6 / Σ-conservation), so a CANCEL automatically lowers the count without history mutation.
Input { issuerPartyId } (fields ending in ? are optional)
Call POST /v/equity.captable.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.captable.get.
Consolidateequity.consolidate
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Reverse split (1
): divide every holding in the class byratio
(refused if any holding is not divisible - no silent fractional shares).
Input { classId, ratio } (fields ending in ? are optional)
Call POST /v/equity.consolidate with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.consolidate.
Convertequity.convert
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Convert a convertible instrument into shares: appends a CONVERTIBLE_CONVERT ledger entry that ISSUES
quantity shares of classId to toPartyId, allocating a fresh non-overlapping share range and
honouring authorised≥issued (a conversion increases issued just like a primary issuance). Lineage is
stamped via parentEntryId (the convertible’s originating entry) so the holding history is walkable.
Input { classId, toPartyId, quantity, parentEntryId?, pricePerUnitMinor?, currency? } (fields ending in ? are optional)
Call POST /v/equity.convert with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.convert.
Createequity.convertible.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity in ctx.workspace_id.
Call POST /v/equity.convertible.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.convertible.create.
Deleteequity.convertible.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.convertible.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.convertible.delete.
Updateequity.convertible.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Generic patch + conversion flip (status/convertsTo/date). Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.convertible.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.convertible.update.
Createequity.entity.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
workspace_id from ctx. csp_entity_id is @unique -> Conflict.
Call POST /v/equity.entity.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.entity.create.
Deleteequity.entity.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Cascades child equity rows (FK onDelete: Cascade).
Call POST /v/equity.entity.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.entity.delete.
Link Issuer Partyequity.entity.linkIssuerParty
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
SET-IF-NULL the WRITE-ONCE-THEN-STABLE kernel_issuer_party_id (the immutable ledger-spine anchor; Rule-A CI gate forbids re-keying). On contention (rows_affected==0) re-read and return the existing value with changed
- NEVER overwrite.Call POST /v/equity.entity.linkIssuerParty with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.entity.linkIssuerParty.
Updateequity.entity.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Partial patch fenced by workspace_id (direct column).
Call POST /v/equity.entity.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.entity.update.
Exerciseequity.exercise
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Exercise an option grant: convert quantity (default: the
full outstanding) of an OPTION_GRANT into shares for the grantee. NET-ZERO on the class total AND the
holder’s outstanding: the option was ALREADY counted in issued (OPTION_GRANT is +), so exercise must
NOT add a second +qty (the double-count CR-2 forbids on the money path) - it RE-CHARACTERISES the
option as a share. It appends an OPTION_CANCEL (grant-linked: the option leaves the grant’s
outstanding, and frees the pool’s allocated cache for a pool-drawn grant) + a SHARE_ISSUE (the share
arrives to the grantee). After it: the grant’s option-outstanding drops by quantity; an equal share
holding appears; the class total + the grantee’s outstanding are UNCHANGED. Append-only (INV-8).
Input { grantId, quantity? } (fields ending in ? are optional)
Call POST /v/equity.exercise with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.exercise.
Createequity.financing.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity in ctx.workspace_id.
Call POST /v/equity.financing.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.financing.create.
Deleteequity.financing.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.financing.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.financing.delete.
Updateequity.financing.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.financing.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.financing.update.
Createequity.grant.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
The core register-affecting verb. kind is GRANT (an option, default) or ISSUE (a
direct share issuance) - both:
- ENFORCE authorised≥issued: compute Σ-issued from the ledger and REFUSE if issued + quantity > authorised (at the class grain, or summed across the issuer’s classes for a COMPANY-grain class).
- ALLOCATE a non-overlapping monotonic share-number range under SELECT…FOR UPDATE on the counter.
- APPEND ONE ledger entry (the canonical write path). The captable read re-derives the position.
Input { classId, toPartyId, quantity, kind?, planId?, pricePerUnitMinor?, currency?, ocfId? } (fields ending in ? are optional)
Call POST /v/equity.grant.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.grant.create.
Lapseequity.grant.lapse
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Lapse an unexercised grant. Appends a CANCEL ledger entry
for the grant’s outstanding (or a partial quantity) - the position leaves the issued Σ by
construction (the CANCEL kind subtracts in issued_sign_sql). NEVER mutates the original GRANT row.
Input { grantId, quantity? } (fields ending in ? are optional)
Call POST /v/equity.grant.lapse with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.grant.lapse.
Terminateequity.grant.terminate
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Leaver termination - same append-a-CANCEL mechanic as lapse (return-to-pool / cancel-scheduled-vests is the CANCEL), under a distinct ledger kind for provenance.
Input { grantId, quantity? } (fields ending in ? are optional)
Call POST /v/equity.grant.terminate with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.grant.terminate.
Archiveequity.modelling.archive
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Withdraw a scenario from active listing (reversible - set ARCHIVED).
Input { modellingId } (fields ending in ? are optional)
Call POST /v/equity.modelling.archive with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.modelling.archive.
Deleteequity.modelling.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Destructive - autonomy L3 |
| Min. permission | Owner |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Hard-delete a discarded scenario (teardown of an ADVISORY
projection - NEVER a register/ledger_entry write, which is append-only).
Input { modellingId } (fields ending in ? are optional)
Call POST /v/equity.modelling.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.modelling.delete.
Getequity.modelling.get
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Read one round-modelling Version/Snapshot.
Input { modellingId } (fields ending in ? are optional)
Call POST /v/equity.modelling.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.modelling.get.
Listequity.modelling.list
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
List a issuer’s round-modelling scenarios (ACTIVE
only by default; archived withdrawn from active listing unless includeArchived).
Input { issuerPartyId, includeArchived? } (fields ending in ? are optional)
Call POST /v/equity.modelling.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.modelling.list.
Saveequity.modelling.save
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Persist a round-modelling
run as an ACTIVE Version/Snapshot projection. Advisory only - NEVER a ledger_entry write (INV-6).
Input { issuerPartyId, name, scenario?, result?, basedOnAsof? } (fields ending in ? are optional)
Call POST /v/equity.modelling.save with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.modelling.save.
Exportequity.ocf.export
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Serialise the issuer’s cap table in an OCF-shaped bundle: the pinned OCF
version, the share classes (StockClass), and the ledger transactions (each carrying its stable
ocf_id so a re-import is idempotent against uq_ledger_ocf_id). A pure read over the existing ledger.
Input { issuerPartyId } (fields ending in ? are optional)
Call POST /v/equity.ocf.export with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.ocf.export.
Importequity.ocf.import
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Import an
OCF manifest (the shape equity.ocf.export emits) as ledger state, IDEMPOTENTLY:
• each stock class is inserted by its SOURCE id (ON CONFLICT (id) DO NOTHING) at PER_CLASS grain;
• each transaction is inserted by its stable ocf_id (the uq_ledger_ocf_id guard - a re-import is
a no-op, the OCF round-trip property the constraint exists for).
The holder parties + the issuer footprint are NOT minted here - import REPLAYS equity events; a
transaction whose party/class does not exist fails the FK (a malformed import, fail-closed). The
instrument_kind is mapped from the transaction kind (OPTION_* → OPTION_GRANT, WARRANT_* → WARRANT,
CONVERTIBLE_* → CONVERTIBLE, else SHARE_HOLDING); it drives pool reads, not the holder register.
Input { issuerPartyId (or issuer.id), stock_classes?:[...], transactions?:[...] } (fields ending in ? are optional)
Call POST /v/equity.ocf.import with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.ocf.import.
Pinequity.ocf.version.pin
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Upsert the per-workspace OCF version pin (one row per workspace; the one write path, INV-1). Governs the versioned equity.ocf.import|export contract (NFR-EQ-3).
Input { ocfVersion } (fields ending in ? are optional)
Call POST /v/equity.ocf.version.pin with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.ocf.version.pin.
Deleteequity.optionGrant.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.optionGrant.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.optionGrant.delete.
Updateequity.optionGrant.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Generic patch + status/sharesExercised flips. Fence via the parent entity in ctx.workspace_id. (Lifecycle TERMINATE/LAPSE stays the kernel-native equity.grant.* path.)
Call POST /v/equity.optionGrant.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.optionGrant.update.
Createequity.optionPlan.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity in ctx.workspace_id.
Call POST /v/equity.optionPlan.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.optionPlan.create.
Deleteequity.optionPlan.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.optionPlan.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.optionPlan.delete.
Updateequity.optionPlan.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.optionPlan.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.optionPlan.update.
Adoptequity.plan.adopt
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Drive the plan state machine: DRAFT→ADOPTED→ACTIVE, or →SUSPENDED / →CLOSED. Forward/transition rules are enforced here (the state-machine-as-verb).
Input { planId, status } (fields ending in ? are optional)
Call POST /v/equity.plan.adopt with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.plan.adopt.
Createequity.plan.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Create an option plan (starts DRAFT).
Input { issuerPartyId, name, poolId? } (fields ending in ? are optional)
Call POST /v/equity.plan.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.plan.create.
Createequity.pool.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Reserve an option pool over a class.
Input { issuerPartyId, classId, name, size } (fields ending in ? are optional)
Call POST /v/equity.pool.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.pool.create.
Statusequity.pool.status
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Pool size / allocated (reconciled from the ledger, INV-6) / available.
Input { poolId } (fields ending in ? are optional)
Call POST /v/equity.pool.status with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.pool.status.
Topupequity.pool.topup
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Raise a pool’s reserved size to a new (larger-or-equal) target.
Input { poolId, size } (fields ending in ? are optional)
Call POST /v/equity.pool.topup with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.pool.topup.
Reclassifyequity.reclassify
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Reclassify quantity of a holder’s
shares from one class to another within the SAME issuer. Composes from EXISTING ledger kinds (no new
enum, no sign-function change): a SHARE_CANCEL on the FROM class (the holder loses qty there) + a
REISSUANCE on the TO class (the holder gains qty there). Both kinds are already attributed correctly
by holder_replay_union arm 1 and signed by issued_sign_sql - so the HOLDER’s total economic units
are conserved while the per-CLASS totals shift. GUARDS: the holder must hold >= qty in the FROM class
(no negative holding); the TO class authorised >= issued + qty (the ceiling, like grant.create).
Both classes FOR UPDATE so the floor/ceiling cannot be raced. Append-only (INV-8).
Input { fromClassId, toClassId, partyId, quantity } (fields ending in ? are optional)
Call POST /v/equity.reclassify with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.reclassify.
Asofequity.register.asof
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
The statutory register reconstructed by REPLAY over ledger_entry
up to asOf (default: now). Per (holder, class) the shares OWNED at that instant = Σ signed ledger
quantities with effective_at <= asOf. NEVER a stored snapshot (INV-6) - a CANCEL before the as-of
date correctly lowers the holding; an entry effective AFTER the as-of date is excluded.
Input { issuerPartyId, asOf? } (fields ending in ? are optional)
Call POST /v/equity.register.asof with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.register.asof.
Convertequity.round.convert
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Convert a MODELLED round’s SAFEs/notes into the priced round, as an
ADVISORY projection saved back onto the modelling row. NB this is the ENGINE convert (advisory) - it is
NOT equity.convert (the ledger-writing write-pack verb). SCOPE: the seam is real (it reads the saved
scenario + records a conversion projection); the full per-instrument cap/discount/MFN conversion math
is the NAMED follow-on (ADR-0020 §4).
Input { modellingId } (fields ending in ? are optional)
Call POST /v/equity.round.convert with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.round.convert.
Modelequity.round.model
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Model a
priced round: compute the post-money + the new investor ownership % from the EXISTING issued total
(replayed from the ledger, INV-6) and the round’s money (integer minor-units, C14). ADVISORY ONLY -
the output is a modelling projection, never a register write. Optionally saves it as a modelling row.
SCOPE: this is the SIMPLE, MONEY-EXACT priced-round arithmetic (pre+new → post, ownership = new ÷ post). The FULL 8-mechanism SAFE/note conversion + the Gaussian 2^n option-pool-shuffle solver (ADR-0020 §4, risk R13) is the NAMED follow-on - the seam (modelling save/get/list) is real now.
Input { issuerPartyId, preMoneyMinor, newMoneyMinor, currency?, save?, name? } (fields ending in ? are optional)
Call POST /v/equity.round.model with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.round.model.
Adjust Issuedequity.shareClass.adjustIssued
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
ATOMIC relative counter: total_issued += delta, with the authorised>=issued cap enforced as a Conflict on increment. FOR UPDATE precondition.
Call POST /v/equity.shareClass.adjustIssued with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareClass.adjustIssued.
Createequity.shareClass.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity in ctx.workspace_id.
Call POST /v/equity.shareClass.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareClass.create.
Deleteequity.shareClass.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.shareClass.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareClass.delete.
Updateequity.shareClass.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Generic field set (NOT the total_issued counter). Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.shareClass.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareClass.update.
Createequity.shareHolding.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity AND share class in ctx.workspace_id.
Call POST /v/equity.shareHolding.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareHolding.create.
Deleteequity.shareHolding.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via the parent entity in ctx.workspace_id.
Call POST /v/equity.shareHolding.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareHolding.delete.
Updateequity.shareHolding.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Generic patch + status/quantity flips. quantity is an ABSOLUTE set (the kernel cannot take a Prisma {decrement}); callers express the new value. Fence via the parent entity in ctx.workspace_id.
Call POST /v/equity.shareHolding.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.shareHolding.update.
Subdivideequity.subdivide
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Stock split (N:1): multiply every holding in the class by ratio.
Input { classId, ratio } (fields ending in ? are optional)
Call POST /v/equity.subdivide with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.subdivide.
Createequity.transaction.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Append-only audit-of-record (no updated_at column). Fence parent entity in ctx.workspace_id; recorded_by_id resolves the acting human (RECIPE rule 2 - FK targets users). Best emitted INSIDE the composite issue/transfer/exercise verbs (deferred follow-up).
Call POST /v/equity.transaction.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.transaction.create.
Transferequity.transfer
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| High-risk oversight | Human four-eyes approval in HIGH-risk orgs (EU AI Act Art. 14) |
Move quantity shares of a class from one holder to another. Σ-CONSERVING by construction: the read
side (holder_replay_union) credits to_party +qty and debits from_party -qty for a SHARE_TRANSFER,
and issued_sign_sql treats SHARE_TRANSFER as net-zero on the class total - so the company’s issued Σ
is UNCHANGED and only the per-holder split moves. NO new share-number range is minted (a transfer
moves EXISTING shares). GUARD: a holder cannot transfer more than they currently OWN (the no-negative-
holding floor). Append-only (INV-8): never mutates a prior entry.
Input { classId, fromPartyId, toPartyId, quantity, pricePerUnitMinor?, currency?, ocfId? } (fields ending in ? are optional)
Call POST /v/equity.transfer with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.transfer.
Createequity.valuation.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity in ctx.workspace_id.
Call POST /v/equity.valuation.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.valuation.create.
Deleteequity.valuation.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.valuation.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.valuation.delete.
Updateequity.valuation.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.valuation.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.valuation.update.
Accelerateequity.vesting.accelerate
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
ONE aggregate VESTING_ACCELERATION ledger_entry for the whole event, then mark the accelerated
tranches vested. Selection: earliest unvested tranches; if quantity given, the fewest earliest
whole tranches whose cumulative qty >= quantity; else ALL remaining. Net-zero on issued_sign_sql.
Input { issuerPartyId, grantId, quantity?, trigger: "single" | "double", reason? } (fields ending in ? are optional)
Call POST /v/equity.vesting.accelerate with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vesting.accelerate.
Materialiseequity.vesting.materialise
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Materialise a
TIME-based vesting schedule: split totalQuantity into tranches SHARE-CONSERVING integer tranches
(the remainder lands on the last tranche so Σ tranches == totalQuantity EXACTLY - no fractional
shares, no lost/created share), each vestAt one period after the prior. IDEMPOTENT: re-materialising
the same (grant/holding, seq) is a no-op (ON CONFLICT) - re-running cannot double-vest. ADVISORY: this
writes the SCHEDULE rows; landing a vested tranche to the register is a separate VESTING_EVENT
ledger_entry (not written here - flagged follow-on). SCOPE: TIME allocator only; MILESTONE/
ACCELERATION + the OCF condition-graph are the NAMED follow-on (ADR-0020 §4).
Input { issuerPartyId, grantId|holdingId, totalQuantity, tranches, startAt } (fields ending in ? are optional)
Call POST /v/equity.vesting.materialise with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vesting.materialise.
Scheduleequity.vesting.schedule
| Property | Value |
|---|---|
| Capability | equity.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Read the materialised vesting tranches for a grant XOR a holding (the rows the materialiser wrote), ordered by tranche sequence.
Input { grantId? , holdingId? } (fields ending in ? are optional)
Call POST /v/equity.vesting.schedule with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vesting.schedule.
Defineequity.vesting.schedule.define
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Persist the durable definition (0071), then materialise tranches via the shared helper (cliff + period honoured). REFUSES a re-define (Conflict). Writes NO ledger row (define is advisory; vesting lands the register rows).
Input { issuerPartyId, grantId | holdingId, kind?, cliffMonths?, periodMonths, totalQuantity, startAt, tranches, accelerationTerms? } (fields ending in ? are optional)
Call POST /v/equity.vesting.schedule.define with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vesting.schedule.define.
Vestequity.vesting.vest
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Vertical (MCP tier 3) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Land every DUE tranche (vest_at <=
asOf, default now) whose vested = false: append ONE VESTING_EVENT ledger_entry per tranche, flip
equity_vesting_event.vested = true + stamp ledger_entry_id. IDEMPOTENT (re-run is a no-op).
Σ-CONSERVATION: VESTING_EVENT is NOT in issued_sign_sql -> net-zero on the class Σ (vesting mints no
shares; the grant’s OPTION_GRANT already counted them). INV-8: INSERT-only on the append-only ledger.
Input { issuerPartyId, grantId | holdingId, asOf? } (fields ending in ? are optional)
Call POST /v/equity.vesting.vest with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vesting.vest.
Createequity.vestingTerm.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Reusable term template (distinct from kernel-owned equity_vesting_event). Fence parent entity in ctx.workspace_id.
Call POST /v/equity.vestingTerm.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vestingTerm.create.
Deleteequity.vestingTerm.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.vestingTerm.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vestingTerm.delete.
Updateequity.vestingTerm.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.vestingTerm.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.vestingTerm.update.
Createequity.warrant.create
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence parent entity in ctx.workspace_id.
Call POST /v/equity.warrant.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.warrant.create.
Deleteequity.warrant.delete
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.warrant.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.warrant.delete.
Updateequity.warrant.update
| Property | Value |
|---|---|
| Capability | equity.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Generic patch + exercise flip (status/exerciseDate). Fence via parent entity in ctx.workspace_id.
Call POST /v/equity.warrant.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool equity.warrant.update.