Embedding USCG Passenger Manifest Collection into JADA's Charter Confirmation Email Pipeline

What Was Done

JADA's charter operations workflow relied on a liability waiver ("Passenger Manifest & Waiver") collected day-of at the dock to satisfy passenger identification requirements. In practice, this template is a blank 30-row signature sheet with no pre-populated passenger names—it captures signatures, not a pre-departure manifest. The U.S. Coast Guard requires actual passenger rosters prior to departure, not signature sheets filled at boarding. This work integrates a mandatory pre-charter passenger name collection step into the existing guest confirmation email workflow, ensuring names arrive 48+ hours before each sailing.

Technical Details: The Template Architecture

JADA's ops scripts use a shared template module pattern to keep email content in sync across multiple scripts that generate different types of confirmation emails. The canonical content lives in ~/icloud-jada-ops/templates/boat_policy.py, a Python module that exports reusable HTML and plain-text content blocks:

# Existing pattern in boat_policy.py (simplified)
ONBOARD_POLICY_HTML = "<h3>Onboard Policy</h3>..."
ONBOARD_POLICY_PLAIN = "Onboard Policy\n..."

# New blocks added:
MANIFEST_REQUEST_HTML = """
<h3>Passenger Manifest</h3>
<p>...reply with full names of all passengers...48 hours before departure</p>
"""
MANIFEST_REQUEST_PLAIN = "Passenger Manifest\nPlease reply with full names..."

This pattern avoids duplicating content across scripts. Any script that imports from boat_policy.py automatically picks up the new blocks on next execution.

Integration into send_charter_emails.py

The primary confirmation email generator, ~/icloud-jada-ops/send_charter_emails.py, builds guest HTML by composing these shared blocks. The manifest request was inserted immediately after the existing waiver block in the guest_html() function:

from templates.boat_policy import (
    MANIFEST_REQUEST_HTML,
    MANIFEST_REQUEST_PLAIN,
    # ... existing imports
)

def guest_html(booking):
    parts = [
        # ... earlier content ...
        boat_policy.WAIVER_HTML,
        boat_policy.MANIFEST_REQUEST_HTML,  # NEW: inserted here
        # ... rest of template ...
    ]
    return "\n".join(parts)

This placement is intentional: guests receive the waiver and immediately see the manifest request in the same email, so they understand both requirements in one touchpoint rather than creating a separate follow-up email.

Workflow Documentation: CHARTER-WORKFLOW.md

The canonical ops checklist, ~/icloud-jada-ops/CHARTER-WORKFLOW.md, documents this as a mandatory step. A new Step D2 was added between "Guest Confirmation Page Provisioned" and "Crew Dispatch":

## D2. Collect & Verify Passenger Manifest (USCG Requirement)

**Why this is separate from the waiver:**
- The waiver is a blank signature sheet (filled day-of at the dock)
- USCG requires a pre-departure passenger roster with full names
- Waivers ≠ manifests; both are required

**Process:**
1. Guest receives manifest request in confirmation email
2. Expected response: guest replies with full name of every passenger (including self)
3. Landing spot: `passengers/contacts.csv` and printed manifest (see print/ directory)
4. Escalation: if list not received by charter T-24h, SMS/call guest to confirm

**Status tracking:**
- [ ] Manifest received
- [ ] Manifest cross-checked against waiver signees
- [ ] Manifest printed for captain

This documentation clarifies that the day-of waiver was never intended to be a manifest and explains why the pre-departure request is necessary.

Key Decisions

Why Reuse the Existing Email, Not Create a Separate Request?

Charter guests already receive a multi-section confirmation email (waiver, onboard policies, logistics). Adding another email risks email fatigue and raises the barrier for compliance. By embedding the manifest request in the existing email, we piggyback on an already-open communication channel. Guests see it alongside the waiver in a single read, and reply-to workflows stay simple.

Why 48 Hours Before Charter?

The confirmation email is typically sent 48–72 hours pre-charter once the guest has signed the waiver. This timing allows:

  • Guest enough time to confirm final headcount with any co-booking parties
  • Ops team time to follow up if the list doesn't arrive
  • Captain time to review the manifest before boarding

Tighter windows risk incomplete data; looser windows reduce time for escalation.

Why Not Generate the Manifest Automatically From Payment Records?

JADA's booking system records purchaser name and party size, but not the individual names of all passengers. A guest might book for 6 people but only 5 actually sail, or different people might attend than anticipated at booking time. The Coast Guard manifest must reflect who actually departs, so guest confirmation of the full name list is the authoritative step—not something that can be inferred from the transaction.

Handling Custom / Hand-Built Emails

The workflow doc includes a note for future work: some charters still use hand-built confirmation emails (copied and rewritten per-charter rather than generated from shared templates). These need to be migrated or manually audited to ensure they include the manifest request block. This is a data-integrity risk and a future refactor target.

What's Next

  • Monitoring manifest arrival rate: Track how many charters receive timely passenger name lists vs. require escalation (SMS/call). Target: 95%+ arrival within 48h of confirmation email sent.
  • Audit existing hand-built templates: Identify charters using non-generated confirmation emails and either migrate them to shared templates or manually add the manifest request block.
  • Captain print workflow: Verify that the printed manifest (generated from generate_manifest.py) actually makes it to the captain pre-departure. Currently documented as "print/ directory" but the end-to-end handoff should be tested.
  • USCG compliance audit: After 2–3 months of data, validate that manifests are being collected early enough and with enough detail (full legal names, spellings) to satisfy Coast Guard inspection standards.

Summary

By embedding the passenger manifest request into the existing guest confirmation email and documenting it as a mandatory ops step, JADA closes a compliance gap without introducing new communication channels or operational complexity. The shared template architecture ensures consistency across all scripts, and the workflow doc makes clear that waivers and manifests serve different purposes—both required, neither sufficient alone.