Side-Effect Free Ephemeral Preview & Plugin Whitelisting

This document describes how we want to implement an ephemeral “preview” mode in the Lava REPL, where a user’s typed expression is evaluated in a temporary clone of the interpreter state, to show the result but without producing any real side effects.

Additionally, we plan to adopt a default deny approach: no bridging function is allowed in ephemeral mode unless it is explicitly declared “preview safe.” As we progress, we will refine or add “stub” logic for certain side-effectful calls if needed.


Plan for Safe Ephemeral Preview with Whitelisting

  1. Default Deny: By default, any plugin function that does not explicitly declare itself as ephemeral-safe will raise an error or be blocked in the ephemeral environment. This ensures we do not accidentally run side effects, spawn tasks, or do I/O in the “dry run.”
  2. Opt-In “Preview-Safe” Declarations: Each bridging call that is purely functional (e.g., math:plus, string:upper) can be whitelisted so ephemeral calls proceed normally in the cloned environment. They either do not cause side effects at all, or we have carefully verified that ephemeral calls are harmless.
  3. Side-Effectful Functions => Forbid or Stub: If a function definitely does real I/O or changes global state (like file:write or math:srand), ephemeral calls by default are forbidden. Over time, if we want ephemeral usage for certain calls, we can define a “stub” method. For example, math:srand might do nothing in ephemeral mode, returning a dummy result. The plugin itself provides that stub if needed.
  4. Use math Plugin as Pilot: Because math is mostly pure, we can easily mark math:plus, math:pow, math:sum, etc. as ephemeral-safe. Meanwhile, we forbid ephemeral usage of math:srand. We then test ephemeral previews in real code, verifying that: This pilot step ensures the system logic works before broadening the approach to all plugins.
  5. Then, Tackle Each Plugin One by One: For each plugin:
  6. Extra Considerations:

Repeating the Explanation: “PreviewSafety” Flag

We previously described a pattern for each bridging function to define a metadata field, for example:

enum PreviewSafety {
    Safe,    // no side effects -> ephemeral calls are allowed
    Forbid,  // definitely has side effects -> ephemeral calls blocked
    Stub,    // ephemeral calls do a custom stub method
}

Under a default deny approach, if a function does not set preview_safety = Safe or Stub, it becomes Forbid by default. This ensures no bridging function can slip through ephemeral mode without an explicit “yes, we are safe” from the plugin developer.


List of Functions by Plugin – Purity Classification

Math Plugin

String Plugin

Array Plugin

File Plugin

Net Plugin

Process Plugin

Test Plugin

Event Plugin

Date Plugin


Conclusion

By default, we disallow ephemeral calls on all bridging functions except for those explicitly marked as PreviewSafety::Safe or Stub. We use the math plugin first as a test bed, since math:plus and others are pure numeric transforms. We’ll see ephemeral previews returning correct results with zero side effects. Functions like math:srand or file:write remain disallowed until/unless we create stub logic for ephemeral usage or decide to forgo ephemeral calls entirely.

Then, one plugin at a time, we’ll document each bridging function as purely functional, side-effectful, or conditionally so. If side-effectful but we want ephemeral usage, the plugin must provide a stub function (e.g., returning a dummy success) for ephemeral mode. Otherwise ephemeral calls remain blocked.

This approach ensures minimal rewriting of existing code, and a safe default deny policy so no new bridging calls are inadvertently run with side effects in ephemeral.