# Vaultfire V3 — Multisig + Timelock Deployment Plan

## Objective
Every V3 admin-controlled contract must transfer ownership to a fresh
`MultisigGovernanceV3` instance at deployment. No EOA may ever own a V3
production contract. This document is the ordered runbook.

## Admin transaction transport (mandatory)

The ownership contract—not a Safe and not an EOA—calls administered targets.
For any owner-only factory or module action:

1. an existing signer submits `MultisigGovernanceV3.propose(target, value, calldata)`;
2. three distinct current signers call `confirm(proposalId)`;
3. after the proposal event's `eta` and the immutable 24-hour floor, a current
   signer calls `execute(proposalId)`.

Do not submit a transaction directly to an owned factory/module. It will fail
under the intended model and is not an approved fallback. A Safe may participate
only as one signer, in which case it sends the proposal/confirmation/execution
call to `MultisigGovernanceV3`; it is never described as the owner. The guardian
is pause-only and cannot propose, confirm, execute, or change configuration.

## Signer set (must be filled before Step 1)
- Signer 1: (hardware wallet, name/role, physical location)
- Signer 2: (hardware wallet, name/role, physical location)
- Signer 3: (hardware wallet, name/role, physical location)
- Signer 4: (hardware wallet, name/role, physical location)
- Signer 5: (hardware wallet, name/role, physical location)
- Threshold: 3-of-5.
- Guardian (separate hot key, pause-only): (name/role)
- Timelock: 86 400 seconds (24 h).

Do NOT proceed if any row above is blank.

## Deployment order (Base only, capped pilot)

1. Deploy
   `MultisigGovernanceV3(signers, threshold=3, timelock=86400,
   minimumTimelock=86400, guardian, guardianRotationDelay,
   immutableGuardianPauseTargets)`.
   - Verify: signer addresses are unique and nonzero; no signer is the
     guardian; `threshold()==3`; `timelockSeconds()==86400`;
     `minimumTimelockSeconds()==86400`; `guardian()` matches; and every
     append-only pause target is the intended V3 contract and may be added only by a confirmed, timelocked governance self-call.
   - Set a nonzero guardian rotation delay appropriate to the incident
     response process. A pending guardian cannot act until the cooldown has
     elapsed and that key calls `acceptGuardian()`.
2. For the bonds-only pilot, do not deploy `RewardProgramV3` or any identity,
   validation, escrow, pool, vault, evidence, mandate, Solana, cross-chain, or
   x402 surface.
3. Deploy `BasePilotAccessControllerV3(governance=multisig,
   maxGlobalCap=0.40 ether, maxPerPositionCap=0.20 ether)` on Base. It starts
   with `deployEnabled=false` and `writeEnabled=false`; its constructor-pinned
   maximums are the upper bound for every later `setCaps` call.
4. Deploy `ThresholdConsensusV3`, then `DisputeRegistryV3`, each bound to the
   already deployed governance address.
5. Generate the reviewed fresh-deployment package from the finalization-candidate
   bonds-only manifest and deploy `SafeBondFactoryV3` with its four
   immutable-patched expected runtime hashes. The controller code is a
   precondition for the coordinator constructor: a nonzero controller without
   code is rejected.
6. Deploy `PartnershipBondFactoryV3` with the already deployed coordinator,
   governance, consensus, dispute registry, controller, and manifest caps.
7. Deploy `AccountabilityBondFactoryV3` with the already deployed coordinator,
   governance, consensus, dispute registry, controller, and manifest caps.
   `EIP712BaseV3` computes the unchanged EIP-712 domain separator at use time,
   while its inherited version-hash immutable is bound into each child runtime
   identity. The coordinator has four `bytes32` constructor arguments, a
   one-time factory-binding storage configuration, and no proxy-upgrade or
   storage-migration assumption.
8. Multisig proposal:
   `SafeBondFactoryV3.configureFactories(partnershipFactory, accountabilityFactory)`.
   After the 24-hour timelock, execute and verify both `extcodehash` values
   against the coordinator's immutable expectations before deployment enablement.
9. The governed controller sequence follows the verified factory binding:
   `setModule(coordinator,true)`, then `setDesignPartner(partner,true)`, then
   `setCaps(exactManifestGlobal,exactManifestPerPosition)`, then
   `setDeployEnabled(true)`. The requested caps may be lower than the
   constructor-pinned maximums but can never exceed `0.40/0.20 ETH`. Record
   every proposal ID and verified Base transaction hash.
10. Multisig proposal: `SafeBondFactoryV3.setDeployAllowed(true)` after the
   factory binding is verified.
11. Multisig proposal:
   `SafeBondFactoryV3.deployPartnership(designPartner, address(0))`.
   Verify: `PartnershipBondV3Safe.owner()==multisig`.
12. Multisig proposal: `SafeBondFactoryV3.deployAccountability(designPartner)`.
   Verify: `AccountabilityBondV3Safe.owner()==multisig`.
13. Use the child deployment receipts to submit separate governance self-calls
   adding the two actual child pause targets. Verify controller pause coverage
   and both child runtime hashes. Only then may a separate timelocked
   `setWriteEnabled(true)` proposal be considered. It is never part of the
   construction batch.

## Post-deploy verification (before pilot enable)
- `forge inspect --gas` on every deployed address to confirm no unbounded loops (invariant #12).
- Selector scan: no admin selector reachable except via `owner()==multisig`.
- Verify only the Base bonds-only contracts and gates in the finalization
  manifest. No x402, payment, cross-chain, Solana, identity, validation,
  escrow, pool, or vault activation is in this pilot.

## Guardian usage
- Guardian is authorized ONLY to call
  `MultisigGovernanceV3.guardianPause(target)` for a target in the immutable
  constructor allowlist.
- Guardian cannot unpause, execute proposals, change signers, rotate itself,
  alter the target allowlist, enable the pilot controller, or move funds.
- To rotate the guardian, execute a timelocked
  `proposeGuardian(newGuardian)` proposal, wait the configured cooldown, then
  have exactly `newGuardian` call `acceptGuardian()`. A bad pending address can
  be cancelled only through a timelocked `cancelGuardianRotation()` proposal.
- Any guardian pause triggers a mandatory post-incident review.

## Timelock override for emergency unpause
- Emergency unpause requires a full multisig proposal + 24 h timelock.
- No shorter path exists on purpose.

## Rollback path
- If ANY step above fails verification, halt. Do not proceed.
- Contracts already deployed remain owner-controlled by multisig but with
  `deployAllowed=false` on `SafeBondFactoryV3`, so no new pilot bonds can be
  created until the fault is resolved.
