Skip to content

feat: contract ops reorg signing process#182

Open
0xth4nh wants to merge 8 commits into
contract-ops-reorg-task-origin-verificationfrom
contract-ops-reorg-signing-process
Open

feat: contract ops reorg signing process#182
0xth4nh wants to merge 8 commits into
contract-ops-reorg-task-origin-verificationfrom
contract-ops-reorg-signing-process

Conversation

@0xth4nh

@0xth4nh 0xth4nh commented Jun 28, 2026

Copy link
Copy Markdown

Summary

This updates the signing process for the new Contract Ops active EVM task layout.

The signer UI now discovers active EVM task folders and keeps task, network, and signer profile selection explicit:

  • EVM root: active/evm
  • task folders: active/evm/tasks/<task-id>
  • validation configs: active/evm/tasks/<task-id>/config/<network>/validations
  • task-origin signatures: active/evm/tasks/<task-id>/config/<network>/signatures

Stacked on #181.

What changed

Task discovery

  • Removed old root-level network/task discovery from the signing flow.
  • Added discovery for active task folders under active/evm/tasks/<task-id>.
  • getUpgradeOptions(network) now returns active tasks that have validation configs for the selected network.
  • Task display metadata is read from active/evm/tasks/<task-id>/config/<network>/README.md, active/evm/tasks/<task-id>/README.md, or active/evm/README.md when present.

Signer flow

  • Added an explicit network selection step after task selection.
  • The signer flow is now: select task, select network, select user profile, review/validate, Ledger sign, confirmation.
  • The task list groups ready-to-sign network configs by task, then the network step shows the networks available for that selected task.
  • After a network is selected, the app uses that network's own task metadata instead of keeping the first grouped network's metadata.
  • upgradeId remains part of the app contract because multiple active tasks can exist at the same time.

API changes

  • /api/upgrades?readyToSign=true returns ready-to-sign active task/network pairs.
  • /api/upgrade-config accepts network and upgradeId.
  • /api/install-deps accepts network and upgradeId, verifies the selected task exists, and runs make deps from active/evm.
  • Ready-to-sign task results are sorted by date and task id.

Docs

  • Updated README examples to document the active/evm/tasks/<task-id>/config/<network> layout.
  • Updated signing flow documentation to describe task-first and network-second selection.
  • Updated dependency installation and validation config examples for the active EVM layout.

Tests

  • Updated route and deployment tests for the active task layout.
  • Added coverage for multiple active task folders.
  • Added coverage that old root-level task directories are no longer discovered.
  • Added coverage for network-specific task metadata selection.

Verification

  • npm test
  • npm run lint
  • npm run build

All checks passed locally.

0xth4nh added a commit that referenced this pull request Jun 28, 2026
- Use shared isSafePathSegment from path-validation in install-deps route
  instead of a duplicated local regex
- Restore dropped id assertion in upgrades route test
- Eliminate double README read in getUpgradeOption by removing redundant
  defaultDate pre-computation (readDeploymentInfoFromReadme already derives
  the date from the content it reads)
- Remove redundant hasTaskLayout guard inside getUpgradeOption; the caller
  getUpgradeOptions already confirms the tasks directory exists before
  invoking this function

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread scripts/genTaskOriginSig.ts Outdated
Comment thread src/lib/deployments.ts Outdated
Comment thread src/app/page.tsx Outdated
Comment thread src/lib/task-selection.ts Outdated
Comment thread src/components/NetworkSelection.tsx Outdated
Comment thread src/app/api/upgrades/route.ts Outdated
Comment thread src/app/api/validate/__tests__/route.test.ts Outdated
Comment thread src/app/page.tsx Outdated
Comment thread src/components/ui/StepIndicator.tsx Outdated
Comment thread README.md Outdated
- **Optional README parsing**: If `<network>/<task>/README.md` exists, the tool may parse it to display status and execution links.
- **Validation configs**: Place config files under `active/evm/tasks/<task-id>/config/<network>/validations/` with concise human-readable names, such as `coinbase-signer.json` or `security-council-signer.json`.
- **Script execution**: Validation commands run from `active/evm/`, so validation `cmd` values should reference scripts relative to that directory.
- **Task origin verification**: Task-origin signatures are verified over `active/evm/`, which is the same directory used for simulation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite .. task origin signatures should be over the network config

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refer to this: #177 (comment)

I think it should be all over active/evm/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree and have already talked to security about this

0xth4nh added a commit that referenced this pull request Jul 6, 2026
- Sign over network config dir instead of active/evm (comment 1)
- Remove network selection step; auto-select from task option (comment 6)
- Delete availableNetworksForTask derived state (comment 7)
- Remove unreachable empty-state branch in NetworkSelection (comment 8)
- Remove options param from readDeploymentInfoFromReadme; preserve folder date for date-prefixed tasks (comments 3, 4)
- Inline and delete getUpgradeForNetwork one-liner (comment 5)
- Revert upgrades sort to by-id (comment 11)
- Remove unnecessary String() cast on upgradeId (comment 10)

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh and others added 6 commits July 6, 2026 20:17
Co-authored-by: Codex <codex-noreply@coinbase.com>
- Use shared isSafePathSegment from path-validation in install-deps route
  instead of a duplicated local regex
- Restore dropped id assertion in upgrades route test
- Eliminate double README read in getUpgradeOption by removing redundant
  defaultDate pre-computation (readDeploymentInfoFromReadme already derives
  the date from the content it reads)
- Remove redundant hasTaskLayout guard inside getUpgradeOption; the caller
  getUpgradeOptions already confirms the tasks directory exists before
  invoking this function

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Test placeholder upgradeIds were renamed to real-looking task names
('2026-06-18-beryl-1') but this was unnecessary. Restored:
- upgrade-config tests: back to 'test'
- validate tests: back to '2025-08-01-upgrade-qux'

The path traversal test values ('foo/bar', '../...') are kept as-is
since they intentionally test those specific characters.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Replace real-looking task IDs (beryl-1, beryl-2, jasper-1) with generic
names (2025-06-04-upgrade-foo, 2025-07-12-upgrade-bar) across test files
and README. Expand config/ tree in README to show multiple networks
(mainnet, zeronet, sepolia).

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
- Sign over network config dir instead of active/evm (comment 1)
- Remove network selection step; auto-select from task option (comment 6)
- Delete availableNetworksForTask derived state (comment 7)
- Remove unreachable empty-state branch in NetworkSelection (comment 8)
- Remove options param from readDeploymentInfoFromReadme; preserve folder date for date-prefixed tasks (comments 3, 4)
- Inline and delete getUpgradeForNetwork one-liner (comment 5)
- Revert upgrades sort to by-id (comment 11)
- Remove unnecessary String() cast on upgradeId (comment 10)

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
…athSegment

- Revert taskOriginDir to scriptPath (active/evm/) matching PR #181
- Revert README signing example to --task-folder active/evm
- Remove isSafePathSegment from install-deps route (removed in PR #181)
- Drop path separator tests from validate route (no longer enforced at route layer)

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@0xth4nh 0xth4nh force-pushed the contract-ops-reorg-signing-process branch from 973cb34 to 64a8d5c Compare July 7, 2026 00:56

@jackchuma jackchuma left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR still seems to be trying to do way too much and still has significant bloat. What are the minimal changes needed to support the new active/evm/ directory structure?

Comment thread src/app/api/install-deps/route.ts Outdated
}

const actualNetwork = network.toLowerCase();
const actualUpgradeId = upgradeId;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we re-assigning upgradeId to actualUpgradeId ?

Comment thread src/app/page.tsx Outdated

const handleUpgradeSelection = (upgrade: Upgrade) => {
const handleUpgradeSelection = (taskOption: TaskOption) => {
const network = taskOption.networks[0];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we selecting the network on behalf of the user? The previous UI showed all ready to sign tasks, regardless of network. We should not change this

Comment thread src/components/NetworkSelection.tsx Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following why any of the diff in this file is necessary

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user doesn't "pick a network". The UI displays all ready-to-sign tasks regardless of network and the user selects one. This is how it was already working so we should not change that

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think this entire component can just be removed

Comment thread src/components/NetworkSummary.tsx Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a NetworkSummary now?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow why any of this file's diff is necessary either

Comment thread src/lib/task-selection.ts Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary

Comment thread README.md Outdated
- **Optional README parsing**: If `<network>/<task>/README.md` exists, the tool may parse it to display status and execution links.
- **Validation configs**: Place config files under `active/evm/tasks/<task-id>/config/<network>/validations/` with concise human-readable names, such as `coinbase-signer.json` or `security-council-signer.json`.
- **Script execution**: Validation commands run from `active/evm/`, so validation `cmd` values should reference scripts relative to that directory.
- **Task origin verification**: Task-origin signatures are verified over `active/evm/`, which is the same directory used for simulation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree and have already talked to security about this

Comment thread src/lib/deployments.ts Outdated
return isDirectory(path.join(root, 'active', 'evm', 'tasks'));
}

export function findContractDeploymentsRoot(startDir: string = process.cwd()): string {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we adding a startDir input param that is never used? Unnecessary diff

Comment thread README.md
- **Validation configs**: Place config files under `active/evm/tasks/<task-id>/config/<network>/validations/` with concise human-readable names, such as `coinbase-signer.json` or `security-council-signer.json`.
- **Script execution**: Validation commands run from `active/evm/`, so validation `cmd` values should reference scripts relative to that directory.
- **Task origin verification**: Task-origin signatures are verified over `active/evm/`, which is the same directory used for simulation.
- **Signature storage**: Store signatures in `active/evm/tasks/<task-id>/config/<network>/signatures/`. The signer tool excludes the nested `signatures/` directory from the signed tarball, so generating signatures does not change the attested payload.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update the signatures location here

0xth4nh and others added 2 commits July 7, 2026 10:27
…ouping

NetworkSelection and NetworkSummary were dead code — exported but never
imported in page.tsx. TaskOption/groupUpgradesByTask was built for an
explicit network-selection step that was never wired up; auto-picking
networks[0] was a silent alphabetically-first bug.

UpgradeSelection now renders Upgrade[] directly, one card per upgrade.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
- Remove actualUpgradeId no-op alias in install-deps route
- Remove startDir param from findContractDeploymentsRoot (no callers pass it)
- Remove deriveDateFromContent and folderHasDate logic (task folders always have date prefix)
- Remove redundant sort in upgrades route (getUpgradeOptions already sorts)
- Revert StepIndicator CSS change (unrelated to this PR)
- Update README: task-origin signatures are over the network config folder, not active/evm

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@0xth4nh 0xth4nh force-pushed the contract-ops-reorg-task-origin-verification branch from f6e330e to d99a7fe Compare July 7, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants