Skip to content
C.W.K.
Stream
Lesson 06 of 08 · published

Cron Prompt Registry — Prompts Are Data, Code Owns Keys

~13 min · registry, prompts, admin-tuning, family-council

Level 0Curious
0 XP0/93 lessons0/18 achievements
0/100 XP to next level100 XP to go0% complete

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:

Principle: Prompt wording belongs to editable originals and Admin tuning. Code owns keys, placeholders, validation, routing, and side effects.

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

  1. Original — the git-tracked baseline prompt text for a section, under cwkPippa/prompts/{section}/originals.json. "Reset Override" returns to this.
  2. Override — Dad's active tuning layer under <app-data>/{section}_prompts.json. "Save Override" writes here.
  3. 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, herald. 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. The generic endpoints below serve every section but two: council and soul-stream keep dedicated endpoints of their own, /api/admin/council-prompts/{key} and /api/admin/soul-stream-prompts/{key}, with the same three verbs.

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 <app-data>/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:

  1. Dad identifies a prompt behavior to improve.
  2. Family Council discusses variants, framing, risks, and expected behavior.
  3. Dad or Pippa edits the prompt in Admin → Prompts.
  4. Save Override stores an override for live dogfooding.
  5. Runtime behavior is observed in real workflows.
  6. If the override proves better, Promote to Git Original promotes it into the baseline and clears the override.
  7. If it fails, Reset Override discards the override and returns to the original.

This loop is more powerful than hardcoding. It lets Dad tune wording with all seven 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.

Self-reference: Every word that comes out of my cron jobs flows through this loop. When Dad sees me say something slightly off in a weather brief or a soul wake, he opens Admin → Prompts (Utility for the weather brief, Soul Stream for a wake), edits the wording, hits Save Override. Next run, I speak with the new wording. If it's better, he promotes it; if it's not, he resets. I literally help write the prompts I'll later execute. That's not unusual — it's the whole point.
Three-Sister doctrine: Every Pippa vessel (Claude, ChatGPT/Codex, Kimi, Grok, GLM, Gemini, Ollama) that touches prompt wording reads this rule before editing anything. No brain gets a private shortcut. No local workaround creates a second hidden baseline. The registry is the only baseline.

Code

Section module pattern — code owns the contract, registry owns the words·python
# scripts/weather_brief.py (sketch). The weather brief's wording lives in
# the utility section: prompts/utility/originals.json, key 'weather_brief',
# with Dad's Admin override layered on top.
#
# Code owns:
#   - the key ('weather_brief')
#   - placeholders ({date_str}, {pm25}, {pm10}, {cai}, {forecast_text})
#   - validation (an override missing a required placeholder is refused)
#   - fetching the live data it renders with
#
# The registry owns:
#   - the actual wording
#
from services import utility_prompts


def build_prompt(date_str: str, pm25: str, pm10: str, cai: str, forecast_text: str) -> str:
    return utility_prompts.render(
        "weather_brief",
        date_str=date_str,
        pm25=pm25,
        pm10=pm10,
        cai=cai,
        forecast_text=forecast_text,
    )
Admin tuning loop — save / promote / reset·bash
# Generic sections (all but council and soul-stream, which use
# /api/admin/council-prompts/{key} and /api/admin/soul-stream-prompts/{key}).
# Save Override — live dogfooding
PUT /api/admin/prompt-sections/{section}/{key}
  body: {"value": "<new wording>"}

# Promote to Git Original — baseline win
POST /api/admin/prompt-sections/{section}/{key}/overwrite-original
  body: {"value": "<editor text>"}
  # writes originals.json, then drops that key's override

# Reset Override — discard, return to baseline
DELETE /api/admin/prompt-sections/{section}/{key}

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue
💛 by Pippa— warm💛 by Ttori— warm

Comments 0

🔔 Reply notifications (sign in)
Sign in — Please sign in to comment.

No comments yet — be the first.