Every proposal and governor command requires
--vault (CLI ≥ 0.71.1). Each vault has its own governor (a BeaconProxy deployed at creation), so the CLI resolves the target governor on the fly via factory.governorOf(vault). Proposal IDs are scoped per vault. The one exception is sherwood governor set-protocol-fee, which targets the protocol-wide ProtocolConfig and takes no --vault.sherwood proposal create
Agent submits a strategy proposal with pre-committed execute + settle calls.
No per-proposal fee.
proposal create does not take a fee flag — the proposal snapshots the vault’s agentFeeBps at propose time, which the vault owner sets via sherwood fund set-agent-fee. At settlement the governor uses that snapshot, clamped to its maxPerformanceFeeBps (default 5%, capped at 15% by the vault).Metadata pinning (IPFS via Pinata)
When--metadata-uri is not provided, the CLI builds a metadata JSON from --name and --description, pins it to IPFS via the Pinata API, and uses the resulting ipfs:// URI. This follows the same pattern as fund create.
- Pin:
POST https://api.pinata.cloud/pinning/pinJSONToIPFSwithPINATA_API_KEYfrom env - Resolve: Metadata displayed in the dashboard via
PINATA_GATEWAY(default:sherwood.mypinata.cloud) - Schema:
{ name, description, proposer, vault, strategyDuration, createdAt }
Call JSON format
Each calls file is an array ofCall objects:
Flow
- Validate caller is a registered agent on the vault
- Parse and validate calls JSON
- If no
--metadata-uri: build metadata JSON, pin to IPFS via Pinata, getipfs://Qm...URI - Display proposal summary for review (name, duration, call count, metadata URI)
- Call
governor.propose(vault, strategy, metadataURI, strategyDuration, envelope, executeCalls, executeCallCaps, settlementCalls, settlementCallCaps, coProposers)—strategyis the clone that holds on-venue positions (passaddress(0)for a queue-only proposal);envelopeis theRiskEnvelope(maxCapital,maxDrawdownBps);executeCallCapsandsettlementCallCapsare parallel per-call gross-outflow caps in the vault asset (oneuint256per corresponding call; each batch’s sum must be<= envelope.maxCapital, checked independently);coProposersis the optional collaborative-proposal co-signer list. The agent fee is not a proposal argument — the governor snapshots the vault’sagentFeeBpsonto the proposal at propose time (clamped tomaxPerformanceFeeBpsat settlement) - Print proposalId and voting period end time
sherwood fund set-agent-fee
Set the vault’s agent performance fee. Vault owner only. This is a vault property — the governor snapshots it onto each proposal at propose time (immutable for that proposal), then clamps the snapshot to maxPerformanceFeeBps at settlement.
- Proposal state is
Executed(other states have their own recovery path — see below) - Strategy duration has elapsed (
emergencySettlerequires it) - The proposal is currently the vault’s active proposal
- Caller is the vault owner
governor.emergencySettle(id, fallbackCalls) with a single no-op asset.balanceOf(vault) fallback. The governor’s _tryPrecommittedThenFallback catches the revert from the stuck pre-committed calls and runs the no-op instead. No funds move. The proposal transitions to Settled, the vault unlocks, and depositors can then vault redeem.
Recovery paths for other states:
sherwood governor info
Display a vault’s governor address and parameters. Resolves the governor via factory.governorOf(vault).
sherwood governor set-protocol-fee (ProtocolConfig)
The protocol fee moved off the per-vault governor to the protocol-wide ProtocolConfig (resolved via factory.protocolConfig()), so this one takes no --vault and is protocol-owner only (the protocol multisig), not the vault owner. Max 1000 bps (10%).
UX Considerations
- Duration format: Accept human-readable durations (
7d,24h,1h) in addition to raw seconds - Call encoding: For common actions (swaps through the vault’s swap adapter, ERC-20 approvals), the CLI provides built-in call builders so agents don’t need to manually encode calldata
- Metadata via Pinata:
proposal createpins metadata to IPFS usingPINATA_API_KEY(same env var used byfund create). Dashboard resolves metadata viaPINATA_GATEWAY(sherwood.mypinata.cloud). If the agent provides--metadata-uridirectly, pinning is skipped - Vote weight display: Shows the user’s voting power before they vote, so they understand their influence
- Settlement routing: Auto-detects the correct settlement path based on caller identity and timing