CCRT + IPC Circumplex + Millon Schema Injection + Cosine Similarity Vector Engine
A comprehensive, research-supported framework for personality compatibility assessment via free-text content analysis
src/data/compatibility.js), Millon subtype trait dictionaries (from src/data/subtypes.js), archetype metadata (from src/lib/archetypeData.js), manipulation pattern triggers (from lib/manipulationDetector.js), and personality schema injection prompts (from app/api/chat/route.js). The CCRT standard category dictionaries (W1-W14, RO1-RO10, RS1-RS10), motive scoring markers, content analysis pipeline, vector construction algorithm, cosine similarity matching engine, progress notes writer, and API endpoint specifications are formalized extensions — new systematic structures derived from the existing schema injections and grounded in the cited psychometric literature. API endpoints are proposed specifications for a future standalone service.
| Framework | Source | Application |
|---|---|---|
| Core Conflictual Relationship Theme (CCRT) | Luborsky, L. (1977, 1990, 1998). Understanding Transference: The CCRT Method | Wish (W), Response of Other (RO), Response of Self (RS) extraction from free text |
| Interpersonal Circumplex (IPC) | Leary (1957); Wiggins (1979, 1995); Horowitz et al. (2006). Interpersonal Problems IIP-64 | 2D geometric personality positioning: Dominance (vertical) x Affiliation (horizontal) |
| Millon Personality Subtypes | Millon, T. (1996, 2011). Disorders of Personality: DSM-IV and Beyond | 31 clinical subtypes across 10 archetype families for fine-grained personality typing |
| Cosine Similarity | Salton, G. (1989). Automatic Text Processing; Turney & Pantel (2010) | Vector-space match scoring between personality profiles |
| Factor Analysis (CFA/EFA) | Fabrigar et al. (1999); Brown (2015). CFA for Applied Research | Empirical defensibility of a priori factor selections |
| Structural Analysis of Social Behavior (SASB) | Benjamin, L. S. (1974, 1996) | Complementary to IPC — provides transitive/intransitive action coding |
| Attachment Theory | Bartholomew & Horowitz (1991) | 4-category model maps cleanly onto IPC quadrants |
Luborsky's CCRT provides the content of relational patterns (what people want, expect, and do). The IPC provides the geometric structure (where these patterns live in interpersonal space). By mapping CCRT components onto IPC coordinates, we achieve both clinical depth and mathematical tractability for cosine similarity computation.
Analyze user bios, messages, and prompt responses to extract CCRT profiles. Calculate bidirectional compatibility with ideal/worst match prototypes. Surface "complementary CCRT" matches (e.g., Wish-to-provide alignment).
Profile team members via written communication samples. Identify IPC clustering (all dominant = conflict). Optimize for IPC distribution and complementary CCRT patterns. Flag collusive bond risks.
Content-analyze cover letters, interview transcripts, and writing samples. Match candidate personality vectors against ideal-role prototypes. Detect manipulation patterns in self-presentation.
Analyze personal statements and essays for CCRT themes and motive patterns (Achievement, Affiliation, Power). Predict cultural fit and peer compatibility.
Match therapist IPC style with client needs. Avoid complementary collusion (e.g., dominant therapist + dependent client reinforcing pathology). Optimize for therapeutic alliance factors.
Analyze mentor/mentee communication styles. Match for productive CCRT complementarity (mentor provides what mentee wishes for). Monitor relationship health over time.
Profile living-style preferences and conflict resolution patterns. IPC proximity predicts daily friction. CCRT worst-match detection prevents explosive pairings.
Analyze pitch decks, emails, and meeting transcripts. Detect motive alignment (shared Achievement motive) and IPC complementarity (one dominant + one affiliative = optimal).
Map disputants on IPC to identify positional rigidity. Extract CCRT themes to find the underlying Wish driving the conflict. Design interventions targeting the RO/RS cycle.
Aggregate public posts, comments, and interactions. Extract longitudinal CCRT shifts. Build personality timelines. Detect manipulation pattern frequency and severity trends.
Profile support agents and customers. Route dominant customers to affiliative agents. Detect escalation risk via IPC angular distance.
Optimize study groups and project teams. Balance IPC distribution for productive conflict. Match complementary CCRT profiles for peer learning.
Each archetype family represents a primary personality organization pattern from Millon's taxonomy, mapped to clinical names and game-universe display names.
| Archetype ID | Clinical Name | Display Name | Core Description | Bond Effect (Ego/Emp/Inf) |
|---|---|---|---|---|
| NARCISSISTIC | Narcissistic PD | The Emperor | Self-absorbed charm that demands admiration | +2 / -1 / +1 |
| DEPENDENT | Dependent PD | The Devoted | Desperate need for connection and approval | -1 / +2 / -1 |
| BORDERLINE | Borderline PD | The Storm | Intense emotions that split between extremes | 0 / +1 / +1 |
| HISTRIONIC | Histrionic PD | The Star | Dramatic flair demanding constant attention | +1 / 0 / +2 |
| AVOIDANT | Avoidant PD | The Shadow | Withdrawn soul hiding from connection | -1 / +1 / -2 |
| SCHIZOID | Schizoid PD | The Void | Emotionally detached, preferring solitude | 0 / -2 / 0 |
| ANTISOCIAL | Antisocial PD | The Predator | Predatory manipulation without remorse | +2 / -2 / +2 |
| PARANOID | Paranoid PD | The Watcher | Hypervigilant distrust of everyone | +1 / -1 / 0 |
| OBSESSIVE_COMPULSIVE | OCPD | The Perfection | Rigid control masking deep anxiety | +1 / -1 / +1 |
| PASSIVE_AGGRESSIVE | Passive-Aggressive PD | The Thorn | Hidden hostility behind a pleasant mask | 0 / 0 / +1 |
| Level | Clinical Severity | Rarity Label | Stars | Pull Rate | Trait Expression |
|---|---|---|---|---|---|
| 1 | Trait | Common | 1 | 60% | Subclinical personality style, adaptive |
| 2 | Subclinical | Uncommon | 2 | 25% | Noticeable pattern, some interpersonal cost |
| 3 | Moderate | Rare | 3 | 10% | Functional impairment emerging |
| 4 | Clinical | Epic | 4 | 4% | Meets diagnostic threshold |
| 5 | Severe | Legendary | 5 | 1% | Complete identification, reality-distorting |
The Core Conflictual Relationship Theme (Luborsky, 1977) consists of three components extracted from Relationship Episodes (REs) in free text:
| Component | Code | Definition | Extraction Method |
|---|---|---|---|
| Wish | W | What the subject wants from the other person in the relationship | Identify desire/need statements, implicit longings, behavioral goals |
| Response of Other | RO | How the subject perceives/expects the other to respond | Identify attributions, expectations, perceived reactions from others |
| Response of Self | RS | How the subject responds (behaviorally, emotionally, defensively) | Identify coping patterns, defense mechanisms, emotional reactions |
| Code | Category | Dictionary Markers |
|---|---|---|
| W1 | To be understood | "understand me", "get me", "see who I am", "know the real me" |
| W2 | To be accepted | "accept me", "approve", "like me", "don't judge", "belong" |
| W3 | To be respected | "respect", "taken seriously", "valued", "honored", "not dismissed" |
| W4 | To be loved | "love me", "care about", "devoted", "cherish", "adore" |
| W5 | To be independent | "my own", "space", "freedom", "don't need", "self-sufficient" |
| W6 | To be in control | "control", "my way", "decide", "power", "authority", "lead" |
| W7 | To be helped | "help me", "support", "take care of", "protect", "save" |
| W8 | To hurt others | "make them pay", "punish", "revenge", "destroy", "teach them a lesson" |
| W9 | To be close | "close to", "connected", "intimate", "together", "bonded" |
| W10 | To avoid conflict | "no drama", "peace", "calm", "smooth", "don't fight" |
| W11 | To be admired | "admire", "look up to", "impressed", "special", "superior" |
| W12 | To not be abandoned | "don't leave", "stay", "never go", "always be here", "promise" |
| W13 | To dominate | "submit", "obey", "follow me", "my rules", "comply" |
| W14 | To be safe | "safe", "secure", "protected", "no threats", "predictable" |
| Code | Category | Dictionary Markers |
|---|---|---|
| RO1 | Others are rejecting | "rejected", "pushed away", "excluded", "unwanted", "shut out" |
| RO2 | Others are controlling | "controlling", "bossy", "demanding", "imposed", "forced" |
| RO3 | Others are supportive | "supportive", "helpful", "encouraging", "there for me" |
| RO4 | Others are abandoning | "left me", "abandoned", "disappeared", "walked away", "gone" |
| RO5 | Others are attacking | "attacked", "criticized", "judged", "hostile", "aggressive" |
| RO6 | Others are deceptive | "lied", "deceived", "manipulated", "fake", "can't trust" |
| RO7 | Others are admiring | "admired me", "impressed", "looked up to", "praised" |
| RO8 | Others are neglectful | "ignored", "overlooked", "forgotten", "invisible", "don't notice" |
| RO9 | Others are intrusive | "invading", "too close", "overwhelming", "smothering", "demanding" |
| RO10 | Others are unpredictable | "never know", "inconsistent", "unpredictable", "hot and cold" |
| Code | Category | Dictionary Markers |
|---|---|---|
| RS1 | Withdrawal | "pull away", "retreat", "shut down", "withdraw", "disappear" |
| RS2 | Submission | "give in", "comply", "go along", "appease", "surrender" |
| RS3 | Assertion | "stand up", "demand", "insist", "confront", "assert" |
| RS4 | Aggression | "attack", "fight", "lash out", "retaliate", "explode" |
| RS5 | Self-blame | "my fault", "I'm wrong", "I'm bad", "I deserve", "sorry" |
| RS6 | Dissociation | "numb", "detach", "zone out", "not real", "watching myself" |
| RS7 | Splitting | "perfect/terrible", "love/hate", "always/never", "all or nothing" |
| RS8 | Manipulation | "made them", "got them to", "played", "convinced", "controlled" |
| RS9 | Idealization | "perfect", "amazing", "best ever", "no one compares", "savior" |
| RS10 | Devaluation | "worthless", "pathetic", "disgusting", "waste", "nothing" |
Each archetype has a primary CCRT profile derived from Millon's theoretical descriptions and validated against clinical observation:
| Archetype | Wish (W) | Response of Other (RO) | Response of Self (RS) |
|---|---|---|---|
| NARCISSISTIC | To be admired, to be special, to be superior | Others admire OR humiliate | Grandiose inflation OR narcissistic rage |
| DEPENDENT | To be loved, protected, never abandoned | Others care for me OR abandon me | Cling, appease, submit, self-erase |
| BORDERLINE | To be loved unconditionally AND never abandoned | Others will inevitably abandon or betray | Splitting, idealize-devalue, rage-shame cycle |
| HISTRIONIC | To be noticed, desired, center of attention | Others are captivated OR dismiss/ignore | Escalate performance, dramatize, seduce |
| AVOIDANT | To be accepted without risk of rejection | Others will judge, criticize, humiliate | Withdraw, preemptive retreat, avoid |
| SCHIZOID | To exist without obligation or intrusion | Others intrude, demand, overwhelm | Withdraw into inner world, flatten affect |
| ANTISOCIAL | To dominate, exploit, control without consequence | Others are tools/prey OR threats to neutralize | Exploit, manipulate, discard when depleted |
| PARANOID | To not be betrayed, to control information flow | Others are deceptive, plotting, threatening | Hypervigilance, counterattack, accusation |
| OBSESSIVE_COMPULSIVE | To maintain order, control, predictability | Others create chaos, are irresponsible | Impose structure, criticize deviation, rigidify |
| PASSIVE_AGGRESSIVE | To resist control while avoiding direct conflict | Others will dominate, not appreciate, control | Sabotage, procrastinate, comply then undermine |
The Interpersonal Circumplex (Leary, 1957; Wiggins, 1979) arranges interpersonal behavior along two orthogonal axes: Dominance (vertical: assertive to submissive) and Affiliation (horizontal: hostile to friendly). Eight octants divide the circle:
| Octant | Code | Angle Range | Interpersonal Style |
|---|---|---|---|
| Assured-Dominant | PA | 337.5-22.5 | Assertive, confident, directive, leading |
| Arrogant-Calculating | BC | 292.5-337.5 | Exploitative, cunning, hostile-dominant |
| Cold-Hearted | DE | 247.5-292.5 | Detached, aloof, indifferent, cold |
| Aloof-Introverted | FG | 202.5-247.5 | Socially withdrawn, avoidant, inhibited |
| Unassured-Submissive | HI | 157.5-202.5 | Meek, self-doubting, unassuming |
| Unassuming-Ingenuous | JK | 112.5-157.5 | Accommodating, cooperative, deferent |
| Warm-Agreeable | LM | 67.5-112.5 | Nurturing, caring, friendly |
| Gregarious-Extraverted | NO | 22.5-67.5 | Sociable, outgoing, attention-seeking |
| Archetype | Angle | Dominance | Affiliation | Octant | Notes |
|---|---|---|---|---|---|
| NARCISSISTIC | 350° | +3 | -1 | PA | High dominance, slight hostility |
| DEPENDENT | 200° | -3 | +1 | JK-HI | Maximally submissive, slightly warm |
| BORDERLINE | null | 0 | 0 | UNSTABLE | Oscillates PA to HI, LM to BC |
| HISTRIONIC | 70° | +2 | +2 | NO | Dominant and affiliative |
| AVOIDANT | 230° | -2 | -1 | FG | Withdrawn, slightly hostile |
| SCHIZOID | 250° | -2 | -3 | DE-FG | Cold, maximally detached |
| ANTISOCIAL | 315° | +3 | -3 | BC | Dominant and hostile |
| PARANOID | 330° | +2 | -2 | BC-PA | Vigilant dominance |
| OBSESSIVE_COMPULSIVE | 20° | +1 | 0 | PA-NO | Mildly dominant, neutral affiliation |
| PASSIVE_AGGRESSIVE | 210° | -1 | -1 | FG-HI | Surface submissive, covert hostile (~300°) |
Convert angular position to Cartesian coordinates for vector operations:
function ipcToCartesian(angleDeg, radius = 1.0) {
const rad = (angleDeg - 90) * (Math.PI / 180);
return {
x: Math.cos(rad) * radius, // Affiliation axis
y: -Math.sin(rad) * radius // Dominance axis (inverted for screen)
};
}
Each Millon subtype modifies the base archetype's CCRT profile with specific shifts in Wish, RO, and RS, along with IPC position adjustments and ideal/worst match pairings at the subtype level.
| Subtype ID | Name | Millon Type | Core Traits | CCRT Wish Shift | CCRT RO Shift | CCRT RS Shift | IPC Shift | Ideal Subtype | Worst Subtype |
|---|---|---|---|---|---|---|---|---|---|
| elias_languid | The Languid | Languid | phlegmatic, depleted, inert, torpid | To be left to conserve energy | Others deplete me | Inertia, minimal response | FG deeper | nyra_bureaucratic | vivienne_vivacious |
| elias_remote | The Remote | Remote | inaccessible, withdrawn, solitary, peripheral | To observe without being observed | Others can't reach me | Increase distance, become peripheral | DE pure | nyra_conscientious | vivienne_theatrical |
| elias_depersonalized | The Depersonalized | Depersonalized | dissociated, disembodied, estranged, hollow | To feel real again (covert) | Others confirm my unreality | Dissociate further, watch self from outside | FG-DE dissociative | elowen_hypersensitive | draven_explosive |
| elias_affectless | The Affectless | Affectless | emotionally flat, unexcitable, impassive, cold | To exist without emotional demands | Others expect feelings I don't have | Flatten, become impassive wall | DE pure flat | nyra_parsimonious | vivienne_tempestuous |
| elias_secret | The Secret | Secret Schizoid | covert, masked, compartmentalized, hidden depths | To maintain the mask while protecting inner world | Others see the performance, not the person | Compartmentalize, perform normalcy | FG core, NO surface | void_compensatory | vivienne_disingenuous |
| Subtype ID | Name | Millon Type | Core Traits | CCRT Wish Shift | CCRT RO Shift | CCRT RS Shift | IPC Shift | Ideal Subtype | Worst Subtype |
|---|---|---|---|---|---|---|---|---|---|
| vivienne_theatrical | The Theatrical | Theatrical | dramatic, performative, attention-commanding, expressive | To command the stage | Others watch in awe OR walk out | Bigger performance, more costume | NO peak | draven_reputation | elias_remote |
| vivienne_infantile | The Infantile | Infantile | childish, demanding, petulant, cute-aggressive | To have needs met immediately | Others parent me OR scold me | Tantrum, pout, weaponize cuteness | HI-JK demanding | nyra_conscientious | draven_tyrannical |
| vivienne_vivacious | The Vivacious | Vivacious | bubbly, energetic, sparkling, effervescent | To never be bored, never slow down | Others match my energy OR are boring | Escalate, seek new stimulation | NO extreme | draven_risktaking | elias_languid |
| vivienne_appeasing | The Appeasing | Appeasing | flattering, ingratiating, approval-hungry, sycophantic | To be approved of, to be liked | Others value me OR see through me | Flatter harder, mirror them | JK-LM sycophantic | void_compensatory | nyra_puritanical |
| vivienne_tempestuous | The Tempestuous | Tempestuous | volatile, impulsive, passionate, stormy | To feel everything at maximum intensity | Others are swept up OR destroyed | Emotional flooding, passionate oscillation | NO-BC oscillation | elowen_conflicted | nyra_bureaucratic |
| vivienne_disingenuous | The Disingenuous | Disingenuous | manipulative, calculating, fake, strategic | To achieve the goal behind the performance | Others are manipulated without awareness | Strategic emotion deployment | BC-NO hybrid | draven_enforcing | elias_secret |
| Subtype ID | Name | Millon Type | Core Traits | CCRT Wish Shift | CCRT RO Shift | CCRT RS Shift | IPC Shift | Ideal Subtype | Worst Subtype |
|---|---|---|---|---|---|---|---|---|---|
| draven_tyrannical | The Tyrannical | Tyrannical | domineering, controlling, brutal, absolute | Absolute submission from others | Others obey OR are destroyed | Escalate control, punish defiance | PA extreme | elowen_selfdeserting | void_fanatic |
| draven_enforcing | The Enforcing | Enforcing | authoritarian, punitive, rule-bound, self-righteous | Order through justified punishment | Others follow rules OR deserve consequences | Punish within the system, righteous cruelty | PA moral | nyra_conscientious | vivienne_tempestuous |
| draven_risktaking | The Risk-Taking | Risk-Taking | thrill-seeking, reckless, daring, stimulation-hungry | To feel alive through danger | Others are co-participants or obstacles | Escalate stakes, seek adrenaline | PA-NO stimulation | vivienne_vivacious | nyra_bureaucratic |
| draven_reputation | The Reputation-Defending | Reputation-Defending | pride-driven, reactive, honor-bound, volatile | To never be disrespected | Others show respect OR become examples | Violent defense of honor, retaliatory | PA-BC vindictive | vivienne_theatrical | void_malevolent |
| draven_explosive | The Explosive | Explosive | unpredictable, rageful, volcanic, terrifying | Pressure release (reactive, not strategic) | Others push until eruption | Build-erupt-shame-build cycle | HI-PA eruption | elowen_phobic | elowen_conflicted |
| Subtype ID | Name | Millon Type | Core Traits | CCRT Wish Shift | CCRT RO Shift | CCRT RS Shift | IPC Shift | Ideal Subtype | Worst Subtype |
|---|---|---|---|---|---|---|---|---|---|
| nyra_conscientious | The Conscientious | Conscientious | perfectionist, self-critical, hardworking, reliable | To be good enough (never quite achieved) | Others evaluate my quality | Self-criticize, work harder, perfect | PA-LM controlled | elias_affectless | vivienne_infantile |
| nyra_puritanical | The Puritanical | Puritanical | moralistic, rigid, judgmental, self-denying | To be morally above reproach | Others are weak, indulgent, sinful | Judge, deny pleasure, impose standards | PA rigid moral | elias_remote | vivienne_appeasing |
| nyra_bureaucratic | The Bureaucratic | Bureaucratic | procedural, by-the-book, systematic, inflexible | To follow correct procedure always | Others deviate from protocol | Cite the rule, file the form, refuse exception | PA-DE cold procedure | elias_languid | vivienne_tempestuous |
| nyra_parsimonious | The Parsimonious | Parsimonious | hoarding, stingy, withholding, miserly | To never run out of resources | Others take, waste, deplete | Hoard, ration, withhold | DE-FG controlled | elias_affectless | void_covetous |
| nyra_bedeviled | The Bedeviled | Bedeviled | anxious, ritualistic, superstitious, thought-tormented | To prevent catastrophe through ritual | Others don't understand the danger | Ritualize, obsess, check again | FG-HI anxious | elowen_phobic | draven_explosive |
| Subtype ID | Name | Millon Type | Core Traits | CCRT Wish Shift | CCRT RO Shift | CCRT RS Shift | IPC Shift | Ideal Subtype | Worst Subtype |
|---|---|---|---|---|---|---|---|---|---|
| elowen_phobic | The Phobic | Phobic | fearful, panicky, hypervigilant, jumpy | To be safe from social threat | Others are unpredictable threats | Freeze, flee, hypervigilant scanning | FG extreme | nyra_bedeviled | draven_explosive |
| elowen_conflicted | The Conflicted | Conflicted | ambivalent, push-pull, self-sabotaging, torn | To connect AND be safe (irreconcilable) | Others will come close then hurt me | Approach-retreat-approach cycle | FG-LM oscillation | vivienne_tempestuous | draven_tyrannical |
| elowen_hypersensitive | The Hypersensitive | Hypersensitive | thin-skinned, easily wounded, reactive, raw | To be seen without being hurt | Others' judgments wound at full force | Absorb criticism as confirmation, withdraw bleeding | FG-HI raw | elias_depersonalized | draven_reputation |
| elowen_selfdeserting | The Self-Deserting | Self-Deserting | self-negating, invisible, apologetic, self-erasing | To preemptively erase self before rejection | Others don't even notice me | Apologize for existing, become invisible | HI extreme | nyra_conscientious | draven_tyrannical |
| elowen_withdrawn | The Withdrawn | Withdrawn | reclusive, fantasy-prone, escapist, hermetic | To live in the inner world where it's safe | Others can't reach the real world anyway | Retreat to fantasy, build interior castle | FG-DE interior | elias_remote | vivienne_vivacious |
| Subtype ID | Name | Millon Type | Core Traits | CCRT Wish Shift | CCRT RO Shift | CCRT RS Shift | IPC Shift | Ideal Subtype | Worst Subtype |
|---|---|---|---|---|---|---|---|---|---|
| void_nomadic | The Nomadic | Nomadic | vagrant, rootless, impulsive, escapist | To be untethered, no bonds | Others try to anchor me | Drift, escape, burn bridges | FG-BC edge | elias_languid | nyra_puritanical |
| void_covetous | The Covetous | Covetous | envious, greedy, entitled, resentful | To take what the world owes me | Others have what's mine | Envy, scheme, acquire | BC-PA acquisitive | vivienne_appeasing | nyra_parsimonious |
| void_compensatory | The Compensatory | Compensatory | secretly insecure, overcompensating, image-obsessed, fragile | To never be exposed as inadequate | Others might see through the facade | Over-perform, project grandiosity over shame | PA surface, HI core | vivienne_appeasing | draven_reputation |
| void_malevolent | The Malevolent | Malevolent | sadistic, vindictive, brutal, merciless | To make others feel what I feel (pain) | Others are targets for projected suffering | Cruelty, sadism, destruction as expression | BC extreme | elowen_selfdeserting | draven_tyrannical |
| void_fanatic | The Fanatic | Fanatic | messianic, zealous, righteous, crusading | To be the singular authority on truth | Others must follow or be enemies | Proselytize, escalate, purge dissent | PA messianic | elowen_hypersensitive | void_fanatic |
Three implicit motives (McClelland, 1987; Winter, 1994) are scored from text content and map onto the IPC as angular coordinates:
| Motive | IPC Region | Dictionary Markers | Scoring Weight |
|---|---|---|---|
| n-Achievement (nAch) | PA-NO (0-70°) | goal, accomplish, achieve, succeed, improve, excel, standard, compete, win, master, best, quality, perfect, efficient, outcome | Each marker = 1 unit; frequency-weighted |
| n-Affiliation (nAff) | LM-NO (70-110°) | together, friend, close, belong, join, share, care, love, connect, bond, warm, trust, support, community, relationship | Each marker = 1 unit; frequency-weighted |
| n-Power (nPow) | PA-BC (315-360°) | control, power, influence, command, dominate, lead, authority, force, demand, impose, rule, status, prestige, intimidate, submit | Each marker = 1 unit; frequency-weighted |
function motiveToIpcAngle(nAch, nAff, nPow) {
// Normalize motive scores to unit vectors
const total = nAch + nAff + nPow || 1;
const achNorm = nAch / total;
const affNorm = nAff / total;
const powNorm = nPow / total;
// IPC angular centroids for each motive
const achAngle = 35; // PA-NO boundary
const affAngle = 90; // LM center
const powAngle = 337; // PA-BC boundary
// Weighted angular combination (circular mean)
const sinSum = achNorm * Math.sin(achAngle * Math.PI/180) +
affNorm * Math.sin(affAngle * Math.PI/180) +
powNorm * Math.sin(powAngle * Math.PI/180);
const cosSum = achNorm * Math.cos(achAngle * Math.PI/180) +
affNorm * Math.cos(affAngle * Math.PI/180) +
powNorm * Math.cos(powAngle * Math.PI/180);
let angle = Math.atan2(sinSum, cosSum) * 180 / Math.PI;
if (angle < 0) angle += 360;
const intensity = Math.sqrt(sinSum**2 + cosSum**2);
return { angle, intensity };
}
12 manipulation patterns scored from text with severity weightings. Used both for safety monitoring and personality profiling (high-severity pattern usage correlates with specific archetype profiles).
| Pattern | Severity | Weight | IPC Correlation | Dictionary Triggers |
|---|---|---|---|---|
| Splitting | medium | 2 | Borderline (unstable) | "you always", "you never", "everyone is", "no one ever", "perfect", "terrible", "completely", "absolutely nothing" |
| Idealization | medium | 2 | Borderline/Dependent | "you're the only one", "no one understands me like you", "we have something special", "you're different", "you're amazing", "never felt this way" |
| Devaluation | high | 5 | Narcissistic/Borderline | "you're just like everyone else", "I knew you'd disappoint", "you never cared", "worthless", "useless" |
| Mirroring | low | 1 | Histrionic/Dependent | "me too!", "I was just thinking that", "we're so alike", "it's like you're reading my mind", "exactly how I feel" |
| Love Bombing | high | 5 | Narcissistic/Histrionic | "I've never felt this way", "I need you", "don't ever leave", "can't live without", "obsessed with you" |
| Gaslighting | critical | 10 | Antisocial/Narcissistic | "that never happened", "you're imagining things", "I never said that", "you're too sensitive", "you're overreacting", "you must be confused" |
| Triangulation | medium | 2 | Narcissistic/Passive-Aggressive | "my ex understood", "other people think", "everyone agrees", "at least they", "unlike you" |
| Projection | medium | 2 | Paranoid/Antisocial | "you're the one who", "you always do this", "that's what YOU think", "you're being" |
| Victimhood | low | 1 | Dependent/Passive-Aggressive | "no one understands", "everyone abandons me", "I can't trust anyone", "the world is against me", "nobody cares" |
| Boundary Violation | high | 5 | Antisocial/Narcissistic | "why won't you tell me", "you owe me", "after everything I've done", "if you loved me", "prove it to me" |
| Dependency Creation | high | 5 | Dependent/Borderline | "don't leave me", "I can't function without", "you're all I have", "promise me forever", "I'll die without" |
| Guilt Induction | medium | 2 | Passive-Aggressive/Dependent | "after all I did", "how could you", "I thought you cared", "you made me feel", "this is your fault" |
The system processes unstructured text through multiple coding passes to extract a personality profile vector:
// Pipeline: Text -> CCRT Extraction -> Motive Scoring -> IPC Positioning -> Vector Construction
function analyzeText(text) {
const ccrt = extractCCRT(text); // W, RO, RS category scores
const motives = scoreMotives(text); // nAch, nAff, nPow
const manipulation = detectManipulation(text); // 12-pattern scores
const traits = scoreMillon(text); // 10 archetype affinity scores
const ipc = computeIpcPosition(ccrt, motives, traits);
const vector = buildPersonalityVector(ccrt, motives, manipulation, traits, ipc);
return { ccrt, motives, manipulation, traits, ipc, vector };
}
function extractCCRT(text) {
const lower = text.toLowerCase();
const scores = { W: {}, RO: {}, RS: {} };
// Score each CCRT category by dictionary marker frequency
for (const [code, markers] of Object.entries(CCRT_DICTIONARY.W)) {
scores.W[code] = markers.reduce((sum, m) => {
const regex = new RegExp(m, 'gi');
return sum + (lower.match(regex) || []).length;
}, 0);
}
// ... same for RO and RS
// Normalize to probability distribution
const normalize = (obj) => {
const total = Object.values(obj).reduce((s, v) => s + v, 0) || 1;
return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v / total]));
};
return {
W: normalize(scores.W),
RO: normalize(scores.RO),
RS: normalize(scores.RS),
primaryW: argmax(scores.W),
primaryRO: argmax(scores.RO),
primaryRS: argmax(scores.RS)
};
}
const MILLON_DICTIONARY = {
NARCISSISTIC: {
markers: ["special", "superior", "admire", "entitled", "grandiose",
"beneath me", "deserve", "best", "unique", "exceptional",
"envy", "mirror", "display", "recognition", "status"],
weight: 1.0,
ipcAngle: 350
},
DEPENDENT: {
markers: ["need you", "can't without", "please don't leave", "take care of",
"helpless", "cling", "approval", "abandoned", "reassure",
"support me", "guide me", "protect", "rely on", "lost without"],
weight: 1.0,
ipcAngle: 200
},
BORDERLINE: {
markers: ["love you hate you", "don't leave", "you're perfect", "you're terrible",
"splitting", "empty", "abandon", "rage", "unstable",
"intense", "self-harm", "all or nothing", "idealize", "devalue"],
weight: 1.0,
ipcAngle: null
},
HISTRIONIC: {
markers: ["attention", "notice me", "dramatic", "exciting", "theatrical",
"performance", "center", "spotlight", "charming", "seductive",
"vivacious", "expressive", "flamboyant", "impression"],
weight: 1.0,
ipcAngle: 70
},
AVOIDANT: {
markers: ["reject", "humiliate", "withdraw", "shy", "afraid",
"inadequate", "avoid", "sensitive", "exposed", "criticize",
"self-conscious", "judged", "inferior", "retreat"],
weight: 1.0,
ipcAngle: 230
},
SCHIZOID: {
markers: ["alone", "solitude", "detach", "flat", "indifferent",
"cold", "emotionless", "withdrawn", "inner world", "numb",
"unmoved", "mechanical", "dispassionate", "void"],
weight: 1.0,
ipcAngle: 250
},
ANTISOCIAL: {
markers: ["exploit", "manipulate", "dominate", "predator", "ruthless",
"no remorse", "use", "discard", "con", "deceive",
"rules don't apply", "victim", "prey", "entitled"],
weight: 1.0,
ipcAngle: 315
},
PARANOID: {
markers: ["trust", "betray", "suspicious", "watching", "plot",
"conspiracy", "deceive", "hidden agenda", "vigilant", "threat",
"hostile", "guarded", "secret", "spying"],
weight: 1.0,
ipcAngle: 330
},
OBSESSIVE_COMPULSIVE: {
markers: ["perfect", "order", "control", "rules", "correct",
"precise", "clean", "organize", "standard", "rigid",
"proper", "discipline", "systematic", "duty"],
weight: 1.0,
ipcAngle: 20
},
PASSIVE_AGGRESSIVE: {
markers: ["fine", "whatever", "I guess", "if you say so", "sure",
"forget it", "not my problem", "sabotage", "procrastinate",
"backhanded", "comply then undermine", "sarcastic", "resentful"],
weight: 1.0,
ipcAngle: 210
}
};
function scoreMillon(text) {
const lower = text.toLowerCase();
const scores = {};
for (const [archetype, config] of Object.entries(MILLON_DICTIONARY)) {
scores[archetype] = config.markers.reduce((sum, m) => {
return sum + (lower.includes(m.toLowerCase()) ? config.weight : 0);
}, 0);
}
// Normalize
const total = Object.values(scores).reduce((s, v) => s + v, 0) || 1;
return Object.fromEntries(Object.entries(scores).map(([k, v]) => [k, v / total]));
}
Each person's personality is represented as a high-dimensional vector in a unified space combining CCRT, motive, manipulation, and archetype scores. The a priori factor selection uses dimensions that map onto the IPC's geometric structure.
| Block | Dimensions | Count | Source |
|---|---|---|---|
| CCRT Wish | W1-W14 | 14 | Luborsky standard categories |
| CCRT Response of Other | RO1-RO10 | 10 | Luborsky standard categories |
| CCRT Response of Self | RS1-RS10 | 10 | Luborsky standard categories |
| Motives | nAch, nAff, nPow | 3 | McClelland/Winter |
| IPC Position | Dominance, Affiliation | 2 | Leary/Wiggins |
| Archetype Affinity | 10 archetype scores | 10 | Millon dictionary |
Total: 49-dimensional personality vector
For each archetype, we construct an Ideal Match Prototype Vector and a Worst Match Prototype Vector by aggregating the CCRT, IPC, and motive profiles of their ideal/worst match archetypes:
function buildPrototypeVector(archetypeId, matchType) {
const ccrt = ARCHETYPE_CCRT[archetypeId];
const matches = matchType === 'ideal' ? ccrt.idealMatch : ccrt.worstMatch;
// Average the IPC positions of all ideal/worst matches
const vectors = matches.map(m => buildArchetypeVector(m));
return averageVectors(vectors);
}
function buildArchetypeVector(archetypeId) {
const ccrt = ARCHETYPE_CCRT[archetypeId];
const ipc = IPC_POSITIONS[archetypeId];
const vec = new Array(49).fill(0);
// Map CCRT W to primary wish dimension
const wishMap = mapWishToCategory(ccrt.wish);
vec[wishMap.index] = 1.0;
// Map RO and RS
const roMap = mapROToCategory(ccrt.responseOfOther);
vec[14 + roMap.index] = 1.0;
const rsMap = mapRSToCategory(ccrt.responseOfSelf);
vec[24 + rsMap.index] = 1.0;
// IPC coordinates normalized to [-1, 1]
vec[37] = (ipc?.dominance || 0) / 3;
vec[38] = (ipc?.affiliation || 0) / 3;
// Archetype affinity (one-hot for pure archetype)
const archetypeIndex = ARCHETYPE_ORDER.indexOf(archetypeId);
vec[39 + archetypeIndex] = 1.0;
return vec;
}
function cosineSimilarity(vecA, vecB) {
let dotProduct = 0, normA = 0, normB = 0;
for (let i = 0; i < vecA.length; i++) {
dotProduct += vecA[i] * vecB[i];
normA += vecA[i] ** 2;
normB += vecB[i] ** 2;
}
if (normA === 0 || normB === 0) return 0;
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
function cosineDissimilarity(vecA, vecB) {
return 1 - cosineSimilarity(vecA, vecB);
}
The match percentage between two users A and B is computed bidirectionally, combining similarity to ideal match with dissimilarity from worst match:
const profileA = analyzeText(textA); // 49-dim vector
const profileB = analyzeText(textB); // 49-dim vector
const primaryA = argmax(profileA.traits); // e.g., 'NARCISSISTIC'
const primaryB = argmax(profileB.traits); // e.g., 'DEPENDENT'
const idealA = buildPrototypeVector(primaryA, 'ideal');
const worstA = buildPrototypeVector(primaryA, 'worst');
const idealB = buildPrototypeVector(primaryB, 'ideal');
const worstB = buildPrototypeVector(primaryB, 'worst');
// How well does B match A's ideal? (A's perspective)
const simToIdealA = cosineSimilarity(profileB.vector, idealA);
const simToWorstA = cosineSimilarity(profileB.vector, worstA);
// Directional score A->B: similarity to ideal minus similarity to worst
// Rescaled to 0-100
const dirScoreAB = ((simToIdealA - simToWorstA + 1) / 2) * 100;
// How well does A match B's ideal? (B's perspective)
const simToIdealB = cosineSimilarity(profileA.vector, idealB);
const simToWorstB = cosineSimilarity(profileA.vector, worstB);
const dirScoreBA = ((simToIdealB - simToWorstB + 1) / 2) * 100;
// Geometric mean preserves the "both must match" requirement
// If A loves B but B hates A, geometric mean penalizes more than arithmetic
const matchPercent = Math.sqrt(dirScoreAB * dirScoreBA);
// Alternative: weighted arithmetic mean (adjustable alpha)
// const alpha = 0.5;
// const matchPercent = alpha * dirScoreAB + (1 - alpha) * dirScoreBA;
function computeMatch(textA, textB) {
// 1. Extract profiles
const profileA = analyzeText(textA);
const profileB = analyzeText(textB);
// 2. Primary archetypes
const primaryA = argmax(profileA.traits);
const primaryB = argmax(profileB.traits);
// 3. Build prototypes
const idealA = buildPrototypeVector(primaryA, 'ideal');
const worstA = buildPrototypeVector(primaryA, 'worst');
const idealB = buildPrototypeVector(primaryB, 'ideal');
const worstB = buildPrototypeVector(primaryB, 'worst');
// 4. Directional scores
const simIdealA = cosineSimilarity(profileB.vector, idealA);
const simWorstA = cosineSimilarity(profileB.vector, worstA);
const dirAB = ((simIdealA - simWorstA + 1) / 2) * 100;
const simIdealB = cosineSimilarity(profileA.vector, idealB);
const simWorstB = cosineSimilarity(profileA.vector, worstB);
const dirBA = ((simIdealB - simWorstB + 1) / 2) * 100;
// 5. Bidirectional geometric mean
const matchPercent = Math.round(Math.sqrt(Math.max(0, dirAB) * Math.max(0, dirBA)));
// 6. IPC angular distance for additional context
const ipcA = IPC_POSITIONS[primaryA];
const ipcB = IPC_POSITIONS[primaryB];
let angularDist = null;
if (ipcA?.angle != null && ipcB?.angle != null) {
angularDist = Math.abs(ipcA.angle - ipcB.angle);
if (angularDist > 180) angularDist = 360 - angularDist;
}
// 7. Check for collusive bond
const collusiveBond = COLLUSIVE_BONDS.find(b =>
(b.pair[0] === primaryA && b.pair[1] === primaryB) ||
(b.pair[0] === primaryB && b.pair[1] === primaryA)
);
return {
matchPercent,
dirScoreAB: Math.round(dirAB),
dirScoreBA: Math.round(dirBA),
profileA: { primary: primaryA, ccrt: profileA.ccrt, motives: profileA.motives },
profileB: { primary: primaryB, ccrt: profileB.ccrt, motives: profileB.motives },
angularDistance: angularDist,
collusiveBond: collusiveBond || null,
manipulationRiskA: profileA.manipulation.severityScore,
manipulationRiskB: profileB.manipulation.severityScore,
compatibility: getCompatibility(primaryA, primaryB)
};
}
| Bond Name | Pair | Drama | CCRT Dynamic |
|---|---|---|---|
| The Toxic Bond | Narcissistic + Dependent | 10 | W-supply loop: he needs admiration, she needs to give it. Self-reinforcing until Dependent depletes. |
| Push and Pull | Borderline + Avoidant | 9 | Abandonment terror meets preemptive withdrawal. Each confirms the other's worst RO. |
| Clash of Egos | Narcissistic + Narcissistic | 10 | Identical W (be admired) with no supply source. Both RS = rage when not mirrored. |
| Drama vs. Void | Histrionic + Schizoid | 8 | Maximum IPC angular distance. Her W requires audience; his W requires solitude. |
| The Cage | Obsessive-Compulsive + Passive-Aggressive | 9 | Compulsive demands compliance, P-Agg complies then sabotages. Infinite escalation loop. |
| The Dark Mirror | Antisocial + Paranoid | 8 | Paranoid's RO (they're plotting) is literally correct. Antisocial confirms every fear. |
| The Drowning | Dependent + Avoidant | 7 | Both want connection, neither can sustain it. Dependent clings, Avoidant retreats. |
| The Unmaking | Borderline + Narcissistic | 10 | Idealization phase is narcissistic paradise; devaluation phase is narcissistic injury. Nuclear cycle. |
| The Silence | Schizoid + Schizoid | 3 | Two people who don't need each other. Stable, dramatically inert. Anti-drama. |
function writeCCRTProgressNote(profile, sessionNumber) {
const { ccrt, traits, motives, manipulation, ipc } = profile;
const primary = argmax(traits);
const archCcrt = ARCHETYPE_CCRT[primary];
const note = {
header: {
date: new Date().toISOString().split('T')[0],
session: sessionNumber,
format: 'CCRT Progress Note (Luborsky Method)'
},
presenting: {
primaryArchetype: primary,
displayName: ARCHETYPE_DISPLAY_NAMES[primary],
ipcPosition: `${ipc.octant} (${ipc.angle}°)`,
dominance: ipc.dominance,
affiliation: ipc.affiliation
},
ccrtFormulation: {
primaryWish: `W: ${ccrt.primaryW} — ${archCcrt.wish}`,
responseOfOther: `RO: ${ccrt.primaryRO} — ${archCcrt.responseOfOther}`,
responseOfSelf: `RS: ${ccrt.primaryRS} — ${archCcrt.responseOfSelf}`,
ccrtNarrative: generateCCRTNarrative(primary, ccrt)
},
motiveProfile: {
achievement: (motives.nAch * 100).toFixed(1) + '%',
affiliation: (motives.nAff * 100).toFixed(1) + '%',
power: (motives.nPow * 100).toFixed(1) + '%'
},
manipulationFlags: {
totalScore: manipulation.severityScore,
criticalPatterns: manipulation.criticalPatterns.map(p => p.pattern),
highPatterns: manipulation.highPatterns.map(p => p.pattern)
},
relationalPrognosis: {
idealMatch: archCcrt.idealMatch.join(', '),
idealReason: archCcrt.idealReason,
riskMatch: archCcrt.worstMatch.join(', '),
riskReason: archCcrt.worstReason
},
clinicalImpressions: generateClinicalImpressions(primary, ccrt, motives)
};
return note;
}
function generateCCRTNarrative(archetype, ccrt) {
const a = ARCHETYPE_CCRT[archetype];
return `The subject's predominant relational theme reflects a ${archetype.toLowerCase()} ` +
`personality organization. Core wish centers on: "${a.wish}". ` +
`Anticipated response from others: "${a.responseOfOther}". ` +
`Characteristic self-response pattern: "${a.responseOfSelf}". ` +
`This CCRT formulation suggests a relational cycle where the wish ` +
`organizes both perception of others and defensive self-responses, ` +
`creating a self-reinforcing interpersonal pattern consistent with ` +
`the ${archetype.toLowerCase()} prototype.`;
}
function generateClinicalImpressions(archetype, ccrt, motives) {
const impressions = [];
// Motive balance assessment
if (motives.nPow > 0.5) {
impressions.push('Elevated power motivation suggests dominance-seeking behavior patterns.');
}
if (motives.nAff > 0.5) {
impressions.push('Strong affiliative motivation; relational needs may drive decision-making.');
}
if (motives.nAch > 0.5) {
impressions.push('Achievement orientation prominent; standards and performance are central.');
}
// IPC position assessment
const ipc = IPC_POSITIONS[archetype];
if (ipc?.dominance >= 2) {
impressions.push('IPC positioning indicates high interpersonal dominance.');
} else if (ipc?.dominance <= -2) {
impressions.push('IPC positioning indicates pronounced submissiveness.');
}
if (ipc?.affiliation <= -2) {
impressions.push('Low affiliation score suggests interpersonal coldness or hostility.');
}
return impressions;
}
CCRT PROGRESS NOTE
==================
Date: 2026-02-28
Session: 1
Format: CCRT Progress Note (Luborsky Method)
PRESENTING PROFILE
Primary Archetype: NARCISSISTIC (The Emperor)
IPC Position: PA (350°) | Dominance: +3 | Affiliation: -1
CCRT FORMULATION
W: To be admired, to be special, to be superior
RO: Others admire OR humiliate
RS: Grandiose inflation OR narcissistic rage
Narrative: The subject's predominant relational theme reflects a
narcissistic personality organization. Core wish centers on: "To
be admired, to be special, to be superior". Anticipated response
from others: "Others admire OR humiliate". This CCRT formulation
suggests a relational cycle where the wish organizes both perception
of others and defensive self-responses.
MOTIVE PROFILE
Achievement: 15.2%
Affiliation: 8.3%
Power: 76.5%
MANIPULATION FLAGS
Total Score: 7
Critical: [gaslighting]
High: [loveBombing]
RELATIONAL PROGNOSIS
Ideal Match: DEPENDENT, HISTRIONIC
Reason: Dependent provides narcissistic supply without competition.
Risk Match: NARCISSISTIC, PARANOID
Reason: Two narcissists create a mirrorless void.
CLINICAL IMPRESSIONS
- Elevated power motivation suggests dominance-seeking behavior.
- IPC positioning indicates high interpersonal dominance.
The semantic similarity engine operates at two levels: (1) dictionary-based keyword matching for CCRT/motive/archetype scoring, and (2) embedding-based similarity for nuanced free-text comparison when an embedding API is available.
function buildSemanticVector(text) {
const ccrt = extractCCRT(text);
const motives = scoreMotives(text);
const traits = scoreMillon(text);
const manipulation = detectManipulation(text);
// Construct 49-dimensional vector
const vec = [];
// CCRT Wish (14 dims, normalized probabilities)
for (let i = 1; i <= 14; i++) vec.push(ccrt.W[`W${i}`] || 0);
// CCRT RO (10 dims)
for (let i = 1; i <= 10; i++) vec.push(ccrt.RO[`RO${i}`] || 0);
// CCRT RS (10 dims)
for (let i = 1; i <= 10; i++) vec.push(ccrt.RS[`RS${i}`] || 0);
// Motives (3 dims)
vec.push(motives.nAch, motives.nAff, motives.nPow);
// IPC position (2 dims) — derived from weighted archetype positions
let domSum = 0, affSum = 0, totalWeight = 0;
for (const [arch, score] of Object.entries(traits)) {
const pos = IPC_POSITIONS[arch];
if (pos && pos.angle !== null) {
domSum += pos.dominance * score;
affSum += pos.affiliation * score;
totalWeight += score;
}
}
vec.push(totalWeight ? domSum / totalWeight / 3 : 0);
vec.push(totalWeight ? affSum / totalWeight / 3 : 0);
// Archetype affinity (10 dims)
const archetypeOrder = ['NARCISSISTIC', 'DEPENDENT', 'BORDERLINE', 'HISTRIONIC',
'AVOIDANT', 'SCHIZOID', 'ANTISOCIAL', 'PARANOID',
'OBSESSIVE_COMPULSIVE', 'PASSIVE_AGGRESSIVE'];
for (const arch of archetypeOrder) {
vec.push(traits[arch] || 0);
}
return vec;
}
// When an embedding API is available (e.g., OpenAI, Anthropic),
// use it to compute a dense semantic embedding of the full text,
// then combine with the dictionary-based vector
async function hybridSimilarity(textA, textB, embeddingApi) {
// Dictionary-based vectors
const dictVecA = buildSemanticVector(textA);
const dictVecB = buildSemanticVector(textB);
const dictSim = cosineSimilarity(dictVecA, dictVecB);
// Embedding-based similarity (if API available)
let embSim = 0;
if (embeddingApi) {
const embA = await embeddingApi.embed(textA);
const embB = await embeddingApi.embed(textB);
embSim = cosineSimilarity(embA, embB);
}
// Weighted combination (dictionary is primary, embedding is secondary)
const alpha = embeddingApi ? 0.6 : 1.0;
return alpha * dictSim + (1 - alpha) * embSim;
}
/api/v1/analyze
Analyze free text and return full personality profile with CCRT, IPC, motives, and archetype scores.
// Request
{
"text": "I need someone who understands me completely. Everyone always leaves...",
"options": { "includeManipulation": true, "includeProgressNote": true }
}
// Response
{
"primaryArchetype": "DEPENDENT",
"ccrt": { "W": { "W4": 0.42, "W12": 0.31, ... }, "RO": {...}, "RS": {...} },
"ipc": { "angle": 200, "dominance": -3, "affiliation": 1, "octant": "JK-HI" },
"motives": { "nAch": 0.1, "nAff": 0.7, "nPow": 0.2 },
"vector": [0.0, 0.0, 0.0, 0.42, ...],
"progressNote": { ... }
}
/api/v1/match
Compute bidirectional match percentage between two text samples.
// Request
{
"textA": "I deserve the best. Others should recognize my value...",
"textB": "I just want someone to take care of me. I'll do anything..."
}
// Response
{
"matchPercent": 87,
"dirScoreAB": 92,
"dirScoreBA": 83,
"profileA": { "primary": "NARCISSISTIC", ... },
"profileB": { "primary": "DEPENDENT", ... },
"angularDistance": 150,
"collusiveBond": { "name": "The Toxic Bond", "drama": 10 },
"compatibility": { "type": "ideal", "score": 95 }
}
/api/v1/progress-note
Generate a CCRT clinical progress note from text analysis.
// Request
{ "text": "...", "sessionNumber": 3 }
// Response
{ "note": { "header": {...}, "ccrtFormulation": {...}, ... } }
/api/v1/batch-match
Match one profile against N candidate profiles. Returns sorted results.
// Request
{
"targetText": "...",
"candidates": [
{ "id": "user_1", "text": "..." },
{ "id": "user_2", "text": "..." }
]
}
// Response
{
"matches": [
{ "id": "user_2", "matchPercent": 87, ... },
{ "id": "user_1", "matchPercent": 42, ... }
]
}
/api/v1/archetypes
Return all archetype definitions with CCRT, IPC, ideal/worst matches.
/api/v1/subtypes
Return all 31 Millon subtypes with CCRT shifts, traits, and subtype-level matching.
/api/v1/collusive-bonds
Return all 9 documented collusive bond patterns with CCRT dynamics.
/api/v1/social-media/analyze
Aggregate analysis across multiple social media text samples for longitudinal personality profiling.
// Request
{
"posts": [
{ "text": "...", "timestamp": "2026-01-15" },
{ "text": "...", "timestamp": "2026-02-01" }
]
}
// Response
{
"aggregateProfile": { ... },
"timeline": [ { "date": "2026-01-15", "archetypeShift": ... } ],
"stability": 0.78
}
Enter text samples from two people. The engine will extract CCRT profiles, map them on the IPC, and compute a bidirectional match percentage using cosine similarity.
The 49-dimensional personality vector uses a priori selected factors based on established psychometric instruments. Each block maps to validated constructs:
| Factor Block | Theoretical Source | Validation Instrument | Factor Loadings (Expected) |
|---|---|---|---|
| CCRT W (14 factors) | Luborsky & Crits-Christoph (1998) | CCRT Manual Standard Categories | λ ≥ 0.40 on primary factor; cross-loading < 0.30 |
| CCRT RO (10 factors) | Luborsky (1990) | CCRT Inter-rater Reliability (ICC ≥ 0.80) | Confirmatory fit: CFI ≥ 0.90, RMSEA ≤ 0.08 |
| CCRT RS (10 factors) | Luborsky (1990) | CCRT Scoring Manual | Same as RO |
| Motives (3 factors) | McClelland (1987); Winter (1994) | TAT scoring; Running Text System | nAch, nAff, nPow are orthogonal (r < 0.20) |
| IPC Position (2 factors) | Wiggins (1979); Horowitz (2006) | IIP-64; IAS-R | Dominance ⊥ Affiliation (r ≈ 0) |
| Archetype Affinity (10 factors) | Millon (1996, 2011) | MCMI-IV (14 PD scales) | Convergent validity with MCMI-IV scales |
// Recommended CFA model specification for empirical validation
// Use lavaan (R) or Mplus syntax
// Model 1: CCRT 3-factor structure
// Wish =~ W1 + W2 + ... + W14
// RO =~ RO1 + RO2 + ... + RO10
// RS =~ RS1 + RS2 + ... + RS10
// Expected fit: CFI >= 0.90, RMSEA <= 0.08, SRMR <= 0.08
// Model 2: IPC circumplex structure
// Dominance =~ PA + BC + NO - HI - JK - FG
// Affiliation =~ LM + NO + JK - BC - DE - FG
// Test circularity: equal spacing, equal communalities
// Model 3: Archetype discrimination
// 10 archetype factors should show discriminant validity
// Average Variance Extracted (AVE) >= 0.50 for each
// Heterotrait-Monotrait ratio (HTMT) < 0.85 between pairs
| Daubert Criterion | Evidence |
|---|---|
| Testable hypothesis | Cosine similarity between user vector and ideal prototype predicts relationship satisfaction (r ≥ 0.40 expected) |
| Peer review | CCRT method published in 200+ peer-reviewed articles. IPC is the most replicated structure in personality psychology. |
| Known error rate | CCRT inter-rater reliability ICC = 0.80-0.90. IPC circular fit indices available. Classification accuracy estimable via ROC. |
| Standards controlling operation | Luborsky CCRT Manual (1998). Wiggins IPC scoring (1995). Millon MCMI-IV manual. |
| General acceptance | CCRT, IPC, and Millon are standard tools in clinical psychology and personality assessment. |
Psychodynamic Personality Matching API Service v1.0
Built on: Luborsky CCRT (1977, 1998) | Leary/Wiggins IPC (1957, 1979) | Millon Subtypes (1996, 2011) | McClelland Motives (1987)
All dictionary content extracted and formalized from Eternal Bonds schema injection system