Skip to content

fix(script): treat unknown tx as dropped to avoid receipt-poll hang #553

Merged
Dargon789 merged 10 commits into
Dargon789:masterfrom
foundry-rs:master
May 12, 2026
Merged

fix(script): treat unknown tx as dropped to avoid receipt-poll hang #553
Dargon789 merged 10 commits into
Dargon789:masterfrom
foundry-rs:master

Conversation

@Dargon789
Copy link
Copy Markdown
Owner

Motivation

Solution

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

decofe and others added 10 commits May 10, 2026 13:49
feat: add Amsterdam hardfork mapping to SpecId

Add EthereumHardfork::Amsterdam => SpecId::AMSTERDAM mapping in
spec_id_from_ethereum_hardfork. Without this, Amsterdam would hit the
unreachable!() catch-all arm.

The default evm_version is already set to Osaka.

Amp-Thread-ID: https://ampcode.com/threads/T-019e113f-5bda-711b-8ec5-4841042ba62c

Co-authored-by: Centaur AI <ai@centaur.local>
Issue14212Test (test_rollForkToTxOnBase, test_transactDepositTxOnBase) depends on
Base RPCs to fetch tx 0xe2f4bff... which intermittently fails with 'could not get
transaction'. This is the same class of flakiness as the existing Polygon RPC skip.

Move the contract into FLAKY_TESTDATA_CONTRACTS so it runs in the nightly
flaky profile instead of blocking every CI run.

Amp-Thread-ID: https://ampcode.com/threads/T-019e15de-2292-74cf-a885-b65acaa41d3c

Co-authored-by: Centaur AI <ai@centaur.local>
* feat: improve forge build lint-failure UX

* dedup lint-failure bypass message and revert parse emitter to stderr

* address review: lead with bug-report CTA, add failure-notice tests

- Rewrite LINT_FAILURE_NOTICE to lead with the report-the-bug CTA
  (deep-linked to BUG-FORM.yml) and demote --no-lint to a per-run
  workaround, with a docs link for temporarily disabling lint-on-build.
- Drop the RUST_BACKTRACE suggestion: the failure is an eyre error built
  at a single call site, so a backtrace adds no signal.
- Add integration tests for the failure notice (positive + negative
  --no-lint case) using COUNTER_A + deny=Notes to deterministically
  trigger the lint Err path without breaking compilation.
- Add unit tests for the new convert_solar_errors non-buffer branch
  covering singular/plural messaging and the no-error path.

Amp-Thread-ID: https://ampcode.com/threads/T-019e15e7-6907-723c-bd10-ac64558ed4ce
Co-authored-by: Amp <amp@ampcode.com>

* fix: fmt

* use snapshot assertions for failure-notice tests; trim doc comment

- Replace the fan-out of assert!(stderr.contains(...)) checks with a
  single snapbox stderr_eq snapshot, so the full expected output
  (lint diagnostic + notice + eyre cause chain) lives in one place
  and is trivially refreshed via SNAPSHOTS=overwrite.
- Snapshot the negative --no-lint case as empty stderr too.
- Drop the verbose doc comment on LINT_FAILURE_NOTICE; the constant's
  contents already speak for themselves.
- Trim 'attach the full `forge build` output' to the more general
  'attach the full output above'.

Amp-Thread-ID: https://ampcode.com/threads/T-019e15e7-6907-723c-bd10-ac64558ed4ce
Co-authored-by: Amp <amp@ampcode.com>

* trim verbose test comments

Amp-Thread-ID: https://ampcode.com/threads/T-019e15e7-6907-723c-bd10-ac64558ed4ce
Co-authored-by: Amp <amp@ampcode.com>

---------

Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
)

* feat(invariant): assert all invariants

* Tests and Nits

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* fix: check all invariants in afterInvariant gate and preflight

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* fix: use per-invariant fail_on_revert when recording handler revert failures

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73

* fix: commit state between txs in generate_counterexample

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* fix: preflight check all invariants, not just primary

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* fix: exclude secondary invariants from optimization mode runs

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* refactor: rename invariant_fn to primary_invariant_fn, deterministic preflight error, debug_assert on empty invariants

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* feat: show broken invariant count in progress bar during continuous runs

Amp-Thread-ID: https://ampcode.com/threads/T-019dbf48-3fb0-7762-a01f-b5e966339e73
Co-authored-by: Amp <amp@ampcode.com>

* feat(invariant): rename continuous_run to assert_all and default to true

Renames the InvariantConfig field to better describe its semantics
("assert every invariant in the suite, don't stop on first failure")
and flips the default to true so multi-invariant suites report all
broken invariants by default, matching Echidna/Medusa behavior.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dcd68-66ac-76ed-ac5c-7ea722a9c9ae

* feat(invariant): parameterize shrinker by target invariant + persisted failures footer

- Generalize shrink_sequence, shrink_sequence_value, replay_run, replay_error
  to accept target_invariant: &Function (currently always primary; unblocks
  per-secondary shrinking).
- Move reset_shrink_progress out of shrink fns; called once per invariant from
  replay_error. Progress label now 'Shrink: <invariant_name>'.
- Add TestResult.invariant_failure_dir; Display appends
  'N invariant failures persisted to <dir> — rerun to shrink' when secondary
  failures were written.

Amp-Thread-ID: https://ampcode.com/threads/T-019dcd68-66ac-76ed-ac5c-7ea722a9c9ae
Co-authored-by: Amp <amp@ampcode.com>

* feat(invariant): structured InvariantOtherFailure for assert_all secondaries

Promotes TestResult.other_failures from Vec<String> to Vec<InvariantOtherFailure>
carrying name, reason, optional counterexample, and persisted path. Display
renders each secondary symmetrically with [FAIL: reason] + [Sequence] block
when a counterexample is available, falling back to the terse 'name: reason'
one-liner otherwise.

Amp-Thread-ID: https://ampcode.com/threads/T-019dcd68-66ac-76ed-ac5c-7ea722a9c9ae
Co-authored-by: Amp <amp@ampcode.com>

* feat(invariant): serial secondary shrinking + Ctrl-C persists un-shrunk secondaries

PR-3 of the assert_all rollout. After the campaign finishes, every broken
secondary invariant is shrunk in turn via replay_error so users get a
ready-to-debug counterexample for each failure in a single run (matching
how the primary is rendered: [FAIL: reason] <name> + [Sequence] block).

On Ctrl-C, instead of dropping known secondaries (previous behavior was a
'break' before pushing them), the loop keeps recording every failure the
campaign discovered. The shrink + replay step is skipped to honor the
interrupt, but the un-shrunk sequence is persisted via
BaseCounterExample::from_invariant_call (no execution required), so a
re-run targeting that secondary picks up the saved counterexample and
shrinks from there — same UX as re-running an interrupted primary.

Output of an interrupted run now includes a terse
'<invariant>: <reason>' line for each secondary the campaign saw,
preserving visibility of all broken invariants while keeping the
interrupt fast.

Adds e2e coverage:
- assert_all: extended to verify secondary failures render symmetrically
  with shrunk sequences and that re-running skips persisted secondaries.
- assert_all_only_primary: new test confirming no secondary [FAIL] blocks
  or persisted-failures footer appear when only the primary breaks.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dcdd3-53f5-76b6-ac36-d59f06b58280

* feat(invariant): assert_all polish — [i/N] shrink counter, suite roll-up, opt-mode warning

Three small UX wins for assert_all campaigns. No behavior change, no
new dependencies.

1. Shrink progress bar gets an [i/N] queue counter when more than one
   invariant needs shrinking, so users see how many shrinkers are
   queued behind the current one (e.g. '[2/3] Shrink: invariant_X').
   reset_shrink_progress and replay_error gain a position parameter;
   single-invariant call sites pass None.

2. Suite-level roll-up footer: when assert_all exercised >1 invariant
   and the test failed, render 'Suite assert_all: <broken>/<total>
   invariants broken' above the per-invariant blocks. Gives CI logs
   and Slack pastes a glanceable health line. New Option<usize>
   field on TestResult, populated only when meaningful.

3. Startup warning when assert_all + optimization-mode are combined.
   Optimization mode tracks one int256 return value, so any boolean
   secondary invariants in the same contract are filtered out before
   the campaign — previously silent. Now emits a once-per-suite warning
   naming the optimization invariant and every dropped boolean so users
   can move them to a separate contract.

E2E tests: extend assert_all to assert the new 4/5 roll-up;
assert_all_only_primary covers the 1/2 case; new
assert_all_optimization_mode_warning verifies the warning fires with
the dropped invariant names.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dcdd3-53f5-76b6-ac36-d59f06b58280

* feat(invariant): warn when assert_all skips invariants with persisted failures

Symmetric with the primary's existing persisted-replay warning. Echidna
and Medusa never silently drop properties between runs — properties are
re-evaluated every campaign and a previous failure doesn't suppress
them. Foundry's per-property failure file model meant secondaries with
a stale persisted counterexample were filtered out of the campaign with
no acknowledgment, so users coming from Echidna/Medusa would see fewer
invariants in the report than their contract defines.

Now emits one stderr line listing every skipped name and the cache dir
to clean, e.g.:

  Warning: test/X.t.sol:Suite: 3 invariant(s) skipped due to persisted
  failures: invariant_a, invariant_b, invariant_c. Run `forge clean`
  or delete files in cache/invariant/failures/Suite to re-include.

E2E: extends assert_all re-run case with stderr_eq snapshot asserting
the warning fires with all 3 skipped names.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dcdd3-53f5-76b6-ac36-d59f06b58280

* fix(invariant): gate afterInvariant per-run under assert_all

Previously afterInvariant was gated on failures.errors.is_empty()
campaign-wide. Under assert_all that gate stayed closed for the rest
of the campaign once any invariant broke, silently skipping the
afterInvariant hook on every subsequent run. Any assertions or
cleanup logic in afterInvariant therefore stopped running after the
first unrelated invariant failure.

Now snapshot failures.errors.len() at the start of each run and only
skip afterInvariant when the current run produced a new failure.
Preserves the legacy 'don't run afterInvariant on a run that already
failed' semantics while letting it run on subsequent runs once an
earlier invariant has broken.

E2E: new assert_all_after_invariant_runs_after_earlier_failure case
breaks invariant_first in run 1, keeps the campaign alive with a
second never-breaking invariant, and asserts an always-reverting
afterInvariant surfaces its marker in failure output.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dce2d-57c7-734a-bbc6-6fa5e34b25de

* fix(invariant): re-evaluate secondary persisted failures on settings change

The secondary persisted-failure skip used a bare `.exists()` check at
two sites in runner.rs (the warning + InvariantContract::new filter,
and the post-campaign shrink loop). Under the new `assert_all = true`
default this meant any leftover failure file from a previous run was
treated as still valid even after the user changed a tracked setting
(target contracts/selectors, target/excluded senders, fail_on_revert),
silently dropping the secondary from the campaign with a misleading
'skipped due to persisted failures' warning.

Now both sites use the same settings-aware compatibility check the
primary's replay path uses (persisted_call_sequence settings.diff).
Stale caches fall back to a fresh evaluation; only secondaries whose
persisted settings still match the current run are honored.

Also hoists current_settings up so the new
secondary_has_compatible_persisted closure can reuse it across all
three call sites (warning, filter, shrink-loop skip).

E2E: new assert_all_secondary_persisted_revalidates_on_settings_change
runs once with fail_on_revert=false, flips it to true, re-runs and
asserts the suite roll-up shows 2/2 invariants broken — proving the
secondary was re-evaluated rather than silently filtered out.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dce2d-57c7-734a-bbc6-6fa5e34b25de

* fix(invariant): drop hollow [FAIL] when only secondaries break under assert_all

When the selected invariant test passes but a secondary breaks under
assert_all, the report previously rendered a hollow '[FAIL]' header
(no reason, no counterexample) for the primary and the suite roll-up
overcounted broken invariants as '1 + other_failures.len()',
attributing a non-existent primary failure.

Now key the primary header on whether the primary actually broke
(`reason.is_some() || counterexample.is_some()`) and skip the
header when it didn't. Roll-up uses the same flag so the count
reflects only invariants that actually broke (e.g., 1/2 instead of
2/2). JSON shape is unchanged: top-level reason/counterexample stay
null when the selected primary didn't break, with full secondary
detail in other_failures.

E2E: new assert_all_secondary_only_failure_no_hollow_fail asserts a
secondary-only break renders 'Suite assert_all: 1/2 invariants broken'
followed by the secondary's '[FAIL: ...] <name>' block, with no
hollow primary header.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dce2d-57c7-734a-bbc6-6fa5e34b25de

* fix(invariant): scope assert_all hollow [FAIL] suppression to secondary-only case

Previous commit suppressed the '[FAIL]' header whenever the primary had
no top-level reason or counterexample, which also matches DS-style
failures (they signal via the 'failed' flag and log events rather than
through TestResult.reason). That regressed failure_assertions::ds_style_test_failing
and test_cmd::core::legacy_assertions in CI.

Now the suppression is scoped strictly to the assert_all secondary-only
case: skip the primary header only when no primary failure AND
assert_all is in play AND there is at least one secondary to render.
DS-style, plain unit and single-invariant failures keep the original
'[FAIL]'/'[FAIL: ...]' rendering.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dce2d-57c7-734a-bbc6-6fa5e34b25de

* fix(invariant): attribute failure event to first broken invariant in declaration order

The structured JSON 'failure' event emitted to stderr at campaign end
(consumed by benchmark and CI tooling) used 'errors.values().next()'
on a HashMap to pick its 'reason' field, while hardcoding the
'invariant' field to the primary's name. With HashMap RandomState,
the same broken set of invariants produced a different reason string
across runs, and the event was self-inconsistent (e.g.,
'invariant: invariant_balance, reason: fee miscalculation'). Three
sites used this pattern: in-run break path, afterInvariant break
path, and the preflight check fallback.

Now they walk 'invariant_contract.invariant_fns' in declaration
order (a Vec, deterministic) and pick the first one with a recorded
failure. Both 'invariant' and 'reason' fields refer to the same
function, and the event is stable across runs.

A new 'first_broken_event' helper centralizes the lookup.

E2E: assert_all_failure_event_uses_declaration_order declares three
invariants (a, b, c) that all break on the same call, runs with
'--mt invariant_c' (primary is the last declared) and asserts the
emitted event names invariant_a with reason 'a broken'.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dce2d-57c7-734a-bbc6-6fa5e34b25de

* refactor(invariant): rename to InvariantSecondaryFailure / invariant_secondary_failures and serialize sparsely

Renames TestResult.other_failures -> invariant_secondary_failures and
the underlying InvariantOtherFailure struct -> InvariantSecondaryFailure.
The previous names were generic ('other relative to what?'); the new
names align with the existing 'primary/secondary' terminology used
throughout the assert_all rollout and follow the Rust Vec<Foo>/foos
plural-of-singular convention.

Also marks the field with #[serde(default, skip_serializing_if =
'Vec::is_empty')] so it is omitted from JSON output for any test that
has no secondary failure data — plain unit tests, fuzz tests, passing
tests. Pre-PR JSON consumers continue to see the same shape on those
results. invariant_failure_dir and assert_all_invariant_count already
had Option::is_none guards.

Updates the SimpleContractTest{NonVerbose,Verbose}.json fixtures to
drop the now-skipped empty field.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019dce2d-57c7-734a-bbc6-6fa5e34b25de

* test(invariant): assert_all + fail_on_revert=false attributes assert() to all live invariants

Amp-Thread-ID: https://ampcode.com/threads/T-019dd262-ed81-723c-aaaa-8e1314bed45a
Co-authored-by: Amp <amp@ampcode.com>

* fix(clippy): use values() instead of iter() with unused key

Amp-Thread-ID: https://ampcode.com/threads/T-019df149-03af-722b-abda-d8ab6332ee3b
Co-authored-by: Amp <amp@ampcode.com>

* fix(clippy): drop redundant references in trimmed_hex format args

Amp-Thread-ID: https://ampcode.com/threads/T-019df149-03af-722b-abda-d8ab6332ee3b
Co-authored-by: Amp <amp@ampcode.com>

* Update crates/evm/evm/src/executors/invariant/error.rs

Co-authored-by: stevencartavia <112043913+stevencartavia@users.noreply.github.com>

* invariant: unify primary/secondary as one list and one failure type

The "anchor" of an invariant campaign is the test entry point selected
by `--mt` (or the per-`Test` invariant function the runner is currently
exercising). Under `assert_all`, the anchor is the campaign's named
test, and any other broken `invariant_*` functions are secondaries
shrunk and reported alongside it.

- InvariantContract: single invariant_fns list in declaration order
  with an anchor_idx pointing at the campaign's anchor invariant
- TestResult: replace primary/secondary split with invariant_failures:
  Vec<InvariantFailure>; each entry carries is_anchor so the renderer
  can omit the function name suffix when a single failure is the anchor
  (its name is already on the trailing summary line)
- assert_invariants/can_continue/assert_after_invariant return the
  broken invariant directly, removing the first_broken_event re-scan
- collapse FailedInvariantCaseData::new + with_assertion_failure into
  InvariantRunCtx::failed_case
- show invariant name on [FAIL: ...] line when not anchor or multiple
  failures (so secondaries in single-failure assert_all runs are
  still visible)

* invariant: validate signatures upstream and reject parameterized invariants

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: George Niculae <george@gxn3ql7y5j.tail388b2e.ts.net>
Co-authored-by: stevencartavia <112043913+stevencartavia@users.noreply.github.com>
…ne for backwards compatibility (#14689)

* feat(forge): add noop --no-commit flag to forge install and forge clone for backwards compatibility

`forge install` and `forge clone` no longer commit by default (commit is
opt-in via `--commit`). Many AI tools and scripts still pass `--no-commit`,
causing an unrecognized flag error. This adds a hidden, noop `--no-commit`
flag so those invocations continue to work.

Follow-up to #14649 which did the same for `forge init`.

Amp-Thread-ID: https://ampcode.com/threads/T-019e15aa-9de3-77a6-9365-21ea300cd785

* test(forge): add test for noop --no-commit flag on forge clone

Amp-Thread-ID: https://ampcode.com/threads/T-019e15aa-9de3-77a6-9365-21ea300cd785

---------

Co-authored-by: Centaur AI <ai@centaur.local>
Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
Upstream reth (paradigmxyz/reth) now requires alloy-eip7928 ^0.3.6 (since
commit d985041). The lockfile here still pinned 0.3.5, which causes
resolution failures for any downstream that patches Foundry to use a
recent reth revision.

Bump the transitive dep to 0.3.7 (latest compatible) so the lockfile
stays resolvable.

Amp-Thread-ID: https://ampcode.com/threads/T-019e1699-eb69-75aa-afdc-c66246d2f217

Co-authored-by: Centaur AI <ai@centaur.local>
flake.lock: Update

Flake lock file updates:

• Updated input 'fenix':
    'github:nix-community/fenix/74c1591' (2026-05-02)
  → 'github:nix-community/fenix/f54d645' (2026-05-09)
• Updated input 'fenix/rust-analyzer-src':
    'github:rust-lang/rust-analyzer/64cdaeb' (2026-05-01)
  → 'github:rust-lang/rust-analyzer/73ca1d4' (2026-05-08)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/c6d6588' (2026-05-01)
  → 'github:NixOS/nixpkgs/b3da656' (2026-05-08)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* feat(lint): add missing-inheritance lint

* fix(lint): consider dependency interfaces as candidates for missing-inheritance
…14626)

* fix(script): treat unknown tx as dropped to avoid receipt-poll hang

`provider.get_transaction_by_hash(hash)` returns `Result<Option<Tx>, _>`.
`check_tx_status` matched `Ok(_)` for the 'node knows the tx' path,
incorrectly bucketing `Ok(None)` (tx unknown) as known. In the
`get_receipt`-error branch this fed `RetryError::Continue`, which is
unbounded — producing an infinite `eth_blockNumber` + `eth_getTransactionReceipt`
loop whenever a tx was rejected at submission or dropped from the
mempool after a halt (e.g. anvil's new -32003 mapping for non-REVERT
EVM halts).

Distinguish `Ok(Some(_))` from `Ok(None)`; treat the latter the same as
a transport error and terminate as `TxStatus::Dropped`.

Amp-Thread-ID: https://ampcode.com/threads/T-019dfe94-2b0d-71bc-a863-633e05594581
Co-authored-by: Amp <amp@ampcode.com>

* test(script): cover check_tx_status dropped/unknown tx paths

Amp-Thread-ID: https://ampcode.com/threads/T-019e0814-2cda-7271-a8d6-c59e6739946b
Co-authored-by: Amp <amp@ampcode.com>

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Sorry @Dargon789, your pull request is larger than the review limit of 150000 diff characters

@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

@stevencartavia is attempting to deploy a commit to the Foundry development Team on Vercel.

A member of the Team first needs to authorize it.

@snyk-io
Copy link
Copy Markdown

snyk-io Bot commented May 12, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
🔚 Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@mergify
Copy link
Copy Markdown

mergify Bot commented May 12, 2026

⚠️ The sha of the head commit of this PR conflicts with #533. Mergify cannot evaluate rules on this PR. Once #533 is merged or closed, Mergify will resume processing this PR. ⚠️

@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
next Ready Ready Preview, Comment May 12, 2026 3:14am

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the assert_all feature for invariant testing, allowing campaigns to continue after the first failure and report all broken invariants. It updates the invariant executor, result structures, and reporting logic to handle multiple failures per test suite. Additionally, a new lint rule missing-inheritance is added to detect contracts implementing interface APIs without explicit inheritance. The forge build command now includes a --no-lint flag and improved error notices. In crates/script, transaction status checking is refined to correctly identify dropped transactions. Review feedback suggests refining error handling in transaction status checks to distinguish between transport errors and dropped transactions, and clarifying the lint failure notice to distinguish between configuration-based denials and actual engine failures.

Comment thread crates/script/src/receipts.rs
Comment thread crates/forge/src/cmd/build.rs
@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

Deployment failed with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/dargon789-forge?upgradeToPro=build-rate-limit

@Dargon789 Dargon789 merged commit 3b2436e into Dargon789:master May 12, 2026
5 of 11 checks passed
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.

5 participants