mumu 0.10.0

Lava Mumu is a language for those in the now and that know
Documentation
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>Side-Effect Free Ephemeral Preview & Plugin Whitelisting</title>
  <style>
    body {
      font-family: sans-serif;
      line-height: 1.4;
      margin: 1.5rem;
    }
    h1, h2, h3 {
      color: #333;
    }
    code {
      background: #f2f2f2; 
      padding: 0.1rem 0.3rem;
      border-radius: 4px;
      font-family: Consolas, "Courier New", monospace;
    }
    .pure {
      color: #218c74;
      font-weight: bold;
    }
    .side-effect {
      color: #b33939;
      font-weight: bold;
    }
    .maybe {
      color: #f39c12;
      font-weight: bold;
    }
    .section {
      margin-bottom: 2rem;
    }
    .fn-list li {
      margin: 0.3rem 0;
    }
    pre code {
      white-space: pre;
    }
    hr {
      margin: 2rem 0;
    }
  </style>
</head>
<body>

<h1>Side-Effect Free Ephemeral Preview &amp; Plugin Whitelisting</h1>

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

<p>
Additionally, we plan to adopt a <strong>default deny</strong> approach: 
<em>no bridging function</em> 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.
</p>

<hr/>

<h2>Plan for Safe Ephemeral Preview with Whitelisting</h2>

<ol>
  <li>
    <strong>Default Deny:</strong> By default, any plugin function that does not explicitly declare itself 
    as <em>ephemeral-safe</em> 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.”
  </li>

  <li>
    <strong>Opt-In “Preview-Safe” Declarations:</strong> Each bridging call that is purely functional 
    (e.g., <code>math:plus</code>, <code>string:upper</code>) can be <em>whitelisted</em> 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.
  </li>

  <li>
    <strong>Side-Effectful Functions => Forbid or Stub:</strong> 
    If a function definitely does real I/O or changes global state (like <code>file:write</code> or <code>math:srand</code>), 
    ephemeral calls by default are <em>forbidden</em>. 
    Over time, if we want ephemeral usage for certain calls, we can define a “stub” method. 
    For example, <code>math:srand</code> might do nothing in ephemeral mode, returning a dummy result. 
    The plugin itself <em>provides</em> that stub if needed.
  </li>

  <li>
    <strong>Use <code>math</code> Plugin as Pilot:</strong> 
    Because <code>math</code> is mostly pure, we can easily mark <code>math:plus</code>, <code>math:pow</code>, 
    <code>math:sum</code>, etc. as ephemeral-safe. Meanwhile, we forbid ephemeral usage of <code>math:srand</code>. 
    We then test ephemeral previews in real code, verifying that:
    <ul>
      <li>Ephemeral calls to <code>math:plus</code> in the cloned interpreter produce correct results but do not alter the real environment.</li>
      <li>Calls to <code>math:srand</code> in ephemeral mode are blocked or stubbed, so we do not truly re-seed in the preview context.</li>
    </ul>
    This pilot step ensures the system logic works before broadening the approach to all plugins.
  </li>

  <li>
    <strong>Then, Tackle Each Plugin One by One:</strong> 
    For each plugin:
    <ul>
      <li>List every bridging function.</li>
      <li>Decide if it is <span class="pure">pure</span>, <span class="side-effect">side-effectful</span>, 
          or <span class="maybe">conditionally side-effectful</span> (e.g., if it calls a user-provided callback that might do I/O).</li>
      <li>If side-effectful, consider whether providing a “stub” is beneficial (like returning a dummy result). 
          If so, the plugin must provide that stub logic. Otherwise, ephemeral calls remain forbidden by default.</li>
      <li>Mark each function with the appropriate preview safety classification, so ephemeral mode either calls it, stubs it, or forbids it.</li>
    </ul>
  </li>

  <li>
    <strong>Extra Considerations:</strong>
    <ul>
      <li>We may also need to handle user-supplied callbacks that might have side effects. 
          For example, <code>array:map</code> is “pure” from the bridging perspective but the user’s function might do printing or file I/O. 
          The ephemeral logic can skip or block side-effectful callbacks unless we stub them too.</li>
      <li>We can eventually refine or enhance “stub” usage so ephemeral calls produce partial or indicative results 
          (e.g., <code>file:read</code> ephemeral might return <code>"(mock file content)"</code> or an empty string 
          so the user sees a “shape” of the result, not real I/O).</li>
      <li>In many cases, just forbidding ephemeral usage is simpler than stubbing. 
          Then, if the user tries <code>file:write</code> while typing, ephemeral mode says 
          <code>"Cannot call file:write in ephemeral mode."</code> which is safer than doing real writes.</li>
    </ul>
  </li>
</ol>

<hr/>

<h2>Repeating the Explanation: “PreviewSafety” Flag</h2>

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

<pre><code>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
}
</code></pre>

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

<hr/>

<h2>List of Functions by Plugin – Purity Classification</h2>

<div class="section">
  <h3>Math Plugin</h3>
  <ul class="fn-list">
    <li>
      <code>math:plus</code>, <code>math:pow</code>, <code>math:sqrt</code>, <code>math:sum</code>, etc.
      &rarr; <span class="pure">Pure</span> &mdash; ephemeral calls are fully safe.
    </li>
    <li>
      <code>math:rand</code> &rarr; can be <span class="maybe">maybe pure</span> if it uses a local RNG 
      that doesn't persist. But if it changes global seeds or a global RNG state, 
      ephemeral calls must be <span class="side-effect">forbidden or stubbed</span>.
    </li>
    <li>
      <code>math:srand</code> &rarr; definitely <span class="side-effect">Side-effectful</span> (reseeding). 
      Mark as <code>Forbid</code> in ephemeral mode or provide a no-op <em>Stub</em>.
    </li>
  </ul>
</div>

<div class="section">
  <h3>String Plugin</h3>
  <ul class="fn-list">
    <li>
      <code>string:lower</code>, <code>string:upper</code>, <code>string:length</code>, <code>string:concat</code>, <code>string:to_string</code> 
      &rarr; <span class="pure">Pure</span>.
    </li>
  </ul>
</div>

<div class="section">
  <h3>Array Plugin</h3>
  <ul class="fn-list">
    <li><code>array:lower</code>, <code>array:upper</code>, <code>array:keys</code>, <code>array:length</code>, <code>array:join</code> 
      &rarr; <span class="pure">Pure</span> bridging logic. 
    </li>
    <li><code>array:filter</code>, <code>array:map</code>, <code>array:reduce</code>, <code>array:each</code> &rarr; 
      <span class="maybe">Maybe</span> because side effects can happen if the user’s callback is side-effectful. 
      The bridging itself is pure, but ephemeral calls might need to block or stub user callbacks that do I/O.
    </li>
    <li><code>array:assoc</code>, <code>array:nth</code>, <code>array:range</code>, <code>array:tail</code> 
      &rarr; <span class="pure">Pure</span>.
    </li>
  </ul>
</div>

<div class="section">
  <h3>File Plugin</h3>
  <ul class="fn-list">
    <li><code>file:read</code>, <code>file:write</code>, <code>file:stream</code> 
      &rarr; <span class="side-effect">Side-effectful I/O</span>. 
      We forbid ephemeral usage or create stubs that return dummy data if needed.
    </li>
  </ul>
</div>

<div class="section">
  <h3>Net Plugin</h3>
  <ul class="fn-list">
    <li><code>net:fetch</code>, <code>net:ping</code>, <code>net:stop</code>, <code>poll_events</code>, <code>block_until_no_tasks</code>, <code>embedded_ping</code>
    &rarr; <span class="side-effect">Side-effectful</span> (networking, threads). 
    Typically <code>Forbid</code> ephemeral usage or stub it.
    </li>
  </ul>
</div>

<div class="section">
  <h3>Process Plugin</h3>
  <ul class="fn-list">
    <li><code>process:info</code> 
      &rarr; <span class="maybe">Potentially safe</span> (it only reads system info). 
      We might mark it <code>Safe</code> if we consider reading system info “pure enough.” 
    </li>
    <li><code>process:check_tasks</code> 
      &rarr; <span class="side-effect">Side-effectful</span>, manipulates background tasks or polls them, 
      so ephemeral usage might be <code>Forbid</code>.
    </li>
  </ul>
</div>

<div class="section">
  <h3>Test Plugin</h3>
  <ul class="fn-list">
    <li>
      <code>describe</code>, <code>it</code>, <code>expect_equal</code>, <code>expect_not_equal</code>, etc.
      &rarr; <span class="side-effect">Side-effectful</span>, storing test state or printing. 
      Typically forbid ephemeral usage or stub with no test state changes.
    </li>
  </ul>
</div>

<div class="section">
  <h3>Event Plugin</h3>
  <ul class="fn-list">
    <li><code>event:timeout</code>, <code>event:interval</code>, <code>event:stop</code>, <code>event:check_tasks</code> 
      &rarr; <span class="side-effect">Side-effectful</span> scheduling tasks. 
      Ephemeral usage is normally <code>Forbid</code> or maybe <em>Stub</em> to produce dummy handles.
    </li>
  </ul>
</div>

<div class="section">
  <h3>Date Plugin</h3>
  <ul class="fn-list">
    <li><code>date:timestamp</code>, <code>date:ms</code>, <code>date:micro</code> 
      &rarr; <span class="pure">Generally pure enough</span> (just reading current time). 
      We can allow ephemeral calls that simply read the system clock in the ephemeral environment.
    </li>
  </ul>
</div>

<hr/>

<h2>Conclusion</h2>

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

<p>
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 <em>must provide</em> a <strong>stub function</strong> 
(e.g., returning a dummy success) for ephemeral mode. Otherwise ephemeral calls remain blocked.
</p>

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

</body>
</html>