#779·MiroFish

Six config fields are generated but never read by any runner (and one is never rendered either)

Author: conradorebuffoCreated Aug 16, 2026Updated Sep 1, 2026
Labelsenhancementhelp wanted

Six fields produced by SimulationConfigGenerator never reach the simulation. Every claim below resolves to a path:line on b5b53acc and can be checked with grep alone — no need to run anything.

The six fields

field written by generator rendered in UI read by any runner
scheduled_events yes (hardcoded to []) no no
narrative_direction yes yes no
stance yes (per agent) yes no
sentiment_bias yes (per agent) yes no
recency_weight yes yes no
echo_chamber_strength yes yes no
git grep -nw -E "scheduled_events|narrative_direction|stance|sentiment_bias|recency_weight|echo_chamber_strength" b5b53acc -- backend/scripts/
# (no output)

The three runners — run_reddit_simulation.py, run_twitter_simulation.py and run_parallel_simulation.py — have zero occurrences of any of them. This is not a limitation of the Reddit path: no path consumes them.

What run_reddit_simulation.py actually reads from the config is four keys that drive the simulation — llm_model (:450), time_config (:478), agent_configs (:479) and event_config.initial_posts (:592-593) — plus simulation_id, echoed to the log at :532.

scheduled_events is the starkest case, and it maps to a README promise

The README advertises:

You can inject variables dynamically from a "God's-eye view"

That is what scheduled_events is for. It exists in exactly two places in the whole repository:

git grep -nw scheduled_events b5b53acc
b5b53acc:backend/app/services/simulation_config_generator.py:121:    scheduled_events: List[Dict[str, Any]] = field(default_factory=list)
b5b53acc:backend/app/services/simulation_config_generator.py:725:            scheduled_events=[],

:121 is the dataclass field. :725 is _parse_event_config overwriting whatever the model returned with a hardcoded empty list — so the generator does not even populate it. And unlike the other five, it has no binding in the frontend at all: it is generated, discarded, and never shown.

The event-config prompt does not ask for it either (simulation_config_generator.py:696-705 asks only for hot_topics, narrative_direction, initial_posts and reasoning).

The mechanism to deliver it already exists

initial_posts is published through ManualAction(action_type=ActionType.CREATE_POST) in a single env.step() before the round loop (run_reddit_simulation.py:597-620), and the loop starts right after at :626 (Twitter is symmetric: :612-627 and :633).

A scheduled event is the same publication, fired from inside the loop at its target round. Nothing new needs inventing.

I have this implemented and tested and am happy to open a PR — see the end.

Notes on the other five, so the issue is accurate rather than tidy

These are not all the same case, and I would rather say so than round them into one bullet:

  • stance / sentiment_bias have a natural destination: the free-text persona field, composed in oasis_profile_generator.py:721 and :770. But it is currently unreachable — SimulationManager.prepare_simulation generates the profiles (around simulation_manager.py:357) before it generates the simulation_config.json that holds the per-agent stances (around :425-443). At persona-building time the value does not exist yet. Fixing that means reordering the pipeline, which felt like the maintainers' call rather than an outside PR — so I left it out.

  • recency_weight does have a real counterpart downstream: calculate_hot_score (oasis/social_platform/recsys.py) already weights recency through a seconds / 45000 term, with 45000 hardcoded. But recsys.py lives in camel-oasis==0.2.5 (backend/requirements.txt:22), a pinned PyPI dependency, not in this repo — so wiring it would be a PR to camel-ai/oasis, not here.

  • echo_chamber_strength has nowhere to live under recsys_type='reddit': that recommender is pure hot score (likes − dislikes + time), with no notion of similarity, affinity or clustering. The only cosine-similarity path is twitter/twhin-bert. Removing it, or scoping it to the twitter path, seems more honest than wiring it.

    Worth noting: recsys_type and max_rec_post_len have zero occurrences in this repository — MiroFish never configures the recommender at all, it takes whatever OASIS defaults to.

A separate defect found while testing: simulation processes never exit

Not part of the six fields, but it surfaced on stock code and seems worth reporting:

  1. simulation_runner.py:517-525 builds the spawn command as [python, script, --config, path] plus optionally --max-rounds. --no-wait is never passed.
  2. run_reddit_simulation.py:710-713--no-wait defaults to False.
  3. run_reddit_simulation.py:732wait_for_commands=not args.no_wait, therefore always True for any simulation started through the API.
  4. simulation_runner.py:641 — the monitor thread runs while process.poll() is None: ... sleep(2), waiting for an exit that never comes, so its finalization block is never reached.

The only way out is an explicit POST /api/simulation/stop; no natural-completion path calls it. Every API-started simulation therefore leaves its process resident, holding the whole OASIS environment, until something stops it.

Happy to split this into its own issue if you prefer.

Offer

I have scheduled_events implemented end to end on top of b5b53acc — generator prompt, parser, agent assignment shared with initial_posts, and both runners — with unit tests, and verified on a clean checkout. With an empty list the execution path is identical to today, so existing configs are unaffected.

One design question I would rather ask than assume: should the trigger be the round number, or the simulated clock time? I used round, because it is what the generator can reason about and what the loop already indexes, but the time config would allow "at simulated hour N" instead. Happy to follow whichever you prefer before opening the PR.

I am also aware of #573, which adds a Narrative Layer with a "God Mode" inject_event. That one explicitly targets the prose layer and lists "Mid-sim OASIS prompt injection" among its non-goals, so the two are complementary rather than overlapping — this would give #573's God Mode something real to push into, if that is ever wanted.