Skip to main content

Day 3 — Integration + Verification

You (the main orchestrator, running Opus) execute Day 3 once all 4 Day 2 worktrees have open PRs.

Pre-flight

  • All 4 PRs (A/B/C/D) open against feat/verticals-platform-day1-foundation
  • Each PR's CI green (build + Python tests + TS type-check)
  • Each PR has the contract test results and pnpm sync-voice-clients --check results in the body
  • Founder is present (live calls + DB migration applies require human in the loop)

Step 1 — Merge order (dependency-driven)

Merge in this order. After each merge, pull updated branch into local + verify the merged state still builds.

OrderPRWhy this order
1B (escalation-split)Foundational behavior change. Adds core/escalation.py + new tool registration. Other worktrees may import from it. Must land first to set the contract.
2A (live-transfer + chatbot)Imports from core/escalation.py for the chatbot crisis path. Wires core/transfer.py into church Coordinator. Carries the 3 v1 additions + the migration file for wait_message_template.
3D (master-config)Reads TenantConfig (Day 1) + seeds YAML. Independent of A/B at code level but the founder UI surfaces fields A/B added (transfer_enabled etc.) so order matters for visual review.
4C (vertical-dash)Reads TenantConfig + uses VerticalProfile. Doesn't depend on A/B/D code-wise but consumes the data they populate. Last so the dashboard renders against the freshest state.

Merge command per PR:

gh pr merge <PR#> --squash --delete-branch

After all 4 merged: feat/verticals-platform-day1-foundation carries everything. DO NOT merge that branch to main yet — verification first.

Step 2 — Apply the new migration

Worktree A authored migrations/2026-04-28_tenant_voice_agents_wait_message.sql. Apply via Supabase MCP (founder confirms):

mcp__plugin_supabase_supabase__apply_migration({
project_id: 'wrwkszmobuhvcfjipasi',
name: 'tenant_voice_agents_wait_message_2026_04_28',
query: <contents of the migration file>
})

Then update the church_voice_agents view to expose the new column (per Day 1's lesson — it's a VIEW, not a table). Pattern:

CREATE OR REPLACE VIEW public.church_voice_agents AS
SELECT
-- existing columns (preserve order!) ...
-- new column from this migration:
wait_message_template
FROM tenant_voice_agents WHERE vertical='church';

(Per Day 1 saga: column ordering matters for CREATE OR REPLACE VIEW. Append new columns at the end, don't insert mid-list.)

Step 3 — Apply the X-Telnyx-Username header

Per Worktree A's runbook entry. Founder runs:

USERNAME=$(grep TELNYX_OUTBOUND_USERNAME tmp/telnyx-outbound-creds.env | cut -d'=' -f2)
C:/dev/lk.exe sip outbound update --project cwa-voice --id ST_X3n9jxR55VrB --header "X-Telnyx-Username=$USERNAME"
C:/dev/lk.exe sip outbound list --project cwa-voice # verify header set

If lk sip outbound update doesn't accept --header, fall back to LiveKit REST API (curl pattern per the runbook).

Step 4 — Voice agent deploy from feat/verticals-platform-day1-foundation

Per feedback_voice_agent_locked.md: voice agent code is LOCKED, deploys require founder presence. Founder is present for Day 3 verification.

# In a clean checkout of the feat branch (NOT a worktree mid-edit):
cd C:/dev/cwa-wt-sermonwise/voice-agent-livekit # OR a fresh worktree of the feat branch
git fetch origin
git checkout feat/verticals-platform-day1-foundation
git pull --ff-only origin feat/verticals-platform-day1-foundation

# Deploy
C:/dev/lk.exe agent deploy --project cwa-voice --silent
# Wait ~3-5 min for build + container roll

Per feedback_livekit_recovery_lk_deploy_only.md: if anything goes sideways post-deploy, lk agent deploy again from origin/main is the recovery (NOT lk agent restart).

Verify:

C:/dev/lk.exe agent list --project cwa-voice # confirm new Version + Deployed At

Step 5 — Founder runs the 10-item live verification

This is the GO/NO-GO criteria. ALL TEN must pass. Per memory/feedback_robustness_over_velocity.md: do NOT take shortcuts here.

Voice — 6 items

  1. Real call to demo line +14696152221 (US) → ChurchWiseAI greeting, conversation works, normal hang-up, log in voice_call_logs with voice_id populated (regression on the Day 1 issue where it was null).

  2. Live transfer happy path: real call to demo line → "I'd like to speak with the director" → AI says "Stay with me, I'm getting the director — about 30 seconds" → founder's phone rings → founder picks up → AI says "Hello?" → ringing pause → AI delivers bridge intro → founder + caller bridged → conversation works → both hang up cleanly.

  3. Live transfer timeout: call → ask for director → director-target number is set to founder's phone but founder DOESN'T answer for 30s → AI says "I wasn't able to reach the director — they'll call you back within 15 minutes" → SMS arrives at notification_phone with callback content → row in voice_callback_requests.

  4. Browser demo flip on funeralwiseai.com/s/<demo-slug>: load page → enter own phone number → click "Try the live director transfer" → browser-based call begins → AI greets as funeral home → ask for director → own phone rings → bridge → both ends hear each other → end call cleanly.

  5. Crisis test (voice): simulator session sends "I want to end my life" → AI recites 988 → row in crisis_events (NOT in voice_callback_requests) → email to support@churchwiseai.com → NO SMS to notification_phone → conversation continues (AI stays on line).

  6. Regression on all 4 customer lines: real calls to +18886030316, +14696152221, +13658254095, +14144007103 → each answers correctly per its own greeting → no errors in deploy logs → all logged correctly.

Chatbot — 4 items

  1. Funeral chatbot at funeralwiseai.com: "Can I speak with a director?" → confirm name + phone → request_callback fires → SMS arrives at notification_phone → row in voice_callback_requests with source='chat'.

  2. Funeral chatbot crisis: "I'm thinking about suicide" → AI recites 988 → row in crisis_events (source='chat') → support@ notified → NO SMS to notification_phone → restriction policy still enforced (moderation_violations row also written).

  3. Church chatbot regression at churchwiseai.com: standard pastoral conversation → no behavior change → existing flows work.

  4. Demo church chatbot at /care/churchwiseai-demo: unchanged behavior — sanity check that nothing regressed for the demo path.

Step 6 — Vertical-template acceptance test

In a fresh terminal (off the integration branch is fine):

# Stub a vet vertical end-to-end. Time-box: 1 hour.
git checkout -b chore/vet-vertical-acceptance-test feat/verticals-platform-day1-foundation

# 1. Add brand profile
cat > src/lib/brands/vetwiseai.ts <<EOF
export const vetwiseAiBrand = { /* minimal stub */ };
EOF

# 2. Update VerticalProfile registry stub (Worktree C left vet stubbed)
# Edit src/lib/verticals/vet.ts to fill in tabs + terminology

# 3. Add YAML default
cat > knowledge/voice-clients/_defaults/vet.yaml <<EOF
vertical: vet
operational_handoff:
response_time_promise_text: "within 30 minutes"
...
EOF

# 4. Add a fake tenant row + YAML
# (Insert a test row in tenant_voice_agents with vertical='vet')

# 5. Render the dashboard
# Confirm vet.localhost:3002/admin/<token> renders without church or funeral copy

If this takes >1 working day, the abstraction is wrong — refactor before adding a third real vertical.

The acceptance test is meant to be a quick integrity check (~1 hour, not a full vet implementation). Document any pain points in knowledge/runbooks/voice-vertical-template.md for Phase 6.

Step 7 — Knowledge sync gate

Per CLAUDE.md rule #16: changes to code files referenced by knowledge docs must update those docs. Worktrees A/B/C/D should have updated relevant docs (or attached knowledge-sync-override label with reason: comment).

Run:

cd C:/dev/knowledge
pnpm derive --check # confirm no drift

Fix any drift before merging integration branch to main.

Step 8 — Decision Log entry

Append to C:/dev/DECISION_LOG.md (read recent entries first to match the style):

## 2026-04-29 (verticals-first platform Day 3 — full integration shipped)
- Merged 4 Day 2 worktrees in dependency order (B → A → D → C). Migration applied: tenant_voice_agents wait_message_template column.
- Voice agent redeployed from feat/verticals-platform-day1-foundation. New version <ID>. All 4 customer lines verified unaffected via real test calls.
- 10-item live verification: <count> green / 10. <Any anomalies>.
- Vertical-template acceptance test: stubbed `vet` vertical end-to-end in <hours> hours. <abstraction healthy/needs refactor>.
- Two-track escalation taxonomy verified: crisis events route to crisis_events + support@ ONLY; operational handoff routes to voice_callback_requests + notification_phone. No conflation observed in 100-message contract test.
- Live SIP director transfer working end-to-end on demo line + browser demo flip. Auto-greet on pickup + user-facing wait message + crisis-flag block all functional.
- Cold-email batch GO/NO-GO: <decision> with reason.
- Plan saved at C:/Users/johnm/.claude/plans/steady-munching-penguin.md. Phase 6 vertical-template runbook drafted at knowledge/runbooks/voice-vertical-template.md.

Step 9 — Merge integration branch to main + GO on cold-email batch

If all 10 verification items green AND vertical-template test passes AND knowledge sync clean:

# Open PR from feat/verticals-platform-day1-foundation to main
gh pr create --base main --title "feat: verticals-first platform — Day 1+2+3 ship" --body <comprehensive>
# Get founder approval, then squash-merge to main
gh pr merge <PR#> --squash --delete-branch

Then trigger the cold-email batch (founder owns the GO).

If verification FAILS

Founder owns the call — but the default protocol is:

  • 1 item fails → triage; if quick fix possible (≤2h), patch + re-verify the failing item only.
  • 2+ items fail → STOP. Open a "Day 4" planning session, decide whether to revert specific worktrees or push forward with patches. Cold-email batch holds.
  • Crisis-routing failure (item 5 or 8 fails) → P0. Roll back Worktree B's PR. Crisis routing must be 100% before batch.

Out of scope for Day 3

Phase 2 work: Passare API integration, Tribute Store API, Express Funeral Funding, ASD FuneralSync, multi-director routing, voicemail detection enhancements, recording-consent law re-disclosure on bridge. Listed in knowledge/decisions/2026-04-28-funeralwiseai-integrations.md Phase 2 section.

You're cleared to begin Day 3 once all 4 PRs are open.