Spoke
preference-modeler
Stated-preference methods as services — , , penny allocation, utilities.
Character
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
{ 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
- 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. - 02
Materialize per-respondent tasks
Call
surveys.tasksto get BIBD-balanced MaxDiff or conjoint task assignments. Deterministic — a respondent gets the same design across sessions. - 03
Ingest answers
Bulk-submit via
surveys.responses. Per-answer validation with rejection reasons; you see what passed and why anything failed. - 04
Query the preference model
surveys.preferencesreturns MNL/conjoint utilities and normalized scores. Add?bySegment=truefor 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.
Try it now
Copy this curl. Paste in any terminal. Public read — no auth needed.
preference-modeler.surveys.preferences
GETAggregated 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.