Skip to content

feat: contract ops reorg task-origin verification#181

Merged
0xth4nh merged 20 commits into
mainfrom
contract-ops-reorg-task-origin-verification
Jul 8, 2026
Merged

feat: contract ops reorg task-origin verification#181
0xth4nh merged 20 commits into
mainfrom
contract-ops-reorg-task-origin-verification

Conversation

@0xth4nh

@0xth4nh 0xth4nh commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

This updates task-origin verification for the new Contract Ops active EVM task layout.

The verification path now matches the directory that validation executes:

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

What changed

Task-origin verification

  • Task-origin validation now signs and verifies active/evm, matching the directory used for simulation.
  • Signature files are read from active/evm/tasks/<task-id>/config/<network>/signatures.
  • Nested signatures/ folders are excluded from deterministic tarballs so generated signatures do not alter the signed payload.
  • Deterministic tarballs are created in unique temporary directories and cleaned up after signing or verification.

Validation flow

  • Validation configs are loaded from active/evm/tasks/<task-id>/config/<network>/validations/<user>.json.
  • Simulations run from active/evm, so validation cmd values should be relative to that directory.
  • Validation requests reject unsafe path segments for task ids and validation config names.
  • Validation runs are serialized in-process because the Foundry state-diff script writes a shared stateDiff.json path.
  • State-diff simulation always enables RECORD_STATE_DIFF=true for validation runs.

Docs and scripts

  • Updated task-origin signing examples so the signed payload is active/evm while signatures remain stored per task/network.
  • Updated validation generation help/examples to write configs under the active task layout.

Tests

  • Added coverage for unsafe validation path segments.
  • Added coverage for temporary task-origin tarball paths and cleanup.
  • Updated task-origin signing and validation route tests for the active EVM layout.

Verification

  • npm test
  • npm run lint
  • npm run build

All checks passed locally.

Co-authored-by: Codex <codex-noreply@coinbase.com>
@cb-heimdall

cb-heimdall commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

✅ Heimdall Review Status

Requirement Status More Info
Reviews 1/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

0xth4nh and others added 3 commits June 28, 2026 18:21
The upgradeId was renamed from '2025-08-01-upgrade-qux' to
'2026-06-18-beryl-1' but this was unnecessary — test placeholder
values should remain stable and not track real task names.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace '2025-08-01-upgrade-qux' with '2025-01-01-upgrade-example'
  for a more obviously synthetic test value
- Remove the hardcoded task/network example from genTaskOriginSig printUsage;
  the README and --help flags section already document the usage pattern

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Replace real-looking task name with generic value in path-traversal test.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread __tests__/genTaskOriginSig.test.ts Outdated
Comment thread src/app/api/validate/route.ts Outdated
Comment thread src/lib/path-validation.ts Outdated
Comment thread src/lib/task-origin-validate.ts Outdated
Comment thread src/lib/validation-service.ts
Comment thread src/lib/validation-service.ts Outdated
Comment thread src/app/api/validate/__tests__/route.test.ts Outdated
0xth4nh and others added 8 commits July 6, 2026 14:17
- Move signature dir from tasks/<id>/config/<network>/signatures to
  tasks/<id>/signatures (signatures are not config)
- Drop taskOriginDir from getConfigData return (always equalled scriptPath)
- Remove taskFolderPath alias in validateSigner; pass taskOriginDir directly
- Remove networkConfigDir intermediate var (no longer needed for sig path)
- Rename cleanupCreatedTarball -> assertTarballInTmpDir; drop rm so tarballs
  persist for debugging
- Refactor two identical path-traversal rejection tests to it.each
- Update task-origin-validate.ts comment and genTaskOriginSig.ts help text

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
validation-service.ts already validates at the service layer; the route
check was pure duplication. Removed the guard, its import, and the tests
that were written specifically to cover it.

Generated with Claude Code

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

assertWithinDir resolves and bounds-checks every user-supplied path segment,
so the extra alphanumeric guard was redundant. isSafePathSegment was not
present before this PR; removing it and its definition in path-validation.ts.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Signing active/evm/ (the entire EVM tree) meant any file change anywhere
would invalidate all task signatures. The tarball should cover only the
specific task folder: active/evm/tasks/<task-id>.

taskPath was already computed in getConfigData but not returned; add it
to the return type and thread it through validateUpgrade.

Update README examples to use the concrete active/evm/tasks/<id> path.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 7, 2026
…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>
Comment thread src/lib/task-origin-validate.ts Outdated
Comment thread src/lib/task-origin-validate.ts Outdated
Comment thread src/lib/task-origin-validate.ts Outdated
Comment thread src/lib/task-origin-validate.ts Outdated
0xth4nh and others added 4 commits July 7, 2026 10:14
Move signed task content into config/chain1/ (the network config dir the
tarball is scoped to) and keep cache/ and out/ build artifacts at the task
root, outside the tarball scope. This mirrors the real
active/evm/tasks/[task-id]/config/[network] structure so cache/out are
excluded by directory scope rather than by deleting fixture files.

Tarball content is unchanged (relative paths from the config dir), so the
existing signatures still verify without regeneration.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
Comment thread src/lib/task-origin-validate.ts Fixed
@0xth4nh 0xth4nh force-pushed the contract-ops-reorg-task-origin-verification branch 2 times, most recently from f6e330e to d99a7fe Compare July 7, 2026 16:37
0xth4nh and others added 4 commits July 8, 2026 16:57
…ation possible

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
…ul for debugging

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
Signatures are signed over the per-network config dir but were stored in a
single signatures/ folder with fixed per-role filenames, so a task spanning
multiple networks would collide. Nest them under signatures/<network>/ to
mirror config/<network>/. Update README to the new active/evm/tasks layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@0xth4nh 0xth4nh merged commit 2c4cf42 into main Jul 8, 2026
6 checks passed
@0xth4nh 0xth4nh deleted the contract-ops-reorg-task-origin-verification branch July 8, 2026 21:35
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
0xth4nh added a commit that referenced this pull request Jul 8, 2026
Update the signing flow for the active EVM task layout introduced by the
task-origin reorg (#181):

- Discover active tasks under active/evm/tasks/<task-id> and expose ready-to-sign
  task/network pairs via /api/upgrades.
- /api/upgrade-config and /api/install-deps accept network + upgradeId; deps run
  from active/evm.
- Task metadata is read from the first README found: config/<network>/README.md,
  then <task>/README.md, then active/evm/README.md; display name uses the first
  heading when present.
- Remove root-level network/task discovery and the unused NetworkSelection
  component.
- Docs: document the signer flow and README fallback on top of the active/evm
  task-origin layout.

Generated with Claude Code

Co-authored-by: Claude <noreply@anthropic.com>
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.

4 participants