Skip to content

Phase C: Contagion, Timeline Events, and Merged Pass Reasoning#65

Merged
DeveshParagiri merged 13 commits intomainfrom
phase-c-contagion-timeline
Feb 16, 2026
Merged

Phase C: Contagion, Timeline Events, and Merged Pass Reasoning#65
DeveshParagiri merged 13 commits intomainfrom
phase-c-contagion-timeline

Conversation

@DeveshParagiri
Copy link
Copy Markdown
Collaborator

Summary

Completes Phase C of the v2 architecture, adding:

  • Timeline events: Static vs evolving scenario detection, timeline generation, background context injection
  • Conformity-aware prompts: High/low conformity self-awareness phrasing in agent prompts
  • Open-ended outcome skip: Pass 2 classification skipped when all outcomes are open_ended
  • Merged pass reasoning: Single-call reasoning mode (--merged-pass) for cheaper/faster simulations
  • Partner/dependent rendering in personas: Household members now appear in persona text
  • Scenario-aware household config: Household hydration respects scenario context (e.g., professional populations skip household structure)

Key Changes

Simulation

  • _reason_agent_merged_async() - single LLM call with combined role-play + classification schema
  • batch_reason_agents_async() now routes based on config.merged_pass
  • Timeline event application via apply_timeline_exposures() in propagation

Scenario

  • New timeline.py module for timeline generation and static/evolving detection
  • --timeline CLI flag (auto, static, evolving)
  • TimelineEvent model with timestep, event, exposure_rules, description

Population

  • Partner and dependent rendering in persona text
  • Scenario-aware household config hydration

Docs

  • docs/capabilities.md - narrative walkthrough of all supported scenarios
  • Updated docs/simulation-v2-architecture.md - removed explicit ratio injection, clarified conformity approach

Test Plan

  • All non-LLM tests pass (769 passed)
  • Ruff check + format passes
  • Manual test: run simulation with --merged-pass flag
  • Manual test: run evolving timeline scenario

Replace incompatible JSON Schema patterns in build_household_config_schema():
- Tuple-style array items (draft-07) -> array of {upper_bound, label} objects
- Schema-valued additionalProperties -> array of objects with explicit keys

Update _parse_household_config() to convert new array-of-objects format back
to dict/tuple structures expected by HouseholdConfig.

Fix _clean_schema_for_tool() to preserve additionalProperties: false (valid)
while stripping schema-valued additionalProperties (unsupported).

Tested with Claude Sonnet 4.5 - Japan-specific data now returned correctly
instead of falling back to US defaults.
Timeline Events:
- Add TimelineEvent model for evolving scenarios (crises, campaigns)
- Scenarios auto-detect static vs evolving via LLM in generate_timeline()
- Timeline events fire exposures at specified timesteps
- CLI --timeline flag: auto/static/evolving

Contagion & Social Pressure:
- Observable peer actions: agents only see peers who will_share=True
- Conformity attribute shapes self-awareness in prompts
- Timeline recap section shows scenario history in prompts

Open-Ended Skip:
- build_pass2_schema() returns None when all outcomes are open_ended
- Skips Pass 2 classification for exploratory scenarios

Merged Pass Flag:
- Add --merged-pass CLI flag (experimental)
- merged_pass field in SimulationRunConfig
Add _should_hydrate_household_config() to conditionally skip the expensive
agentic research call for populations that don't need household context.

Only hydrate household config when:
1. Any discovered attribute has scope="household", OR
2. Population description contains household keywords (family, couple, retired, etc.)

For purely professional populations (physicians, office workers, voters),
skip household research and use defaults if household sampling triggers.

Saves ~30-60s of LLM calls for 70%+ of use cases.
Add scenario keywords (childcare, housing, school district, etc.) to
_should_hydrate_household_config() so scenarios can trigger household
research even when the base population didn't need it.

Examples:
- "2000 physicians" + "malpractice policy" -> skip household (default)
- "2000 physicians" + "subsidized childcare policy" -> research household

Also fix extend.py to pass household_config and name_config to build_spec
so they're properly merged into the final spec.
Add rich household context to agent personas:

1. Generate first names for NPC partners in _generate_npc_partner()
   using the same name generation as regular agents

2. Add render_household_section() to persona renderer with:
   - Partner phrases: "My husband David is 45", "Sarah and I have been
     together for a while"
   - Kids phrases: "Our daughter Sofia is 14, in high school",
     "We have 2 kids: Emma (12) and Jake (8)"
   - Elderly phrases: "My mother Rosa (72) also lives with us"
   - Single parent support: "It's just me and my son Marcus (10)"
   - Baby-friendly age formatting: "less than a year old" for age 0

3. Call household section from render_persona() after the intro

Templates vary randomly (seeded by agent ID) for natural variety.
@DeveshParagiri DeveshParagiri merged commit b41259f into main Feb 16, 2026
4 of 6 checks passed
@DeveshParagiri DeveshParagiri deleted the phase-c-contagion-timeline branch February 16, 2026 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant