Spoke

preference-modeler

Stated-preference methods as services — , , penny allocation, utilities.

Character

A PA professional doing benefits design / values prioritization / comp-tradeoff / employer-value-proposition work. You know ranked-item surveys lie and that MaxDiff or conjoint would give you real answers — but the specialized tools cost $40K+ per project and require a market-research consultant.

Problem

External. Your stack-rank survey produces obvious, useless results. People say what they think you want. The vendors that sell real MaxDiff / conjoint software live in market research, not HR — they don't know your data model and they don't integrate with anything.

Internal. You're stuck explaining methodology to skeptical stakeholders without being able to run the real method that would produce the defensible answer.

Philosophical. Stated-preference methods (MaxDiff, conjoint, penny allocation, paired comparison) are gold-standard in market research and choice theory. They should be table stakes for HR analytics. They aren't.

Guide

Preference-modeler asks your respondents not "rate this 1 to 5" but "which of these matters most, and which least" — the same trade-off questions market researchers use to learn what people actually value. The math underneath estimates how much weight each option carries. preference-modeler — survey response collection plus real preference modeling. MaxDiff with -balanced task generation. Conjoint with full-profile and partial-profile designs. Penny allocation. Paired comparison. MNL utility estimation via Newton-Raphson. Anonymity threshold logic baked into the aggregation contract — small segments return { status: "blocked" } rather than exposing unsafe data.

Abstract

Background. Ranking and Likert-heavy HR surveys systematically misrecover trade-offs; multinomial-logit discrete-choice methods are canonical in economics and conjoint science but seldom accessible without bespoke tooling or prohibitively expensive subscriptions.

Methodology. Survey authoring → task synthesis → ingestion → multinomial modelling. MaxDiff task sets obey balanced incomplete block designs where applicable; utilities converge through Newton–Raphson MNL optimisation with safeguards. Aggregation endpoints execute anonymity-gated suppression returning explicit blocked states beneath configured min-n thresholds.

Scope. Does not build consumer survey UI beyond API contracts; cohort handles originate from segmentation-studio; published exports may route through data-anonymizer.

Contribution. Contracts are typed across HTTP/MCP; MCP supports agent-orchestrated survey operations with audit linkage. Task issuance, ingestion, and preference reads stay decoupled from monolithic HR survey consoles.

Evidence / Provenance. Greenfield preference_modeler schema; evolution chronicled in spoke CHANGELOG.md.

Plan

  1. 01

    Define a survey

    Author sections + questions in one bundle via preference-modeler.surveys.create. Likert, multiple-choice, free-text, MaxDiff, conjoint, penny allocation, paired comparison — all first-class question types.

  2. 02

    Materialize per-respondent tasks

    Call surveys.tasks to get BIBD-balanced MaxDiff or conjoint task assignments. Deterministic — a respondent gets the same design across sessions.

  3. 03

    Ingest answers

    Bulk-submit via surveys.responses. Per-answer validation with rejection reasons; you see what passed and why anything failed.

  4. 04

    Query the preference model

    surveys.preferences returns MNL/conjoint utilities and normalized scores. Add ?bySegment=true for cross-tabs. Cohorts below the anonymity floor are omitted from the response.

Call to Action

Direct. Try the API. Define a survey free via surveys.create.

Transitional. Read the MaxDiff methodology (Phase 3). See the live anonymity gate by hitting the demo survey's preferences endpoint.

Spoke I/O (visual language v1)

Every toolbox spoke shares the same abstract choreography: typed inputs on the left, distilled verbs in the center, typed outputs on the right, and (when relevant) cross-spoke HTTP composition along the bottom rail. Source package: @people-analytics-toolbox/spoke-illustrations.

Preference modelerINPUTSMAIN ACTIONSOUTPUTSSurvey definitionsSurveySpecPackResponse ingest streamAnswerEvent[]Solve conjoint / MaxDiff tasksEstimate guarded utilitiesPreference exportsUtilityTable (+ blocked)anonymity thresholdsCOMPOSES WITHsegmentation-studiodata-anonymizer

Try it now

Copy this curl. Paste in any terminal. Public read — no auth needed.

preference-modeler.surveys.preferences

GET

Aggregated preference weights for the PAT-3 seed survey, with by-segment cross-tab. Public read; anonymity-gated cohorts omitted.

curl -sS "https://people-analytics-toolbox.vercel.app/api/spokes/preference-modeler/surveys/pat3-survey-seed/preferences?bySegment=true"

Vendor the contract

The Zod contract is the source of truth. Vendor a copy into your consumer app — you keep it; we don't break it underneath you. Re-vendor when the version bumps.

// In your consumer app:
import { z } from "zod";

// Vendor a copy of these contracts from the toolbox repo at:
//   src/spokes/preference-modeler/contracts/types.ts
// (consumers vendor; never import at runtime.)

import {
  CreateSurveyRequestSchema,
  FullSurveyPackageSchema,
  RespondentSubmissionSchema,
  GeneratedPreferenceTasksResponseSchema,
  PreferenceWeightsResponseSchema,
  CONTRACT_VERSION,
} from "./vendored/preference-modeler/types";

// Then call the toolbox over HTTP or MCP.
// See docs/EXTERNAL-CONSUMERS.md for onboarding.

Source path: src/spokes/preference-modeler/contracts/types.ts · GitHub

Failure

Executives revert to bogus stack-ranks; legal blocks your deck because anonymity was “handled in QA” instead of at the aggregation boundary—you eat the reputational burn.

Success

Publication-grade utilities with cryptographic clarity on masking. Analysts cite segment differences with numbers that quietly disappear when denominators violate policy—confidence, not improvisation.