Skip to content

feat: Add support for script execution (trigger & filter) runtime flags.#445

Open
TEMHITHORPHE wants to merge 5 commits intoOpenZeppelin:mainfrom
TEMHITHORPHE:feat/script-execution-runtime-flags
Open

feat: Add support for script execution (trigger & filter) runtime flags.#445
TEMHITHORPHE wants to merge 5 commits intoOpenZeppelin:mainfrom
TEMHITHORPHE:feat/script-execution-runtime-flags

Conversation

@TEMHITHORPHE
Copy link

@TEMHITHORPHE TEMHITHORPHE commented Feb 5, 2026

Summary

Feat: Add runtime flags support for scripts (triggers & filters)

Previously, script notifications could accept arguments but lacked a way to pass flags directly to the script runtime (e.g., Node, Python, Bash).
With this change, users can now configure runtime flags (like --max‑old‑space‑size=2048) to customize how scripts are launched.
This PR introduces support for runtime flags for script execution in triggers and filters, fixes #356

✅ Key Changes

New Functionality

  • Introduce a new optional field: runtime_flags: Option<Vec<String>> in trigger/filter configs to allow passing runtime flags to scripts.
  • Update script execution logic to handle and log these runtime flags.

Code & API Updates

  • Modify TriggerConditions and TriggerTypeConfig structs to include the new runtime_flags field.
  • Integrate support for runtime_flags across builder utilities and script execution flows.
  • Add tests verifying correct handling of runtime flags in script executions.

Examples Updated

  • Example configuration updated to show usage of runtime_flags, e.g.:
    "runtime_flags": ["--max‑old‑space‑size=2048"]
    

Testing Process

Checklist

  • Add a reference to related issues in the PR description.
  • Add unit tests if applicable.
  • Add integration tests if applicable.
  • Add property-based tests if applicable.
  • Update documentation if applicable.

Note

If you are using Monitor in your stack, consider adding your team or organization to our list of Monitor Users in the Wild!

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for configurable runtime flags in script triggers and notifications. Scripts can now specify runtime-level flags (e.g., memory optimization flags) that are passed during execution and logged for visibility.
  • Improvements

    • Enhanced cross-platform process execution handling for Unix and Windows environments.

son-oz and others added 2 commits February 5, 2026 02:26
- Introduced `runtime_flags` field in the script notification configuration to allow passing runtime-specific flags.
- Updated the script execution logic to handle and log runtime flags for Python, JavaScript, and Bash scripts.
- Modified the `TriggerConditions` and `TriggerTypeConfig` structs to include `runtime_flags`.
- Enhanced the `MonitorBuilder` and related test utilities to support the new runtime flags feature.
- Updated various tests to validate the correct handling of runtime flags in script execution.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR adds support for configurable runtime flags in script execution. A new optional runtime_flags field is introduced across configuration models, service layers, and script executors, enabling users to pass environment-specific flags (e.g., --max-old-space-size) to scripts at runtime without code changes.

Changes

Cohort / File(s) Summary
Model & Core Types
src/models/core/monitor.rs, src/models/core/trigger.rs, src/models/config/monitor_config.rs, src/models/config/trigger_config.rs
Added runtime_flags: Option<Vec<String>> field to TriggerConditions and TriggerTypeConfig::Script; updated MonitorBuilder::trigger_condition signature to accept and propagate runtime flags.
Bootstrap & Service Wiring
src/bootstrap/mod.rs, src/services/trigger/service.rs, src/services/notification/script.rs
Threaded runtime_flags through trigger execution and script notification paths; execute_trigger_condition now passes runtime flags to ScriptExecutor via .as_deref().
Script Execution
src/services/trigger/script/executor.rs
Extended ScriptExecutor trait and all language implementations (PythonScriptExecutor, JavaScriptScriptExecutor, BashScriptExecutor) to accept runtime_flags: Option<&[String]> and forward to process invocation via .args(runtime_flags.unwrap_or(&[])).
Test Builders
src/utils/tests/builders/evm/monitor.rs, src/utils/tests/builders/midnight/monitor.rs, src/utils/tests/builders/solana/monitor.rs, src/utils/tests/builders/stellar/monitor.rs, src/utils/tests/builders/trigger.rs
Updated all MonitorBuilder::trigger_condition methods to accept runtime_flags parameter; added TriggerBuilder::script_runtime_flags setter method for configuring script triggers.
Integration & Property Tests
tests/integration/bootstrap/main.rs, tests/integration/monitor/execution.rs, tests/properties/repositories/trigger.rs, tests/properties/strategies.rs, tests/properties/triggers/script.rs
Updated test scaffolding to supply runtime_flags arguments in trigger condition calls; added platform-specific ExitStatusExt handling for cross-platform test support.
Configuration Example & Misc
examples/config/triggers/script_notifications.json, examples/config/triggers/scripts/custom_notification.js, src/utils/metrics/server.rs
Added example config with runtime_flags: ["--max-old-space-size=2048"]; updated custom notification script to log process.execArgv; increased metrics server test timeout.

Sequence Diagram

sequenceDiagram
    participant Config as Configuration
    participant Monitor as Monitor/Trigger
    participant Executor as Script Executor
    participant Process as OS Process
    
    Config->>Monitor: Load trigger with runtime_flags
    Monitor->>Monitor: Store runtime_flags in TriggerConditions
    Monitor->>Executor: execute(input, timeout, args, runtime_flags)
    Executor->>Executor: Combine input with runtime_flags
    Executor->>Process: spawn(script_path, args=[...runtime_flags, ...script_args])
    Process-->>Executor: stdout/stderr/exit_code
    Executor-->>Monitor: execution_result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

T-feature, P-high

Suggested reviewers

  • shahnami
  • NicoMolinaOZ
  • zeljkoX
  • collins-w

Poem

🐰 A rabbit hops through scripts with glee,
With runtime flags set wild and free!
--max-old-space now takes its place,
Memory optimized for every race! 🚀
Configuration flows, execution glows,
Runtime control is how it goes! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically summarizes the main change: adding support for script execution runtime flags for both triggers and filters.
Description check ✅ Passed The description covers the main feature, key changes, testing details, and follows the template with issue reference (#356) and completed checklist items. Minor note: documentation update checkbox unchecked but author acknowledged this in comments.
Linked Issues check ✅ Passed The PR fully implements the objective from issue #356 by introducing runtime_flags support allowing users to pass arguments like --max-old-space-size to script runtimes.
Out of Scope Changes check ✅ Passed All changes are directly related to runtime flags support: config structures, execution logic, builders, examples, tests, and minor formatting adjustments. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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 and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@TEMHITHORPHE
Copy link
Author

I confirm that I have read and hereby agree to the OpenZeppelin Contributor License Agreement

@TEMHITHORPHE
Copy link
Author

Hey @shahnami , sorry this took a minute, so I made it a draft cause I wanted to get your thoughts on the PR before I go ahead with updating the docs where necessary.

Copy link
Contributor

@NicoMolinaOZ NicoMolinaOZ left a comment

Choose a reason for hiding this comment

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

Hello @TEMHITHORPHE thanks for open this PR! The content looks good. Btw you can move the PR to ready for review..
Just posting some comments...

@TEMHITHORPHE TEMHITHORPHE marked this pull request as ready for review February 10, 2026 21:28
@TEMHITHORPHE TEMHITHORPHE requested a review from a team as a code owner February 10, 2026 21:28
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/utils/tests/builders/trigger.rs (1)

504-520: ⚠️ Potential issue | 🟡 Minor

Missing assertion for runtime_flags in this test.

script_runtime_flags is called on Line 510 but the match block (Lines 514–517) only asserts on arguments. The runtime_flags value is never verified, so this test wouldn't catch a broken script_runtime_flags builder.

Proposed fix
 		match trigger.config {
-			TriggerTypeConfig::Script { arguments, .. } => {
+			TriggerTypeConfig::Script { arguments, runtime_flags, .. } => {
 				assert_eq!(arguments, Some(vec!["arg1".to_string()]));
+				assert_eq!(runtime_flags, Some(vec!["-v".to_string()]));
 			}
 			_ => panic!("Expected script config"),
 		}
🤖 Fix all issues with AI agents
In `@examples/config/triggers/script_notifications.json`:
- Around line 6-9: The example is misleading because the runtime flag in the
"runtime_flags" array is a Node/V8 flag but the entry uses "language": "Bash"
with "script_path": "./config/triggers/scripts/custom_notification.sh"; update
the example so the runtime flag matches the language: either change "language"
to "Node" and point "script_path" to a .js file (and keep the V8
"--max-old-space-size=2048" flag), or keep "language": "Bash" and replace the
runtime flag with a Bash-relevant example (e.g., a shell option or environment
variable) so "runtime_flags" correctly reflects the chosen language.

In `@src/services/trigger/script/executor.rs`:
- Around line 56-60: The JSON payload currently serializes runtime_flags
inconsistently (null in PythonScriptExecutor::execute and
BashScriptExecutor::execute, but [] in the JavaScript executor), so update the
combined_input construction in PythonScriptExecutor::execute and
BashScriptExecutor::execute to use runtime_flags.unwrap_or(&[]) (or the
Rust-equivalent used in the JS executor) instead of plain runtime_flags so
runtime_flags is always an array in the JSON sent to scripts; keep the
JavaScript executor unchanged.

In `@tests/properties/triggers/script.rs`:
- Line 138: Update the incorrect inline comment next to the status construction
where ExitStatusExt::from_raw(exit_code as u32) is used: change the range
description from "1 >= exit_code <= 255" to the correct range "0..2 (i.e., 0 or
1)" or "0..=1" and note that there is no underflow because exit_code is
non-negative; update the comment adjacent to the status field (the line
referencing std::os::windows::process::ExitStatusExt::from_raw and exit_code)
accordingly.
- Around line 78-82: The Unix call to ExitStatus::from_raw is using the raw wait
status, so using ExitStatus::from_raw(exit_code) treats small integers as signal
deaths rather than exit codes; update all places that construct
std::process::Output on Unix (where ExitStatus::from_raw is invoked with
exit_code, e.g., in the test creating std::process::Output) to pass the encoded
exit status for an exit code by shifting the code left 8 bits (use exit_code <<
8) before calling ExitStatus::from_raw, so status.code() yields Some(exit_code)
and .success() remains correct; apply the same fix for every Unix from_raw call
with non-zero exit codes in this file (including the occurrence around the
second call noted).
🧹 Nitpick comments (8)
src/utils/metrics/server.rs (1)

339-339: Consider splitting unrelated test stability fixes into a separate PR.

The timeout increase from 1 to 2 seconds is reasonable for test stability, but this change appears unrelated to the runtime_flags feature that is the focus of this PR. While not problematic, keeping PRs focused on a single concern improves reviewability and makes it easier to track changes.

tests/properties/strategies.rs (2)

314-321: Consider generating non-None runtime_flags in property tests.

The strategy always sets runtime_flags: None, so property tests never exercise the runtime-flags code path. Consider occasionally generating Some(vec![...]) to increase coverage.

♻️ Example strategy producing optional runtime flags
+let runtime_flags_strategy = option::of(
+    proptest::collection::vec(
+        prop_oneof![
+            Just("--max-old-space-size=2048".to_string()),
+            Just("--cpu-prof".to_string()),
+            Just("--env-file-if-exists=test.env".to_string()),
+        ],
+        1..3,
+    ),
+);

Then thread it through the prop_map and assign to runtime_flags.


364-367: Pre-existing: ExitStatusExt::from_raw(1) on Unix represents signal termination, not exit code 1.

On Unix, the raw wait status encodes exit codes in bits 8–15. from_raw(1) means "killed by signal 1 (SIGHUP)", not "exited with code 1". This happens to satisfy !status.success() so tests still pass, but if any test inspects the exit code directly it will be surprising. Not introduced by this PR, but worth knowing.

src/services/trigger/script/executor.rs (3)

64-67: Runtime flags are injected as interpreter arguments without validation — document the trust assumption.

Flags like --require, --inspect (Node), or -c (Python/sh) placed in runtime_flags could alter script behavior or open debug ports. Since config files are operator-authored (same trust level as script_path), this is acceptable, but consider adding a doc comment on the runtime_flags field or the trait method noting that values are passed directly to the interpreter and must be trusted.

Also applies to: 106-109, 148-151


502-502: Remove debug println! left in test.

Line 502: println!("Result: {:?}", result); appears to be a leftover debug statement.

🧹 Proposed fix
-		println!("Result: {:?}", result);

446-505: Good coverage for JS runtime flags — consider adding equivalent tests for Python and Bash.

There's a dedicated test_javascript_script_executor_runtime_flags_success test, but no corresponding tests for PythonScriptExecutor or BashScriptExecutor verifying that runtime flags are actually received by the interpreter. For Python, you could check sys.flags or sys.argv; for Bash, you could verify shell options with set -o.

src/repositories/monitor.rs (1)

157-198: Consider validating runtime_flags and arguments during monitor reference validation.

The validate_monitor_references function validates script_path, file extension, and timeout_ms for trigger conditions, but does not validate runtime_flags or arguments. These values are passed directly to child process invocations (python3, node, sh) via Command::args(). While Rust's command execution prevents shell injection by design, adding validation for these fields would provide defense-in-depth and prevent potentially malformed or unexpected flag values from reaching the runtime.

src/utils/tests/builders/solana/monitor.rs (1)

278-308: Consider adding a test case exercising non-None runtime_flags.

All four chain-specific builders only test runtime_flags: None. A single test with Some(vec!["--max-old-space-size=2048".to_string()]) and a corresponding assertion would strengthen coverage of the new field.

Copy link
Member

@shahnami shahnami left a comment

Choose a reason for hiding this comment

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

Thanks @TEMHITHORPHE, looks good, just a few questions. Can you also have a look at the CodeRabbit comments?

@shahnami
Copy link
Member

Hi @TEMHITHORPHE -- looks like this test is still failing: test_bash_script_executor_runtime_flags_success


# Ignore logs dir
logs/
*.cpuprofile
Copy link
Contributor

Choose a reason for hiding this comment

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

hey @TEMHITHORPHE, do you remember why do we need this line?

Copy link
Author

@TEMHITHORPHE TEMHITHORPHE Feb 28, 2026

Choose a reason for hiding this comment

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

I added it because the runtime arguments tests of node produced that file artifact (which is like proof of it working), but I'll have it removed 👍🏾

edit: On second thoughts, i think it's best to leave it, to prevent accidental commits to the repo.

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.

Support for Additional Node.js Arguments

4 participants