opbox

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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

Reverse split (1

): divide every holding in the class by ratio (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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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:

  1. 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).
  2. ALLOCATE a non-overlapping monotonic share-number range under SELECT…FOR UPDATE on the counter.
  3. 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classDestructive - autonomy L3
Min. permissionOwner
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
High-risk oversightHuman 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityVertical (MCP tier 3)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityequity.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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.