Context
Split out of #875. This is an operational task, not engineering — there is no contract change to make.
contracts/reputation/src/admin.rs stores a single Address. A Stellar account configured with M-of-N signers is an Address, and require_auth() delegates threshold enforcement to the host. So multisig governance needs no new code: it needs a real multisig account to exist and the admin role to be handed to it.
Everything else is already in place:
docs/GOVERNANCE.md is a complete runbook — target configuration (N=5, M=3), literal stellar account set-options and stellar contract invoke commands, signer-change governance, emergency removal
contracts/reputation/tests/multisig.rs tests the handover, including that the old admin can no longer register anchors afterward
lib/oracle/read.ts::getOracleGovernance / deriveGovernance read the configuration back on chain
scripts/verify-oracle-read.mts already emits ::warning:: when authoritiesSeparated is false
What is actually required
- Identify and confirm ≥3 signers (the M in M-of-N) who will hold real keys
- Create the multisig account and set weights/thresholds per
docs/GOVERNANCE.md
propose_admin(multisig) from the current admin, then accept_admin() from the multisig
- Verify via
getOracleGovernance that the on-chain admin is the multisig and authoritiesSeparated is true
- Record the signer set and the transaction hashes in
docs/GOVERNANCE.md
Blocked on
People, not code. This cannot proceed until the signers are named and hold keys.
Do the upgrade-admin rotation (#963) first — handing the main admin to a multisig while the upgrade admin remains a single unchangeable key moves the custody problem rather than solving it.
Context
Split out of #875. This is an operational task, not engineering — there is no contract change to make.
contracts/reputation/src/admin.rsstores a singleAddress. A Stellar account configured with M-of-N signers is anAddress, andrequire_auth()delegates threshold enforcement to the host. So multisig governance needs no new code: it needs a real multisig account to exist and the admin role to be handed to it.Everything else is already in place:
docs/GOVERNANCE.mdis a complete runbook — target configuration (N=5, M=3), literalstellar account set-optionsandstellar contract invokecommands, signer-change governance, emergency removalcontracts/reputation/tests/multisig.rstests the handover, including that the old admin can no longer register anchors afterwardlib/oracle/read.ts::getOracleGovernance/deriveGovernanceread the configuration back on chainscripts/verify-oracle-read.mtsalready emits::warning::whenauthoritiesSeparatedis falseWhat is actually required
docs/GOVERNANCE.mdpropose_admin(multisig)from the current admin, thenaccept_admin()from the multisiggetOracleGovernancethat the on-chain admin is the multisig andauthoritiesSeparatedis truedocs/GOVERNANCE.mdBlocked on
People, not code. This cannot proceed until the signers are named and hold keys.
Do the upgrade-admin rotation (#963) first — handing the main admin to a multisig while the upgrade admin remains a single unchangeable key moves the custody problem rather than solving it.