Problem
Deploy manifests exist today:- EVM
proof-forge-deploy.jsonrecords chain profiles and constructor args. - Solana deploy packages include program keypairs and upgrade authority.
- EVM: contracts are immutable by default; upgradeability requires a proxy pattern that the compiler cannot hide.
- Solana: programs have an upgrade authority that can be revoked.
- NEAR: code can be redeployed to the same account.
- Aleo: programs can declare
@noupgrade.
Summary
Add anupgradePolicy intent to the contract model and lower it honestly per
chain:
For signing, ProofForge emits unsigned transactions and manifests only.
Key custody stays outside the compiler in wallets, KMS, or CI secrets. Live
gates document their throwaway-key convention.
Upgrade Policy Intent
The intent lives in the contract/module metadata, not in target-specific flags. Example:keyRef is a logical name resolved by the signer at deployment time, not a
raw private key. This keeps the compiler key-agnostic.
Lowering Rules
EVM
immutable: emit bytecode directly; no proxy.authority(keyRef): rejected in v0. EVM proxy patterns (EIP-1967, UUPS, transparent proxy) change the ABI surface, storage layout guarantees, and deployment flow. Supporting them requires a separate RFC that specifies which proxy pattern, how storage collision is avoided, and how upgrades are validated.governance(ref): rejected in v0.
Solana
immutable: deploy with the upgrade authority set to a known burn address (e.g.11111111111111111111111111111111) so the program is effectively immutable.authority(keyRef): deploy with the upgrade authority set to the public key resolved fromkeyRefat signing time.governance(ref): rejected in v0.
NEAR
immutable: record in deploy metadata that the account key is the only upgrade path; no code changes.authority(keyRef): record that the account key identified bykeyRefis the upgrade authority.governance(ref): rejected in v0.
Aleo
immutable: emit@noupgradein the Leo source.- Other policies: rejected.
Psy DPN
immutable: default; circuits are immutable.- Other policies: rejected.
Signing Boundary
ProofForge never touches private keys. It produces:- Unsigned transaction payloads (where applicable).
- Deployment manifests with placeholders for signatures and addresses.
- Key-reference metadata (
key_ref) that a signer resolves.
- Local development: Foundry
cast send, Solana CLI,near-cli, Leo wallet. - CI: environment-injected secrets used by thin wrapper scripts.
- Cloud platform: KMS-backed signers (future).
- Which key references they use.
- That keys are throwaway/testnet-only.
- How to rotate or revoke them.
Manifest Extension
proof-forge-deploy.json gains an upgradePolicy field:
signingBoundary:
Acceptance Criteria
immutableis supported and documented for all Tier-0 targets.authority(keyRef)is supported for Solana and NEAR.- Unsupported policies produce a compile-time diagnostic, not a silent divergence.
- Live-gate documentation states the throwaway-key convention.
Milestones
- M1: Add
upgradePolicyto the contract intent model and reject unsupported combinations. - M2: Implement lowering for EVM
immutable, Solanaimmutable/authority, and NEARimmutable/authority. - M3: Update deploy manifests with
upgradePolicyandsigningfields. - M4: Document live-gate key conventions and add a CI check that no private key is committed.
Non-goals
- This RFC does not implement proxy patterns on EVM.
- It does not implement on-chain governance.
- It does not provide a key management service.
Related
- RFC 0001: cloud platform and key management open question.
- RFC 0002: target profiles and artifact kinds.
- RFC 0012: deploy manifest schema versioning.
- Workstream 32: deployment lifecycle, upgrades, and signing.