# ─────────────────────────────────────────────────────────────────────────────
# Test + critical-path registry
#
# Drives the critical-path-gate GitHub Action in each repo. Any PR that
# modifies a file listed under `code_files` of a `critical_path: true` entry
# must either:
#   (a) attach an artifact named `<playwright_spec>-playwright-run.zip` showing
#       a green live-flow run, OR
#   (b) carry the label `critical-path-override` with a reason comment.
#
# Without one of the above, the gate blocks merge.
#
# This file is the single source of truth. Edit here, push, and every repo's
# gate workflow picks up the new definition on its next PR.
#
# Expanded 2026-04-14 Phase 1: renamed `critical_paths:` → `entries:`, added
# `type` and `schedule` fields, grew from 3 entries to 30. The critical-path-gate
# workflow still uses hardcoded patterns (Phase 4.5 will rewrite it to read this
# file dynamically — safe to expand freely now).
#
# 2026-04-17 — OPTIONAL `property:` field added (readiness orchestrator).
# The `/ensure-solid` skill reads `knowledge/readiness/<property>.yaml` which
# declares which registry entries apply to that property. Matching works by
# EITHER:
#   - new explicit `property: <cwa | pewsearch | itw | sermonwise | sharewise |
#     pro-website>` field on the entry, OR
#   - existing `covers:` list (if it contains a spec path listed under the
#     property's `registry_filter.covers_tokens`).
# No bulk edit required; add `property:` opportunistically when you touch an
# entry for other reasons.
# ─────────────────────────────────────────────────────────────────────────────

entries:

  # ─── COLD OUTREACH / CHURCH DEMO ─────────────────────────────────────────

  - name: cold-outreach-church
    critical_path: true
    property: cwa
    type: playwright
    schedule: on-pr
    description: >
      End-to-end verification of the cold-outreach + per-prospect church demo page
      flow. Proves that a cold-email recipient can land on a demo page at
      /s/[slug], see church branding, interact with the AI chatbot, see a voice
      demo section or equivalent CTA, and navigate toward the Stripe checkout path.
      Without this spec we cannot ship cold-email campaigns with confidence.
      Added Sprint 0 Lane 1 (2026-05-13) as part of the revenue-readiness plan.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/lib/outreach/provision.ts
      - src/app/s/[slug]/page.tsx
      - src/components/cold-outreach/DirectorTransferDemo.tsx
      - src/components/templates/ServiceBusinessTemplate.tsx
      - src/components/templates/UnifiedTemplate.tsx
      - src/components/ChatWidgetStream.tsx
      - src/app/api/chatbot/stream/route.ts
      - src/app/api/outreach/
      - src/app/api/stripe/church-checkout/
    spec_file: e2e/cold-outreach-church-e2e.spec.ts
    baseline_file: null
    playwright_spec: e2e/cold-outreach-church-e2e.spec.ts
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers:
      - processes/agent-quality-principles.md

  # ─── STRIPE / PAYMENTS ────────────────────────────────────────────────────

  - name: stripe-live-checkout
    critical_path: true
    type: playwright
    schedule: on-pr
    description: >
      Live Stripe checkout + webhook provisioning. Covers the flow from
      customer clicking "Subscribe" on a pricing page to the subscription
      landing in premium_churches with entitlements set.
    owner: churchwiseai-web
    repo: churchwiseai-web
    # code_files corrected 2026-04-22: removed fictional src/lib/stripe/ dir and
    # src/app/checkout/ page (doesn't exist). Real paths verified by directory scan.
    code_files:
      - src/app/api/stripe/webhook/route.ts
      - src/app/api/stripe/checkout/
      - src/app/api/stripe/checkout-embedded/
      - src/app/api/stripe/church-checkout/
      - src/app/api/cron/process-stripe-webhooks/
      - src/lib/stripe.ts
      - src/lib/stripe-prices.ts
      - src/lib/tier-config.ts
    spec_file: e2e/stripe-e2e-validator.spec.ts
    baseline_file: null
    playwright_spec: stripe-live-checkout
    override_label: critical-path-override
    last_run: "2026-05-13T00:00:00Z"
    last_run_result: "29 passed, 23 skipped (desktop/Chromium) — unit tests green, E2E gated (RUN_COUPON_VALIDATION not set)"
    last_run_sha: "51463cd6"
    last_break: 2026-04-14
    last_break_notes: >
      Webhook returned 200 on silent provisioning failure. Customer paid,
      subscription never provisioned. Root cause under investigation in a
      separate refactor PR. This gate was added to prevent the failure mode
      from being reintroduced after the fix lands.
    founder_verified: 2026-04-22
    covers:
      - processes/stripe-testing-harness.md

  - name: stripe-e2e-validation-monthly
    critical_path: false
    type: playwright
    schedule: "0 5 1 * *"
    description: >
      Monthly 21-tier coupon validation harness. Runs all plan tiers through
      the full checkout → provisioning → entitlement cycle in Stripe test mode.
      Executed via GitHub Actions workflow on the 1st of each month at 05:00 UTC.
    repo: churchwiseai-web
    # code_files corrected 2026-04-22: removed fictional src/lib/stripe/ dir and
    # src/app/checkout/ page (doesn't exist). Real paths verified by directory scan.
    code_files:
      - src/app/api/stripe/
      - src/app/api/cron/process-stripe-webhooks/
      - src/lib/stripe.ts
      - src/lib/stripe-prices.ts
      - src/lib/tier-config.ts
    spec_file: e2e/stripe-e2e-validator.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers:
      - processes/stripe-testing-harness.md

  - name: stripe-synthetic-validator
    critical_path: false
    type: harness
    schedule: on-pr
    description: >
      Synthetic Stripe validation harness library. Used by stripe-e2e-validator
      and the monthly scheduled run. Validates tier gating, coupon application,
      and provisioning logic without hitting live Stripe.
    repo: churchwiseai-web
    code_files:
      - e2e/stripe-synthetic-validator.spec.ts
      - src/lib/stripe/
    spec_file: e2e/stripe-synthetic-validator.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers:
      - processes/stripe-testing-harness.md

  - name: pro-website-upgrade
    property: pro-website
    critical_path: true   # flipped 2026-04-21 after first green run — customer billing flow
    type: playwright
    schedule: manual   # touches live Stripe state; run with RUN_UPGRADE_VALIDATION=1
    description: >
      BUG-051 upgrade-flow regression guard. Asserts the business invariant
      that after an upgrade via /api/stripe/church-checkout OR
      /api/stripe/checkout-embedded, the Stripe customer has exactly ONE
      active/trialing subscription — updated to the new price — not a
      second one created alongside the old. Covers
      pro_website → starter_both → pro_both → suite_both chaining, same-tier
      no-op, and the checkout-embedded belt-and-suspenders fallback path.
      Seeds Stripe state via live-mode + 100% coupon (zero real charges);
      cleans up customer + subscription + DB rows in afterEach.
    repo: churchwiseai-web
    code_files:
      - src/app/api/stripe/checkout-embedded/route.ts
      - src/app/api/stripe/church-checkout/route.ts
      - src/lib/stripe-prices.ts
      - src/app/admin/[token]/components/UpgradeTab.tsx
      - src/app/onboard/checkout/UpgradeCheckoutForm.tsx
    spec_file: e2e/pro-website-upgrade.spec.ts
    baseline_file: null
    playwright_spec: pro-website-upgrade
    override_label: critical-path-override
    last_run: 2026-04-21T00:00Z  # 5/5 passed against https://churchwiseai.com production
    last_break: null
    founder_verified: 2026-04-22
    covers:
      - decisions/2026-04-20-bug-051-upgrade-double-billing.md

  - name: pro-website-cancelled-tombstone
    property: pro-website
    critical_path: true
    type: playwright
    schedule: on-pr
    description: >
      FA-046 regression guard. Verifies that admin/[token]/page.tsx intercepts
      status='cancelled' before rendering the full dashboard (auth hole fix).
      Asserts: tombstone heading visible, Reactivate CTA links to /pricing,
      portal link present, dashboard tab nav absent, no enabled form inputs.
      Also confirms active accounts are NOT tombstoned (regression guard).
      Demo token: demo-cancelled-2026 (Riverside Fellowship Church, cwa_starter_chat, cancelled).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/admin/[token]/page.tsx
      - src/app/admin/[token]/components/CancelledTombstone.tsx
    spec_file: e2e/journeys/cancelled-subscription-tombstone.spec.ts
    baseline_file: null
    playwright_spec: cancelled-subscription-tombstone
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-04-22
    founder_verified: 2026-04-22
    tags: [auth, cancelled, tombstone, pro-website, lifecycle]
    covers:
      - acceptance/cancelled.md

  - name: modular-pricing
    property: pro-website
    # `critical_path` stays false until this spec is confirmed green on the
    # production preview URL. Flip to true in a follow-up commit after the
    # first green run + founder sign-off on flipping NEXT_PUBLIC_MODULAR_PRICING
    # to `on` in Vercel.
    critical_path: false
    type: playwright
    schedule: manual
    description: >
      Modular Pricing (2026-04-21) entitlement + checkout gates. Covers:
      Website tab visibility driven by premium_churches.has_website_subscription
      (canonical) OR isProWebsitePlan(plan) fallback — NOT bundle-plan
      membership; cwa_pro_website_site_only + cwa_pro_website combo checkout
      routes resolve without 4xx/5xx; pricing page renders the modular layout
      under NEXT_PUBLIC_MODULAR_PRICING=on and is backward-compatible with
      the flag OFF. Protects the plan-column canonical contract
      (knowledge/architecture/db/plan-column-contract.md) from a recurrence
      of the 2026-04-17 P0 (normalized-tier write back to plan).
    repo: churchwiseai-web
    code_files:
      - src/lib/tier-config.ts
      - src/lib/premium-shared.ts
      - src/lib/stripe-prices.ts
      - src/app/api/stripe/webhook/route.ts
      - src/app/api/stripe/church-checkout/route.ts
      - src/app/s/[slug]/page.tsx
      - src/app/admin/[token]/components/AdminDashboard.tsx
      - src/app/admin/[token]/components/UpgradeTab.tsx
      - src/app/admin/[token]/components/WebsiteTab.tsx
      - src/app/admin/[token]/components/WebsiteTabEditor.tsx
      - src/app/api/premium/publish/route.ts
      - src/app/api/premium/update/route.ts
      - src/app/pricing/page.tsx
    spec_file: e2e/modular-pricing.spec.ts
    baseline_file: null
    playwright_spec: modular-pricing
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-04-21
    tags: [billing, pro-website, entitlement, modular-pricing]
    covers:
      - implementation/MODULAR_PRICING_DESIGN_2026_04_21.md
      - architecture/db/plan-column-contract.md

  - name: cron-process-stripe-webhooks
    critical_path: false
    type: cron
    schedule: "* * * * *"
    description: >
      Every-minute cron that dequeues stripe_webhook_inbox rows and processes
      them with retries + exponential backoff. P0 alert on abandon. This is the
      inbox-pattern worker introduced 2026-04-14 to replace inline provisioning.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/process-stripe-webhooks/route.ts
      - src/app/api/stripe/webhook/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  - name: cron-stripe-live-validation
    critical_path: false
    type: cron
    schedule: "*/15 * * * *"
    description: >
      Every-15-minute live Stripe validation check. Monitors for subscription
      drift between Stripe and the premium_churches table.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/stripe-live-validation/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  - name: cron-stripe-supabase-reconciliation
    critical_path: false
    type: cron
    schedule: "*/15 * * * *"
    description: >
      Every-15-minute reconciliation between Stripe subscription state and
      Supabase premium_churches rows. Catches missed webhooks and silent failures.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/stripe-supabase-reconciliation/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  - name: multi-item-self-serve
    critical_path: true   # Phase 7 live 2026-05-12 — ENABLE_MULTI_ITEM_ADDS=monthly in prod; real customer-money flow
    type: playwright
    schedule: on-pr
    description: >
      FA-082 Phase 7 self-serve add/remove/resume of Chat/Voice/Pro-Website as
      managed Stripe line items. Monthly-interval customers can self-serve via
      the admin Upgrade tab "Add a service" cards and per-product Cancel /
      Resume links. Gates merge for any change to these routes or their UI
      components. The spec (e2e/multi-item-self-serve.spec.ts) itself contained
      the TODO registry YAML that this entry fulfills — Phase 7 flipped
      ENABLE_MULTI_ITEM_ADDS=monthly live 2026-05-12.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - churchwiseai-web/src/app/admin/[token]/components/AddProductCard.tsx
      - churchwiseai-web/src/app/admin/[token]/components/AddProductConfirmModal.tsx
      - churchwiseai-web/src/app/admin/[token]/components/ActiveProductCard.tsx
      - churchwiseai-web/src/app/admin/[token]/components/RemoveProductConfirmModal.tsx
      - churchwiseai-web/src/app/admin/[token]/components/ResumeProductButton.tsx
      - churchwiseai-web/src/app/admin/[token]/components/ProductStatusBadge.tsx
      - churchwiseai-web/src/app/admin/[token]/components/CancellationReasonSurvey.tsx
      - churchwiseai-web/src/app/admin/[token]/components/UpgradeTab.tsx
      - churchwiseai-web/src/app/api/stripe/add-product/route.ts
      - churchwiseai-web/src/app/api/stripe/remove-product/route.ts
      - churchwiseai-web/src/app/api/stripe/resume-product/route.ts
    spec_file: e2e/multi-item-self-serve.spec.ts
    baseline_file: null
    playwright_spec: multi-item-self-serve
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-05-12
    founder_verified: 2026-05-12
    tags: [billing, multi-item, self-serve, subscription, add-product, remove-product]
    covers:
      - acceptance/multi-item-self-serve.md

  - name: multi-item-stripe
    critical_path: true   # API E2E matrix for add/remove routes — BILLING tier, Phase 7 live
    type: playwright
    schedule: on-pr
    description: >
      FA-082 Stripe API E2E matrix — 8 scenarios covering add-product and
      remove-product routes end-to-end. Complements multi-item-self-serve
      (UI Playwright) with a direct API layer test. Phase 7 live 2026-05-12.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - churchwiseai-web/src/app/api/stripe/add-product/route.ts
      - churchwiseai-web/src/app/api/stripe/remove-product/route.ts
      - churchwiseai-web/src/app/api/stripe/resume-product/route.ts
      - churchwiseai-web/src/lib/tier-config.ts
      - churchwiseai-web/src/lib/stripe-prices.ts
    spec_file: e2e/multi-item-stripe.spec.ts
    baseline_file: null
    playwright_spec: multi-item-stripe
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-05-12
    tags: [billing, multi-item, stripe, api, add-product, remove-product]
    covers:
      - acceptance/multi-item-self-serve.md

  # ─── VOICE AGENT ──────────────────────────────────────────────────────────

  - name: voice-live-call
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — customer-impacting
    type: playwright
    schedule: manual
    description: >
      Inbound voice call flow: SIP → LiveKit → voice agent → response.
      Pending gate enablement after first green Playwright run.
    repo: churchwiseai-web
    code_files:
      - voice-agent-livekit/session.py
      - voice-agent-livekit/main.py
    spec_file: null
    baseline_file: null
    playwright_spec: voice-live-call
    override_label: critical-path-override
    last_run: null
    last_break: null
    founder_verified: 2026-04-22
    covers: []

  - name: voice-routing-integration
    critical_path: true   # added 2026-04-22 after FK-join regression — see decisions/2026-04-22-voice-fk-join-regression.md
    type: pytest
    schedule: on-pr
    description: >
      Unit + integration tests that verify voice agent routing end-to-end.
      - tests/test_routing.py — resolve_route() coverage for every PHONE_REGISTRY entry
      - tests/test_load_church_data_integration.py — LIVE Supabase query against every
        demo + paying-customer church_id; asserts load_church_data returns a non-None
        dict. This test would have caught the 2026-04-22 P0 where the M2 migration
        dropped FK constraints, causing PostgREST join syntax in _fetch_voice_agent_row
        to fail and all demo calls to silently fall to the Sales Agent.
      - tests/test_calls_limit.py — call-limit enforcement + at-capacity TTS
      Runs via `.github/workflows/voice-routing-integration-on-pr.yml` on every PR
      that touches voice-agent-livekit Python code.
    repo: churchwiseai-web
    code_files:
      - voice-agent-livekit/session.py
      - voice-agent-livekit/main.py
      - voice-agent-livekit/verticals/church/integrations/supabase_church.py
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: 2026-04-22  # M2 migration FK drop silently broke every dedicated-trunk demo for ~24h
    founder_verified: 2026-04-22
    covers:
      - voice-routing
      - load_church_data
      - phone_registry
      - calls_limit_enforcement

  - name: voice-behavioral-nightly
    critical_path: false
    type: playwright
    schedule: "0 6 * * *"
    description: >
      Nightly behavioral test suite for the church voice agent vertical. Runs
      live against the deployed LiveKit agent using Haiku as judge. Results
      ingest to /api/cron/voice-behavioral-summary for persistence + alerts.
    repo: churchwiseai-web
    code_files:
      - voice-agent-livekit/session.py
      - voice-agent-livekit/verticals/church/
    spec_file: .github/workflows/voice-behavioral-nightly-church.yml
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers: []

  - name: cron-voice-health
    critical_path: false
    type: cron
    schedule: "*/15 * * * *"
    description: >
      Every-15-minute voice infrastructure health check. Verifies LiveKit
      agent is running and SIP trunk is reachable.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/voice-health/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  # ─── AUTH / LOGIN ─────────────────────────────────────────────────────────

  - name: user-login-cwa
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — blocks every authenticated flow
    type: playwright
    schedule: on-pr
    description: >
      Magic-link login to churchwiseai.com admin. Blocks every authenticated
      flow if broken.
    repo: churchwiseai-web
    # code_files corrected 2026-05-12: src/app/login/ does not exist. Real auth
    # code lives at src/app/auth/ (callback/route.ts, confirm/page.tsx). Added
    # SIGNUP-FA-106 protected auth files per churchwiseai-web CLAUDE.md table.
    code_files:
      - src/app/api/auth/
      - src/app/auth/callback/route.ts
      - src/app/auth/confirm/page.tsx
      - src/components/auth/SignupForm.tsx
      - src/components/auth/SigninForm.tsx
      - src/lib/supabase/client.ts
      - src/app/api/sermons/log-first-visit/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: user-login-cwa
    override_label: critical-path-override
    last_run: null
    last_break: null
    founder_verified: 2026-04-22
    covers: []

  - name: signup-email-confirm-flow
    critical_path: true   # FA-106 fix (2026-05-11): email confirmation must route via token_hash + verifyOtp, NOT PKCE code exchange, so cross-profile/cross-browser/cross-device users still auto-sign-in. If this regresses, every new pastor who signs up on church laptop + clicks email on phone gets stuck.
    type: playwright
    schedule: on-pr
    description: >
      SermonWise password signup → email confirm → land on /sermons/app
      auto-signed-in. Includes the cross-profile case (sign up in profile A,
      click email link in profile B — must still work). Also exercises the
      OAuth path so the same /auth/callback file serving both flows can't
      regress one while fixing the other.
    repo: churchwiseai-web
    code_files:
      - src/components/auth/SignupForm.tsx
      - src/components/auth/SigninForm.tsx
      - src/app/auth/callback/route.ts
      - src/app/auth/confirm/page.tsx
      - src/lib/supabase/client.ts
      - src/middleware.ts
      - src/app/api/sermons/log-first-visit/route.ts
      - migrations/2026-05-11-signup-email-confirmed-auth-trigger.sql
    spec_file: null
    baseline_file: null
    playwright_spec: null   # TODO: author e2e/contracts/signup-email-confirm-flow.contract.spec.ts (Mailhog/Resend test mode needed for real PKCE-bypass via email link)
    override_label: critical-path-override
    last_run: 2026-05-11   # manual verify9 cross-profile + churchwiseai@gmail.com OAuth
    last_break: null
    founder_verified: 2026-05-11
    canonical_source: knowledge/architecture/auth-signup-flow.md
    covers:
      - signup_email_confirmed PostHog event firing path (auth_trigger or log_first_visit fallback)
      - cross-profile / cross-browser / cross-device email confirmation
      - Google OAuth signin no-regression
      - signin_lag_seconds = 0 after email confirm
      - Supabase email template uses {{ .TokenHash }} not {{ .ConfirmationURL }}

  # ─── CWA ONBOARDING / CUSTOMER JOURNEY ────────────────────────────────────

  - name: cwa-04-onboarding
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — onboarding wizard = step 3 of customer flow
    type: playwright
    schedule: on-pr
    description: >
      Post-signup onboarding wizard flow. 10-step guided setup on the Overview
      tab: slide-over panels, skip/minimize, celebration, OptimizationTips.
      Covers the pro-website-wizard agent's acceptance criteria.
    repo: churchwiseai-web
    code_files:
      - src/app/admin/
      - src/components/onboarding/
    spec_file: e2e/delivers/churchwiseai/04-onboarding.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    founder_verified: 2026-04-22
    covers:
      - acceptance/

  - name: cwa-pastor-discovery-signup
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Full pastor discovery-to-signup journey: Google → landing page →
      pricing → checkout. The primary customer acquisition flow.
    repo: churchwiseai-web
    code_files:
      - src/app/
      - src/app/pricing/
      - src/app/checkout/
    spec_file: e2e/journeys/pastor-discovers-and-signs-up.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers: []

  - name: cwa-chatbot-live-response
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — core customer-facing product
    type: playwright
    schedule: on-pr
    description: >
      Visitor uses the live chatbot on a church page. Validates streaming SSE
      response, tier-gating, and HEAR protocol. Placeholder for future critical
      path — gate enablement pending first green run.
    repo: churchwiseai-web
    code_files:
      - src/app/api/chatbot/stream/route.ts
      - src/app/api/chatbot/
    spec_file: e2e/journeys/visitor-uses-chatbot.spec.ts
    baseline_file: null
    playwright_spec: chatbot-live-response
    override_label: critical-path-override
    last_run: 2026-04-27
    last_break: null
    founder_verified: 2026-04-27
    covers: []

  - name: cwa-production-smoke
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — catches total outages
    type: playwright
    schedule: on-commit
    description: >
      Smoke test across all three production hostnames (churchwiseai.com,
      sermonwise.ai, sharewiseai.com) — checks pages load, no 5xx, key
      elements visible.
    repo: churchwiseai-web
    code_files:
      - src/app/
    spec_file: e2e/production-smoke-all-sites.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: 2026-04-24T14:45:00Z  # 20/20 pass, TEST_PRODUCTION=1 against live https://{churchwiseai.com,pewsearch.com,illustratetheword.com,sermonwise.ai}. Exposed + fixed demo-slug drift in PR #187.
    last_break: null
    founder_verified: 2026-04-24
    covers: []

  # ─── PERSONA-BASED TESTS ──────────────────────────────────────────────────

  - name: persona-pastor-ai-skeptic
    critical_path: false
    type: playwright
    schedule: weekly
    description: >
      Persona: Pastor Ezekiel (AI skeptic). Tests that skeptical objections
      are handled gracefully across marketing copy, chatbot, and admin UI.
    repo: churchwiseai-web
    code_files:
      - src/app/
      - src/app/api/chatbot/stream/route.ts
    spec_file: e2e/delivers/personas/pastor-ezekiel-ai-skeptic.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  - name: persona-pastor-tiny-church
    critical_path: false
    type: playwright
    schedule: weekly
    description: >
      Persona: Pastor Ruth (tiny church, budget-conscious). Validates that
      the Starter tier messaging, pricing, and onboarding are appropriate
      for very small congregations.
    repo: churchwiseai-web
    code_files:
      - src/app/
    spec_file: e2e/delivers/personas/pastor-ruth-tiny-church.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  - name: persona-committee-buyer
    critical_path: false
    type: playwright
    schedule: weekly
    description: >
      Persona: Committee buyer (board meeting evaluation). Tests that the
      product can be evaluated by a non-technical board and that the
      pricing/ROI story is clear.
    repo: churchwiseai-web
    code_files:
      - src/app/
    spec_file: e2e/delivers/personas/committee-buyer-board-meeting.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  # ─── ACCEPTANCE / TIER SPECS ──────────────────────────────────────────────

  - name: acceptance-starter-chat
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Acceptance spec for Starter Chat tier. Validates entitlements, agent
      count, and dashboard UI match the approved acceptance spec.
    repo: churchwiseai-web
    code_files:
      - src/app/admin/
      - src/lib/premium/
    spec_file: e2e/delivers/acceptance/starter-chat.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers:
      - acceptance/

  - name: acceptance-pro-suite-chat
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Acceptance spec for Pro Suite Chat tier. Validates 4-agent config,
      premium tool access, and tier-gated dashboard features.
    repo: churchwiseai-web
    code_files:
      - src/app/admin/
      - src/lib/premium/
    spec_file: e2e/delivers/acceptance/pro-suite-chat.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    covers:
      - acceptance/

  # ─── CONSISTENCY / CONTENT ACCURACY ───────────────────────────────────────

  - name: consistency-price-matching
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — drift defense for founder-edit iterations
    type: playwright
    schedule: on-pr
    description: >
      Verifies that prices displayed on marketing pages match the canonical
      pricing.yaml values. Guards against stale hardcoded copy.
    repo: churchwiseai-web
    code_files:
      - src/app/pricing/
      - src/components/
    spec_file: e2e/delivers/consistency/price-matching.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers:
      - data/pricing.yaml

  - name: consistency-stale-copy-detection
    critical_path: false
    type: playwright
    schedule: weekly
    description: >
      Scans marketing pages for stale agent counts, feature claims, and
      pricing that contradict the current product_knowledge table or YAML.
    repo: churchwiseai-web
    code_files:
      - src/app/
    spec_file: e2e/delivers/consistency/stale-copy-detection.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  # ─── CROSS-PROPERTY ────────────────────────────────────────────────────────

  - name: cross-property-pewsearch-to-cwa-upsell
    critical_path: false
    type: playwright
    schedule: weekly
    description: >
      Tests the PewSearch → ChurchWiseAI upsell path: premium-page owner
      sees upsell CTA, clicks through to churchwiseai.com, and can initiate
      a chatbot/voice trial.
    repo: churchwiseai-web
    code_files:
      - src/app/
      - src/app/api/
    spec_file: e2e/delivers/cross-property/pewsearch-to-cwa-upsell.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  - name: cross-property-itw-to-sermonwise
    critical_path: false
    type: playwright
    schedule: weekly
    description: >
      Tests the IllustrateTheWord → SermonWise upsell path: ITW subscriber
      sees SermonWise CTA and can navigate to the sermonwise.ai signup.
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/
    spec_file: e2e/delivers/cross-property/itw-to-sermonwise.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  # ─── PEWSEARCH ─────────────────────────────────────────────────────────────

  - name: pewsearch-claim-flow
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — PewSearch core acquisition funnel
    type: playwright
    schedule: on-pr
    description: >
      Church listing claim flow: pastor finds their listing, initiates claim,
      verifies ownership, and reaches the admin dashboard. Core acquisition
      funnel for PewSearch.
    repo: pewsearch
    code_files:
      - src/app/claim/
      - src/app/api/claim/
    spec_file: e2e/claim.spec.ts
    baseline_file: null
    playwright_spec: pewsearch-claim-flow-playwright-run
    override_label: critical-path-override
    last_run: 2026-04-28
    last_break: null
    founder_verified: 2026-04-28
    covers: []

  - name: pewsearch-premium-checkout
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — PewSearch revenue flow
    type: playwright
    schedule: on-pr
    description: >
      PewSearch Premium ($9.95/mo) checkout and provisioning. Separate from
      the CWA checkout gate — PewSearch has its own Stripe integration.
      As of FA-094 (2026-04-28), the route is POST-only for state-changing
      branches; GET returns 405 for non-pro_website tiers. Spec covers 4
      POST flows + 2 GET regressions.
    repo: pewsearch
    code_files:
      - src/app/checkout/
      - src/app/api/stripe/
    spec_file: e2e/checkout.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: 2026-04-28
    last_break: null
    founder_verified: 2026-04-28
    covers:
      - FA-094  # GET-mutates-state P0 closed; route is POST-only
    notes: >
      2026-04-28 local run: 17/18 PASS across desktop/tablet/mobile. Single
      failure was a stale test-church slug collision in the tablet worker's
      beforeEach setup (DB unique constraint hit a leftover row from a
      prior aborted run) — not a regression. FA-094 logic verified green
      on all 3 viewports.

  - name: pewsearch-directory-smoke
    property: pewsearch
    critical_path: false
    type: playwright
    schedule: on-commit
    description: >
      Smoke test for the PewSearch directory: search returns results,
      church detail pages load, no 5xx errors. Guards the 218K-listing index.
      2026-04-24 run covered desktop + tablet + mobile projects — 18/18 pass
      against https://pewsearch.com.
    repo: pewsearch
    code_files:
      - src/app/directory/
      - src/app/churches/
    spec_file: e2e/smoke.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: 2026-04-24T15:22:00Z
    last_break: null
    founder_verified: 2026-04-24
    covers: []

  # ─── ILLUSTRATE THE WORD (ITW) ─────────────────────────────────────────────

  - name: itw-premium-checkout
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      IllustrateTheWord Premium ($9.95/mo) Stripe checkout + Supabase Auth
      provisioning. Tests content-gating before and after purchase.
    repo: sermon-illustrations
    code_files:
      - src/app/checkout/
      - src/app/api/
    spec_file: e2e/checkout.spec.ts
    baseline_file: null
    playwright_spec: itw-premium-checkout-playwright-run
    override_label: critical-path-override
    last_run: 2026-04-28
    last_break: null
    founder_verified: 2026-04-28
    covers: []

  - name: itw-content-gating
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Verifies that free vs premium illustration content is gated correctly
      on ITW. Guards against regressions that expose premium content for free.
    repo: sermon-illustrations
    code_files:
      - src/app/
      - src/lib/
    spec_file: e2e/content-gating.spec.ts
    baseline_file: null
    playwright_spec: itw-content-gating-playwright-run
    override_label: critical-path-override
    last_run: 2026-04-27
    last_break: null
    founder_verified: 2026-04-27
    covers: []

  - name: itw-smoke
    critical_path: false
    type: playwright
    schedule: on-commit
    description: >
      ITW smoke test: homepage, browse, illustration detail load without
      errors. Guards against deploy regressions.
    repo: sermon-illustrations
    code_files:
      - src/app/
    spec_file: e2e/smoke.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    founder_verified: 2026-04-22
    covers: []

  - name: itw-responsive
    property: itw
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      ITW responsive viewport guard — verifies no horizontal scroll at 375px
      on / and /illustrations, and search is reachable on mobile. Closes the
      v6 P1-1 ("viewports never run") by giving the viewports dimension a
      registry-tracked spec with a stamped last_run.
    repo: sermon-illustrations
    code_files:
      - src/app/
    spec_file: e2e/responsive.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: 2026-04-24T15:08:00Z  # 6/6 pass against https://illustratetheword.com (mobile + tablet projects)
    last_break: null
    founder_verified: 2026-04-24
    covers: []

  - name: itw-signup
    property: itw
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      ITW free-tier signup flow: visitor arrives at illustratetheword.com,
      creates an account (email + password via Supabase Auth), confirms email,
      and reaches the authenticated browse page. Core acquisition funnel for
      IllustrateTheWord. Referenced by signup-free-tier journey in
      knowledge/readiness/itw.yaml. Added 2026-04-22 — see FA-071.
    repo: sermon-illustrations
    code_files:
      - src/app/auth/
      - src/app/signup/
      - src/app/api/
    # spec not yet authored — see FA-071-itw
    # e2e/auth.spec.ts covers existing auth flows and is the likely home.
    spec_file: e2e/auth.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    founder_verified: 2026-04-22
    covers: []

  # ─── SERMONWISE ────────────────────────────────────────────────────────────

  - name: sermonwise-signup-checkout
    property: sermonwise
    critical_path: true
    type: playwright
    schedule: on-pr
    description: >
      SermonWise Pro signup and Stripe checkout: auth'd user → POST
      /api/sermons/checkout → live stripe.com URL returned (monthly +
      annual). The core money-path for SermonWise. Spec is self-
      provisioning (ephemeral Supabase user via service role, cleaned
      up after). FA-061 resolved 2026-04-24.
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/signup/
      - src/app/sermons/pricing/
      - src/app/api/sermons/checkout/
      - src/lib/sermon-pricing.ts
      - src/lib/stripe-prices.ts
      - src/lib/stripe.ts
      - src/app/api/stripe/webhook/route.ts
    spec_file: e2e/sermonwise-signup-checkout.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-signup-checkout
    override_label: critical-path-override
    last_run: 2026-05-11T00:00:00Z  # 4/4 green against https://sermonwise.ai — must run with BASE_URL=https://sermonwise.ai
    last_break: null
    founder_verified: 2026-04-24
    ci_workflow: .github/workflows/sermonwise-checkout-critical.yml
    gate_workflow: .github/workflows/critical-path-gate.yml
    covers:
      - acceptance/sermonwise-pro.md

  - name: sermonwise-generate
    property: sermonwise
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      SermonWise sermon generation: authenticated user enters prompt, scripture,
      tradition lens, and method → streaming outline returns. The core
      customer-value action for SermonWise. Referenced by generate-sermon
      journey in knowledge/readiness/sermonwise.yaml. Added 2026-04-22 — see FA-063.
      NOTE: Full generation test (LLM call) must be run manually against production
      (sermonwise.ai) with BASE_URL set. Non-LLM tests (Login, API Contract) confirmed
      green 2026-05-11. No SERMON_TEST_SESSION_TOKEN gate — uses hardcoded free-tier
      account. Skips gracefully when monthly limit is reached.
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/generate/
      - src/app/sermons/dashboard/
      - src/app/api/sermons/
    spec_file: e2e/sermon-generation.spec.ts
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: 2026-05-11T00:00:00Z  # non-LLM tests (Login, API Contract) 6/6 green against https://sermonwise.ai
    last_break: null
    covers:
      - acceptance/sermonwise-pro.md

  # ─── KNOWLEDGE / CONTENT HEALTH ────────────────────────────────────────────

  - name: cron-knowledge-check
    critical_path: false
    type: cron
    schedule: "30 8 * * *"
    description: >
      Daily 08:30 UTC cron that validates product_knowledge table — checks for
      duplicates, suspiciously short answers, and stale entries. Complements
      the DB trigger that blocks >3 identical answer rows.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/knowledge-check/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers:
      - processes/expected-output-methodology.md

  - name: cron-knowledge-freshness
    critical_path: false
    type: cron
    schedule: "0 9 * * 1"
    description: >
      Weekly Monday 09:00 UTC cron that checks whether knowledge docs are
      drifting from their linked code files. Alerts when knowledge/ content
      is stale relative to code changes.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/knowledge-freshness/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers: []

  # ─── LIFECYCLE / OUTREACH ──────────────────────────────────────────────────

  - name: cron-lifecycle-emails
    critical_path: false
    type: cron
    schedule: "0 13 * * *"
    description: >
      Daily 13:00 UTC lifecycle email trigger. Sends trial-expiry, upgrade
      nudge, and onboarding-incomplete emails via MailerLite automations.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/lifecycle-emails/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers:
      - flows/

  - name: cron-outreach-followup
    critical_path: false
    type: cron
    schedule: "15 13 * * *"
    description: >
      Daily 13:15 UTC outreach follow-up trigger. Processes pending
      outreach_contacts sequences for church prospect campaigns.
    repo: churchwiseai-web
    code_files:
      - src/app/api/cron/outreach-followup/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    covers:
      - flows/

  # ─── PRO WEBSITE (added 2026-04-17 by /ensure-solid) ─────────────────────

  - name: cwa-onboarding-wizard
    property: pro-website
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — step 3 of 10 customer flow
    type: playwright
    schedule: on-pr
    description: >
      Pro Website onboarding wizard end-to-end: landing → /onboard → Stripe
      checkout → magic link → wizard completion (hero photo, colors, service
      times, staff) → live subdomain. Flips critical_path=true after first
      green run.
    repo: churchwiseai-web
    code_files:
      - src/app/onboard/
      - src/app/api/onboard/route.ts
      - src/app/admin/[token]/components/WebsiteTab.tsx
    spec_file: e2e/pro-website-standalone.spec.ts
    baseline_file: null
    playwright_spec: cwa-onboarding-wizard
    override_label: critical-path-override
    last_run: 2026-04-18T02:40Z  # 15 passed, 6 skipped against https://churchwiseai.com
    last_break: null
    founder_verified: 2026-04-22
    covers:
      - acceptance/cwa-pro-website.md
      - acceptance/pewsearch-pro-website.md
      - processes/pro-website-wizard.md

  - name: cwa-pro-website-ssr
    property: pro-website
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — step 5 of 10 customer flow
    type: playwright
    schedule: on-pr
    description: >
      Public Pro Website SSR renderer at *.john316.church. Verifies ISR
      HTML doesn't leak CWA chrome, hero video/photo renders, service times
      + staff + contact form all present, custom color scheme applied.
    repo: churchwiseai-web
    code_files:
      - src/app/s/[slug]/page.tsx
      - src/middleware.ts
    spec_file: e2e/pro-website-standalone.spec.ts
    baseline_file: null
    playwright_spec: cwa-pro-website-ssr
    override_label: critical-path-override
    last_run: 2026-04-18T02:40Z  # 15 passed, 6 skipped against https://churchwiseai.com
    last_break: null
    founder_verified: 2026-04-22
    covers:
      - acceptance/cwa-pro-website.md
      - acceptance/pewsearch-pro-website.md

  - name: cwa-pro-website-edit
    property: pro-website
    critical_path: true   # flipped 2026-04-17 (founder-os week 1) — step 6 of 10 customer flow
    type: playwright
    schedule: on-pr
    description: >
      Admin dashboard Pro Website editor: customer can change hero photo,
      music, staff, events, contact form, color scheme. Every edit writes to
      premium_churches + invalidates ISR cache so the public subdomain
      reflects the change within 60s.
    repo: churchwiseai-web
    code_files:
      - src/app/admin/[token]/components/WebsiteTab.tsx
      - src/app/api/admin/website/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: cwa-pro-website-edit
    override_label: critical-path-override
    last_run: null
    last_break: null
    founder_verified: 2026-04-22
    covers:
      - acceptance/cwa-pro-website.md

  - name: cwa-pro-website-multipage
    property: pro-website
    critical_path: false   # additive feature; the critical ssr/edit paths it
                           # builds on are covered by cwa-pro-website-ssr/edit
    type: playwright
    schedule: on-pr
    description: >
      Multi-page Pro Website ("A Few Simple Pages"). Verifies an extra page
      renders at /s/[slug]/[page] via SimplePageTemplate + BlockRenderer, the
      home nav lists the extra pages, a single-page site still renders with
      no regression, and unknown page slugs 404.
    repo: churchwiseai-web
    code_files:
      - src/app/s/[slug]/[page]/page.tsx
      - src/components/templates/SimplePageTemplate.tsx
      - src/components/templates/shared/BlockRenderer.tsx
      - src/lib/pro-website-pages.ts
      - src/app/admin/[token]/components/WebsiteEditor/PagesEditor.tsx
    spec_file: e2e/pro-website-multipage.spec.ts
    baseline_file: null
    playwright_spec: pro-website-multipage
    override_label: critical-path-override
    last_run: 2026-05-22
    last_break: null
    founder_verified: null
    covers:
      - acceptance/pro-website-multipage.md

  - name: cwa-pro-website-funnel-synthetic
    property: pro-website
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Synthetic marketing funnel smoke: landing /pro-website returns 200,
      pricing /pricing renders with $19.95 Pro Website tier, clicking
      "Get Started" POSTs to /api/stripe/church-checkout and receives a
      valid session.url. Doesn't complete payment — just proves the funnel
      is wired end-to-end.
    repo: churchwiseai-web
    code_files:
      - src/app/pro-website/page.tsx
      - src/app/pricing/page.tsx
      - src/app/api/stripe/church-checkout/route.ts
    spec_file: e2e/synthetic/pro-website-funnel.spec.ts
    baseline_file: null
    playwright_spec: cwa-pro-website-funnel-synthetic
    override_label: null
    last_run: 2026-04-18T02:40Z  # 9 passed against https://churchwiseai.com
    last_break: null
    covers:
      - acceptance/cwa-pro-website.md

  - name: pro-website-planning-center
    property: pro-website
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Pro Website Planning Center calendar integration v1. Editor Events
      section source toggle (Enter manually / Connect Planning Center) +
      connect-panel state machine (pc_not_connected / pc_synced /
      pc_sync_error); a manual-events church renders byte-identically
      (regression guard); a PC-sourced church renders synced PC events +
      the discreet "Events synced from Planning Center" attribution line.
    repo: churchwiseai-web
    code_files:
      - src/app/s/[slug]/page.tsx
      - src/app/api/premium/update/route.ts
      - src/app/admin/[token]/components/WebsiteTabEditor.tsx
      - src/app/admin/[token]/components/WebsiteEditor/EventsSourceEditor.tsx
      - src/app/api/cron/sync-pc-calendars/route.ts
      - src/lib/planning-center/ical.ts
      - src/lib/planning-center/sync.ts
      - src/lib/planning-center/resolve-events.ts
    spec_file: e2e/pro-website-planning-center.spec.ts
    baseline_file: null
    playwright_spec: pro-website-planning-center
    override_label: null
    last_run: null
    last_break: null
    covers:
      - acceptance/pro-website-planning-center.md

  - name: sermonwise-help-page
    property: sermonwise
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      FA-076 regression guard. Verifies sermonwise.ai/help renders (not
      404), core section headings are present (getting-started, generating,
      subscription, billing, traditions, troubleshooting), back-to-app CTA
      points at /sermons/app, and the support email is visible.
      Page lives at src/app/sermons/help/page.tsx and is reached via the
      middleware hostname rewrite (sermonwise.ai/* → /sermons/*).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/help/page.tsx
    spec_file: e2e/journeys/sermonwise-help-accessible.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-help-accessible
    override_label: null
    last_run: 2026-05-11T00:00:00Z  # 3/3 green against https://sermonwise.ai
    last_break: null
    added: 2026-04-22
    tags: [sermonwise, help, docs]
    covers:
      - products/sermonwise/help.md
      - acceptance/sermonwise-pro.md

  - name: programmatic-passage-pages-contract
    property: sermonwise
    critical_path: false
    type: contract-e2e
    schedule: on-pr
    description: >
      Asserts 10 contract properties for programmatic /sermons/passage/[passage]/[tradition]
      pages — HTTP 200, h1 + tradition name in body, JSON-LD validity (Article +
      BreadcrumbList @type), page byte length > 5000, CTA href contains
      /sermons/app/new, content differs across traditions (reformed vs catholic
      for john-3-16), canonical href matches page URL, 404 on invalid slug.
      Runs against deployed sermonwise.ai (or preview via TEST_URL env var).
      RED until Subagents B + C merge and deploy. Phase 2 programmatic SEO sprint.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/passage/[passage-slug]/[tradition-slug]/page.tsx
      - src/data/passages/phase1-passages.ts
      - src/app/sitemap.ts
    spec_file: e2e/contracts/programmatic-passage-pages.contract.spec.ts
    baseline_file: null
    playwright_spec: programmatic-passage-pages-contract
    override_label: null
    last_run: 2026-05-11T00:00:00Z  # 33/33 green against https://sermonwise.ai — all 5 passage×tradition pairs + 10 contract assertions
    last_break: null
    added: 2026-05-08
    founder_verified: 2026-05-11
    tags: [sermonwise, seo, programmatic, passage, tradition, json-ld]
    covers: []

  - name: sermonwise-posthog-funnel
    property: sermonwise
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Live PostHog API verification — 6 SermonWise signup→upgrade funnel events
      (signup_form_submitted, signup_email_confirmed, first_app_visit,
      first_sermon_generated, upgrade_clicked, upgrade_completed) fire with
      correct properties and identity stitching against https://sermonwise.ai.
      Drives a real signup → confirm → first-app-visit → first-sermon flow via
      a CONSISTENT test user (john+testuser@churchwiseai.com — Workspace `+`
      alias to founder inbox so welcome/confirmation/onboarding emails are
      visible). Uses Supabase service-role to provision/cleanup the user
      idempotently between runs (and cleans the corresponding PostHog Person).
      Queries PostHog read-only API (POSTHOG_PERSONAL_API_KEY) to assert events
      are ingested with assertFunnelSequence + assertPersonIdentified helpers.
      upgrade_completed is SKIPPED in this spec (requires Stripe live-mode
      checkout completion + Supabase subscription cleanup) — tracked as a
      separate manual spec sermonwise-upgrade-completed.spec.ts.
      Flip critical_path to true after 3 consecutive green runs on production.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/components/auth/SignupForm.tsx
      - src/app/sermons/app/page.tsx
      - src/app/auth/callback/route.ts
      - src/app/api/sermons/generate/route.ts
      - src/components/sermons/SermonUpgradeButton.tsx
      - src/components/sermons/SermonUpgradeNudge.tsx
      - src/app/api/stripe/webhook/route.ts
    spec_file: e2e/contracts/sermonwise-posthog-funnel.contract.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-posthog-funnel
    override_label: critical-path-override
    last_run: 2026-05-11T12:53:08Z  # manual founder click-through — 5/6 events fired live in PostHog
    last_break: null
    added: 2026-05-08
    founder_verified: 2026-05-11
    findings:
      - "5/6 events fired live with correct properties (signup_form_submitted, first_app_visit, first_sermon_generated, upgrade_clicked, upgrade_completed)"
      - "signup_email_confirmed did NOT fire — needs diagnosis (auth/callback redirect chain may strip ?confirmed=1 before /sermons/app page reads it)"
      - "tradition→lens mapping works end-to-end: form 'methodist' → handle_new_user trigger sets lens_id=5 → first_sermon_generated event has lens_name='Wesleyan'"
      - "Stripe webhook inbox: 3/3 events (checkout.session.completed, customer.subscription.created, invoice.payment_succeeded) succeeded in 14s with 0 errors"
    tags: [sermonwise, analytics, posthog, funnel, identity-stitching]
    covers: []

  # ─── CWA LIFECYCLE — CANCELLED + TRIAL-EXPIRED ──────────────────────────────

  - name: cwa-cancelled
    property: cwa
    critical_path: true
    type: playwright
    schedule: on-pr
    description: >
      FA-063. Verifies the full cancellation experience across all plan types:
      cancellation flow (Settings > Billing), dashboard state during remaining
      billing period (full access + amber banner), dashboard state AFTER service
      ends (read-only, Export My Data, Reactivate button), public pages offline
      state, voice-specific phone number retention 30 days, and reactivation
      flow leads to /pricing. Applies to all paid plans (chat, voice, bundle).
      Uses demo account: Riverside Fellowship Church (demo-cancelled-2026).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/admin/
      - src/app/api/stripe/
      - src/lib/tier-config.ts
    spec_file: e2e/journeys/cancelled.spec.ts
    baseline_file: null
    playwright_spec: cwa-cancelled
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-04-22
    founder_verified: 2026-04-22
    tags: [cwa, lifecycle, cancellation, billing]
    covers:
      - acceptance/cancelled.md

  - name: cwa-trial-expired
    property: cwa
    critical_path: true
    type: playwright
    schedule: on-pr
    description: >
      FA-063. Verifies behavior when a 14-day chat plan trial expires without
      successful payment: dashboard state (gated UI, upgrade CTA visible),
      public page fallback messaging, and re-subscribe flow. Applies to
      Starter Chat, Pro Chat, Suite Chat (monthly + annual). Does NOT apply
      to Voice or Bundle plans (no trial). Uses demo account:
      Harbor Light Methodist Church (demo-trial-expired-2026).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/admin/
      - src/app/api/stripe/
      - src/lib/tier-config.ts
    spec_file: e2e/journeys/trial-expired.spec.ts
    baseline_file: null
    playwright_spec: cwa-trial-expired
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-04-22
    founder_verified: 2026-04-22
    tags: [cwa, lifecycle, trial, billing]
    covers:
      - acceptance/trial-expired.md

  # ─── PRO WEBSITE — CUSTOM DOMAIN ─────────────────────────────────────────

  - name: cwa-custom-domain-setup
    critical_path: true
    type: playwright
    schedule: on-pr
    property: pro-website
    description: >
      Custom domain workflow for the Pro Website bundled tier ($19.95/mo).
      Covers: site-only tombstone, bundled form visibility, domain add API,
      pending_dns status transition, missing Vercel token graceful degradation.
      Tests 2-4 are @authored-only until a demo-pro-website-bundled-2026 token
      is provisioned. Test 1 (site-only tombstone) runs against demo-bridge-2026.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/api/premium/domain/add/route.ts
      - src/app/api/premium/domain/verify/route.ts
      - src/lib/vercel-domains.ts
      - src/lib/stripe-invoice-items.ts
      - src/lib/tier-config.ts
      - src/app/admin/[token]/components/DomainSection.tsx
      - src/app/admin/[token]/components/SettingsTab.tsx
      - src/lib/premium-shared.ts
      - src/lib/premium-queries.ts
      - migrations/20260422_add_custom_domain_status.sql
    spec_file: e2e/journeys/custom-domain-setup.spec.ts
    baseline_file: null
    playwright_spec: cwa-custom-domain-setup
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-04-22
    founder_verified: null
    tags: [cwa, pro-website, domain, stripe, vercel, billing]
    covers:
      - acceptance/cwa-pro-website.md

  - name: sermonwise-export-share
    property: sermonwise
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Verify the export-share flow for generated sermons — save, export
      as PDF/Word/Text, copy as markdown. Authored 2026-04-22 EOD to
      close the registry gap in sermonwise.yaml `critical_journeys`.
      Spec not yet written — create before first production run.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/app/
      - src/app/api/sermons/
    spec_file: null   # spec pending — see FA filed separately
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    added: 2026-04-22
    tags: [sermonwise, export, sermons]
    covers:
      - acceptance/sermonwise-pro.md

  - name: sermonwise-derive-small-group-guide
    property: sermonwise
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      Verify the streaming-derivative generation flow — from a completed
      sermon, generate a small group guide, kids sermon, and social media
      posts. Authored 2026-04-22 EOD to close the registry gap in
      sermonwise.yaml `critical_journeys`. Spec not yet written.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/sermons/app/
      - src/app/api/sermons/
    spec_file: null   # spec pending — see FA filed separately
    baseline_file: null
    playwright_spec: null
    override_label: null
    last_run: null
    last_break: null
    added: 2026-04-22
    tags: [sermonwise, derivatives, streaming]
    covers:
      - acceptance/sermonwise-pro.md

  - name: sermonwise-saved-titles
    property: sermonwise
    critical_path: false
    type: contract-e2e
    schedule: on-pr
    description: >
      Contract: SavedTitlesSection — 5 assertions. Guards the saved sermon
      titles UI in src/components/sermons/SavedTitlesSection.tsx. Covers:
      (1) empty state — section hidden when no saved titles, (2) populated
      state — section visible with saved title text, (3) Use This href has
      /sermons/app/new + correct query params, (4) Remove button triggers
      optimistic removal from DOM, (5) Remove failure triggers snap-back
      and error message. Auth: authed (createOrResetTestUser — ephemeral).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/components/sermons/SavedTitlesSection.tsx
      - src/app/api/sermons/titles/saved/route.ts
    spec_file: e2e/contracts/sermonwise-saved-titles.contract.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-saved-titles
    override_label: null
    last_run: null
    last_break: null
    added: 2026-05-11
    tags: [sermonwise, saved-titles, contract, ui]
    covers:
      - acceptance/sermonwise-pro.md

  - name: sermonwise-auth-chrome
    property: sermonwise
    critical_path: false
    type: contract-e2e
    schedule: on-pr
    description: >
      Contract: SermonWise auth-aware chrome — 6 assertions (3 anon + 3 authed).
      Guards the conditional rendering of SermonNav (anon) vs SermonAppHeader
      (authed) across all SermonWise surfaces. Covers: (1) /sermons and
      /sermons/pricing show SermonNav with Get Started Free CTA visible (no
      Account menu), (2) /sermons/signup shows signup form not Account menu,
      (3) authed /sermons/app, /sermons/app/new, /sermons/titles show
      SermonAppHeader Account menu button. Auth: fresh anon contexts (no
      storageState) + authed (createOrResetTestUser — ephemeral).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/components/sermons/SermonAppHeader.tsx
      - src/components/sermons/SermonNav.tsx
      - src/app/sermons/titles/page.tsx
      - src/middleware.ts
    spec_file: e2e/contracts/sermonwise-auth-chrome.contract.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-auth-chrome
    override_label: null
    last_run: null
    last_break: null
    added: 2026-05-11
    tags: [sermonwise, auth, chrome, nav, contract, ui]
    covers:
      - acceptance/sermonwise-pro.md

  - name: sermonwise-derivative-cap
    property: sermonwise
    critical_path: false
    type: contract-e2e
    schedule: on-pr
    description: >
      Contract: SermonWise derivative cap 429 UI — 4 assertions. Guards the
      derivative generation rate-limiting behavior in
      src/app/api/sermons/derive/route.ts (DERIVATIVE_MONTHLY_LIMIT = 60).
      Covers: (1) free-tier user gets 403 (tier gate before cap gate) — confirms
      derive route reachable and returns JSON error shape, (2) 429 response shape
      via network intercept: error contains "60", limit=60, current=60,
      (3) DerivativePanel 429 banner: intercepted mock returns correct error
      pattern, (4) refund-on-failure: /api/sermons/usage derivativeCount does
      not increment after a failed derive call. Auth: authed (createOrResetTestUser).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/api/sermons/derive/route.ts
      - src/lib/sermon-usage.ts
      - src/components/sermons/DerivativePanel.tsx
    spec_file: e2e/contracts/sermonwise-derivative-cap.contract.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-derivative-cap
    override_label: null
    last_run: null
    last_break: null
    added: 2026-05-11
    tags: [sermonwise, derivative, rate-limit, 429, contract, api]
    covers:
      - acceptance/sermonwise-pro.md

  - name: sermonwise-app-header
    property: sermonwise
    critical_path: false
    type: contract-e2e
    schedule: on-pr
    description: >
      Contract: SermonAppHeader interactions — 5 assertions. Guards the
      interactive behaviours of SermonAppHeader
      (src/components/sermons/SermonAppHeader.tsx). Covers: (1) user menu
      dropdown opens on avatar button click — dropdown visible + aria-expanded=true,
      (2) usage progressbar in dropdown: role="progressbar", aria-valuemin=0,
      aria-valuemax=100, aria-valuenow set, (3) mobile hamburger (375px viewport)
      opens nav panel + aria-expanded=true, (4) Escape key closes open user menu
      + aria-expanded=false, (5) header sticky on scroll: boundingBox().y remains
      within 5px tolerance after scrollBy(0,500). Auth: authed (createOrResetTestUser).
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/components/sermons/SermonAppHeader.tsx
    spec_file: e2e/contracts/sermonwise-app-header.contract.spec.ts
    baseline_file: null
    playwright_spec: sermonwise-app-header
    override_label: null
    last_run: null
    last_break: null
    added: 2026-05-11
    tags: [sermonwise, app-header, accessibility, keyboard, sticky, contract, ui]
    covers:
      - acceptance/sermonwise-pro.md

  # ─── SYNTHETIC FUNNEL SPECS (dim-8 coverage) ──────────────────────────────

  - name: cwa-funnel-synthetic
    property: cwa
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      CWA marketing funnel smoke — asserts churchwiseai.com landing +
      pricing page (with all canonical $ amounts) + /api/stripe/church-checkout
      returns a Stripe session URL for cwa_starter_chat. Authored 2026-04-22 EOD.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/page.tsx
      - src/app/pricing/page.tsx
      - src/app/api/stripe/church-checkout/route.ts
    spec_file: e2e/synthetic/cwa-funnel.spec.ts
    baseline_file: null
    playwright_spec: cwa-funnel-synthetic
    override_label: null
    last_run: null
    last_break: null
    added: 2026-04-22
    tags: [cwa, synthetic, marketing, funnel]
    covers: []

  - name: itw-funnel-synthetic
    property: itw
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      ITW marketing funnel smoke — asserts illustratetheword.com landing +
      pricing ($9.95 Premium) + /api/stripe/checkout endpoint reachability.
      Closes FA-074. Authored 2026-04-22 EOD.
    owner: sermon-illustrations
    repo: sermon-illustrations
    code_files:
      - src/app/page.tsx
      - src/app/pricing/page.tsx
      - src/app/api/stripe/checkout/route.ts
    spec_file: e2e/synthetic-funnel.spec.ts
    baseline_file: null
    playwright_spec: itw-funnel-synthetic
    override_label: null
    last_run: null
    last_break: null
    added: 2026-04-22
    tags: [itw, synthetic, marketing, funnel]
    covers: []

  - name: pewsearch-funnel-synthetic
    property: pewsearch
    critical_path: false
    type: playwright
    schedule: on-pr
    description: >
      PewSearch marketing funnel smoke — asserts pewsearch.com landing +
      pricing ($4.95 Premium Page) + /api/stripe/pre-checkout reachability.
      Authored 2026-04-22 EOD.
    owner: pewsearch
    repo: pewsearch
    code_files:
      - web/src/app/page.tsx
      - web/src/app/pricing/page.tsx
      - web/src/app/api/stripe/pre-checkout/route.ts
    spec_file: web/e2e/synthetic-funnel.spec.ts
    baseline_file: null
    playwright_spec: pewsearch-funnel-synthetic
    override_label: null
    last_run: null
    last_break: null
    added: 2026-04-22
    tags: [pewsearch, synthetic, marketing, funnel]
    covers: []

  # ─── VOICE / LIVE-TRANSFER — COLD-OUTREACH DEMO ──────────────────────────

  - name: cold-outreach-director-transfer
    property: cwa
    critical_path: true
    type: playwright
    schedule: on-pr
    description: >
      Full round-trip integration spec for the FuneralWiseAI cold-outreach
      director-transfer demo. Exercises the complete path: real browser →
      fake mic (WAV fixture) → LiveKit Cloud → voice agent runtime → STT →
      LLM → transfer_to_director tool → SIP outbound → DB write.

      Catches the four P0 regressions that slipped through PR #251 (Day 2 A)
      on 2026-04-29 because all prior tests stubbed every layer:
        P0 #3 — RoomEvent.TrackSubscribed not wired (audio element missing in DOM)
        P0 #4 — mic-permission race (getUserMedia after room.connect())
        P0 #5 — transfer_to_director registered on CareAgent only, not CoordinatorAgent
        P0 #8 — TransferSIPParticipant (SIP REFER) called on WebRTC caller leg

      Required for cold-email GO/NO-GO gate on FuneralWiseAI batch.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/components/cold-outreach/
      - src/app/s/[slug]/
      - src/app/api/livekit/token/
      - src/components/brand-family/WebRTCDemoButton.tsx
      - src/components/templates/ServiceBusinessTemplate.tsx
      - voice-agent-livekit/core/transfer.py
      - voice-agent-livekit/verticals/church/agents.py
      - voice-agent-livekit/verticals/funeral/
      - voice-agent-livekit/main.py
      - voice-agent-livekit/session.py
    spec_file: e2e/cold-outreach-director-transfer.spec.ts
    baseline_file: null
    playwright_spec: cold-outreach-director-transfer
    override_label: critical-path-override
    last_run: null
    last_break: 2026-04-29
    last_break_notes: >
      8 P0s in PR #251 all from the browser→LiveKit→agent→carrier path. None caught by
      stubbed unit tests. This spec is the retrospective gate that would have blocked merge.
      Lane A (feat/day4-A-webrtc-sip-bridge) must also land before assertion #10 (P0 #8)
      passes fully end-to-end (WebRTC↔SIP architectural fix).
    founder_verified: null
    added: 2026-04-29
    tags: [voice, livekit, webrtc, funeral, cold-outreach, director-transfer, round-trip]
    covers:
      - specs/day2-verticals-platform/07-DAY4-HANDOFF.md
      - processes/voice-provisioning.md

  # ─── VERTICAL PREVIEW TEMPLATES (jiggly-bubble sprint, 2026-05-04) ──────────

  - name: cwa-preview-funeral
    property: cwa
    critical_path: false
    type: playwright
    schedule: manual
    description: >
      Verifies /preview/[slug] renders FuneralPreview (not the church PreviewClient)
      when the slug resolves to an outreach_contacts row with vertical='funeral'.
      Checks: 200 status, funeral home name in hero h1, "FuneralWiseAI" brand label,
      chatbot CTA with funeral suggested questions, /onboard activation CTA.
      BLOCKED until: (a) a real funeral outreach slug is seeded in outreach_contacts,
      (b) matching funeral_homes + premium_funeral_homes rows exist.
      BrowserVoiceDemo button assertion pending FuneralPreview widget integration.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/preview/[slug]/page.tsx
      - src/app/preview/[slug]/templates/FuneralPreview.tsx
      - src/lib/outreach/provision.ts
    spec_file: e2e/preview-funeral.spec.ts
    baseline_file: null
    playwright_spec: preview-funeral
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-05-04
    founder_verified: null
    tags: [vertical, funeral, preview, cold-outreach, template]
    covers: []

  - name: cwa-preview-vet
    property: cwa
    critical_path: false
    type: playwright
    schedule: manual
    description: >
      Verifies /preview/[slug] renders VetPreview when the slug resolves to an
      outreach_contacts row with vertical='veterinary'. Checks: 200 status, clinic
      name in hero h1, "VetWiseAI" brand label (not ChurchWiseAI/FuneralWiseAI),
      chatbot CTA with vet suggested questions (hours, chocolate), after-hours
      triage copy, /onboard activation CTA.
      BLOCKED until: (a) vet identity table (premium_vet_clinics) exists — Stream B
      task pending as of 2026-05-04, (b) real vet outreach slug seeded, (c) vet
      provision.ts path creates outreach_contacts row with vertical='veterinary'.
      BrowserVoiceDemo button assertion pending VetPreview widget integration.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/preview/[slug]/page.tsx
      - src/app/preview/[slug]/templates/VetPreview.tsx
      - src/lib/outreach/provision.ts
    spec_file: e2e/preview-vet.spec.ts
    baseline_file: null
    playwright_spec: preview-vet
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-05-04
    founder_verified: null
    tags: [vertical, vet, veterinary, preview, cold-outreach, template]
    covers: []

  - name: cwa-chatbot-vertical-aware
    property: cwa
    critical_path: false
    type: playwright
    schedule: manual
    description: >
      Verifies the chatbot routing is vertical-aware — requests tagged with
      brand='playground-funeral' or brand='playground-vet' resolve the correct
      per-vertical system prompt, not the church HEAR prompt. Covers the
      prospectSlug branch added in the jiggly-bubble sprint. No spec file exists
      yet — add when the unified chatbot route has a stable integration surface
      for vertical mocking.
    owner: churchwiseai-web
    repo: churchwiseai-web
    code_files:
      - src/app/api/chatbot/unified/route.ts
      - src/app/api/livekit/token/route.ts
    spec_file: null
    baseline_file: null
    playwright_spec: null
    override_label: critical-path-override
    last_run: null
    last_break: null
    added: 2026-05-04
    founder_verified: null
    tags: [chatbot, vertical, funeral, vet, routing]
    covers: []
