New Features (2026-06-19) — Memory & Determinism

Two pure-standard-library tools surfaced by the agent / QA research round, wired through the full stack (facade, AC_* executor commands, MCP tools, Script Builder): a persistent agent episodic memory store and a deterministic run harness.

Agent episodic memory

An agent that re-derives “how do I log in to this app” every run wastes tokens and repeats mistakes. AgentMemory records each episode — the goal, the trajectory (steps / tool-calls), and the outcome — to a SQLite file, and recalls the most relevant past episodes by keyword so they can be injected into the planner’s context:

from je_auto_control import AgentMemory

mem = AgentMemory("agent.memory.db")
mem.remember("log in to the billing portal",
             steps=recorded_actions, outcome="success", tags=["auth"])

for episode in mem.recall("portal login", limit=3):
    ...   # feed episode.goal / episode.steps back to the planner

Recall scores each episode by term frequency over its goal + tags + outcome (a dependency-free BM25 stand-in); a vector tier can be added later without changing the API. Commands: AC_memory_remember / AC_memory_recall / AC_memory_recent / AC_memory_forget / AC_memory_stats (and the matching ac_memory_* MCP tools).

Deterministic run

Time and randomness are two of the top causes of flaky automation. DeterministicRun pins both for a with block and records the choices so a run can be reproduced exactly:

from je_auto_control import DeterministicRun

with DeterministicRun(seed=42, freeze_time=1_750_000_000.0) as run:
    ...                      # random.* reproducible; time.time() frozen
manifest = run.manifest()    # {"seed": 42, "freeze_time": 1750000000.0}

Scope (pure standard library — no freezegun dependency): it seeds the global random generator (and numpy if present) and restores its state on exit, and patches time.time / time.time_ns to a fixed instant. time.monotonic is deliberately left alone so duration measurements and timeouts keep working.

seed_everything(seed) is the standalone seeding helper, also exposed as AC_seed_everything / ac_seed_everything for run-wide reproducibility from a flow.