The link.* family (3 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.
Createlink.create
| Property | Value |
|---|---|
| Capability | party.link.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
One PartyRelationship edge. The DB CHECKs enforce no-self-edge + share range; the partial-unique on ACTIVE rejects a duplicate live (from,to,role) edge (a resigned/INACTIVE edge is kept for audit).
Input
| Field | Type | Required | Description |
|---|---|---|---|
fromPartyId | string | yes | |
toPartyId | string | yes | |
role | string | yes | e.g. AUTHORIZED_SIGNATORY |
appointedAt | string | no | ISO date |
Call POST /v/link.create with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Querylink.query
| Property | Value |
|---|---|
| Capability | party.link.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Returns the typed edges IDOR-scoped to the workspace.
Input { partyId, direction?: from|to|both, role?, status? } (fields ending in ? are optional)
Call POST /v/link.query with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Updatelink.update
| Property | Value |
|---|---|
| Capability | party.link.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
The governance/financial-relation
admin gate (catalogue L191): the agent allow-list is related_to/mentions only, so a governance edge
(DIRECTOR/SHAREHOLDER/UBO/…) is mutated ONLY through this ADMIN-tiered verb (the tier gate at dispatch
enforces it - the handler does not re-check the tier).
A resigned director is INACTIVE-NOT-DELETED (INV-3 status-not-timestamp + INV-8 audit-retention): the
edge row is RETAINED for the statutory register; status=INACTIVE is the resignation, and setting
resignedAt is the dated record. Setting status to INACTIVE WITHOUT a resignedAt is allowed (a status
flip with no recorded date); the DB party_rel_dates CHECK enforces resignedAt >= appointedAt. RLS-
scoped with an explicit workspace_id = $ predicate; an edge in another workspace reads back not-found.
At least one mutable field must be supplied (an empty update is a no-op-shaped BadInput, never a silent
touch).
Input { id, status?, sharePercentage?, resignedAt? } (fields ending in ? are optional)
Call POST /v/link.update with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.