Skip to content

fix(parked-tasks): reject enqueue for networks not active in networks.json - #2192

Open
gvladika wants to merge 2 commits into
mainfrom
fix/exsc-764-parked-task-active-network-guard
Open

fix(parked-tasks): reject enqueue for networks not active in networks.json#2192
gvladika wants to merge 2 commits into
mainfrom
fix/exsc-764-parked-task-active-network-guard

Conversation

@gvladika

Copy link
Copy Markdown
Contributor

Which Linear task belongs to this PR?

Fixes EXSC-764

Why did I implement it this way?

The scheduled reconcile-parked-tasks workflow crashed with Chain evmos does not exist in config/networks.json and aborted the entire run. The cause is a source-of-truth mismatch: the parked-task enqueue path (driven by /deprecate-contract) enumerates target networks from the deploy logs (deployments/<network>.json), which outlive a network's removal from config/networks.json. A deprecated network like evmos (a 2022 deployment) keeps its deploy log, so a facet-removal task was parked for it — but the reconcile/drain path resolves chains via networks.json, where evmos no longer exists, so it threw and blocked reconciliation for every other network. evmos is one of 9 orphaned networks that have deploy logs but no networks.json entry.

The fix makes networks.json authoritative at write time. The guard lives in enqueueParkedTask — the single enqueue chokepoint that already validates prUrl/facetName — so every caller (CLI, /deprecate-contract, the future drain) is covered; it throws unless the network is status: 'active' in config/networks.json. A matching fail-fast pre-check in the enqueue-parked-task.ts CLI gives a clean exit before the Mongo connect, mirroring the existing prUrl/facetName belt-and-suspenders pattern. The predicate reuses the canonical networks map from viemScriptHelpers (the same status === 'active' definition getAllActiveNetworks uses), so no new config reader is introduced. The already-parked evmos task was separately cancelled to unblock the current run; two follow-ups (reconcile skip-and-warn resilience, and cleaning up the 9 orphaned deploy logs) are noted on the ticket and left out of this PR to keep it single-concern.

Checklist before requesting a review

Checklist for reviewer (DO NOT DEPLOY and contracts BEFORE CHECKING THIS!!!)

  • I have checked that any arbitrary calls to external contracts are validated and or restricted
  • I have checked that any privileged calls (i.e. storage modifications) are validated and or restricted
  • I have ensured that any new contracts have had AT A MINIMUM 1 preliminary audit conducted on by <company/auditor>

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lifi-action-bot
lifi-action-bot marked this pull request as draft August 11, 2026 13:56
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@gvladika, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 3 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eb7fa064-3d7b-4fc2-b9d4-a274aa14054a

📥 Commits

Reviewing files that changed from the base of the PR and between 0b5ff17 and b915de5.

📒 Files selected for processing (3)
  • script/deploy/safe/enqueue-parked-task.ts
  • script/deploy/safe/parked-tasks.test.ts
  • script/deploy/safe/parked-tasks.ts

Walkthrough

The parked-task enqueue paths now normalize network names and accept only networks marked active in config/networks.json. Unknown and inactive networks are rejected without task insertion. The deprecation workflow documentation reflects this restriction.

Changes

Active network enqueue validation

Layer / File(s) Summary
Validate active networks before enqueueing
script/deploy/safe/enqueue-parked-task.ts, script/deploy/safe/parked-tasks.ts, script/deploy/safe/parked-tasks.test.ts, .agents/commands/deprecate-contract.md
The enqueue paths validate normalized networks against config/networks.json. Unknown and inactive networks are rejected, tests confirm that no task is stored, and the deprecation workflow documentation describes the validation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: QA AI Reviewing

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: rejecting parked-task enqueueing for networks that are not active in networks.json.
Description check ✅ Passed The description explains the cause, implementation, scope, tests, documentation, linked Linear task, and completed checklist items.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/exsc-764-parked-task-active-network-guard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gvladika
gvladika marked this pull request as ready for review August 11, 2026 14:02
@gvladika

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
script/deploy/safe/parked-tasks.test.ts (1)

317-334: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Parameterize the two rejection cases.

Both tests create the same fake collection, assert the same error, and verify zero stored rows. Use one parameterized test table for evmos and localanvil, while keeping a descriptive case label in the test name.

As per coding guidelines, use parameterized tests to reduce code duplication when testing multiple scenarios.

Example table-driven form
-  it('throws when the network is not in config/networks.json', async () => {
-    const coll = createFakeCollection()
-    await expectRejects(
-      enqueueParkedTask(coll, buildInput({ network: 'evmos' })),
-      /not an active network/
-    )
-    expect(coll.rows).toHaveLength(0)
-  })
-
-  it('throws when the network exists but is not active', async () => {
-    const coll = createFakeCollection()
-    await expectRejects(
-      enqueueParkedTask(coll, buildInput({ network: 'localanvil' })),
-      /not an active network/
-    )
-    expect(coll.rows).toHaveLength(0)
-  })
+  it.each([
+    ['unknown network', 'evmos'],
+    ['configured inactive network', 'localanvil'],
+  ])('rejects a %s without inserting a task', async (_caseName, network) => {
+    const coll = createFakeCollection()
+    await expectRejects(
+      enqueueParkedTask(coll, buildInput({ network })),
+      /not an active network/
+    )
+    expect(coll.rows).toHaveLength(0)
+  })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@script/deploy/safe/parked-tasks.test.ts` around lines 317 - 334, The two
rejection tests duplicate setup, assertions, and cleanup; combine them into one
parameterized test covering network values evmos and localanvil. Use a
table-driven test with descriptive case labels, while preserving the existing
error assertion and zero-row verification for each case.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@script/deploy/safe/parked-tasks.ts`:
- Around line 320-327: Extract a pure shared network-validation helper that
normalizes the input, returns the normalized active network, and distinguishes
unknown networks from configured inactive ones with appropriate rejection
messages. In script/deploy/safe/parked-tasks.ts lines 320-327, invoke it before
building or inserting the parked-task document; in
script/deploy/safe/enqueue-parked-task.ts lines 123-136, invoke the same helper
before getParkedTasksCollection() and reuse its normalized return value.
Preserve the CLI validation before any MongoDB access and reuse existing network
utilities.

---

Nitpick comments:
In `@script/deploy/safe/parked-tasks.test.ts`:
- Around line 317-334: The two rejection tests duplicate setup, assertions, and
cleanup; combine them into one parameterized test covering network values evmos
and localanvil. Use a table-driven test with descriptive case labels, while
preserving the existing error assertion and zero-row verification for each case.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3633f471-362f-455f-8bf4-5d308c039b60

📥 Commits

Reviewing files that changed from the base of the PR and between afca752 and 0b5ff17.

📒 Files selected for processing (4)
  • .agents/commands/deprecate-contract.md
  • script/deploy/safe/enqueue-parked-task.ts
  • script/deploy/safe/parked-tasks.test.ts
  • script/deploy/safe/parked-tasks.ts

Comment thread script/deploy/safe/parked-tasks.ts Outdated
…absent vs inactive

Addresses CodeRabbit review on PR #2192.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gvladika

Copy link
Copy Markdown
Contributor Author

Addressed in b915de5. Extracted a shared assertActiveNetwork(network) helper (exported from parked-tasks.ts) that both enqueueParkedTask and the CLI now call — single source for the normalization, the active-network rule, and the message. It also distinguishes the two cases you flagged: an absent network ("not in config/networks.json" → gone, clean up via /deprecate-network) vs. a present-but-inactive one ("is "" (not active)" → exists in config but not parkable). The CLI validates before the MongoDB connect as before. Added a direct unit test covering all three branches.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show --stat --oneline --decorate --no-renames b915de590
git diff b915de590^ b915de590 -- \
  script/deploy/safe/parked-tasks.ts \
  script/deploy/safe/enqueue-parked-task.ts \
  script/deploy/safe/parked-tasks.test.ts \
  .agents/commands/deprecate-contract.md

printf '\n== Symbol outline ==\n'
ast-grep outline script/deploy/safe/parked-tasks.ts --items all --view expanded
ast-grep outline script/deploy/safe/enqueue-parked-task.ts --items all --view expanded
ast-grep outline script/deploy/safe/parked-tasks.test.ts --items all --view expanded

printf '\n== Helper call sites ==\n'
rg -n -C 4 '\bassertActiveNetwork\s*\(' \
  script/deploy/safe/parked-tasks.ts \
  script/deploy/safe/enqueue-parked-task.ts \
  script/deploy/safe/parked-tasks.test.ts

Length of output: 15917


@gvladika The follow-up is correct.

assertActiveNetwork is now the single validation path. It normalizes the network key and distinguishes absent networks from configured non-active networks. The CLI validates before it accesses MongoDB. The unit tests cover all three helper branches.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gvladika
gvladika enabled auto-merge (squash) August 11, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants