P6 and Microsoft Project
P6 Cstr_type ↔ Project Constrainttype
P6 CS_* ↔ Project ConstraintType 0–7; holes marked

Only pairs we can source from both sides. P6 codes are from Oracle CPP / Prime maps + MPXJ PrimaveraReader, not from the XER TASK column map (that map only says cstr_type = Primary Constraint). Project integers are Microsoft ConstraintType.
Sourced pairs
| P6 (CS_*) | Project ConstraintType | Notes |
|---|---|---|
CS_ALAP | 1 As late as possible | Prime map + MPXJ. Not in the CPP list fetched |
CS_MSOA | 4 Start no earlier than | MPXJ; Oracle "Start On or After" |
CS_MSOB | 5 Start no later than | MPXJ; Oracle "Start On or Before" |
CS_MEOA | 6 Finish no earlier than | MPXJ; Oracle "Finish On or After" |
CS_MEOB | 7 Finish no later than | MPXJ; Oracle "Finish On or Before" |
CS_MSO | 2 Must start on | Not the same. P6 help: Start On is soft. Project MSO is a must |
CS_MEO | 3 Must finish on | Same caveat (P6 Finish On is soft in P6 help) |
CS_MANDSTART | 2 Must start on | P6 mandatory overrides network logic. Project has no separate mandatory. MPXJ collapses this with CS_MSO |
CS_MANDFIN | 3 Must finish on | Same collapse |
Holes (do not invent a pair)
| Hole | Why |
|---|---|
| P6 "no constraint" / ASAP | Whether XER stores blank, CS_ASAP, or omits the field is unverified. Project ASAP is ConstraintType 0. CPP lists CS_ASAP; historical MPXJ map we fetched did not include it |
CS_ASAP → 0 | Plausible, not dual-sourced from MPXJ + a live XER |
Secondary constraint cstr_type2 | Project has one constraint per task. Drop / ignore is the usual converter outcome; unverified as MPXJ behavior |
Expected Finish (expect_end_date) | Not a cstr_type. No cited MSPDI equivalent |
| CPP vs P6-help hard/soft | CPP tags CS_MSO / CS_MEO / CS_MSOB / CS_MEOB as hard. P6 Professional/EPPM help: only Mandatory Start/Finish are hard. Write both; do not pick |
A round-trip cannot restore Mandatory vs Start On / Finish On. That is a proved team fact (msp/constraints.md).
Never write a real MPP. Generate MSPDI.