| name | genesis-kernel-staging-pattern |
| description | Safe staged rollout pattern for Bible-inspired agent simulations: MVP → provenance → provider routing → failure hardening → dry-run → single live call → chapter framework → family viewer → story polish → visual story viewer |
Genesis Kernel Staging Pattern
When building agent-based simulations that reference sacred texts and will eventually use live LLM APIs, follow this staged rollout. Each phase adds capability while maintaining safety boundaries. Never skip phases.
Phase Order
Phase 0 → MVP loop + UI
Phase 1A → Source/provenance boundary hardening
Phase 1B → Provider routing scaffold
Phase 1C → Provider failure/malformed-output hardening
Phase 2A → NIM dry-run integration
Phase 2B → Adam live single-call
Phase 2C → Eve live single-call
Phase 2D → Both live, manual tick only
Phase 3A → Chapter framework + story sanitizer
Phase 3B → Mom story polish (warmer language, read-aloud text)
Phase 3C → Visual story viewer (garden scene, watch mode)
Phase 3D → Visual polish (bigger markers, better phone layout)
Phase 0: MVP
Goal: Smallest working simulation loop.
- 2 agents (Adam, Eve) with mock responses
- 1 environment (Eden) with deterministic consequences
- Simulation loop: observe → decide → act → consequence → memory
- Simple 4-panel UI: World State, Adam, Eve, Event Log
- Event log persists to JSONL
- No external API calls, no NIM keys
Acceptance: npm install/pip install works, app runs locally, tick loop advances, both agents produce actions per tick, consequences resolve deterministically.
Phase 1A: Source/Provenance Hardening
Goal: Prevent generated content from being mistaken for source truth.
- Add three-layer labeling: CANON_ANCHOR, INTERPRETIVE_BRIDGE, SIMULATION_EVENT
- CANON_ANCHOR requires non-null
source_anchor — enforced by validation
- Default all generated events to SIMULATION_EVENT
- Add quarantine for invalid events (
data/quarantine_events.jsonl)
- UI shows Source reference and Type on every event card
- Add
docs/SOURCE_BOUNDARIES.md and docs/EVENT_PROVENANCE_CONTRACT.md
Key rule: Routine generated tick actions should NOT be CANON_ANCHOR. Only events that directly match documented source passages with 3+ keyword matches.
Acceptance: 20 ticks run without invalid CANON_ANCHOR events. CANON_ANCHOR events always show source reference. Quarantine stays empty during normal run.
Phase 1B: Provider Routing Scaffold
Goal: Prepare agents for real LLM providers while keeping mock default.
- Add
BaseProvider abstract interface
- Add
MockProvider (default) and NvidiaNimProvider (placeholder)
- Per-agent provider selection via config (
ADAM_PROVIDER, EVE_PROVIDER)
- Provider call logging without secret leakage
.env.example with variable names only, no real keys
.gitignore protects .env, *.key, secrets/, data/private/
Acceptance: Mock mode runs 20 ticks. Adam and Eve route through separate providers. No external API calls. No secrets in logs.
Phase 1C: Provider Failure Hardening
Goal: Prove simulation survives provider chaos.
- Add test providers:
FailingProvider, MalformedProvider, BoundaryViolatingProvider
- Agent fallback: if provider fails or returns invalid output, use safe mock action
- Output validation: parse JSON, check fields, block CANON_ANCHOR without source_anchor
- Quarantine invalid provider outputs to
data/quarantine_provider_outputs.jsonl
- Fallback actions use generic language (no canon keywords)
Key rules:
- LLM output cannot corrupt canon labels
- LLM failure cannot stop the sim
- LLM weirdness cannot poison memory
- LLM provider logs cannot leak keys
Acceptance: Failing provider doesn't crash tick loop. Malformed provider doesn't corrupt world state. Boundary-violating provider cannot create invalid CANON_ANCHOR. Fallback actions labeled SIMULATION_EVENT.
Phase 2A: NIM Dry-Run Integration
Goal: Build real request payloads without sending network calls.
- Add
nim-dry-run mode
- Build exact outbound payload (model, messages, temperature, max_tokens, response_format)
- Validate payload structure
- Log redacted summary (provider, agent, model, payload size, estimated tokens, key_present)
- Do NOT send the request
- Add prompt contracts: role, memory, world snapshot, allowed labels, source-boundary warning
Acceptance: Dry-run builds valid payload. Zero network calls. Prompt includes source-boundary warning. Secrets redacted in logs. Adam and Eve can use separate dry-run configs.
Phase 2B: Adam Live Single-Call
Goal: Verify exactly one live NIM call for Adam while all safety gates hold.
- Add
nim-live-adam-single mode
- Adam uses live NIM, Eve stays mock
- Only "One Tick" path allowed — batch ticks blocked
max_live_calls_per_run = 1 — hard limit in code
- Print operator checkpoint before live call
- Live response goes through same validation pipeline
- Fallback to SIMULATION_EVENT if parsing/validation fails
Operator checkpoint:
LIVE_CALL_ARMED:
agent: Adam
provider: NVIDIA NIM
mode: nim-live-adam-single
max_calls: 1
eve_provider: mock
batch_ticks: disabled
operator_approval_required: true
Acceptance: Adam makes exactly one live call. Eve makes zero. Exactly one tick advances. Event label is valid. No invalid CANON_ANCHOR. Quarantine empty. No secrets in logs.
Phase 2C: Eve Live Single-Call
Goal: Symmetry proof — Eve live alone works, Adam stays mock.
- Add
nim-live-eve-single mode
- Same safety gates as Phase 2B but for Eve
- Same operator checkpoint pattern
Acceptance: Same as Phase 2B but with Eve live, Adam mock.
Phase 2D: Both Live (Future)
Goal: Both agents live, manual tick only.
max_live_calls_per_run = 2
- No batch ticks, no loop
- Still no new characters
Phase 3A: Chapter Framework + Story Sanitizer
Goal: Structure the story into chapters and clean all raw output for non-technical viewers.
- Define 7 chapters: Garden → Adam → Eve → Boundary → Question → Choice → Expulsion
- Chapters 1-4 enabled, 5-7 locked
- Each chapter has: title, plain_language_summary, canon_anchors, allowed_simulation_events, locked_events, completion_conditions
- Add story sanitizer layer: strips mock/provider prefixes, detects technical phrases, replaces with gentle story language
- Create
/api/mom/state endpoint that returns sanitized data with chapter info
- Viewer shows: current chapter, Bible source, sanitized Adam/Eve text, sanitized events
- Never show raw text like
[mock:Adam:197] or "Max live calls already used" on /mom
Key rule: Two-layer cleaning — sanitize in backend API AND in frontend JS.
Acceptance: /mom shows chapter title and summary. No raw provider/mock text visible. Chapters 1-4 advance. Chapters 5-7 locked. Provenance validation still passes.
Phase 3: Family Viewer
Goal: Non-technical audience can watch the simulation.
/mom and /viewer routes
- Mobile-first layout (94vw cards, single column)
- Large text (22px+ body, 32px+ headings)
- Simplified wording ("Moment" not "Tick", "Bible source" not "CANON_ANCHOR")
- Clean agent text (strip mock/provider prefixes)
- Show 3 recent moments by default with "Show more" button
- Extra Large Text toggle persisted in localStorage
- No admin details, no secrets, no provider settings
- LAN access via
http://<PC-IP>:19734/mom
Key Principles Across All Phases
- Never skip phases — each builds on the previous
- One change at a time — don't add live calls and new characters simultaneously
- Mock is always the default —
GENESIS_PROVIDER_MODE=mock
- Validate before trusting — two-layer validation (provider output + event log)
- Quarantine, don't crash — invalid outputs go to separate files
- No secrets anywhere — keys from env only, never logged, never in UI
- Test after every phase — full test suite passes before moving to next phase
- Document boundaries —
docs/SOURCE_BOUNDARIES.md, docs/EVENT_PROVENANCE_CONTRACT.md
Anti-Patterns
- ❌ Skipping from MVP directly to live API calls
- ❌ Adding new characters before provenance is hardened
- ❌ Switching both agents live at once
- ❌ Allowing batch ticks in live-single mode
- ❌ Not enforcing hard call limits in code
- ❌ Logging API keys or auth headers
- ❌ Skipping validation for live responses
- ❌ Showing admin details on family viewer page
- ✅ Print operator checkpoint before every live call
- ✅ Verify mock mode still works after live test
- ✅ Use quarantine files for audit trail
- ✅ Proceed to Eve-only live only after Adam-only live passes
- ✅ Build family viewer only after both agents work live