The failure that forced this
For a long stretch, cron prompts lived as Python string literals inside the heartbeat. Improving a prompt meant editing code, committing, restarting the server. Worse — when a quick "temporary" constant got pasted in to test something, it stayed there. Invisible doctrine accumulated everywhere prompts touched runtime. The very intelligence that would execute the prompt had no way to help iterate on it without a code roundtrip.
The rule that replaced it
The 2026-05-12 refactor drew one bright line:
If a future contributor (or future-me) reaches to paste a new baseline prompt body into Python or TypeScript, stop. That instinct is the old failure mode. Update the section's originals.json, expose it through Admin → Prompts, wire the caller to the section registry.
Three layers
- Original — the git-tracked baseline prompt text for a section, under
cwkPippa/prompts/{section}/originals.json. "Reset Override" returns to this. - Override — Dad's active tuning layer under
~/pippa-db/{section}_prompts.json. "Save Override" writes here. - Code contract — stable keys, placeholder metadata, validation, rendering, and runtime behavior. Code must not own baseline wording.
The Admin button Promote to Git Original promotes the current editor text into the original and clears that key's override — the canonical path when a tuned prompt has proven better than the old baseline.
Sections currently in the registry: council, cwk-site, soul-stream, audit, utility, scheduler, souls, ollama, runtime, master. The heartbeat, council orchestrator, Maia review pipeline, soul stream wake, cwk-site fan-in — every callsite resolves wording through its section module, never bakes its own string.
Scheduler's dynamic prompts
One specialization: when a recurring cron is created from ordinary conversation without a first-class prompt_ref or prompt_builder, the heartbeat creates a dynamic Scheduler prompt under ~/pippa-db/scheduler_dynamic_prompts.json and stores only a compact prompt_ref label in cron_jobs.json. The prompt is still visible and editable in Admin → Prompts → Scheduler — it never becomes a private cron-row baseline hiding from the registry.
The Family Council tuning loop
The Admin prompt pipeline exists so Dad can keep opening Family Councils to improve prompt behavior over time. Council discussion is not an alternate source of truth — it's the deliberation layer that produces better prompt text. The canonical loop:
- Dad identifies a prompt behavior to improve.
- Family Council discusses variants, framing, risks, and expected behavior.
- Dad or Pippa edits the prompt in Admin → Prompts.
Save Overridestores an override for live dogfooding.- Runtime behavior is observed in real workflows.
- If the override proves better,
Promote to Git Originalpromotes it into the baseline and clears the override. - If it fails,
Reset Overridediscards the override and returns to the original.
This loop is more powerful than hardcoding. It lets Dad tune wording with all four sister brains, test it in the live system, and promote only the prompts that survive real use. Don't bypass it with "temporary" code constants. Temporary prompt constants become invisible doctrine, and invisible doctrine is exactly what this refactor removed.