Six config fields are generated but never read by any runner (and one is never rendered either)
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_biashave a natural destination: the free-textpersonafield, composed inoasis_profile_generator.py:721and:770. But it is currently unreachable —SimulationManager.prepare_simulationgenerates the profiles (aroundsimulation_manager.py:357) before it generates thesimulation_config.jsonthat 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_weightdoes have a real counterpart downstream:calculate_hot_score(oasis/social_platform/recsys.py) already weights recency through aseconds / 45000term, with45000hardcoded. Butrecsys.pylives incamel-oasis==0.2.5(backend/requirements.txt:22), a pinned PyPI dependency, not in this repo — so wiring it would be a PR tocamel-ai/oasis, not here.echo_chamber_strengthhas nowhere to live underrecsys_type='reddit': that recommender is pure hot score (likes − dislikes + time), with no notion of similarity, affinity or clustering. The only cosine-similarity path istwitter/twhin-bert. Removing it, or scoping it to the twitter path, seems more honest than wiring it.Worth noting:
recsys_typeandmax_rec_post_lenhave 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:
simulation_runner.py:517-525builds the spawn command as[python, script, --config, path]plus optionally--max-rounds.--no-waitis never passed.run_reddit_simulation.py:710-713—--no-waitdefaults toFalse.run_reddit_simulation.py:732—wait_for_commands=not args.no_wait, therefore alwaysTruefor any simulation started through the API.simulation_runner.py:641— the monitor thread runswhile 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.
Source: 666ghj/MiroFish