AI Agent Playbook

Bootstrap Migration

Paste this playbook into Claude, ChatGPT, or any AI agent with access to your oneme/Titan/FoxScience systems. It will execute the migration step by step.

Developer Console
oneme + TitanImport CustomersMint HandlesLinkScience DataVerifyPurge
READ FIRST
Overview
# Proven.dev Bootstrap Playbook
# One-Time Migration: oneme + Titan + FoxScience → Proven

## What This Does
You are migrating existing customer and patient data into Proven.dev's
privacy-first health data infrastructure. After this bootstrap:
- Customer profiles from oneme/Titan are stored in Proven
- Patient identifiers are replaced with opaque subject_handles
- FoxScience only has handles + science data (no PHI)
- All temporary identity data is purged

## Prerequisites
- A Proven.dev API key (hid_key_*) with 'mint' + 'ingest' + 'mailbox' scopes
- Access to oneme, Titan, and FoxScience databases/APIs
- The issuer_handle for your organization (from Proven registration)

## Order of Operations
1. Import customer profiles from oneme + Titan
2. Mint subject handles for FoxScience patient_ids
3. Link handles to customer profiles
4. Push de-identified science data
5. Verify everything
6. Purge temporary identity data

## Base URL
All endpoints use: https://proven.dev/api/

## Authentication
All requests require:
  Authorization: Bearer hid_key_<your-key>
  Content-Type: application/json
STEP 1
Step 1: Import Customers
# Step 1: Import Customer Profiles from oneme + Titan

## What to do:
1. Query oneme database for all customer/org records
2. Query Titan database for all customer/org records
3. Merge/dedup by company name or external ID
4. Push to Proven via POST /api/bootstrap/customers

## Endpoint
POST https://proven.dev/api/bootstrap/customers

## Payload
{
  "issuerHandle": "iss_<your-issuer-handle>",
  "customers": [
    {
      "externalId": "oneme-cust-001",
      "source": "oneme",
      "orgName": "Acme Health Corp",
      "contactName": "John Smith",
      "contactEmail": "[email protected]",
      "industry": "pharma",
      "tier": "enterprise",
      "metadata": { "plan": "annual", "seats": 50 }
    },
    {
      "externalId": "titan-cust-042",
      "source": "titan",
      "orgName": "BioGen Labs",
      "contactName": "Jane Doe",
      "contactEmail": "[email protected]",
      "industry": "biotech",
      "tier": "pro",
      "metadata": { "region": "northeast" }
    }
  ]
}

## curl Example
curl -X POST https://proven.dev/api/bootstrap/customers \
  -H "Authorization: Bearer hid_key_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "issuerHandle": "iss_<handle>",
    "customers": [
      {
        "externalId": "oneme-001",
        "source": "oneme",
        "orgName": "Acme Health",
        "contactName": "John Smith",
        "contactEmail": "[email protected]",
        "industry": "pharma",
        "tier": "enterprise"
      }
    ]
  }'

## Expected Response
{
  "issuerHandle": "iss_abc123",
  "total": 2,
  "created": 2,
  "updated": 0,
  "skipped": 0,
  "customers": [
    { "externalId": "oneme-cust-001", "customerId": 1, "status": "created" },
    { "externalId": "titan-cust-042", "customerId": 2, "status": "created" }
  ]
}

## Notes
- Run oneme customers first, then Titan
- If a customer with the same externalId + source exists, it will be UPDATED (not duplicated)
- contactName will be purged in Step 6 — it's only held temporarily for matching
- You can batch up to 500 customers per request
STEP 2
Step 2: Mint Handles
# Step 2: Mint Subject Handles from FoxScience Patient IDs

## What to do:
1. Query FoxScience for all distinct patient_ids
2. Send them to Proven's mint endpoint
3. Proven returns opaque subject_handles for each patient_id
4. Write the subject_handles BACK to FoxScience (add column, drop patient_id later)

## Endpoint
POST https://proven.dev/api/healthid/mint

## Payload
{
  "issuerHandle": "iss_<your-issuer-handle>",
  "uuids": [
    "patient-uuid-001",
    "patient-uuid-002",
    "patient-uuid-003"
  ]
}

## curl Example
curl -X POST https://proven.dev/api/healthid/mint \
  -H "Authorization: Bearer hid_key_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "issuerHandle": "iss_<handle>",
    "uuids": ["patient-001", "patient-002", "patient-003"]
  }'

## Expected Response
{
  "issuerHandle": "iss_abc123",
  "totalMinted": 3,
  "newMinted": 3,
  "mapping": [
    {
      "uuid": "patient-001",
      "subjectHandle": "hid_a7f3b2c1d4e5",
      "healthIdDomain": "a7x9k2.healthid",
      "isNew": true
    },
    {
      "uuid": "patient-002",
      "subjectHandle": "hid_b8g4c3d2e6f7",
      "healthIdDomain": "b8y0l3.healthid",
      "isNew": true
    }
  ]
}

## IMPORTANT: Save the mapping!
The response contains the uuid → subjectHandle mapping.
You MUST save this mapping to update FoxScience:

For each row in the mapping:
  UPDATE foxscience.patient_intake_forms
  SET subject_handle = '<subjectHandle>'
  WHERE patient_id = '<uuid>';

After ALL handles are written:
  ALTER TABLE foxscience.patient_intake_forms
  DROP COLUMN patient_id;

## Notes
- Minting is deterministic: same issuer + same UUID = same handle every time
- You can re-run this safely — existing handles won't be duplicated
- Batch up to 1000 UUIDs per request
- Each new handle automatically gets a .healthid domain
STEP 3
Step 3: Link Handles to Customers
# Step 3: Link Subject Handles to Customer Profiles

## What to do:
1. For each customer from Step 1, determine which patient_ids belong to them
2. Look up the subject_handles from Step 2's mapping
3. Link them via POST /api/bootstrap/link-handles

## Endpoint
POST https://proven.dev/api/bootstrap/link-handles

## Payload
{
  "issuerHandle": "iss_<your-issuer-handle>",
  "links": [
    {
      "customerExternalId": "oneme-cust-001",
      "subjectHandles": ["hid_a7f3b2c1d4e5", "hid_b8g4c3d2e6f7"]
    },
    {
      "customerExternalId": "titan-cust-042",
      "subjectHandles": ["hid_c9h5d4e3f8g9"]
    }
  ]
}

## curl Example
curl -X POST https://proven.dev/api/bootstrap/link-handles \
  -H "Authorization: Bearer hid_key_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "issuerHandle": "iss_<handle>",
    "links": [
      {
        "customerExternalId": "oneme-001",
        "subjectHandles": ["hid_a7f3b2c1d4e5"]
      }
    ]
  }'

## Expected Response
{
  "issuerHandle": "iss_abc123",
  "total": 2,
  "linked": 2,
  "notFound": 0,
  "results": [
    { "customerExternalId": "oneme-cust-001", "handlesLinked": 2, "status": "linked" },
    { "customerExternalId": "titan-cust-042", "handlesLinked": 1, "status": "linked" }
  ]
}

## Notes
- customerExternalId must match the externalId used in Step 1
- You can link multiple handles to one customer (e.g., one org has many patients)
- Re-running is safe — handles are deduplicated per customer
STEP 4
Step 4: Push Science Data
# Step 4: Push De-identified Science Data

## What to do:
1. Query FoxScience for science data (biomarkers, panel results, features)
2. Use the subject_handles from Step 2 (NOT patient_ids)
3. Push via POST /api/healthid/ingest
4. This is the SAME endpoint used for normal operations — no special bootstrap needed

## Endpoint
POST https://proven.dev/api/healthid/ingest

## Payload
{
  "issuerHandle": "iss_<your-issuer-handle>",
  "packets": [
    {
      "subjectHandle": "hid_a7f3b2c1d4e5",
      "features": {
        "panel_type": "microbiome_16s",
        "shannon_diversity": 3.45,
        "firmicutes_ratio": 0.62,
        "bacteroidetes_ratio": 0.28,
        "proteobacteria_ratio": 0.05,
        "actinobacteria_ratio": 0.03,
        "diagnosis_codes": ["K58.0", "R19.7"],
        "biomarker_calprotectin": 145.2
      }
    }
  ]
}

## curl Example
curl -X POST https://proven.dev/api/healthid/ingest \
  -H "Authorization: Bearer hid_key_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "issuerHandle": "iss_<handle>",
    "packets": [
      {
        "subjectHandle": "hid_a7f3b2c1d4e5",
        "features": {
          "panel_type": "microbiome_16s",
          "shannon_diversity": 3.45,
          "firmicutes_ratio": 0.62
        }
      }
    ]
  }'

## Expected Response
{
  "ingested": 1,
  "packets": [
    { "subjectHandle": "hid_a7f3b2c1d4e5", "packetId": 42 }
  ]
}

## CRITICAL: No PHI in features!
The features object must contain ONLY science/clinical data:
  ✅ biomarkers, lab values, panel results, diagnosis codes, diversity indices
  ❌ names, DOBs, SSNs, addresses, phone numbers, emails

The subject_handle is the ONLY link to identity.
Proven's PII firewall will reject packets containing known identity fields.

## Notes
- Batch up to 100 packets per request
- Each packet creates a science record and an encounter event
- Discovery matching runs automatically after ingestion
STEP 5
Step 5: Verify
# Step 5: Verify Bootstrap Progress

## What to do:
1. Check the bootstrap status endpoint
2. Verify all customers are imported
3. Verify all handles are linked
4. Verify science data is ingested

## Endpoint
GET https://proven.dev/api/bootstrap/status

## curl Example
curl -X GET https://proven.dev/api/bootstrap/status \
  -H "Authorization: Bearer hid_key_<your-key>"

## Expected Response (when complete)
{
  "phase": "science_pushed",
  "customers": {
    "total": 150,
    "purged": 0,
    "unpurged": 150
  },
  "batches": {
    "total": 5,
    "completed": 5
  },
  "staging": {
    "pending": 0,
    "purged": 0
  },
  "readyToPurge": true
}

## Also verify with:

# List all customers
curl -X GET "https://proven.dev/api/bootstrap/customers?limit=50" \
  -H "Authorization: Bearer hid_key_<your-key>"

# List all .healthid domains
curl -X GET https://proven.dev/api/healthid/domains \
  -H "Authorization: Bearer hid_key_<your-key>"

# Check mailbox for any discovery events
curl -X GET "https://proven.dev/api/healthid/mailbox?issuerHandle=iss_<handle>" \
  -H "Authorization: Bearer hid_key_<your-key>"

## Checklist before purging:
- [ ] All customers from oneme show up in /api/bootstrap/customers
- [ ] All customers from Titan show up in /api/bootstrap/customers
- [ ] All FoxScience patient_ids have been minted (check domain count)
- [ ] Handles are linked to correct customer profiles
- [ ] Science data packets are ingested (check encounter counts)
- [ ] FoxScience database has subject_handle column populated
- [ ] FoxScience patient_id column is ready to drop
STEP 6
Step 6: Purge
# Step 6: Purge Temporary Identity Data

## What this does:
- Deletes all staging records (raw uploaded data)
- Clears contactName from customer profiles
- Marks all customers as identity-purged
- After this, Proven only holds: org names + handles + de-identified science

## ⚠️ THIS IS IRREVERSIBLE
Make sure Step 5 verification is complete before proceeding.

## Endpoint
POST https://proven.dev/api/bootstrap/purge

## Payload
{
  "confirm": true
}

## curl Example
curl -X POST https://proven.dev/api/bootstrap/purge \
  -H "Authorization: Bearer hid_key_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{ "confirm": true }'

## Expected Response
{
  "success": true,
  "message": "Bootstrap purge complete. Temporary identity data has been removed. Science data and handles are preserved.",
  "note": "All customers marked as purged. Contact names cleared."
}

## After purge, also clean FoxScience:
ALTER TABLE foxscience.patient_intake_forms DROP COLUMN patient_id;

## Final state:
- Proven: customer profiles (org name only) + handles + science data
- FoxScience: subject_handles + science data (no patient_ids)
- oneme/Titan: unchanged (they keep their own data)
- No PHI stored anywhere in Proven

## 🎉 Bootstrap complete! 
From now on, all new data flows through Proven's normal upload pipeline:
  Upload → AI Map → Mint Handles → Strip PII → Emit to FoxScience

Ready to migrate?

Copy the full playbook, paste it into your AI agent, and let it handle the rest. The entire migration takes about 15 minutes.