Skip to main content
Paul Welty, PhD AI, WORK, AND STAYING HUMAN

Work log: Phantasmagoria — March 23, 2026

What shipped today

The narrative-first pipeline is now fully integrated into all three production generators. Yesterday we built and tested the new Phase 1 → Phase 2 → Phase 3 architecture with test harnesses; today we replaced the old code paths in generate_standalone.py, generate_anomaly.py, and generate_site.py with the new flow. The old GUIDE_*.md prompt building (hundreds of lines of string concatenation per generator) was replaced by simple template loading from PROMPT_*.md files with variable substitution. The old inline YAML assembly (LiteralStr/LiteralDumper/convert_to_literal, duplicated in each generator) was replaced by centralized event_assembler.py calls. The old roller-based follow-up generator was replaced by the inline follow-up pattern where Phase 1 defines follow-ups and Phase 2 assigns effects. Net result: -737 lines across the three generators while gaining better narrative quality, coherent effects, and simpler code.

Before the integration work, we ran a comprehensive codebase scout (4 parallel agents scanning dead code, error handling, feature gaps, and test coverage). This surfaced 5 issues: stale PRODUCT.md, missing tests for event_assembler.py, dead code from the migration, tech diversity problems in Phase 2, and the generator integration itself. All 5 were executed in this session — the scout-to-ship cycle completed in a single day.

Other improvements: PRODUCT.md was updated to reflect the new “AI for creativity, constraints for balance” principle (replacing the stale “determinism for balance” language). 38 unit tests were added for event_assembler.py including 7 new tests for banned resource name enforcement. 730 lines of dead code were removed (deprecated functions, orphaned guide files, unused exports). Phase 2’s tech section was reorganized by narrative theme to improve tech diversity.

Completed

  • #224 — Update PRODUCT.md to reflect narrative-first architecture
  • #225 — Add unit tests for event_assembler.py (38 tests)
  • #226 — Remove dead code from narrative-first migration (-730 lines)
  • #227 — Improve Phase 2 tech diversity and enforce banned resource names
  • #223 — Integrate narrative-first prompts into production generators (decomposed → #232, #233, #234)
  • #232 — Integrate narrative-first prompts into generate_standalone.py (-252 lines)
  • #233 — Integrate narrative-first prompts into generate_anomaly.py (-209 lines)
  • #234 — Integrate narrative-first prompts into generate_site.py (-276 lines)

Carry-over

  • Generate a test release with the new pipeline — run generate_standalone.py, generate_anomaly.py, and generate_site.py against celestial_equinox and playtest the results in Stellaris 4.3
  • Fix 3 pre-existing test failurestest_outcome_prompt.py (2 tests checking old prompt text) and test_render_lint_integration.py (1 test) have been failing since the prompt rewrite; the assertions need updating
  • Old followup_generator.py still in tree — no longer called by any production generator, but still imported by extract_trigger_events_yaml which is used. The follow-up generation functions are dead; extract_trigger_events_yaml could move to event_assembler.py

Risks

  • The generators now produce a different Phase 1 output format (simple JSON with name, description, options) vs the old format (full event structure with slug, kind, interaction_events). Any external tooling that reads Phase 1 output would break — but nothing does, since it’s internal.
  • Phase 2 temperature was changed from 1.0 (matching Phase 1) to 0.7 across all generators. This should produce more consistent effect assignments but hasn’t been batch-tested yet.

Flags and watch-outs

  • The old GUIDE_STANDALONE.md, GUIDE_ANOMALY.md, and GUIDE_SITE.md files still exist but are no longer used by the generators. They’re referenced by build_prompt() (the old all-in-one prompt builder) which itself is only used by build_existing_events_context(). These should be cleaned up eventually.
  • roll_options_for_event and build_phase2_prompt/build_phase2_flavor_prompt functions still exist in the generators but are dead code now. Follow-up cleanup issue needed.

Next session

  1. Playtest the new pipeline — generate a full celestial_equinox release (3 standalones, 3 anomalies, 3 dig sites) and test in Stellaris 4.3. This is the first real batch run with the new narrative-first flow.
  2. Fix pre-existing test failures — update test_outcome_prompt.py assertions to match the rewritten prompt text.
  3. Clean up remaining dead code — remove build_phase2_prompt, build_phase2_flavor_prompt, old build_prompt(), and dead GUIDE_*.md files that are no longer referenced.

Why customer tools are organized wrong

This article reveals a fundamental flaw in how customer support tools are designed—organizing by interaction type instead of by customer—and explains why this fragmentation wastes time and obscures the full picture you need to help users effectively.

Infrastructure shapes thought

The tools you build determine what kinds of thinking become possible. On infrastructure, friction, and building deliberately for thought rather than just throughput.

Server-side dashboard architecture: Why moving data fetching off the browser changes everything

How choosing server-side rendering solved security, CORS, and credential management problems I didn't know I had.

The work of being available now

A book on AI, judgment, and staying human at work.

The practice of work in progress

Practical essays on how work actually gets done.

When your agents start breaking each other's code

Two agents modified the same file independently and created database locks. The fleet hit 135 issues in one day — and the coordination problem that comes with it.

The removal tax

The most productive thing you can do with a product is take features away. Eighty-nine issues closed across eight projects, and the hardest lesson came from a pipeline that ran perfectly and produced nothing.

The product changed its mind

A product pivoted its entire philosophy mid-session — from 'here's your list' to 'here's your next thing.' The code shipped in the same conversation as the idea. That's not iteration. That's something else.