Download Game! Currently 82 players and visitors. Last logged in:DynaMutaFrenorDeepwood

Blitzer's Blog >> 71942

Back to blogs index
Posted: 02 Sep 2026 20:35 [ permalink ]
This is a fascinating and highly consequential architectural question.

You are proposing adding **behavior (function execution)** directly into the
parameter resolution phase, rather than restricting it to the `EXECUTE_TOOL`
nodes.

Let's break down the implications of adding a syntax like `[[locals.this_user->
logout]]` into the AST.

### The Problem with Inline Function Calls

If we implement `->` to execute functions during the `resolveParams()` step,
we fundamentally break the "Hexagonal Architecture" and the deterministic
nature of the pure state machine.

Here is why:

1. **Hidden Side Effects:** The core principle of our engine is that all I/O
and state mutations happen explicitly via `EXECUTE_TOOL` (which yields to the
Host) or `MATH_OP` (which alters local memory). If a parameter string
evaluation can trigger `->logout`, a simple data-read operation is suddenly
causing a system side-effect.
2. **Synchronous Blocking:** The `resolveParams()` function is a synchronous
`while` loop. If `->logout` requires network I/O (like invalidating a token on
a server), the `AgentCore` cannot pause and yield during a string replacement.
It would freeze the thread.
3. **Core Dump Corruption:** If the agent halts immediately after resolving
`[[locals.this_user->logout]]` but before emitting the primary syscall, the
system state has mutated (the user is logged out), but the `intent_log` has no
record of the `EXECUTE_TOOL` that caused it. Resuming the core dump will fail
because the environment is now out of sync with the event log.

### The Data-Oriented Alternative

In a strict Event-Sourced model, **data and actions must be strictly
separated.**

If `this_user` is an object in local memory, it should only contain *data*
(e.g., `{"id": "user_992", "session_token": "abc"}`). It should not contain
methods.

If you want to log a user out, that must be a distinct node in the AST,
explicitly telling the Host Environment to execute that action.

```json
/ The Data-Oriented (Safe) Way
{
  "type": "EXECUTE_TOOL",
  "tool_name": "logout_user",
  "params": {
    // We strictly read data using the dot notation
    "token": "[[locals.this_user.session_token]]" 
  },
  "next": "node_05"
}

```

### When to Use "Functions" in the AST

There is *one* scenario where inline functions are acceptable: **Pure Data
Transformation**.

Sometimes, you need to format data before sending it to a tool, and you don't
want to waste an entire AST node just to do a regex replace or to lowercase a
string.

For this, instead of object methods (`->`), you use **Pipeline Operators
(`|`)** to apply pure, synchronous, side-effect-free helper functions.

**Syntax Example: `[[locals.user_name | lowercase]]**`

If we want to support this, we modify the `resolveParams()` parser to
recognize the pipe `|` and apply a strict whitelist of pure JS functions (like
`toUpperCase`, `trim`, `uriEncode`).

```javascript
/ Adding pure pipelines to the resolveString parser:

const resolveString = (str) => {
    let currentStr = str;
    const innerBracketRegex = /\[\[([^\[\]]+)\]\]/g; 

    while (innerBracketRegex.test(currentStr)) {
        currentStr = currentStr.replace(innerBracketRegex, (match, pathStr) =>
{
            
            // Split by pipe to separate the path from the formatter functions
            const parts = pathStr.split('|').map(p => p.trim());
            const dataPath = parts[0];
            const formatters = parts.slice(1);
            
            // 1. Resolve the data
            const keys = dataPath.split('.');
            let value = keys.reduce((acc, key) => (acc && acc[key] !==
undefined) ? acc[key] : null, context);
            
            if (value === null) return "";

            // 2. Apply pure formatters sequentially
            formatters.forEach(formatter => {
                if (formatter === 'lowercase') value = String(value).toLowerCas
e();
                if (formatter === 'trim') value = String(value).trim();
                if (formatter === 'url_encode') value = encodeURIComponent(Stri
ng(value));
            });

            return value; 
        });
    }
    return currentStr;
};

```

### Summary

* **Rule of Thumb:** If it causes a side-effect (network request, file write,
database update), it **must** be an `EXECUTE_TOOL` node yielding to the host.
* **Reading Data:** Use `[[locals.variable.property]]`.
* **Transforming Data (Pure):** Use pipeline syntax `[[locals.variable.property
 | uppercase]]`.

By adhering to this separation, your AST remains fully deterministic, your
core dumps remain perfectly restorable, and your JSON engine stays lean.