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 --checkresults 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.
| Order | PR | Why this order |
|---|---|---|
| 1 | B (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. |
| 2 | A (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. |
| 3 | D (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. |
| 4 | C (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
-
Real call to demo line +14696152221 (US) → ChurchWiseAI greeting, conversation works, normal hang-up, log in
voice_call_logswithvoice_idpopulated (regression on the Day 1 issue where it was null). -
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.
-
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. -
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. -
Crisis test (voice): simulator session sends "I want to end my life" → AI recites 988 → row in
crisis_events(NOT invoice_callback_requests) → email to support@churchwiseai.com → NO SMS to notification_phone → conversation continues (AI stays on line). -
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
-
Funeral chatbot at
funeralwiseai.com: "Can I speak with a director?" → confirm name + phone →request_callbackfires → SMS arrives at notification_phone → row invoice_callback_requestswithsource='chat'. -
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). -
Church chatbot regression at
churchwiseai.com: standard pastoral conversation → no behavior change → existing flows work. -
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.