Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8824a6e
feat(sim): reflexive world-state model for the calendar simulation
Oct 16, 2026
4b2858f
docs: record reflexive world-state design, handoff and progress
Oct 16, 2026
4749466
Fix review findings for world model robustness and resume handling
Copilot Oct 16, 2026
92ad35d
docs: record live validation of the reflexive world-state simulation
Oct 16, 2026
15b977e
docs: track the reflexive world-state handoff with the live-run evidence
Oct 16, 2026
7f18af4
Merge remote-tracking branch 'legacy/claude-reflexive-world-state-mod…
Oct 16, 2026
7a5318a
test(sim): interrupt the partial-resume loop test with the shutdown s…
Oct 16, 2026
03dcd94
feat(ui): make the World State period strip a round selector
Oct 16, 2026
abb5ddc
fix(report): survive provider content filters in binary extraction; r…
Oct 16, 2026
5797ae0
fix(sim): precise provider-failure records, run-language check and un…
Oct 16, 2026
0e57c77
fix(sim): seed plans from v3 dossiers, chart seed point, intact simul…
Oct 16, 2026
a481453
fix(report): survive provider content filters in section generation; …
Oct 16, 2026
9945b50
docs(handoff): record the no-fallback-provider decision and the trans…
Oct 16, 2026
cb94a2f
Merge branch 'claude/friendly-murdock-e4a17e' into claude-reflexive-w…
Oct 17, 2026
4c6a7e2
Merge branch 'claude/quirky-lamport-99f71d' into claude-reflexive-wor…
Oct 17, 2026
5f9f54a
Merge branch 'claude/wizardly-shamir-b82bf9' into claude-reflexive-wo…
Oct 17, 2026
35de0e4
feat(ui): per-period world state and feed in the simulation tab
Oct 17, 2026
1de81a5
feat(sim): port consent, modelling gaps and behaviour diagnostics fro…
Oct 17, 2026
f78397e
docs(handoff): record the Codex-port commit and the merge to main
Oct 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ LLM_PROVIDER=claude-cli
# SIM_HORIZON_DEFAULT_MONTHS=12 # 问题中解析不出预测期限(确定性各档+LLM 兜底均失败)时的降级默认时域(月)
# SIM_WORLD_DELTA=true # 世界时钟头部附带上一时段变化摘要(纯确定性拼装,无数值份额外泄;仅日历模式生效)
# SIM_DECISION_CHANNEL_INBAND=true # 决策通道逐轮在环内引出承诺并推进 WorldState(仅日历模式;关闭=回退事后一次性通道)
# SIM_WORLD_MODEL=true # 反身世界模型(docs/handoff/reflexive-world-state/design.md):PREPARE 封印 world_model 块(研究/官方数据的状态变量、角色行动杠杆类别、带价关系),
# # 运行期每轮每个决策角色一次结构化决策(选项菜单由其角色契约与当前世界生成,声明以帖子发布),双平台对齐后提交唯一一次世界更新
# # (机械内核 + 有界仲裁 LLM),下一轮所有 agent 观察到变化后的世界。false=回退旧的环内情景份额演化(逐字节不变);仅日历模式生效
# SIM_WORLD_ARBITER=true # 世界更新中的仲裁 LLM 调用(裁决争议行动、移动状态变量、产生涌现事件/延迟效应);false=仅机械推进(容量/承诺/关系/到期效应/日程事件)
# SIM_WORLD_BARRIER_TIMEOUT_S=1800 # 平台等待另一平台交付本轮的秒数;超时按已交付内容提交并把缺席平台标为 stalled
# SIM_WORLD_DECISION_MAX_ACTORS=24 # 每轮决策角色上限(principal 优先,其后按影响力取活跃具名角色;受众填充不决策)
# SIM_WORLD_DECISION_CONCURRENCY=6 # 每轮并发的决策 LLM 调用数
# SIM_WORLD_MAX_VARIABLES=24 # 种子状态变量上限(先取定量事实,再取官方序列最新观测)
# SIM_WORLD_MAX_CHANGE_RATIO=0.5 # 仲裁对数值变量的单轮变动钳制(相对当前量级的比例;不变式 I-2)
# WORLDSTATE_ENTROPY_MIX=true # WorldState.step 熵地板:按时段天数向种子基率先验混合,防长时域份额锁死(仅日历模式生效)
# OASIS_MAX_AGENTS=80 # 智能体上限;超过按(匹配actor,影响力,邻边数)排序保留,始终保留研究 actor(T3.13)
# ACTOR_CAST_MAX=20 # 主角色阵容硬上限(actor-cast discipline):只保留决策/行动会因果性影响预测结果的 main actors;
Expand Down Expand Up @@ -646,6 +655,7 @@ RESEARCH_ALLOW_LOW_QUALITY_SOURCES=false
# REPORT_VIZ_PLOTLYJS_INLINE=false # i1 回退旋钮:true 恢复逐图内联 plotly.min.js(每图 ~4.86MB);默认 directory 模式 + 服务时内联(每图 ~8.4KB)
# REPORT_SECTION_RETRY_MAX=2 # RPT-2 每章写失败占位符前的重试次数;RQ-1 1→2;0=旧的无重试
# REPORT_SECTION_RETRY_BACKOFF_S=8.0 # RPT-2 章节重试基础退避秒数(按次线性,封顶 60s)
# REPORT_FILTER_SAFE_LADDER=true # FILTER-SAFE 章节被提供方内容审查(HTTP 400 code 1301 / 422)拒绝后的处置:采纳仅因工具调用下限被退回且通过污染检测的完整草稿;无草稿时不退避、立即升级重试(L1 机构称谓写作指令+工具下限 1+检索回包截断 6k 字;L2 无检索工具、仅据背景档案与已完成章节成文)。走过该处置的章节记入 meta.json 的 filter_safe_sections(0/1/2)。false=旧的原样退避重试
# REPORT_CRITIQUE_BEFORE_PROSE=true # RPT-3 自校准/premortem 移到写散文**之前**,钉定骨架==交付 forecast.json(仅 REPORT_FORECAST_SELF_CRITIQUE 开启时生效)
# FORECAST_BINARY_CONTRARIAN=true # RPT-4 二元预测提示词加入逆向框架规则 + stdev<0.12 或全部 p>0.5 时一轮有界(0.05-0.35)低概率重构
# FORECAST_SIM_SENSITIVITY=true # XRUN-1(b) 二元预测抽取注入模拟定量信号包,每条概率须说明相对 base_rate_anchor 的移动及具名模拟信号来源
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1000,11 +1000,13 @@ sequenceDiagram
- On Twitter: create post, like, repost, quote, comment, follow, search posts, trend, do nothing.
- On Reddit: create post, comment, like or dislike a post, like or dislike a comment, search posts, search users, trend, refresh, follow, mute, do nothing.
- Recommendations come from a model-free recommender, which makes no extra LLM calls.
- **World state.** A shared WorldState advances once per paired round. After both platforms have delivered round *i*:
- one batched LLM call reads the agents' commitments;
- the state steps forward, with inertia scaled to the calendar unit and a base-rate entropy floor.
- **Reflexive world state** (`SIM_WORLD_MODEL=true`, calendar mode). Every round is a cycle of observe → decide → act → world update, shared by both platforms:
- *Observe.* Each active agent receives the committed WORLD STATE brief: tracked facts (seeded from the dossier's quantitative facts and the official-data snapshot, each with unit, as-of date and provenance), last period's moves and their consequences, alliance and rivalry shifts, and open commitments. Scenario probabilities are never shown to agents.
- *Decide.* Each deciding actor (principals first, then active named actors, capped by `SIM_WORLD_DECISION_MAX_ACTORS`) makes ONE structured decision from a menu grounded in its sealed role brief and the current world: responses to moves aimed at it, its documented plans, its agency class's catalogued levers (government, regulator, legislature, central bank, firm, union, NGO, coalition, individual leader…) filtered by remaining capacity, and `hold_position`. The answer carries targets, magnitude, a public statement, the exact terms when the move is an offer, a dated commitment, alliance moves and the scenario the move pushes toward. An offer (talks, alliance, concession, agreement, deal) binds nobody until the recipient accepts, counters, rejects or defers it from its own menu; unanswered offers lapse after two periods. Invalid or failed answers degrade to a typed hold, never to silence.
- *Act.* The statement is published as that actor's post on both platforms (one decision per actor per round, shared across platforms) and the reaction step lets everybody reply.
- *World update.* When both platforms have delivered the round, ONE update runs: the deterministic kernel consumes capacity, settles offers (acceptance binds both parties with obligations; a lapsed obligation or a withdrawal is a breach that costs reputation and the relationship), registers commitments (honoured by acting when due, lapsing otherwise), nudges relationships, fires due delayed effects and research events; then a single bounded arbiter call resolves contested moves, moves state variables (clamped by `SIM_WORLD_MAX_CHANGE_RATIO`), emits emergent events and delayed effects. The scenario-share WorldState steps from the actors' scenario commitments with the calendar inertia and entropy floor. A platform never starts round *i+1* before update *i* is committed.

The trajectory is saved to `world_state_trajectory.json` and charted in the report.
`world_state.json` (latest world, with its offers, the seed's modelling gaps and per-round behaviour diagnostics), `world_state_history.jsonl`, `world_actions.jsonl`, `world_state_trajectory.json` and `decisions.jsonl` are saved; the report's diagnostic pack renders the evolution, offers, gaps and a world-variables chart, and the dashboard's simulation tab shows a live World State panel whose period strip opens any committed round — the feed beside it then shows that period's posts and replies only. With `SIM_WORLD_MODEL=false` the legacy in-band scenario evolution runs unchanged.
- **Monitoring and completion.**
- A monitor thread in the backend tails the action logs every 2 s into `run_state.json`.
- The pipeline polls every 5 s and stops a run that makes no round progress for 30 minutes.
Expand All @@ -1019,6 +1021,7 @@ Output, in `backend/uploads/simulations/<sim_id>/`:
- `simulation_config.json` and its seal;
- `twitter/actions.jsonl` and `reddit/actions.jsonl`, plus the two platform SQLite databases;
- `world_state_trajectory.json` and `decisions.jsonl`;
- `world_state.json`, `world_state_history.jsonl` and `world_actions.jsonl` (reflexive world model);
- `run_summary.json` and `simulation.log`.

`SIM_TEMPORAL_MODE=hours` restores the legacy news-cycle mode, in which an LLM picks 24–168 simulated hours.
Expand Down Expand Up @@ -1491,6 +1494,8 @@ Provider credentials are optional environment inputs, passed only to the relevan
| Setting | Default | Purpose |
|---|---|---|
| `SIM_TEMPORAL_MODE` | `calendar` | `calendar` or the legacy `hours` |
| `SIM_WORLD_MODEL` · `SIM_WORLD_ARBITER` | `true` · `true` | Reflexive world model (structured actor decisions, one world update per round) and its arbiter call; `false` keeps the legacy scenario-share evolution |
| `SIM_WORLD_DECISION_MAX_ACTORS` · `SIM_WORLD_MAX_CHANGE_RATIO` | `24` · `0.5` | Deciding actors per round; per-round clamp on arbiter numeric changes |
| `SIM_CALENDAR_TARGET_MAX_ROUNDS` · `OASIS_DEFAULT_MAX_ROUNDS` | `36` · `36` | Round budget used to choose the calendar unit |
| `ACTOR_CAST_MAX` | `20` | Maximum researched cast size |
| `SIM_AUDIENCE_AGENTS` | `0` | Extra rule-generated audience agents |
Expand Down
13 changes: 9 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -1000,11 +1000,13 @@ sequenceDiagram
- 在 Twitter 上:发帖、点赞、转发、引用、评论、关注、搜索帖子、查看趋势、什么都不做。
- 在 Reddit 上:发帖、评论、给帖子点赞或点踩、给评论点赞或点踩、搜索帖子、搜索用户、查看趋势、刷新、关注、屏蔽、什么都不做。
- 信息流由免模型的推荐器生成,不产生额外的 LLM 调用。
- **世界态。** 共享的 WorldState 每对齐一轮前进一次。两个平台都提交第 *i* 轮之后:
- 一次批量 LLM 调用读取智能体的承诺;
- 世界态随之推进一步,其惯性按日历单位缩放,并设有基率熵下限。
- **反身世界态**(`SIM_WORLD_MODEL=true`,日历模式)。每一轮都是观察 → 决策 → 行动 → 世界更新的循环,两个平台共享:
- *观察。* 每个活跃智能体收到已提交的「世界状态」简报:追踪事实(由档案定量事实与官方数据快照播种,带单位、截止日与来源)、上一时段的行动及其后果、结盟与对立的变动、以及未兑现的承诺。情景概率绝不展示给智能体。
- *决策。* 每个决策角色(主角优先,其后为活跃具名角色,受 `SIM_WORLD_DECISION_MAX_ACTORS` 约束)从一份基于其封印角色简报与当前世界生成的菜单中做出**一次**结构化决策:对针对自己的行动的回应、档案记载的计划、其行动杠杆类别(政府、监管机构、立法机关、央行、企业、工会、NGO、联盟、个人领导者……)在剩余容量内的目录动作,以及 `hold_position`。答案携带目标、力度、公开声明、当行动是要约时的确切条款、带期限的承诺、结盟动作与该行动所推向的情景。要约(谈判、结盟、让步、协议、交易)在对方从自己的菜单中接受、反要约、拒绝或暂缓之前对任何一方都不具约束力;两个时段无人应答的要约自动失效。无效或失败的回答降级为有类型标注的观望,而非沉默。
- *行动。* 声明作为该角色的帖子在两个平台发布(每轮每个角色一次决策,跨平台共享),回应步骤让所有人回复。
- *世界更新。* 两个平台都交付本轮后,只运行**一次**更新:确定性内核消耗容量、结算要约(接受即对双方产生义务;义务失效或单方退出即为违约,损及声誉与关系)、登记承诺(到期时以行动兑现,否则失效)、推移关系、触发到期的延迟效应与研究事件;随后一次有界的仲裁调用裁决争议行动、移动状态变量(受 `SIM_WORLD_MAX_CHANGE_RATIO` 钳制)、产生涌现事件与延迟效应。情景份额 WorldState 依据角色的情景承诺、按日历惯性与熵下限推进。任一平台在第 *i* 轮更新提交前绝不开始第 *i+1* 轮。

轨迹保存在 `world_state_trajectory.json`,并在报告中绘成图表。
保存 `world_state.json`(最新世界,含其要约、种子的建模缺口与逐时段行为诊断)、`world_state_history.jsonl`、`world_actions.jsonl`、`world_state_trajectory.json` 与 `decisions.jsonl`;报告的诊断信号包渲染世界演化、要约、缺口与世界变量图,仪表盘的模拟页显示实时「世界状态」面板,其时段条可打开任一已提交轮次——旁边的信息流随之只显示该时段的帖子与回复。`SIM_WORLD_MODEL=false` 时旧的环内情景演化原样运行。
- **监控与完成判定。**
- 后端的一个监控线程每 2 秒把行为日志汇总进 `run_state.json`。
- 管线每 5 秒轮询一次;连续 30 分钟没有回合进展的模拟会被停止。
Expand All @@ -1019,6 +1021,7 @@ sequenceDiagram
- `simulation_config.json` 及其封印;
- `twitter/actions.jsonl` 与 `reddit/actions.jsonl`,以及两个平台的 SQLite 数据库;
- `world_state_trajectory.json` 与 `decisions.jsonl`;
- `world_state.json`、`world_state_history.jsonl` 与 `world_actions.jsonl`(反身世界模型);
- `run_summary.json` 与 `simulation.log`。

设置 `SIM_TEMPORAL_MODE=hours` 可恢复旧式的新闻周期模式,由 LLM 选定 24–168 个模拟小时。
Expand Down Expand Up @@ -1491,6 +1494,8 @@ npm run dev # 另一种方式:在前台同时运行两者(Ctrl
| 设置 | 默认值 | 作用 |
|---|---|---|
| `SIM_TEMPORAL_MODE` | `calendar` | `calendar`,或旧式的 `hours` |
| `SIM_WORLD_MODEL` · `SIM_WORLD_ARBITER` | `true` · `true` | 反身世界模型(结构化角色决策、每轮一次世界更新)及其仲裁调用;`false` 保留旧的情景份额演化 |
| `SIM_WORLD_DECISION_MAX_ACTORS` · `SIM_WORLD_MAX_CHANGE_RATIO` | `24` · `0.5` | 每轮决策角色数;仲裁数值变动的单轮钳制 |
| `SIM_CALENDAR_TARGET_MAX_ROUNDS` · `OASIS_DEFAULT_MAX_ROUNDS` | `36` · `36` | 选择日历单位时使用的回合预算 |
| `ACTOR_CAST_MAX` | `20` | 研究阵容的最大规模 |
| `SIM_AUDIENCE_AGENTS` | `0` | 额外按规则生成的受众智能体数量 |
Expand Down
Loading
Loading