From 2efa376bb0bb3002343fc7d55901bc194a59430f Mon Sep 17 00:00:00 2001 From: Leopold Joy Date: Thu, 20 Aug 2026 02:54:56 +0100 Subject: [PATCH 1/4] fix(active-evm): require network-scoped address artifacts Co-authored-by: OpenCode --- AGENTS.md | 9 ++++++++- active/evm/script/common/README.md | 11 +++++++---- .../verifier-update/DeployAggregateVerifier.s.sol | 2 +- .../common/verifier-update/UpdateVerifierHashes.s.sol | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f42c2567..d3f985cb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,4 +1,11 @@ -This is a repo of onchain operational tasks. Each network has its own directory with each individual task as a sub-directory. +This is a repo of onchain operational tasks. Active EVM tasks live under `active/evm/tasks/`; one task directory may contain configurations for multiple networks under `config//`. + +Active EVM task lifecycle: + +- A task directory represents one logical operation and carries its shared Makefile, scripts, and facilitator guide across network rollouts. Add another `config//` to the existing task instead of creating a duplicate task solely to change networks. +- Keep a task under `active/evm/tasks/` while any currently intended network rollout remains pending. Do not run `make archive-task` between network rollouts; archive only after every intended network configuration is executed or canceled and its final artifacts are committed. +- Treat `archive/evm/` as historical. Do not edit or execute an archived task in place. If the same operation later needs another network rollout, restore the entire task directory to `active/evm/tasks/` before adding that network. +- Store network-specific deployment address artifacts such as `addresses.json` under `config//`. Keep Forge broadcast records at task scope under `records/`; Foundry separates them by script and chain ID. Task writing: diff --git a/active/evm/script/common/README.md b/active/evm/script/common/README.md index df185461..d7db9255 100644 --- a/active/evm/script/common/README.md +++ b/active/evm/script/common/README.md @@ -7,7 +7,8 @@ Reusable EVM operation scripts live here. A script belongs in this directory whe Reference common scripts by explicit Forge target path from `active/evm`: ```bash -mise exec -- forge script --rpc-url "$L1_RPC_URL" script/common/verifier-update/UpdateVerifierHashes.s.sol:UpdateVerifierHashes +ADDRESSES_JSON="tasks//config//addresses.json" \ + mise exec -- forge script --rpc-url "$L1_RPC_URL" script/common/verifier-update/UpdateVerifierHashes.s.sol:UpdateVerifierHashes ``` In Makefiles, prefer the same explicit path: @@ -22,8 +23,8 @@ This keeps validation JSON portable and avoids ambiguity when different files de | Folder | Script | Purpose | Required task files | | --- | --- | --- | --- | -| `verifier-update/` | `DeployAggregateVerifier.s.sol` | Deploys a replacement `AggregateVerifier` by copying immutable constructor inputs from the live implementation and replacing verifier hashes. | `tasks//config//.env`, `tasks//config//network.env`, `ADDRESSES_JSON` output path | -| `verifier-update/` | `UpdateVerifierHashes.s.sol` | Multisig script that updates `DisputeGameFactory.gameImpls(gameType)` to a deployed `AggregateVerifier`. | `ADDRESSES_JSON` pointing at a JSON file with `aggregateVerifier` | +| `verifier-update/` | `DeployAggregateVerifier.s.sol` | Deploys a replacement `AggregateVerifier` by copying immutable constructor inputs from the live implementation and replacing verifier hashes. | `tasks//config//.env`, `ADDRESSES_JSON=tasks//config//addresses.json` | +| `verifier-update/` | `UpdateVerifierHashes.s.sol` | Multisig script that updates `DisputeGameFactory.gameImpls(gameType)` to a deployed `AggregateVerifier`. | `ADDRESSES_JSON=tasks//config//addresses.json` containing `aggregateVerifier` | | `funding/` | `Fund.s.sol` | Sends native token from a Safe to recipients listed in `funding.json`. | `funding.json` | | `gas/` | `IncreaseEip1559ElasticityAndIncreaseGasLimit.s.sol` | Updates gas limit, EIP-1559 elasticity, and DA footprint gas scalar on `SystemConfig`. | config env values | | `bridge/` | `PauseBridge.s.sol` | Deposits an L2 transaction through the portal to pause or unpause the L2 bridge. | config env values | @@ -34,6 +35,8 @@ This keeps validation JSON portable and avoids ambiguity when different files de ## Adding Scripts -Use exact Solidity pragmas based on the contracts the script imports; preserve a script's original exact pragma when moving it here. Load config from environment variables into immutable variables where possible. Keep task-specific values in `tasks//config//.env`, `tasks//config//network.env`, or task-local JSON files rather than hardcoding them in common scripts. +Use exact Solidity pragmas based on the contracts they import; preserve a script's original exact pragma when moving it here. Load config from environment variables into immutable variables where possible. Keep scalar task-specific values in `tasks//config//.env`, or use the script-documented JSON input when structured data is required, rather than hardcoding values in common scripts. + +Network-specific deployment address artifacts belong under `tasks//config//addresses.json`. Common verifier scripts must require `ADDRESSES_JSON` explicitly instead of defaulting to the shared project or task root. Forge broadcast records remain at task scope because Foundry separates them by script and chain ID. If a script needs task-specific behavior, prefer a small task-local wrapper or Makefile target that passes environment variables into a common script. Move the underlying Solidity into this directory only when the operation itself is reusable. diff --git a/active/evm/script/common/verifier-update/DeployAggregateVerifier.s.sol b/active/evm/script/common/verifier-update/DeployAggregateVerifier.s.sol index 5f08c228..d8958252 100644 --- a/active/evm/script/common/verifier-update/DeployAggregateVerifier.s.sol +++ b/active/evm/script/common/verifier-update/DeployAggregateVerifier.s.sol @@ -134,7 +134,7 @@ contract DeployAggregateVerifier is Script { string memory root = "root"; string memory json = vm.serializeAddress({objectKey: root, valueKey: "aggregateVerifier", value: aggregateVerifier}); - string memory path = vm.envOr("ADDRESSES_JSON", string("addresses.json")); + string memory path = vm.envString("ADDRESSES_JSON"); vm.writeJson({json: json, path: path}); } } diff --git a/active/evm/script/common/verifier-update/UpdateVerifierHashes.s.sol b/active/evm/script/common/verifier-update/UpdateVerifierHashes.s.sol index 343522e4..be68f9e4 100644 --- a/active/evm/script/common/verifier-update/UpdateVerifierHashes.s.sol +++ b/active/evm/script/common/verifier-update/UpdateVerifierHashes.s.sol @@ -43,7 +43,7 @@ contract UpdateVerifierHashes is MultisigScript { currentAggregateVerifier = IDisputeGameFactoryAdmin(disputeGameFactoryProxyEnv).gameImpls(gameTypeEnv); - string memory path = vm.envOr("ADDRESSES_JSON", string("addresses.json")); + string memory path = vm.envString("ADDRESSES_JSON"); string memory json = vm.readFile(path); nextAggregateVerifier = vm.parseJsonAddress({json: json, key: ".aggregateVerifier"}); From 2d2ae520deb9ea20d5c69c756c2b85a320f3bf95 Mon Sep 17 00:00:00 2001 From: Leopold Joy Date: Thu, 20 Aug 2026 03:20:41 +0100 Subject: [PATCH 2/4] docs(active-evm): define multi-network task workflow Co-authored-by: OpenCode --- AGENTS.md | 2 ++ README.md | 47 +++++++++++++++++++---------------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d3f985cb..e41b470f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,6 +3,8 @@ This is a repo of onchain operational tasks. Active EVM tasks live under `active Active EVM task lifecycle: - A task directory represents one logical operation and carries its shared Makefile, scripts, and facilitator guide across network rollouts. Add another `config//` to the existing task instead of creating a duplicate task solely to change networks. +- A task with multiple network configurations must require `TASK_NETWORK` on each `make` command line. Do not set a mutable default or rely on an exported environment value; use `make TASK_NETWORK= ` so the selected network is visible at every invocation. +- Keep the task-root `FACILITATOR.md` network-agnostic. Put addresses, chain IDs, validation policy, rollback anchors, signer identities, and other network-specific operational notes in `config//FACILITATOR.md`. - Keep a task under `active/evm/tasks/` while any currently intended network rollout remains pending. Do not run `make archive-task` between network rollouts; archive only after every intended network configuration is executed or canceled and its final artifacts are committed. - Treat `archive/evm/` as historical. Do not edit or execute an archived task in place. If the same operation later needs another network rollout, restore the entire task directory to `active/evm/tasks/` before adding that network. - Store network-specific deployment address artifacts such as `addresses.json` under `config//`. Keep Forge broadcast records at task scope under `records/`; Foundry separates them by script and chain ID. diff --git a/README.md b/README.md index 75b9814b..ea0e4c88 100644 --- a/README.md +++ b/README.md @@ -105,47 +105,38 @@ All address variables are prefixed with `export` so they are available to child ## Directory structure -Active EVM tasks live under `active/evm/`, which is a single shared Foundry -project rather than a standalone project per task. A single `active/evm/Makefile` -selects the active task via `TASK_ID` / `TASK_NETWORK`, reusable operation -scripts are shared across tasks under `script/common//`, and each task -directory holds only its own config, docs, and (per-network) validations and -signatures: +Active EVM tasks share the Foundry project under `active/evm/`, while each task owns its Makefile, facilitator guide, network configurations, signatures, and execution records. Reusable operation scripts live under `script/common//`; one-off scripts stay with their task. ```text active/evm/ -├── Makefile # shared; selects the task via TASK_ID / TASK_NETWORK -├── foundry.toml # shared Foundry config (base-contracts v8.2.1) +├── foundry.toml # shared Foundry configuration +├── lib/ # generated shared dependencies; not committed ├── script/ │ └── common/ # reusable scripts, shared across tasks │ └── / # bridge, funding, gas, ownership, safe, superchain, verifier-update └── tasks/ └── / - ├── FACILITATOR.md + ├── Makefile # task dependencies, validation, approvals, and execution + ├── FACILITATOR.md # network-agnostic facilitator procedure + ├── script/ # optional one-off task scripts ├── config/ │ └── / - │ ├── .env # task inputs + BASE_CONTRACTS_COMMIT + RECORD_STATE_DIFF - │ ├── network.env # RPC, chain ids, Safe/contract addresses - │ ├── README.md # status + description (parsed by the signer tool) + │ ├── .env # network-specific task inputs + BASE_CONTRACTS_COMMIT + │ ├── FACILITATOR.md # network-specific operational notes + │ ├── addresses.json # generated network-specific deployment addresses + │ ├── README.md # status + description parsed by the signer tool │ └── validations/ # generated per-signer validation JSON - └── signatures/ - └── / # task-origin signatures (when required) + ├── signatures/ + │ └── / # task-origin signatures when required + └── records/ + └──