> For the complete documentation index, see [llms.txt](https://docs.bitsafe.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bitsafe.finance/decentralization-manager/operations-and-reference/membership-and-governance-changes.md).

# Membership and governance changes

[Decentralized Party and Canton topology](/decentralization-manager/concepts-and-development/decentralized-party-and-canton-topology.md)

[Decentralization Manager governance lifecycle](/decentralization-manager/concepts-and-development/governance-lifecycle.md)

### Goal

Change the membership or approval rules of an existing Decentralized Party without losing access to active contract state or leaving governance and Canton topology inconsistent.

### Understand the four sets

Decentralization Manager tracks related but separate sets. A change to one set does not automatically change the others.

| Set                            | What it controls                                                     | Change surface                                          |
| ------------------------------ | -------------------------------------------------------------------- | ------------------------------------------------------- |
| Governance members             | Daml parties that can confirm governed actions                       | `GovernanceRules` self-management action                |
| Namespace owners               | Keys that authorize decentralized namespace topology changes         | Add-member, kick, or change-threshold topology workflow |
| Hosting participants           | Canton participants included in the `PartyToParticipant` mapping     | Add-member or kick topology workflow                    |
| Decentralization Manager peers | Application instances allowed to coordinate over the Noise transport | Peer configuration                                      |

An authorized additional proposer is separate again. A proposer can submit a domain action but does not gain a governance vote.

{% hint style="info" %}
**Do not treat a combined membership change as one atomic action.** Adding or removing a governance member changes a Daml contract. Adding or removing a hosting participant changes Canton topology. Plan and verify each change separately.
{% endhint %}

### Before you begin

* Confirm every participating Decentralization Manager instance is healthy and mutually reachable.
* Confirm the joining participant is already configured as a peer before an add-member workflow.
* Record the current governance members, governance threshold, additional proposers, namespace owners, hosting participants, topology threshold, topology serials, and peer records.
* Record all pending governance actions and active Decentralization Manager workflows.
* Confirm the final governance threshold and final topology threshold independently.
* Confirm the remaining members can satisfy both final thresholds after a removal.
* Confirm the joining participant has the required packages, Canton access, storage, authentication, and operator support.
* Back up Decentralization Manager persistent data and follow the approved Canton backup procedure.
* Test the exact change on DevNet with the same release and Canton version.
* Schedule a maintenance window. Do not start another membership or topology workflow on a participating node during the change.

### Choose the change

<table data-search="false"><thead><tr><th>Goal</th><th>Required operation</th><th>Does not do</th></tr></thead><tbody><tr><td>Add a voter only</td><td>Add a <code>GovernanceRules</code> member</td><td>Does not host the Decentralized Party on another participant</td></tr><tr><td>Add a host and namespace owner</td><td>Run the add-member topology workflow</td><td>Does not add the new member party to <code>GovernanceRules</code></td></tr><tr><td>Remove a voter only</td><td>Remove a <code>GovernanceRules</code> member</td><td>Does not remove a hosting participant or peer record</td></tr><tr><td>Remove a host and namespace owner</td><td>Run the kick topology workflow</td><td>Does not remove the member party from <code>GovernanceRules</code></td></tr><tr><td>Change topology approvals</td><td>Run the change-threshold workflow</td><td>Does not change the Daml governance threshold</td></tr><tr><td>Change governance approvals</td><td>Execute a <code>core_self</code> threshold action</td><td>Does not change the topology signing threshold</td></tr><tr><td>Grant or revoke propose-only access</td><td>Execute an additional-proposer <code>core_self</code> action</td><td>Does not grant a vote or topology authority</td></tr></tbody></table>

### Recommended ordering

Use this conservative sequence unless the supported release documents a different procedure.

#### Add a participant and a governance member

1. Complete the add-member topology workflow.
2. Verify the new participant is active and has the required active contract state.
3. Add the new member party to `GovernanceRules`.
4. Verify the new member can read, confirm, and execute only the intended actions.

This order avoids granting a vote before the new participant can observe the state needed to review that vote.

#### Remove a participant and a governance member

1. Complete or cancel pending governance actions.
2. Remove the departing member party from `GovernanceRules` and set a valid final governance threshold.
3. Verify the remaining members can govern the application.
4. Run the kick topology workflow with a valid final topology threshold.
5. Revoke peer, identity-provider, Canton, and operational access that is no longer required.

This order avoids removing the participant that may still be needed to approve the governance change.

### Add a hosting participant

#### 1. Start the workflow

In the web interface, open the Decentralized Party and select **Add Member**. Select a configured peer and set the topology threshold that should apply after the add.

For the API path:

```bash
curl -X POST "$BASE_URL/add-party" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "decentralized_party_id": "joint-party::1220...",
    "new_participant_id": "participant-d::1220...",
    "new_threshold": 3,
    "previous_threshold": 2
  }'
```

The response includes an `instance_name`. Use that identifier when inspecting the workflow feed or addressing the specific run.

#### 2. Review and accept invitations

Existing participants and the joining participant review the Decentralized Party, proposed participant set, and threshold before accepting the workflow invitation.

#### 3. Let the workflow complete

At the reviewed commit, the workflow:

1. Generates local keys for the joining participant.
2. Creates updated decentralized namespace and `PartyToParticipant` proposals.
3. Collects the required owner signatures.
4. Submits the topology changes with the new participant marked as onboarding.
5. Exports the party's Active Contract Set from the coordinator.
6. Imports the snapshot on the joining participant when active contracts exist.
7. Clears the onboarding marker after the import succeeds.

The reviewed implementation uses Canton 3.4 offline party replication. It does not require repair mode or a participant restart. The workflow automates the brief synchronizer disconnect required by the import. Verify the supported Canton version in the compatibility reference.

{% hint style="info" %}
If the workflow stops after topology activation but before Active Contract Set import or onboarding-marker clearance, do not clear the marker manually. Inspect the current workflow, topology, and contract visibility, then follow the Engineering-approved recovery procedure.
{% endhint %}

#### 4. Verify the result

* Confirm the workflow is `completed`.
* Read the decentralized namespace definition from each relevant participant.
* Read the `PartyToParticipant` mapping from each relevant participant.
* Confirm the new participant appears with the intended permission and without the onboarding marker.
* Confirm the intended topology threshold is active.
* Confirm the joining participant can see every active contract required for operation.
* Confirm existing participants still see the same active contracts.
* Confirm the Decentralized Party can complete a low-risk test action.

### Add a governance member

The governance member is a Daml party. It may differ from the Canton participant identifier used by the topology workflow.

Each eligible member confirms the same `core_self` action from its own authorized environment:

```bash
curl -X POST "$BASE_URL/governance/confirm" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "party_id": "joint-party::1220...",
    "rules_contract_id": "<governance-rules-cid>",
    "action": {
      "type": "governance_add_member",
      "member": "member-d::1220...",
      "new_threshold": 3
    },
    "governance_type": "core_self"
  }'
```

After enough eligible confirmations exist, execute the exact same action with the active confirmation contract IDs:

```bash
curl -X POST "$BASE_URL/governance/execute" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "party_id": "joint-party::1220...",
    "rules_contract_id": "<governance-rules-cid>",
    "action": {
      "type": "governance_add_member",
      "member": "member-d::1220...",
      "new_threshold": 3
    },
    "confirmation_cids": ["<confirmation-cid-1>", "<confirmation-cid-2>"],
    "governance_type": "core_self"
  }'
```

Successful self-management execution returns a new `GovernanceRules` contract. Record its contract ID and verify the new member set and threshold.

### Remove a governance member

Use `governance_remove_member` with the final governance threshold:

```json
{
  "type": "governance_remove_member",
  "member": "member-c::1220...",
  "new_threshold": 2
}
```

Confirm and execute it through the same `core_self` flow. Verify the new rules contract before changing topology.

### Remove a hosting participant

#### 1. Start the workflow

In the web interface, select the participant and choose **Kick Participant**. Confirm the namespace owner key that will be removed and set the topology threshold for the remaining owner set.

For the API path:

```bash
curl -X POST "$BASE_URL/kick" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "decentralized_party_id": "joint-party::1220...",
    "participant_id": "participant-c::1220...",
    "new_threshold": 2,
    "previous_threshold": 3
  }'
```

#### 2. Complete the workflow

The coordinator reads the active namespace and party mappings, creates updated proposals, collects signatures from the remaining owners, and submits the change to Canton.

#### 3. Verify the result

* Confirm the departing namespace owner is absent from the active decentralized namespace definition.
* Confirm the departing participant is absent from the active `PartyToParticipant` mapping.
* Confirm the final topology threshold is valid and active.
* Confirm every remaining participant observes the same topology.
* Confirm remaining governance members can complete a low-risk action.
* Revoke the departing instance's peer record and credentials only after the topology result is confirmed.

{% hint style="info" %}
A topology removal revokes future hosting and signing authority. It does not delete local contract data, logs, backups, or secrets held by the former operator. Handle data cleanup and evidence through the approved offboarding and retention process.
{% endhint %}

### Change a threshold

#### Topology threshold

Use the **Change Threshold** action or call:

```bash
curl -X POST "$BASE_URL/change-threshold" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "decentralized_party_id": "joint-party::1220...",
    "new_threshold": 3,
    "previous_threshold": 2
  }'
```

This reissues the decentralized namespace and party mappings with the new topology threshold. It does not change `GovernanceRules`.

#### Governance threshold

Use a `core_self` action:

```json
{
  "type": "governance_set_threshold",
  "new_threshold": 3
}
```

Confirm and execute the action through the governance lifecycle. Verify the new `GovernanceRules` contract and retain its contract ID.

### Manage additional proposers

Grant propose-only access with:

```json
{
  "type": "governance_add_additional_proposer",
  "additional_proposer": "ops-console::1220..."
}
```

Revoke it with `governance_remove_additional_proposer`. Both are `core_self` actions and require the active governance threshold. Propose-only access does not grant confirmation or execution authority.

### Pending actions and concurrent changes

Complete or cancel pending work before changing membership, proposer authorization, confirmation timeout, or either threshold.

* Do not assume a confirmation collected under the previous rules remains eligible.
* Read the active rules contract again before execution.
* Match confirmations to the exact action or proposal contract.
* If execution returns an ambiguous result, query current contract and topology state before retrying.
* Do not submit a second membership workflow to repair the first until the first workflow's state and topology effects are known.

### Troubleshooting

| Symptom                                    | Check                                                                                                 | Safe response                                                                                                         |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Joining participant is not selectable      | Peer configuration and whether the participant already hosts the party                                | Configure and verify the peer before retrying                                                                         |
| Workflow waits for peers                   | Invitation acceptance, Noise reachability, identity keys, and active workflows                        | Resolve connectivity or decline the invitation. Do not create a duplicate run                                         |
| Topology changed but contracts are missing | Onboarding marker, Active Contract Set export or import, package availability, and synchronizer state | Stop. Preserve the marker and escalate through the approved replication recovery path                                 |
| Removal cannot meet the threshold          | Current owner set, current threshold, available signers, and final threshold                          | Restore signer availability or approve a threshold change before removal                                              |
| Governance action cannot execute           | Active rules contract, member set, action value, expiry, and confirmation contract IDs                | Re-read state. Reconfirm or re-propose only when the current contracts require it                                     |
| Coordinator becomes unavailable            | Workflow instance, current step, invitations, and topology side effects                               | Do not assume another coordinator can continue the same run. Follow the approved cancel, retry, or recovery procedure |

### Expected outcome

The Decentralized Party keeps the same party identifier. Its governance rules, namespace owners, hosting participants, thresholds, and peer access match the approved final state. Every remaining participant observes the same topology and required active contracts.

### Next actions

* Run a low-risk governance action and retain the result record.
* Update the operator inventory, peer records, access controls, backup inventory, and incident contacts.
* Record the before and after governance contract IDs and topology serials.

### Technical sources

* [Architecture at the reviewed commit](https://github.com/DLC-link/decentralization-manager/blob/76d7156c85e605abc008e5fadf8aaa97f4706471/docs/ARCHITECTURE.md)
* [Repository README at the reviewed commit](https://github.com/DLC-link/decentralization-manager/blob/76d7156c85e605abc008e5fadf8aaa97f4706471/README.md)
* [Use cases at the reviewed commit](https://github.com/DLC-link/decentralization-manager/blob/76d7156c85e605abc008e5fadf8aaa97f4706471/docs/USE_CASES.md)
* [Party replication notes at the reviewed commit](https://github.com/DLC-link/decentralization-manager/blob/76d7156c85e605abc008e5fadf8aaa97f4706471/docs/CANTON_PARTY_REPLICATION.md)
* [API request types at the reviewed commit](https://github.com/DLC-link/decentralization-manager/blob/76d7156c85e605abc008e5fadf8aaa97f4706471/crates/common/src/api.rs)

### Next step

👉 **Protect the changed mesh:** [Decentralization Manager backup, recovery, and mesh upgrades](/decentralization-manager/operations-and-reference/backup-recovery-and-upgrades.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.bitsafe.finance/decentralization-manager/operations-and-reference/membership-and-governance-changes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
