{"spokes":[{"slug":"people-graph","schema":"people_graph","contractVersion":"0.2.0","status":"live","contractsTypesPath":"src/spokes/people-graph/contracts/types.ts","contracts":[{"id":"people-graph.connectors","description":"List every HRIS/ATS/LMS connector the people-graph supports (live) or plans (planned).","endpoint":"/api/spokes/people-graph/connectors","method":"GET","responseSchema":"ConnectorsListResponseSchema"},{"id":"people-graph.resolve","description":"Map raw source rows for a sourceSystem into @people-core CanonicalWorkerRecord[]. Stateless.","endpoint":"/api/spokes/people-graph/resolve","method":"POST","requestSchema":"ResolveRequestSchema","responseSchema":"ResolveResponseSchema"}],"consumers":[{"name":"worker-resolution","status":"planned"},{"name":"segmentation-studio","status":"planned"}]},{"slug":"prediction","schema":"prediction","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/prediction/contracts/types.ts","contracts":[{"id":"prediction.predict","description":"Evidence-grounded people prediction (Mode 1): point estimate + uncertainty interval + confidence band + drivers with published evidence; abstains toward the base rate on thin signal. First outcome: voluntary_turnover_12m. Stateless.","endpoint":"/api/spokes/prediction/predict","method":"POST","requestSchema":"PredictRequestSchema","responseSchema":"PredictResponseSchema"}],"consumers":[{"name":"people-graph","status":"planned"},{"name":"principia","status":"planned"}]},{"slug":"reincarnation","schema":"reincarnation","contractVersion":"1.4.0","status":"live","contractsTypesPath":"src/spokes/reincarnation/contracts/types.ts","contracts":[{"id":"reincarnation.adaptive-selection","description":"Information-gain-weighted adaptive item selection from a galaxy's pools.","endpoint":"/api/spokes/reincarnation/adaptive-selection","method":"POST","requestSchema":"AdaptiveSelectionRequestSchema","responseSchema":"AdaptiveSelectionResponseSchema"},{"id":"reincarnation.responses-ingest","description":"Bulk-ingest respondent answers for psychometric scoring.","endpoint":"/api/spokes/reincarnation/responses/ingest","method":"POST","requestSchema":"ResponseIngestRequestSchema","responseSchema":"ResponseIngestResponseSchema"},{"id":"reincarnation.psychometric-feed","description":"Per-galaxy psychometric statistics feed (Cronbach alpha, IRT, virtues).","endpoint":"/api/spokes/reincarnation/psychometric-feed","method":"GET","responseSchema":"PsychometricFeedResponseSchema"},{"id":"reincarnation.galaxies.register","description":"Idempotent consumer bootstrap: register a pool galaxy, universal items (RIDs), and study items (SIDs) in one atomic transaction.","endpoint":"/api/spokes/reincarnation/galaxies","method":"POST","requestSchema":"GalaxyRegisterRequestSchema","responseSchema":"GalaxyRegisterResponseSchema"},{"id":"reincarnation.galaxies.items-append","description":"Append RIDs and/or study items to an existing galaxy (404 if galaxy_id is unknown); same idempotency semantics as galaxies.register.","endpoint":"/api/spokes/reincarnation/galaxies/[id]/items","method":"POST","requestSchema":"GalaxyAppendItemsRequestSchema","responseSchema":"GalaxyAppendItemsResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-7","status":"in-progress"},{"name":"vela","status":"planned"}]},{"slug":"diagnostic-coaching","schema":"diagnostic_coaching","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/diagnostic-coaching/contracts/types.ts","contracts":[{"id":"diagnostic-coaching.adaptive-select","description":"Next adaptive coaching cards for a respondent (effectiveness-ranked, weaker-competency-targeted), each grounded in matched corpus advisory.","endpoint":"/api/spokes/diagnostic-coaching/adaptive-select","method":"POST","requestSchema":"AdaptiveCoachingRequestSchema","responseSchema":"AdaptiveCoachingResponseSchema"},{"id":"diagnostic-coaching.responses-ingest","description":"Bulk-ingest respondent reactions to delivered cards (rubric / committed / not-applicable).","endpoint":"/api/spokes/diagnostic-coaching/responses/ingest","method":"POST","requestSchema":"CoachingResponseIngestRequestSchema","responseSchema":"CoachingResponseIngestResponseSchema"},{"id":"diagnostic-coaching.register","description":"Idempotent bootstrap of competencies + coaching cards for a tenant.","endpoint":"/api/spokes/diagnostic-coaching/register","method":"POST","requestSchema":"CoachingRegisterRequestSchema","responseSchema":"CoachingRegisterResponseSchema"},{"id":"diagnostic-coaching.batch","description":"Population pass: score cards by effectiveness, move pools, rebuild capability profiles.","endpoint":"/api/spokes/diagnostic-coaching/batch","method":"POST","requestSchema":"CoachingBatchRequestSchema","responseSchema":"CoachingBatchResponseSchema"}],"consumers":[{"name":"survey-orchestrator","status":"planned"}]},{"slug":"performance-calibration","schema":"performance_calibration","contractVersion":"1.0.0","status":"live","contractsTypesPath":"src/spokes/performance-calibration/contracts/types.ts","contracts":[{"id":"performance-calibration.health","description":"Per-spoke Postgres reachability shim on `performance_calibration` (heartbeat table probe against shared Supabase).","endpoint":"/api/spokes/performance-calibration/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"performance-calibration.pairs.ingest","description":"UPSERT `{ employeeId × cycleId }` calibration rows per tenant (`parseRating` normalization; optional ELT/L3/L4/L5 leader chain persisted for rollups).","endpoint":"/api/spokes/performance-calibration/pairs","method":"POST","requestSchema":"IngestRequestSchema","responseSchema":"IngestResponseSchema"},{"id":"performance-calibration.cycles.summary","description":"Side-by-side cycle stats: bumped up/down/unchanged + percentages (pct unchanged ≡ calibration-room accuracy among complete parses) plus per-leader aggregates at elt/l3/l4/l5 layers.","endpoint":"/api/spokes/performance-calibration/summary","method":"GET","responseSchema":"CycleQueryResponseSchema"},{"id":"performance-calibration.employees.trajectory","description":"Dedup latest row per calibration cycle then return the trailing N cycles for one employee (`lastNCycles`, default 6) with deltas + attribution to elt/l3 leaders captured at ingest time.","endpoint":"/api/spokes/performance-calibration/trajectory","method":"GET","responseSchema":"EmployeeTrajectoryResponseSchema"}],"consumers":[{"name":"performix","status":"planned"},{"name":"vela","status":"planned"}]},{"slug":"performance-validity","schema":"performance_validity","contractVersion":"1.4.0","status":"live","contractsTypesPath":"src/spokes/performance-validity/contracts/types.ts","contracts":[{"id":"performance-validity.health","description":"Postgres heartbeat on `performance_validity` proving the diagnostics spoke DDL is reachable in the shared project.","endpoint":"/api/spokes/performance-validity/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"performance-validity.analyze.rating-ops-convergence","description":"Q1: Pearson convergence between normalized ratings + operational composites with structured diagnostic-chain rankings.","endpoint":"/api/spokes/performance-validity/rating-ops-convergence","method":"POST","requestSchema":"RatingOpsConvergenceRequestSchema","responseSchema":"RatingOpsConvergenceResponseSchema"},{"id":"performance-validity.analyze.validity-scorecard","description":"Q2: Reliability facets (test–retest, optional ICC inter-rater, cross-cycle stability) plus convergent / predictive / discriminant correlations.","endpoint":"/api/spokes/performance-validity/validity-scorecard","method":"POST","requestSchema":"ValidityScorecardRequestSchema","responseSchema":"ValidityScorecardResponseSchema"},{"id":"performance-validity.analyze.criterion-validity","description":"Predictor→criterion validity in situ (HO-036 #3): observed validity coefficient + Fisher-z CI, plus operational validity after range-restriction (Thorndike II) and criterion-unreliability corrections. Predictor & criterion join on subjectId.","endpoint":"/api/spokes/performance-validity/criterion-validity","method":"POST","requestSchema":"CriterionValidityRequestSchema","responseSchema":"CriterionValidityResultSchema"},{"id":"performance-validity.analyze.predictability-decomposition","description":"Q3: Stacked additive OLS R² deltas using shared inference primitives (baseline → progressively richer covariates).","endpoint":"/api/spokes/performance-validity/predictability-decomposition","method":"POST","requestSchema":"PredictabilityDecompositionRequestSchema","responseSchema":"PredictabilityDecompositionResponseSchema"},{"id":"performance-validity.analyze.trajectory-slope","description":"Q4: Per-employee longitudinal slope/regression diagnostics with pooled-mean regression-to-mean heuristics.","endpoint":"/api/spokes/performance-validity/trajectory-analysis","method":"POST","requestSchema":"TrajectoryAnalysisRequestSchema","responseSchema":"TrajectoryAnalysisResponseSchema"},{"id":"performance-validity.analyze.calibration-value-add","description":"Q5: Five-test calibration ROI panel inferred from PAT-159 rollups fetched over HTTP — validity/reliability/convergence/noise probes.","endpoint":"/api/spokes/performance-validity/calibration-value-add","method":"POST","requestSchema":"CalibrationValueAddRequestSchema","responseSchema":"CalibrationValueAddResponseSchema"},{"id":"performance-validity.analyze.change-attribution","description":"Q6: Ranked explanatory factors comparing two calibration cycles via performance-calibration trajectories fetched over HTTP.","endpoint":"/api/spokes/performance-validity/change-attribution","method":"POST","requestSchema":"ChangeAttributionRequestSchema","responseSchema":"ChangeAttributionResponseSchema"},{"id":"performance-validity.mei.evidence.upsert","description":"Persist univariate predictive r² summaries (per MEI domain × analytic cycle × outcome) that feed manager-effectiveness empirical weight blends.","endpoint":"/api/spokes/performance-validity/mei-predictive-evidence","method":"POST","requestSchema":"MeiPredictiveEvidenceUpsertRequestSchema","responseSchema":"MeiPredictiveEvidenceUpsertResponseSchema"},{"id":"performance-validity.alignment","description":"PA Instrument — Rater alignment diagnostics: per-item convergence between observed ratings.","endpoint":"/api/spokes/performance-validity/alignment","method":"POST","requestSchema":"AlignmentRequestSchema","responseSchema":"AlignmentResultSchema"},{"id":"performance-validity.directional-alignment","description":"PA Instrument — Up/down/lateral directional alignment between a focal rater and each cohort.","endpoint":"/api/spokes/performance-validity/directional-alignment","method":"POST","requestSchema":"DirectionalAlignmentRequestSchema","responseSchema":"DirectionalAlignmentResultSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"preference-modeler","schema":"preference_modeler","contractVersion":"1.6.0","status":"live","contractsTypesPath":"src/spokes/preference-modeler/contracts/types.ts","contracts":[{"id":"preference-modeler.surveys.create","description":"Create a survey definition with sections + questions in one bundle.","endpoint":"/api/spokes/preference-modeler/surveys","method":"POST","requestSchema":"CreateSurveyRequestSchema","responseSchema":"FullSurveyPackageSchema"},{"id":"preference-modeler.surveys.get","description":"Fetch the full survey package by ID.","endpoint":"/api/spokes/preference-modeler/surveys/[id]","method":"GET","responseSchema":"FullSurveyPackageSchema"},{"id":"preference-modeler.surveys.responses","description":"Submit respondent answers; per-question rejection reasons returned alongside accepts.","endpoint":"/api/spokes/preference-modeler/surveys/[id]/responses","method":"POST","requestSchema":"RespondentSubmissionSchema","responseSchema":"SubmitResponseResponseSchema"},{"id":"preference-modeler.surveys.tasks","description":"Materialize deterministic MaxDiff / Conjoint task assignments for one survey respondent.","endpoint":"/api/spokes/preference-modeler/surveys/[id]/respondents/[respondentId]/tasks","method":"POST","responseSchema":"GeneratedPreferenceTasksResponseSchema"},{"id":"preference-modeler.surveys.preferences","description":"Aggregated preference weights, anonymity-gated by minimumResponseThreshold. Optional ?bySegment=true adds bySegment[] (per-segment weights + anonymity); cohorts below threshold omitted.","endpoint":"/api/spokes/preference-modeler/surveys/[id]/preferences","method":"GET","responseSchema":"PreferenceWeightsResponseSchema"},{"id":"preference-modeler.maxdiff.generate","description":"PA Instrument — Generate deterministic MaxDiff task sets from an item list.","endpoint":"/api/spokes/preference-modeler/maxdiff/generate","method":"POST","requestSchema":"MaxDiffGenerateRequestSchema","responseSchema":"MaxDiffTasksSchema"},{"id":"preference-modeler.maxdiff.score","description":"PA Instrument — Score MaxDiff responses into per-item and per-variable preference weights.","endpoint":"/api/spokes/preference-modeler/maxdiff/score","method":"POST","requestSchema":"MaxDiffScoreRequestSchema","responseSchema":"MaxDiffScoresSchema"},{"id":"preference-modeler.present-future","description":"PA Instrument — Present-vs-future dimension gap analysis from marker responses.","endpoint":"/api/spokes/preference-modeler/present-future","method":"POST","requestSchema":"PresentFutureRequestSchema","responseSchema":"PresentFutureResultSchema"}],"consumers":[{"name":"performix","cardId":"PFX-4","status":"in-progress"}]},{"slug":"program-evaluation","schema":"program_evaluation","contractVersion":"0.2.0","status":"live","contractsTypesPath":"src/spokes/program-evaluation/contracts/types.ts","contracts":[{"id":"program-evaluation.health","description":"Per-spoke heartbeat shim for Postgres reachability on `program_evaluation`.","endpoint":"/api/spokes/program-evaluation/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"program-evaluation.experiments.create","description":"Service-key gated experiment metadata + treatment arms (normalized randomization weights) under PAT-N7 tenant context.","endpoint":"/api/spokes/program-evaluation/experiments","method":"POST","requestSchema":"ExperimentCreateRequestSchema","responseSchema":"ExperimentCreateResponseSchema"},{"id":"program-evaluation.experiments.get","description":"Public read of experiment detail (arms + optional pre-registration). Returns 409 when stored pre-registration digest fails verification.","endpoint":"/api/spokes/program-evaluation/experiments/[id]","method":"GET","responseSchema":"ExperimentDetailResponseSchema"},{"id":"program-evaluation.experiments.pre-register","description":"Immutable pre-registration bundle with SHA-256 digest (409 if an operator attempts to rewrite an existing row).","endpoint":"/api/spokes/program-evaluation/experiments/[id]/pre-register","method":"POST","requestSchema":"PreRegistrationWriteRequestSchema","responseSchema":"PreRegistrationWriteResponseSchema"},{"id":"program-evaluation.assignments.resolve","description":"Deterministic HMAC-weighted arm selection for `(experimentId, subjectId)` with lazy assignment persistence.","endpoint":"/api/spokes/program-evaluation/assignments/resolve","method":"POST","requestSchema":"AssignmentResolveRequestSchema","responseSchema":"AssignmentResolveResponseSchema"},{"id":"program-evaluation.lift.estimate","description":"Difference-in-means vs baseline with bootstrap CI; requires successful pre-registration digest verification first.","endpoint":"/api/spokes/program-evaluation/experiments/[id]/lift","method":"POST","requestSchema":"LiftComputeRequestSchema","responseSchema":"LiftComputeResponseSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"talent-value","schema":"talent_value","contractVersion":"0.5.0","status":"live","contractsTypesPath":"src/spokes/talent-value/contracts/types.ts","contracts":[{"id":"talent-value.health","description":"Per-spoke heartbeat shim for Postgres reachability on `talent_value`.","endpoint":"/api/spokes/talent-value/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"talent-value.elv.compute","description":"ELV (Employee Lifetime Value) per segment from HCROI × avg annual cost × tenure-at-exit, inputs exposed as a drill-down + optional seeded-MC uncertainty. Relative/prioritization, not GAAP. Falls back to seeded examples when the tenant has no stored inputs.","endpoint":"/api/spokes/talent-value/elv","method":"GET","responseSchema":"ElvReadResponseSchema"},{"id":"talent-value.inputs.upsert","description":"Service-key gated upsert of a tenant's per-segment ELV inputs (HCROI, avg annual cost, tenure-at-exit + provenance) keyed by segmentation-studio segment id.","endpoint":"/api/spokes/talent-value/inputs","method":"POST","requestSchema":"ElvInputsUpsertRequestSchema","responseSchema":"ElvInputsUpsertResponseSchema"},{"id":"talent-value.nav.compute","description":"NA% (share activated), NAV (NA% × ELV), and Opportunity (ELV − NAV) per segment, sorted by Opportunity descending with portfolio totals. NA% denominator headcount (canonical) or survey-response (labeled). The capital-allocation prioritization signal.","endpoint":"/api/spokes/talent-value/nav","method":"GET","responseSchema":"NavReadResponseSchema"},{"id":"talent-value.activation.upsert","description":"Service-key gated upsert of a tenant's per-segment activation readings (activated/eligible headcount or precomputed NA% + basis + provenance) — the NA% basis for NAV.","endpoint":"/api/spokes/talent-value/activation","method":"POST","requestSchema":"ActivationUpsertRequestSchema","responseSchema":"ActivationUpsertResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-75","status":"planned"},{"name":"performix","cardId":"PFX-74","status":"planned"}]},{"slug":"assessment-library","schema":"assessment_library","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/assessment-library/contracts/types.ts","contracts":[{"id":"assessment-library.health","description":"Per-spoke heartbeat shim for Postgres reachability on `assessment_library`.","endpoint":"/api/spokes/assessment-library/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"assessment-library.kits.list","description":"List a tenant's stored rubric kits per Family×Focus×Level (title, version, status, question/criterion counts, defensibility). Falls back to seeded examples.","endpoint":"/api/spokes/assessment-library/kits","method":"GET","responseSchema":"KitListResponseSchema"},{"id":"assessment-library.kits.read","description":"Read a job's full assessment kit by profileKey — interview question bank, BARS (behaviorally-anchored scales), level-calibrated performance criteria, and the validity/job-relatedness/adverse-impact evidence trail. Falls back to seeded examples.","endpoint":"/api/spokes/assessment-library/kits/[profileKey]","method":"GET","responseSchema":"KitReadResponseSchema"},{"id":"assessment-library.kits.generate","description":"Service-key gated generation (+optional persist) of a paired rubric kit for a Family×Focus×Level — assembled FROM the canon (job-family-agent /construct) and optionally composing reincarnation validated items. Every item provenance-stamped to its canon component.","endpoint":"/api/spokes/assessment-library/kits","method":"POST","requestSchema":"GenerateKitRequestSchema","responseSchema":"GenerateKitResponseSchema"},{"id":"assessment-library.adverse-impact.compute","description":"Service-key gated stateless EEOC four-fifths (4/5ths) adverse-impact computation over per-group applicant/selected counts (defensibility evidence).","endpoint":"/api/spokes/assessment-library/adverse-impact","method":"POST","requestSchema":"AdverseImpactRequestSchema","responseSchema":"AdverseImpactResponseSchema"}],"consumers":[{"name":"enterprise-jobframe","cardId":"PAT-JFE-ENT-8","status":"planned"}]},{"slug":"career-development","schema":"career_development","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/career-development/contracts/types.ts","contracts":[{"id":"career-development.health","description":"Per-spoke heartbeat shim for Postgres reachability on `career_development`.","endpoint":"/api/spokes/career-development/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"career-development.career-paths","description":"Career paths FROM a role (ENT-8): the universal-level LADDER (promotions + IC↔management crossover) + the LATTICE of lateral/cross-functional moves from JobFrame coordinate content-space neighbors (real adjacency; no_match neighbors dropped). Public read.","endpoint":"/api/spokes/career-development/career-paths","method":"GET","responseSchema":"CareerPathsResponseSchema"},{"id":"career-development.development-gap","description":"Service-key gated current-role→target-role development gap (ENT-8): the priority-ranked component KSAOs to acquire/deepen, read from the canon and optionally sharpened by the assessment-library kit. May persist.","endpoint":"/api/spokes/career-development/development-gap","method":"POST","requestSchema":"DevelopmentGapRequestSchema","responseSchema":"DevelopmentGapResponseSchema"},{"id":"career-development.learning-catalog.list","description":"List a tenant's stored learning catalogs per Family×Focus×Level (title, version, status, objective/tool counts). Falls back to seed catalogs.","endpoint":"/api/spokes/career-development/learning-catalog","method":"GET","responseSchema":"CatalogListResponseSchema"},{"id":"career-development.learning-catalog.read","description":"Read a role's learning objectives + curated/hot-swappable tools by profileKey (ENT-13). Falls back to a seed-generated catalog.","endpoint":"/api/spokes/career-development/learning-catalog/[profileKey]","method":"GET","responseSchema":"CatalogReadResponseSchema"},{"id":"career-development.learning-catalog.generate","description":"Service-key gated generation (+optional persist) of a Learning Objectives & Tools catalog for a Family×Focus×Level (ENT-13). Objectives keyed to canon KSAOs + learning_objective components; tools curated from the CanonicAI capability-guide corpus; we-curate-company-controls (hot-swap + LMS-mappable).","endpoint":"/api/spokes/career-development/learning-catalog","method":"POST","requestSchema":"GenerateCatalogRequestSchema","responseSchema":"GenerateCatalogResponseSchema"},{"id":"career-development.measurements.record","description":"Service-key gated capability MEASUREMENT recording (the closed loop) — returns fresh growth roll-ups. The differentiator: tracks capability GROWTH (baseline → re-measure delta), not course completion.","endpoint":"/api/spokes/career-development/measurements","method":"POST","requestSchema":"RecordMeasurementRequestSchema","responseSchema":"RecordMeasurementResponseSchema"},{"id":"career-development.growth.read","description":"Read a subject's capability-growth roll-up by subjectId: per competency baseline→latest level, growth delta, and whether the target bar was reached. Public read (tenant-scoped).","endpoint":"/api/spokes/career-development/growth/[subjectId]","method":"GET","responseSchema":"GrowthReadResponseSchema"}],"consumers":[{"name":"enterprise-jobframe","cardId":"PAT-JFE-ENT-8","status":"planned"}]},{"slug":"leadership-quality","schema":"leadership_quality","contractVersion":"0.2.0","status":"live","contractsTypesPath":"src/spokes/leadership-quality/contracts/types.ts","contracts":[{"id":"leadership-quality.health","description":"Per-spoke heartbeat shim for Postgres reachability on `leadership_quality`.","endpoint":"/api/spokes/leadership-quality/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"leadership-quality.score.read","description":"Leadership Quality (0–100, decomposable) per stored subject — composite over performance-program / activation-CAMS / comp-stewardship component sub-indexes, each independently retrievable. Falls back to seeded examples.","endpoint":"/api/spokes/leadership-quality/score","method":"GET","responseSchema":"LeadershipReadResponseSchema"},{"id":"leadership-quality.score.compute","description":"Service-key gated stateless compute of a Leadership Quality index from a supplied component-reading set (no persistence).","endpoint":"/api/spokes/leadership-quality/score","method":"POST","requestSchema":"LeadershipScoreRequestSchema","responseSchema":"LeadershipScoreResponseSchema"},{"id":"leadership-quality.readings.upsert","description":"Service-key gated upsert of a subject's component readings (sub-index + drill-down + provenance) keyed by component.","endpoint":"/api/spokes/leadership-quality/readings","method":"POST","requestSchema":"ReadingsUpsertRequestSchema","responseSchema":"ReadingsUpsertResponseSchema"},{"id":"leadership-quality.alignment.compute","description":"PA Instrument — the Executive Alignment dispersion analytic (PAT-199, crown-jewel Brief 3): per-dimension spread + exec-vs-ELT-centroid distance (pennies moved) + level-aware tight/scattered verdicts over N executives' elicited priority allocations. Stateless; pairs with linkage-models stated allocations.","endpoint":"/api/spokes/leadership-quality/alignment","method":"POST","requestSchema":"AlignmentRequestSchema","responseSchema":"AlignmentResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-79","status":"planned"}]},{"slug":"linkage-models","schema":"linkage_models","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/linkage-models/contracts/types.ts","contracts":[{"id":"linkage-models.health","description":"Per-spoke heartbeat shim for Postgres reachability on `linkage_models`.","endpoint":"/api/spokes/linkage-models/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"linkage-models.models.list","description":"List registered linkage models (the Models layer / linkage design graph — PAT-198 crown-jewel Brief 1): name, outcome, status, variable count.","endpoint":"/api/spokes/linkage-models/models","method":"GET","responseSchema":"ModelListResponseSchema"},{"id":"linkage-models.models.upsert","description":"Service-key gated register/replace of a causal model: variables with coefficient weights + provenance (the old CoefficientSource enum) + Principia construct/prior grounding hooks.","endpoint":"/api/spokes/linkage-models/models","method":"POST","requestSchema":"ModelUpsertRequestSchema","responseSchema":"ModelUpsertResponseSchema"},{"id":"linkage-models.models.get","description":"Read one model with its full variable set.","endpoint":"/api/spokes/linkage-models/models/[id]","method":"GET","responseSchema":"ModelReadResponseSchema"},{"id":"linkage-models.models.grounding","description":"Resolve each variable's Principia prior via principia-connector (honest three-state per variable: found / none / error, + ungrounded). Never fabricated (PAT-150 rule).","endpoint":"/api/spokes/linkage-models/models/[id]/grounding","method":"GET","responseSchema":"GroundingResponseSchema"},{"id":"linkage-models.edges.query","description":"Query linkage routing edges (persona × priority-dimension → construct/model → measure/metric → analytic/spoke), optionally filtered to a node.","endpoint":"/api/spokes/linkage-models/edges","method":"GET","responseSchema":"EdgesQueryResponseSchema"},{"id":"linkage-models.edges.upsert","description":"Service-key gated upsert of routing edges, idempotent on (from, to).","endpoint":"/api/spokes/linkage-models/edges","method":"POST","requestSchema":"EdgesUpsertRequestSchema","responseSchema":"EdgesUpsertResponseSchema"},{"id":"linkage-models.allocations.list","description":"List recorded executive allocation sets for a model.","endpoint":"/api/spokes/linkage-models/allocations","method":"GET","responseSchema":"AllocationListResponseSchema"},{"id":"linkage-models.allocations.record","description":"Service-key gated record of an executive's elicited penny-allocation joined to a model's variables → persisted stated importance (normalized to 100); unmatched keys reported, never dropped.","endpoint":"/api/spokes/linkage-models/allocations","method":"POST","requestSchema":"AllocationRecordRequestSchema","responseSchema":"AllocationRecordResponseSchema"},{"id":"linkage-models.reconcile.run","description":"Service-key gated stated-vs-empirical reconciliation per executive or cross-exec ELT (the lost elt_* aggregation), blended via calculus.importance-reconcile (reused over HTTP, never rebuilt) and persisted as an importance snapshot.","endpoint":"/api/spokes/linkage-models/reconcile","method":"POST","requestSchema":"ReconcileRequestSchema","responseSchema":"ReconcileResponseSchema"},{"id":"linkage-models.importance.read","description":"Read persisted importance snapshots (stated / empirical / overall / divergence per item; eltStated on elt-scope rows), newest first — divergence is trendable.","endpoint":"/api/spokes/linkage-models/importance","method":"GET","responseSchema":"ImportanceReadResponseSchema"}],"consumers":[{"name":"peopleanalyst-site","cardId":"PA-704","status":"planned"},{"name":"peopleanalyst-site","cardId":"PA-705","status":"planned"}]},{"slug":"forecast-strength","schema":"forecast_strength","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/forecast-strength/contracts/types.ts","contracts":[{"id":"forecast-strength.health","description":"Per-spoke heartbeat shim for Postgres reachability on `forecast_strength`.","endpoint":"/api/spokes/forecast-strength/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"forecast-strength.battery.build","description":"PA Instrument — builds the forecast-elicitation battery (numeric point + 80/90% interval bounds + confidence per measure; elicitation-kit renderable, joinable answer ids). Stateless.","endpoint":"/api/spokes/forecast-strength/battery","method":"POST","requestSchema":"BatteryBuildRequestSchema","responseSchema":"BatteryBuildResponseSchema"},{"id":"forecast-strength.forecasts.list","description":"List logged leader forecasts (?leaderId= optional).","endpoint":"/api/spokes/forecast-strength/forecasts","method":"GET","responseSchema":"ForecastListResponseSchema"},{"id":"forecast-strength.forecasts.log","description":"Service-key gated log of a leader's forecasts (point + 80/90 intervals + confidence); re-forecasting a (measure, period) replaces the prior estimate.","endpoint":"/api/spokes/forecast-strength/forecasts","method":"POST","requestSchema":"ForecastLogRequestSchema","responseSchema":"ForecastLogResponseSchema"},{"id":"forecast-strength.actuals.record","description":"Service-key gated record of observed actuals — every matching forecast auto-(re)scores (PAT-200 crown-jewel Brief 2: Winkler interval score, abs error, hit flags).","endpoint":"/api/spokes/forecast-strength/actuals","method":"POST","requestSchema":"ActualsRecordRequestSchema","responseSchema":"ActualsRecordResponseSchema"},{"id":"forecast-strength.scores.read","description":"A leader's forecast scores + accuracy summary + QUARTERLY calibration trend (hit rates vs nominal coverage; negative gap = overconfident). Computed on read — never stale.","endpoint":"/api/spokes/forecast-strength/scores","method":"GET","responseSchema":"LeaderScoresResponseSchema"},{"id":"forecast-strength.rollup.read","description":"ELT roll-up: per-leader accuracy summaries + the team aggregate + team trend.","endpoint":"/api/spokes/forecast-strength/rollup","method":"GET","responseSchema":"EltRollupResponseSchema"}],"consumers":[{"name":"peopleanalyst-site","cardId":"PA-706","status":"planned"}]},{"slug":"survey-orchestrator","schema":"survey_orchestrator","contractVersion":"0.15.0","status":"live","contractsTypesPath":"src/spokes/survey-orchestrator/contracts/types.ts","contracts":[{"id":"survey-orchestrator.health","description":"Per-spoke heartbeat shim for Postgres reachability on `survey_orchestrator`.","endpoint":"/api/spokes/survey-orchestrator/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"survey-orchestrator.programs.list","description":"Public read of a tenant's survey program catalog.","endpoint":"/api/spokes/survey-orchestrator/programs","method":"GET","responseSchema":"ProgramListResponseSchema"},{"id":"survey-orchestrator.item-benchmarks","description":"PAT-151 Part B — classify item scores typical/above/below their Principia norm (via principia-connector). No fabricated norms: no-norm/unavailable are first-class.","endpoint":"/api/spokes/survey-orchestrator/item-benchmarks","method":"POST","requestSchema":"ItemBenchmarkRequest","responseSchema":"ItemBenchmarkResult[]"},{"id":"survey-orchestrator.programs.upsert","description":"Service-key gated upsert of a survey program (cadence/engine/status + optional triggers + fatigue policy).","endpoint":"/api/spokes/survey-orchestrator/programs","method":"POST","requestSchema":"ProgramUpsertRequestSchema","responseSchema":"ProgramUpsertResponseSchema"},{"id":"survey-orchestrator.waves.schedule","description":"Service-key gated wave scheduling/materialization with an audience snapshot hash.","endpoint":"/api/spokes/survey-orchestrator/waves","method":"POST","requestSchema":"WaveScheduleRequestSchema","responseSchema":"WaveScheduleResponseSchema"},{"id":"survey-orchestrator.triggers.ingest","description":"Service-key gated ATS/HRIS event ingestion → matching-trigger evaluation → wave scheduling (fatigue-respecting).","endpoint":"/api/spokes/survey-orchestrator/triggers/ingest","method":"POST","requestSchema":"TriggerIngestRequestSchema","responseSchema":"TriggerIngestResponseSchema"},{"id":"survey-orchestrator.responses.link","description":"Service-key gated wave invite/response record linked to the program's longitudinal respondent (same person across waves) + fatigue decision.","endpoint":"/api/spokes/survey-orchestrator/responses","method":"POST","requestSchema":"ResponseLinkRequestSchema","responseSchema":"ResponseLinkResponseSchema"},{"id":"survey-orchestrator.journey.read","description":"Public per-respondent longitudinal journey across a program's waves (14d→90d→quarterly→yearly), ordered, with response pointers.","endpoint":"/api/spokes/survey-orchestrator/journey","method":"GET","responseSchema":"RespondentJourneySchema"},{"id":"survey-orchestrator.programs.trend","description":"Public per-wave participation/response trend for a program — a cohort aggregate, min-N suppressed (privacy floor).","endpoint":"/api/spokes/survey-orchestrator/trend","method":"GET","responseSchema":"ProgramTrendResponseSchema"},{"id":"survey-orchestrator.attrition.records.upsert","description":"Service-key gated from-to movement records (reverse-exit 'from' + key-talent-exit 'to') — the attrition-analysis substrate (PAT-183).","endpoint":"/api/spokes/survey-orchestrator/attrition/records","method":"POST","requestSchema":"MovementRecordsUpsertRequestSchema","responseSchema":"MovementRecordsUpsertResponseSchema"},{"id":"survey-orchestrator.attrition.analyze","description":"Public from-to attrition analysis: talent-competitor map (win-from / lose-to + why), regretted + avoidable rates, movement drivers — segment-aligned, min-N suppressed (PAT-183).","endpoint":"/api/spokes/survey-orchestrator/attrition/analysis","method":"GET","responseSchema":"AttritionAnalysisSchema"},{"id":"survey-orchestrator.attraction.analyze","description":"Service-key gated stateless Attraction analysis: funnel-stage yields + offer-accept rate + 0–100 brand/consideration index per segment, min-N suppressed (PAT-185, low priority).","endpoint":"/api/spokes/survey-orchestrator/attraction/analyze","method":"POST","requestSchema":"AttractionAnalyzeRequestSchema","responseSchema":"AttractionAnalyzeResponseSchema"},{"id":"survey-orchestrator.attraction.compare","description":"Service-key gated reverse-exit↔exit SAME-ITEM comparison (the signature Attraction analytic): per-item + per-dimension in-vs-out deltas → advantage / disadvantage / parity over the canonical battery, min-N suppressed on both sides (PAT-185-FU-A). Performix debut consumer.","endpoint":"/api/spokes/survey-orchestrator/attraction/compare","method":"POST","requestSchema":"AttractionCompareRequestSchema","responseSchema":"AttractionCompareResponseSchema"},{"id":"survey-orchestrator.activation.battery","description":"Public read of the canonical CAMS / Activation item battery (12-item on-hand set: 8 validated core C/A/M/S × team/individual + 4 cited extensions; 0–10 scale; Activated≥70 / At-Risk<60). The instrument fielded through reincarnation (PAT-CAMS-INSTRUMENT).","endpoint":"/api/spokes/survey-orchestrator/activation/battery","method":"GET","responseSchema":"CamsBatteryResponseSchema"},{"id":"survey-orchestrator.activation.compute","description":"Service-key gated stateless CAMS / Activation analysis: per-segment NA% (activated÷eligible, min-N suppressed), additive 0–80 mean index, per-dimension means + the min-condition binding constraint, and a talent-value-ready activation reading (PAT-CAMS-INSTRUMENT — the CAMS instrument shared into the toolbox).","endpoint":"/api/spokes/survey-orchestrator/activation/compute","method":"POST","requestSchema":"CamsComputeRequestSchema","responseSchema":"CamsAnalysisResponseSchema"},{"id":"survey-orchestrator.pay-satisfaction.battery","description":"Public read of the canonical Pay Satisfaction battery (8-item, four-facet set — Pay Level / Raises / Benefits / Structure & Administration — paraphrased after the PSQ (Heneman & Schwab, 1985) + cited; 0–10 scale). The pay-sat pulse for the Comp Toolbox; fielded through reincarnation (PAT-JFE-PAY-3).","endpoint":"/api/spokes/survey-orchestrator/pay-satisfaction/battery","method":"GET","responseSchema":"PaySatBatteryResponseSchema"},{"id":"survey-orchestrator.pay-satisfaction.compute","description":"Service-key gated stateless Pay Satisfaction analysis: per-segment facet means + overall + the weakest facet (the binding pay-sat complaint), all min-N suppressed, plus the per-item-per-wave item-mean trend when respondents carry waveIds (PAT-JFE-PAY-3).","endpoint":"/api/spokes/survey-orchestrator/pay-satisfaction/compute","method":"POST","requestSchema":"PaySatComputeRequestSchema","responseSchema":"PaySatAnalysisResponseSchema"},{"id":"survey-orchestrator.pay-fairness-perception.battery","description":"Public read of the Pay Fairness & Equity perceptions battery (11 items across the three organizational-justice dimensions — distributive w/ internal/external/individual equity referents · procedural · interactional — Colquitt 2001 + Adams 1965, paraphrased + cited; 0–10). Measures what KIND of (un)fair, not contentment (PAT-JFE-PAY-6).","endpoint":"/api/spokes/survey-orchestrator/pay-fairness-perception/battery","method":"GET","responseSchema":"FairnessBatteryResponseSchema"},{"id":"survey-orchestrator.pay-fairness-perception.compute","description":"Service-key gated stateless Pay Fairness & Equity analysis: per-segment justice-dimension means + distributive referent breakdown (internal/external/market) + weakest dimension, min-N suppressed, item-mean trend, and the perceived-vs-actual equity read when an actual gap (calculus /oaxaca) is supplied (PAT-JFE-PAY-6).","endpoint":"/api/spokes/survey-orchestrator/pay-fairness-perception/compute","method":"POST","requestSchema":"FairnessComputeRequestSchema","responseSchema":"FairnessAnalysisResponseSchema"},{"id":"survey-orchestrator.pay-elements.bank","description":"Public read of the canonical comp pay-element bank (8 total-rewards elements: base · bonus · equity · benefits · flexibility · growth · security · recognition) fed to preference-modeler's MaxDiff/conjoint/penny machinery (M5–M7, PAT-JFE-PAY-7).","endpoint":"/api/spokes/survey-orchestrator/pay-elements/bank","method":"GET","responseSchema":"PayElementBankResponseSchema"},{"id":"survey-orchestrator.pay-elements.importance","description":"Service-key gated, method-agnostic pay-element importance aggregation: per-segment mean score + normalized importance share + rank per element (top element surfaced), min-N suppressed. Accepts MaxDiff utilities / conjoint part-worths / penny-allocation shares (estimation owned by preference-modeler); this is the comp-interpretation/segmentation layer (PAT-JFE-PAY-7).","endpoint":"/api/spokes/survey-orchestrator/pay-elements/importance","method":"POST","requestSchema":"PayElementImportanceRequestSchema","responseSchema":"PayElementImportanceResponseSchema"},{"id":"survey-orchestrator.pay-program-scorecard","description":"Service-key gated comp program-lever scorecard (the pay-survey capstone): rolls the M1–M7 fairness/equity + PSQ reads into per-lever 'is program X landing?' readings (0–100 + status + weakest segment + perceived-vs-actual flags) and player-ready InsightCards. Maps each survey signal to the comp lever it diagnoses (PAT-JFE-PAY-9).","endpoint":"/api/spokes/survey-orchestrator/pay-program-scorecard","method":"POST","requestSchema":"ProgramScorecardRequestSchema","responseSchema":"ProgramLeverScorecardSchema"},{"id":"survey-orchestrator.entrepreneurial-energy.battery","description":"Public read of the canonical Entrepreneurial Energy vital-sign battery (10-item set: 4 EO posture core — Innovativeness/Proactiveness/Autonomy/Risk-Tolerance, paraphrased after Covin-Slevin & Lumpkin-Dess EO — plus 6 cited CEAI extensions across five dimensions; 0–10 scale; Energized≥65 / At-Risk<50). The instrument fielded through reincarnation (PAT-EE-INSTRUMENT).","endpoint":"/api/spokes/survey-orchestrator/entrepreneurial-energy/battery","method":"GET","responseSchema":"EeBatteryResponseSchema"},{"id":"survey-orchestrator.entrepreneurial-energy.compute","description":"Service-key gated stateless Entrepreneurial Energy analysis: per-segment EE% (energized÷eligible, min-N suppressed), additive 0–100 mean EE index, per-dimension means + the min-condition binding constraint, and a 0–100 → protective-P reading for the org-metabolism model (PAT-EE-INSTRUMENT — the EE vital sign on the CAMS machinery).","endpoint":"/api/spokes/survey-orchestrator/entrepreneurial-energy/compute","method":"POST","requestSchema":"EeComputeRequestSchema","responseSchema":"EeAnalysisResponseSchema"},{"id":"survey-orchestrator.culture-of-innovation.battery","description":"Public read of the canonical Culture of Innovation vital-sign battery (10-item set: 5 TCI/KEYS-anchored core — Shared Vision/Participative Safety/Support for Innovation/Task Orientation/Challenge — plus 5 cited validated extensions including two reverse-coded obstacle items (Edmondson mistake-punishment, KEYS workload-pressure); 0–10 scale; Thriving≥70 / Stalling<40). The innovation-CLIMATE instrument fielded through reincarnation (PAT-COI-INSTRUMENT).","endpoint":"/api/spokes/survey-orchestrator/culture-of-innovation/battery","method":"GET","responseSchema":"CultureInnovationBatteryResponseSchema"},{"id":"survey-orchestrator.culture-of-innovation.compute","description":"Service-key gated stateless Culture of Innovation (innovation-CLIMATE) analysis: per-segment 0–100 climate index (min-N suppressed), per-dimension means across V/S/R/T/O (reverse-coded obstacle items flipped to high-is-healthy) + the min-condition binding constraint, and a 0–100 → protective-P reading for the org-metabolism model (PAT-COI-INSTRUMENT — the sibling of Entrepreneurial Energy; climate vs action).","endpoint":"/api/spokes/survey-orchestrator/culture-of-innovation/compute","method":"POST","requestSchema":"CultureInnovationComputeRequestSchema","responseSchema":"CultureInnovationAnalysisResponseSchema"},{"id":"survey-orchestrator.leadership-mistake-risk.battery","description":"Public read of the canonical Leadership Mistake-Risk / Derailment battery (10 items across five derailment dimensions: hubris / dissent-suppression / institutional-imperative / volatility / judgment-lapses, grounded in Hayward-Hambrick / Edmondson / Buffett / Hogan / Schyns-Schilling, paraphrased + cited; two reverse-coded good-behavior items). The ACUTE 'mistake' axis (PAT-MISTAKE-RISK-INSTRUMENT).","endpoint":"/api/spokes/survey-orchestrator/leadership-mistake-risk/battery","method":"GET","responseSchema":"MistakeRiskBatteryResponseSchema"},{"id":"survey-orchestrator.leadership-mistake-risk.compute","description":"Service-key gated stateless Leadership Mistake-Risk analysis: per-LEADER (subjectId) risk index 0–100 (HIGH = dangerous, min-N suppressed) from direct-report feedback, per-dimension means + the dominant risk facet (HIGHEST dimension), and the → `M_mistake` ACUTE HAZARD MULTIPLIER (≥1) for the org-metabolism model (PAT-MISTAKE-RISK-INSTRUMENT — the inverse of the protective vital signs).","endpoint":"/api/spokes/survey-orchestrator/leadership-mistake-risk/compute","method":"POST","requestSchema":"MistakeRiskComputeRequestSchema","responseSchema":"MistakeRiskAnalysisResponseSchema"},{"id":"survey-orchestrator.activation-diversity.compute","description":"Service-key gated stateless Activation-Diversity (P8) analysis — the DERIVED protective vital sign. From activation-by-segment readings (the CAMS per-segment output shape) returns ONE org-level diversity index 0–100 = √(coverage × evenness): coverage = eligible-weighted share of the workforce in activated segments; evenness = normalized entropy of activation mass across segments. The diversity-of-activation component of the org-metabolism protective term `P` (West's `diversity_innovation → mortality (−)`; broad/decentralized activation is anti-fragile, concentrated activation is a fragile monoculture). Compute-only — derived, no survey battery (PAT-ACTIVATION-DIVERSITY-INSTRUMENT).","endpoint":"/api/spokes/survey-orchestrator/activation-diversity/compute","method":"POST","requestSchema":"ActivationDiversityComputeRequestSchema","responseSchema":"ActivationDiversityResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-76","status":"planned"},{"name":"performix","cardId":"PFX-77","status":"planned"},{"name":"performix","cardId":"PFX-78","status":"planned"}]},{"slug":"network-analysis","schema":"network_analysis","contractVersion":"0.3.0","status":"live","contractsTypesPath":"src/spokes/network-analysis/contracts/types.ts","contracts":[{"id":"network-analysis.health","description":"Per-spoke Postgres reachability shim on `network_analysis` (heartbeat table probe against shared Supabase).","endpoint":"/api/spokes/network-analysis/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"network-analysis.connectivity.compute","description":"Service-key gated stateless Connectivity vital-sign analysis (PAT-ONA-CONNECTIVITY). From an org collaboration edge list (treated undirected) returns ONE org-level connectivity index 0–100 = 0.5·reach + 0.25·cohesion + 0.25·robustness (reach = share of the org in the largest connected component; cohesion = average local clustering; robustness = 1 − articulation-points÷nodes), the binding sub-dimension, component + single-point-of-failure counts, and a 0–100 → protective-`P` reading for the org-metabolism model. West's `Scale` connectivity made measurable. Aggregate-only (no per-node / subgraph emitted — nothing to re-identify).","endpoint":"/api/spokes/network-analysis/connectivity","method":"POST","requestSchema":"ConnectivityComputeRequestSchema","responseSchema":"ConnectivityResponseSchema"},{"id":"network-analysis.measures.compute","description":"Service-key gated stateless ONA summary-measures analysis (PAT-ONA-MEASURES). Boils a collaboration network (treated undirected) down to the headline interpretable measures — reach, density, average distance, cohesion, broker-dependency (betweenness Gini → key-person risk), community structure (modularity), and per-attribute siloing (E-I index) + informal-vs-formal alignment — each benchmark-bearing + display-ready (viz.bullet-bar / viz.forest-plot). Product steer: leaders can't read node-link 'hairball' graphs, so this returns scalars + benchmarks + one-line interpretations, not a graph. Aggregate-only (no per-node export — nothing to re-identify). Inject peer/prior benchmarks via `benchmarks`; never fabricated.","endpoint":"/api/spokes/network-analysis/measures","method":"POST","requestSchema":"NetworkMeasuresRequestSchema","responseSchema":"NetworkMeasuresResponseSchema"},{"id":"network-analysis.networks.upsert","description":"UPSERT a network header + its edge list, tenant-scoped + idempotent (re-ingest replaces the edge set). Read it back with its connectivity at GET /networks/{networkId}.","endpoint":"/api/spokes/network-analysis/networks","method":"POST","requestSchema":"NetworkUpsertRequestSchema","responseSchema":"NetworkUpsertResponseSchema"},{"id":"network-analysis.networks.read","description":"Read a stored network (header + edges) plus its computed Connectivity read. Tenant via `?tenantId=`. 404 when absent.","endpoint":"/api/spokes/network-analysis/networks/[networkId]","method":"GET","responseSchema":"NetworkReadResponseSchema"}],"consumers":[]},{"slug":"research-methods","schema":"research_methods","contractVersion":"0.4.0","status":"live","contractsTypesPath":"src/spokes/research-methods/contracts/types.ts","contracts":[{"id":"research-methods.health","description":"Per-spoke Postgres reachability shim on `research_methods` (heartbeat probe; the capability is stateless compute).","endpoint":"/api/spokes/research-methods/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"research-methods.compare","description":"Service-key gated rigorous two-group comparison (PAT-RM-SPOKE). From two de-identified numeric vectors: checks assumptions (normality via skew/kurtosis + QQ; homoscedasticity via Brown-Forsythe Levene), with test:\"auto\" picks the rigorous test (Mann-Whitney on severe non-normality, Welch on unequal variance, else pooled independent-samples t), runs it, computes Cohen's d, and returns the naïve-pooled-vs-applied 'remedy moment' diff plus catalog-linked assumption remedies. The toolbox owns the math (no Principia round-trip for compute); Principia supplies the cited evidence layer.","endpoint":"/api/spokes/research-methods/compare","method":"POST","requestSchema":"TwoGroupCompareRequestSchema","responseSchema":"TwoGroupCompareResponse"},{"id":"research-methods.check-assumptions","description":"Service-key gated severity-aware assumption checks (effect-size based, not bare p): normality (skew/kurtosis + QQ points) + homoscedasticity (Brown-Forsythe Levene) across groups, each with its catalog remedies + a proceed/apply_remedy recommendation.","endpoint":"/api/spokes/research-methods/check-assumptions","method":"POST","requestSchema":"CheckAssumptionsRequestSchema","responseSchema":"CheckAssumptionsResponse"},{"id":"research-methods.catalog","description":"Public read of the research-methods catalog — the declarative rigor library (statistical tests · assumptions · remedies · sampling methods · the 16 PRN-095 study-design archetypes), each cited to canon + linked to the compute that runs it and the viz that renders it. Optional `?kind=` / `?tag=` filters. The consumer face of the rigor capability (fly the flag).","endpoint":"/api/spokes/research-methods/catalog","method":"GET","responseSchema":"CatalogResponse"},{"id":"research-methods.sample","description":"Service-key gated seeded participant sample (PRN-101). From a de-identified frame [{id,stratum?}]: simple_random | stratified (proportional, largest-remainder); reproducible (same frame+seed → same draw). Returns the sample + per-stratum counts. Empty body → seeded example.","endpoint":"/api/spokes/research-methods/sample","method":"POST","requestSchema":"SampleRequestSchema","responseSchema":"SampleResponse"},{"id":"research-methods.balance","description":"Service-key gated covariate-balance diagnostics: per-covariate standardized mean difference + variance ratio + a severity-tagged verdict (balanced / over- / under-represented) between a group and a reference. The study-designer balance screen.","endpoint":"/api/spokes/research-methods/balance","method":"POST","requestSchema":"BalanceRequestSchema","responseSchema":"BalanceResponse"},{"id":"research-methods.allocate","description":"Service-key gated allocation to comparison arms (PRN-101): randomized | block_random (balanced at every block boundary). Reproducible. Returns the assignment + per-arm audit. Empty body → seeded example.","endpoint":"/api/spokes/research-methods/allocate","method":"POST","requestSchema":"AllocateRequestSchema","responseSchema":"AllocateResponse"},{"id":"research-methods.recommend-design","description":"Service-key gated design-recommendation engine (Cluster 1 P2, the 'shit dizzle'). From a question (construct relationship) + constraints (can-randomize / comparison-group / time-budget / inference-goal / cutoff / instrument / qualitative / synthesizing), returns a ranked, cited research-DESIGN recommendation over the 16 PRN-095 archetypes — each with X–O–R notation, typical analyses (linked to the test catalog), dominant validity threat, and the canon. With withPrior + a question, attaches the Principia effect-size prior (never fabricated). Empty body → seeded example.","endpoint":"/api/spokes/research-methods/recommend-design","method":"POST","requestSchema":"RecommendDesignRequestSchema","responseSchema":"RecommendDesignResponse"}],"consumers":[]},{"slug":"career-pathing","schema":"career_pathing","contractVersion":"0.1.0","status":"coming-soon","contractsTypesPath":"src/spokes/career-pathing/contracts/types.ts","contracts":[{"id":"career-pathing.health","description":"Per-spoke Postgres reachability shim on `career_pathing` (heartbeat probe; the capability is stateless compute).","endpoint":"/api/spokes/career-pathing/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"career-pathing.recommend-next-roles","description":"Service-key gated cohort-similarity career-pathing over a skill ontology (routes around US20200372473A1, abandoned → public-domain). From a person's current role + skill profile and a corpus of historical role transitions (from→to + each mover's skills), builds the cohort of historical movers most similar to the person (cosine similarity over the shared skill graph), ranks the destination roles that cohort actually moved into by similarity-weighted move-share, and returns the per-destination skill gaps to close (skills the destination cohort holds that the person lacks, largest gap first). Standard public-domain cohort/similarity methods; pure + deterministic + stateless (the corpus is posted, no live source). A unique profile with no similar movers returns an honest empty/sparse result. Complements career-development (taxonomy/coordinate pathing) and job-family-agent (candidate↔role matching). Empty body → seeded example.","endpoint":"/api/spokes/career-pathing/recommend-next-roles","method":"POST","requestSchema":"RecommendNextRolesRequestSchema","responseSchema":"RecommendNextRolesResponse"}],"consumers":[]},{"slug":"causal-discovery","schema":"causal_discovery","contractVersion":"0.1.0","status":"coming-soon","contractsTypesPath":"src/spokes/causal-discovery/contracts/types.ts","contracts":[{"id":"causal-discovery.health","description":"Per-spoke Postgres reachability shim on `causal_discovery` (heartbeat probe; the capability is stateless compute).","endpoint":"/api/spokes/causal-discovery/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"causal-discovery.discover","description":"Service-key gated constraint-based causal-structure recovery over a single tabular block (US11620601B2 design-around). Applies the PUBLISHED PC algorithm (Spirtes/Glymour/Scheines) with Fisher-z conditional-independence tests: returns a KPI DEPENDENCY GRAPH (skeleton + conservative v-structure/collider orientation → a CPDAG subset) and, when an `outcome` KPI is named, a LEVERAGE RANKING of drivers by direct (partial) effect — a confounded/mediated correlation (X ⟂ Z | Y) is NOT scored as a direct driver. Deterministic, stateless, no external service. Distinct from calculus.key-driver (a bivariate correlation×priors importance screen). NOT a multi-engine value-graph platform with continuous retraining. Empty body → seeded chain example.","endpoint":"/api/spokes/causal-discovery/discover","method":"POST","requestSchema":"DiscoverRequestSchema","responseSchema":"DiscoverResult"}],"consumers":[]},{"slug":"comp-normalizer","schema":"comp_normalizer","contractVersion":"0.1.0","status":"coming-soon","contractsTypesPath":"src/spokes/comp-normalizer/contracts/types.ts","contracts":[{"id":"comp-normalizer.health","description":"Per-spoke Postgres reachability shim on `comp_normalizer` (heartbeat probe; the capability is stateless compute).","endpoint":"/api/spokes/comp-normalizer/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"comp-normalizer.normalize","description":"Service-key gated schema-first canonical comp-data normalization over HETEROGENEOUS comp records (US11829954B2 design-around). Maps every pay component to a canonical comp schema (base/variable/commission/allowance), converts to one display currency, annualizes, and FTE-normalizes — returning canonical records + per-class totals. A DATA-QUALITY report (missing currency, period mismatch, unmapped class, unknown FX rate) falls out as a BYPRODUCT of schema conformance; it never compares against an expected payroll amount. Deterministic, stateless, no external service. NOT an error-detection-first pipeline. Empty body → seeded multi-source example.","endpoint":"/api/spokes/comp-normalizer/normalize","method":"POST","requestSchema":"NormalizeRequestSchema","responseSchema":"NormalizeResult"}],"consumers":[]},{"slug":"pay-structure-retention","schema":"pay_structure_retention","contractVersion":"0.1.0","status":"coming-soon","contractsTypesPath":"src/spokes/pay-structure-retention/contracts/types.ts","contracts":[{"id":"pay-structure-retention.health","description":"Per-spoke Postgres reachability shim on `pay_structure_retention` (heartbeat probe; the capability is stateless compute).","endpoint":"/api/spokes/pay-structure-retention/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"pay-structure-retention.recommend","description":"Service-key gated pay-STRUCTURE-for-RETENTION recommender (US11636435B2 design-around). Given a workforce COHORT (attributes + current compa-ratio + headcount), its CURRENT pay structure (band midpoint, range spread, base↔variable mix), and a RETENTION SIGNAL (current annual attrition), recommends STRUCTURE ADJUSTMENTS (midpoint lift, spread, variable-share trim) that optimize retention + the PREDICTED RETENTION EFFECT (projected attrition, attrition reduction, retained headcount). A transparent, a-priori, overridable dose-response; deterministic, stateless, no external service. INVERTS the patent's benefits/plan-SELECTION prediction — the target is structure-design→retention, NOT which plan an employee selects. Empty body → seeded below-band cohort example.","endpoint":"/api/spokes/pay-structure-retention/recommend","method":"POST","requestSchema":"RecommendRequestSchema","responseSchema":"RecommendResult"}],"consumers":[]},{"slug":"job-similarity","schema":"job_similarity","contractVersion":"0.1.0","status":"coming-soon","contractsTypesPath":"src/spokes/job-similarity/contracts/types.ts","contracts":[{"id":"job-similarity.health","description":"Per-spoke Postgres reachability shim on `job_similarity` (heartbeat probe; the capability is stateless compute).","endpoint":"/api/spokes/job-similarity/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"job-similarity.score","description":"Service-key gated dense semantic JOB-to-JOB similarity (US12524739B2 design-around). Scores how similar two job descriptions are — each role/responsibility/skill TEXT or precomputed dense embeddings — by COSINE in a shared vector space with standard facet-weighted hierarchical aggregation. Embedding-provider agnostic (precomputed, or a pluggable embedder port with a deterministic in-repo mock; no API key). The representation is a DENSE embedding vector, NOT the patent's custom triplet-extraction schema. Empty body → seeded similar-engineering-roles example.","endpoint":"/api/spokes/job-similarity/score","method":"POST","requestSchema":"ScorePairRequestSchema","responseSchema":"PairScore"},{"id":"job-similarity.rank","description":"Service-key gated dense semantic job-to-job RANK: rank a candidate job set against a QUERY job by cosine over role/responsibility/skill embeddings (facet-weighted), sorted descending, truncated to topK. Same dense-embedding representation as job-similarity.score — NOT a triplet schema.","endpoint":"/api/spokes/job-similarity/rank","method":"POST","requestSchema":"RankRequestSchema","responseSchema":"RankResult"}],"consumers":[]},{"slug":"data-anonymizer","schema":"data_anonymizer","contractVersion":"1.2.0","status":"live","contractsTypesPath":"src/spokes/data-anonymizer/contracts/types.ts","contracts":[{"id":"data-anonymizer.pii-rules","description":"List active PII detection rules (header + content patterns).","endpoint":"/api/spokes/data-anonymizer/pii-rules","method":"GET","responseSchema":"PiiRulesResponseSchema"},{"id":"data-anonymizer.redact","description":"Redact PII spans from text; returns redacted text + flagged spans with category/risk.","endpoint":"/api/spokes/data-anonymizer/redact","method":"POST","requestSchema":"RedactionRequestSchema","responseSchema":"RedactionResponseSchema"},{"id":"data-anonymizer.tokenize","description":"Deterministic HMAC-keyed tokenization with per-tenant cache.","endpoint":"/api/spokes/data-anonymizer/tokenize","method":"POST","requestSchema":"TokenizationRequestSchema","responseSchema":"TokenizationResponseSchema"},{"id":"data-anonymizer.min-n-check","description":"Cohort-size privacy gate.","endpoint":"/api/spokes/data-anonymizer/min-n-check","method":"POST","requestSchema":"MinNCheckRequestSchema","responseSchema":"MinNCheckResponseSchema"},{"id":"data-anonymizer.transform","description":"Apply a deterministic anonymization strategy to a scalar value (faker + keyed hashing; tenant-scoped).","endpoint":"/api/spokes/data-anonymizer/transform","method":"POST","requestSchema":"TransformRequestSchema","responseSchema":"TransformResponseSchema"},{"id":"data-anonymizer.strategies","description":"List supported anonymization strategies for discovery (name, category, description).","endpoint":"/api/spokes/data-anonymizer/strategies","method":"GET","responseSchema":"StrategiesResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-8","status":"in-progress"}]},{"slug":"segmentation-studio","schema":"segmentation_studio","contractVersion":"2.13.0","status":"live","contractsTypesPath":"src/spokes/segmentation-studio/contracts/types.ts","contracts":[{"id":"segmentation-studio.canonical-fields","description":"Active canonical HRIS field definitions: global catalog, or merged with tenant-specific rows (tenant wins at the same key) when ?tenantId= is set.","endpoint":"/api/spokes/segmentation-studio/canonical-fields","method":"GET","responseSchema":"CanonicalFieldsListResponseSchema"},{"id":"segmentation-studio.hris-ingest","description":"Raw HRIS rows → normalized rows + suggested field mappings against the canonical-field priority catalog.","endpoint":"/api/spokes/segmentation-studio/hris/ingest","method":"POST","requestSchema":"HrisIngestRequestSchema","responseSchema":"HrisIngestResponseSchema"},{"id":"segmentation-studio.hris.sync.workday","description":"PAT-65 — Workday SOAP (`Get_Workers`) OR PAT-92 OAuth + Reports-as-a-Service pull mapped through canonical-fields and persisted into tenant-scoped `segmentation_studio.workforce_*` plus `segmentation_studio.ingestion_jobs` audit (returns `runId`, `datasetId`, counts).","endpoint":"/api/spokes/segmentation-studio/hris/sync/workday","method":"POST","requestSchema":"`WorkdaySoapConfig` body for SOAP ({ wsdlUrl, username, password, isuName, tenant?, … }) OR PAT-92 `WorkdayOAuthSyncBodySchema` sans wsdl (`configRef`). Both require Toolbox tenant context.","responseSchema":"HrisWorkdaySyncPersistedResponseSchema"},{"id":"segmentation-studio.hris.sync.bamboo","description":"PAT-65-FU-A — BambooHR REST (+ Basic auth via env-referenced api key pull) persisted into tenant-scoped workforce datasets plus `segmentation_studio.ingestion_jobs` audit (`runId`), matching the Workday PAT-65 loop. Toolbox tenant context required.","endpoint":"/api/spokes/segmentation-studio/hris/sync/bamboo","method":"POST","requestSchema":"`BambooSyncBodySchema` ({ `organizationId` optional cross-check; `configRef`: inline BambooConfig OR `{ ref: \"env\" }` using BAMBOO_* env; optional resolveIdentities).","responseSchema":"HrisBambooSyncPersistedResponseSchema"},{"id":"segmentation-studio.segments-define","description":"Register a SegmentDefinition (criteria-based) into custom_segments.","endpoint":"/api/spokes/segmentation-studio/segments/define","method":"POST","requestSchema":"DefineSegmentRequestSchema","responseSchema":"SegmentSchema"},{"id":"segmentation-studio.cohorts-resolve","description":"Multi-membership cohort resolution: criteria → memberIds + segmentNodeIds.","endpoint":"/api/spokes/segmentation-studio/cohorts/resolve","method":"POST","requestSchema":"ResolveCohortRequestSchema","responseSchema":"ResolveCohortResponseSchema"},{"id":"segmentation-studio.identity-resolve","description":"Batch union-find identity clustering on normalized email + exact/fuzzy name (Levenshtein-backed); returns clusters, deduplication rate, and conflict strings.","endpoint":"/api/spokes/segmentation-studio/identity/resolve","method":"POST","requestSchema":"ResolveIdentitiesRequestSchema","responseSchema":"ResolveIdentitiesResponseSchema"},{"id":"segmentation-studio.recipes-define","description":"Register a derived-dimension recipe (bin breakpoints, key map, or template string) against normalized HRIS fields.","endpoint":"/api/spokes/segmentation-studio/recipes/define","method":"POST","requestSchema":"DefineRecipeRequestSchema","responseSchema":"RecipeSchema"},{"id":"segmentation-studio.recipes-run","description":"Execute a stored recipe on normalized rows; persists recipe_runs audit row and returns synthetic dimension nodes + memberships.","endpoint":"/api/spokes/segmentation-studio/recipes/run","method":"POST","requestSchema":"RunRecipeRequestSchema","responseSchema":"RunRecipeResponseSchema"},{"id":"segmentation-studio.packs-publish","description":"Snapshot current dimensions, nodes, and memberships into a versioned segmentation_packs row; returns the full pack envelope.","endpoint":"/api/spokes/segmentation-studio/packs/publish","method":"POST","requestSchema":"PublishPackRequestSchema","responseSchema":"PublishPackResponseSchema"},{"id":"segmentation-studio.packs-latest","description":"Fetch the most recently published segmentation pack (published_at DESC).","endpoint":"/api/spokes/segmentation-studio/packs/latest","method":"GET","responseSchema":"GetPackResponseSchema"},{"id":"segmentation-studio.packs-version","description":"Fetch a historical segmentation pack by its immutable version string.","endpoint":"/api/spokes/segmentation-studio/packs/[version]","method":"GET","responseSchema":"GetPackResponseSchema"},{"id":"segmentation-studio.data-join.run","description":"Anchor-supplemental data join: merge an anchor HRIS file with N supplemental files using per-column FieldAction policy (OVERWRITE / IGNORE / FILL_HOLES). Returns joinedData, column lineage, overlap conflict report, and unjoined records (PAT-20-FU-A; sequel to identity-resolve).","endpoint":"/api/spokes/segmentation-studio/data-join/run","method":"POST","requestSchema":"DataJoinRequestSchema","responseSchema":"DataJoinResponseSchema"},{"id":"segmentation-studio.hris-ingest.onemodel","description":"Ingest a OneModel admin-export ZIP (base64-encoded). Parses the four required catalogs (metrics / dimensions / tables / entity_relationships), runs canonical-field detection on dimension labels, and persists a semantic_profiles row (PAT-20-FU-B; donor conductor `/api/import/onemodel-zip`).","endpoint":"/api/spokes/segmentation-studio/hris/ingest/onemodel","method":"POST","requestSchema":"OneModelImportRequestSchema","responseSchema":"OneModelImportResponseSchema"},{"id":"segmentation-studio.canonical-segments.list","description":"Canonical Segments Catalog (Catalog 2; PAT-41 / PAT-61): list canonical segment definitions. Optional `dimension`, `category`, and non-negative integer `depth` (roots = 0) query params.","endpoint":"/api/spokes/segmentation-studio/canonical-segments","method":"GET","responseSchema":"CanonicalSegmentListResultSchema"},{"id":"segmentation-studio.canonical-segments.lookup","description":"Canonical Segments Catalog (Catalog 2; PAT-41): fetch one canonical segment by its stable composite id (\"segment.<dimension>.<slug>\").","endpoint":"/api/spokes/segmentation-studio/canonical-segments/[id]","method":"GET","responseSchema":"CanonicalSegmentSchema"},{"id":"segmentation-studio.canonical-segments.resolve","description":"Canonical Segments Catalog (Catalog 2; PAT-41): evaluate a canonical segment's predicate (eq / in / gte / lt / between + and / or / not) against the optionally tenant-scoped employee universe and return matched member ids + counts.","endpoint":"/api/spokes/segmentation-studio/canonical-segments/[id]/resolve","method":"GET","responseSchema":"CanonicalSegmentResolveResultSchema"},{"id":"segmentation-studio.canonical-segments.ancestors","description":"PAT-61 — Ordered ancestor chain (root-first) for a canonical segment id; 404 when missing.","endpoint":"/api/spokes/segmentation-studio/canonical-segments/[id]/ancestors","method":"GET","responseSchema":"CanonicalSegmentAncestorsResultSchema"},{"id":"segmentation-studio.canonical-segments.descendants","description":"PAT-61 — Breadth-first descendant subtree with optional `maxDepth` query param (default 10, cap 50).","endpoint":"/api/spokes/segmentation-studio/canonical-segments/[id]/descendants","method":"GET","responseSchema":"CanonicalSegmentDescendantsResultSchema"},{"id":"segmentation-studio.org.reporting-chain.resolve","description":"Org reporting-chain resolver (PAT-53): walks the manager-employee graph downstream from a focal person and returns everyone reporting up to them, with optional depth cap + tenant scoping. Reads `segmentation_studio.employee_directory`; returns empty arrays when the directory is unseeded.","endpoint":"/api/spokes/segmentation-studio/org/reporting-chain/resolve","method":"GET","responseSchema":"ReportingChainResolveResultSchema"},{"id":"segmentation-studio.custom-segments.list","description":"Tenant custom segments (PAT-58): list the latest version of every distinct (tenantId, name) for a tenant. Requires `?tenantId=` query param.","endpoint":"/api/spokes/segmentation-studio/custom-segments","method":"GET","responseSchema":"TenantCustomSegmentListResultSchema"},{"id":"segmentation-studio.custom-segments.author","description":"Tenant custom segments (PAT-58): author a new logical segment (v1) or append a new version when (tenantId, name) already exists. Predicate uses the same JSON-tree language as canonical segments.","endpoint":"/api/spokes/segmentation-studio/custom-segments","method":"POST","requestSchema":"CreateTenantCustomSegmentRequestSchema","responseSchema":"TenantCustomSegmentSchema"},{"id":"segmentation-studio.custom-segments.get","description":"Tenant custom segments (PAT-58): fetch a single segment by id plus the full version history for its (tenantId, name) pair.","endpoint":"/api/spokes/segmentation-studio/custom-segments/[id]","method":"GET","responseSchema":"TenantCustomSegmentWithHistorySchema"},{"id":"segmentation-studio.custom-segments.update","description":"Tenant custom segments (PAT-58): publish a new monotonically-incremented version for the same (tenantId, name) keyed by an existing row's id; carries a new predicate + actor.","endpoint":"/api/spokes/segmentation-studio/custom-segments/[id]","method":"PATCH","requestSchema":"UpdateTenantCustomSegmentRequestSchema","responseSchema":"TenantCustomSegmentSchema"},{"id":"segmentation-studio.workforce-datasets.upload","description":"Multipart HRIS file upload; creates tenant-scoped workforce_dataset with content-hash idempotency (409 returns existingDatasetId). Requires x-toolbox-tenant-id.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/upload","method":"POST","responseSchema":"WorkforceDatasetUploadResponseSchema"},{"id":"segmentation-studio.workforce-datasets.get","description":"Workforce dataset status + summaries.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]","method":"GET","responseSchema":"WorkforceDatasetSchema"},{"id":"segmentation-studio.workforce-datasets.parse","description":"Parse uploaded CSV (skips vendor metadata rows); stages workforce_dataset_rows.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/parse","method":"POST","responseSchema":"WorkforceDatasetSchema"},{"id":"segmentation-studio.workforce-datasets.recognize","description":"Multi-signal column recognition Pass 1-4 with Bayesian-weighted aggregation.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/recognize","method":"POST","responseSchema":"RecognizeWorkforceDatasetResponseSchema"},{"id":"segmentation-studio.workforce-datasets.map","description":"Operator mapping confirmations; updates signal_accuracy_priors and lynchpin cascade.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/map","method":"POST","requestSchema":"WorkforceDatasetMapRequestSchema","responseSchema":"WorkforceDatasetMappingSchema"},{"id":"segmentation-studio.workforce-datasets.review","description":"Identity resolution, value-level segment mapping, source profile card generation.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/review","method":"POST","responseSchema":"WorkforceDatasetReviewResponseSchema"},{"id":"segmentation-studio.workforce-datasets.persist","description":"Mark dataset persisted (idempotent).","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/persist","method":"POST","responseSchema":"WorkforceDatasetSchema"},{"id":"segmentation-studio.workforce-datasets.rows","description":"Paged normalized rows including normalized._segments canonical segment ids.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/rows","method":"GET","responseSchema":"WorkforceDatasetRowsResponseSchema"},{"id":"segmentation-studio.workforce-datasets.profile-card","description":"Source profile card for wizard PROFILE step.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]/profile-card","method":"GET","responseSchema":"SourceProfileCardSchema"},{"id":"segmentation-studio.workforce-datasets.delete","description":"Soft-delete workforce dataset.","endpoint":"/api/spokes/segmentation-studio/workforce-datasets/[id]","method":"DELETE","responseSchema":"WorkforceDatasetSchema"},{"id":"segmentation-studio.schemas.list","description":"PAT-122: Paginated SegmentationSchemaVersion discovery with optional tenant + purpose filtering + opaque cursor paging.","endpoint":"/api/spokes/segmentation-studio/schemas","method":"GET","responseSchema":"{ items: SegmentationSchemaVersion[], nextCursor?: string }"},{"id":"segmentation-studio.schemas.create","description":"PAT-122: Persist a SegmentationSchemaVersion (hash + UUID assigned server-side; draft default unless caller passes active). Comparable groups mirrored into segmentation_comparable_groups.","endpoint":"/api/spokes/segmentation-studio/schemas","method":"POST","requestSchema":"SegmentationSchemaVersionCreateBodySchema","responseSchema":"SegmentationSchemaVersionSchema"},{"id":"segmentation-studio.schemas.getByVersionId","description":"PAT-137: Fetch SegmentationSchemaVersion by immutable `schemaVersionId` row id (paired with PAT-122 composite GET for schema authoring UX).","endpoint":"/api/spokes/segmentation-studio/schemas/version/[schemaVersionId]","method":"GET","responseSchema":"SegmentationSchemaVersionSchema"},{"id":"segmentation-studio.schemas.get","description":"PAT-122: Fetch a single SegmentationSchemaVersion by `{schemaId, version}` semantic key.","endpoint":"/api/spokes/segmentation-studio/schemas/[schemaId]/[version]","method":"GET","responseSchema":"SegmentationSchemaVersionSchema"},{"id":"segmentation-studio.schemas.branch","description":"PAT-122: Cut a descendant draft schema off a validated SchemaRef (`version` increments `-branchName.<n>` per schema_id family).","endpoint":"/api/spokes/segmentation-studio/schemas/branch","method":"POST","requestSchema":"BranchSegmentationSchemaRequestSchema","responseSchema":"SegmentationSchemaVersionSchema"},{"id":"segmentation-studio.schemas.diff","description":"PAT-122: Compute `SchemaDiff` between two stored schema refs (`computeSchemaDiff` PAT-121) — unsalted read path without service keys.","endpoint":"/api/spokes/segmentation-studio/schemas/diff","method":"POST","requestSchema":"SchemaDiffPairRequestSchema","responseSchema":"SchemaDiffSchema"},{"id":"segmentation-studio.schemas.snapshot","description":"PAT-122: Idempotently freeze a `{schemaVersionId,schemaHash}` row into segmentation_schema_snapshots (201 on first insert; 200 on repeat).","endpoint":"/api/spokes/segmentation-studio/schemas/snapshot","method":"POST","requestSchema":"SchemaSnapshotCreateRequestSchema","responseSchema":"PersistedSegmentationSnapshotResponseSchema"},{"id":"segmentation-studio.declarative-segmentation.rules.get","description":"PAT-160: Loads per-tenant declarative segmentation rules (Config_Segmentation workbook parity — ordered rules, first match wins).","endpoint":"/api/spokes/segmentation-studio/declarative-segmentation/rules","method":"GET","responseSchema":"DeclarativeSegmentationRulesGetResponseSchema"},{"id":"segmentation-studio.declarative-segmentation.rules.put","description":"PAT-160: Replace the entire declarative ruleset for a tenant (optional donor sheet rows appended). Service-key gated.","endpoint":"/api/spokes/segmentation-studio/declarative-segmentation/rules","method":"POST","requestSchema":"PutDeclarativeSegmentationRulesRequestSchema","responseSchema":"DeclarativeSegmentationRulesGetResponseSchema"},{"id":"segmentation-studio.declarative-segmentation.evaluate","description":"PAT-160: Evaluate declarative rules over a workforce record batch; uses tenant store and/or inline rules plus optional donor sheet overlays. Service-key gated.","endpoint":"/api/spokes/segmentation-studio/declarative-segmentation/evaluate","method":"POST","requestSchema":"EvaluateDeclarativeSegmentationRequestSchema","responseSchema":"EvaluateDeclarativeSegmentationResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-9","status":"in-progress"}]},{"slug":"calculus","schema":"calculus","contractVersion":"1.17.0","status":"live","contractsTypesPath":"src/spokes/calculus/contracts/types.ts","contracts":[{"id":"calculus.oaxaca","description":"Oaxaca–Blinder mean outcome gap decomposition (pooled / two-fold / three-fold) between two cohorts.","endpoint":"/api/spokes/calculus/oaxaca","method":"POST","requestSchema":"OaxacaInputSchema","responseSchema":"OaxacaResultSchema"},{"id":"calculus.diagnostics","description":"OLS regression diagnostics (leverage, Cook's D, residuals, fitted) plus optional 1-D DBSCAN on residuals.","endpoint":"/api/spokes/calculus/diagnostics","method":"POST","requestSchema":"DiagnosticsRequestSchema","responseSchema":"DiagnosticsResultSchema"},{"id":"calculus.stats-enrich","description":"Enrich a metric envelope with confidence intervals, z-score, percentile, and change-rate.","endpoint":"/api/spokes/calculus/stats/enrich","method":"POST","requestSchema":"StatsEnrichRequestSchema","responseSchema":"StatsEnrichResponseSchema"},{"id":"calculus.stats-trend","description":"Classify a periods array as rising / stable / falling with OLS slope and change rate.","endpoint":"/api/spokes/calculus/stats/trend","method":"POST","requestSchema":"StatsTrendRequestSchema","responseSchema":"StatsTrendResponseSchema"},{"id":"calculus.stats-impute","description":"Expand an irregular period grid (monthly/quarterly cadence) with forward-fill, linear interpolation, or gap flagging.","endpoint":"/api/spokes/calculus/stats/impute","method":"POST","requestSchema":"ImputePeriodsRequestSchema","responseSchema":"ImputePeriodsResponseSchema"},{"id":"calculus.stats-anomaly","description":"Flag time-series points via z-score threshold, IQR fences, and step-change outliers on first differences.","endpoint":"/api/spokes/calculus/stats/anomaly","method":"POST","requestSchema":"AnomalyDetectRequestSchema","responseSchema":"AnomalyDetectResponseSchema"},{"id":"calculus.factory-build","description":"Combinatorial metric × segment × period grid: build envelopes from a values array, enrich each, return ranked list (impact / significance / change / recency / sample-size). Optional ?persist=true writes envelopes to metric_envelopes.","endpoint":"/api/spokes/calculus/factory/build","method":"POST","requestSchema":"FactoryBuildRequestSchema","responseSchema":"FactoryBuildResponseSchema"},{"id":"calculus.governance.check","description":"Governance-flag layer over a record set: distribution-equity, harshness-bias, recency-bias, calibration-spread (PAT-6-FU).","endpoint":"/api/spokes/calculus/governance/check","method":"POST","requestSchema":"GovernanceCheckRequestSchema","responseSchema":"GovernanceCheckResponseSchema"},{"id":"calculus.monte-carlo.run","description":"PAT-147-C: deterministic Monte Carlo batches with JSONB persistence (per-tenant idempotent run_key) plus numeric column summaries.","endpoint":"/api/spokes/calculus/monte-carlo/run","method":"POST","requestSchema":"MonteCarloRunInputSchema","responseSchema":"MonteCarloRunResultSchema"},{"id":"calculus.regression-surrogate.fit","description":"PAT-147-C: fits an OLS surrogate (ridge ε=1e-6 fallback when singular) from inline trials or a stored MC run id and inserts `surrogate_models`.","endpoint":"/api/spokes/calculus/regression-surrogate/fit","method":"POST","requestSchema":"SurrogateFitRequestSchema","responseSchema":"SurrogateModelSchema"},{"id":"calculus.regression-surrogate.forward","description":"PAT-147-C surrogate forward prediction with t-based 95% mean-response interval.","endpoint":"/api/spokes/calculus/regression-surrogate/forward","method":"POST","requestSchema":"SurrogateForwardInputSchema","responseSchema":"SurrogateForwardOutputSchema"},{"id":"calculus.regression-surrogate.inverse","description":"PAT-147-C surrogate inverse payout solver (interaction-aware) with linearized CI propagation from mean-response SE.","endpoint":"/api/spokes/calculus/regression-surrogate/inverse","method":"POST","requestSchema":"SurrogateInverseInputSchema","responseSchema":"SurrogateInverseOutputSchema"},{"id":"calculus.regression-surrogate.get","description":"Reads a persisted surrogate snapshot (requires tenantId query parameter for scoping).","endpoint":"/api/spokes/calculus/regression-surrogate/[modelId]","method":"GET","responseSchema":"SurrogateModelSchema"},{"id":"calculus.metric-keys.unknown","description":"PAT-40 diagnostic: recent envelope metricKeys that failed metrics-catalog soft-validation. In-process buffer; lost on cold start.","endpoint":"/api/spokes/calculus/metric-keys/unknown","method":"GET","responseSchema":"UnknownMetricKeysResponseSchema"},{"id":"calculus.distribution-fit","description":"PA Instrument — Fit a sample distribution and report goodness-of-fit diagnostics.","endpoint":"/api/spokes/calculus/distribution-fit","method":"POST","requestSchema":"DistributionFitRequestSchema","responseSchema":"DistributionFitResultSchema"},{"id":"calculus.importance-reconcile","description":"PA Instrument — Reconcile stated vs derived importance weights across items.","endpoint":"/api/spokes/calculus/importance-reconcile","method":"POST","requestSchema":"ImportanceReconcileRequestSchema","responseSchema":"ImportanceReconcileResultSchema"},{"id":"calculus.unit-linkage","description":"Unit-linkage analysis (Gelade/Harter service-profit-chain): per-condition unit-level Pearson r + Fisher-z CI + significance + outcome-oriented direction, with optional segment cuts. Build-once for constraint × delivery / CSAT / churn.","endpoint":"/api/spokes/calculus/unit-linkage","method":"POST","requestSchema":"UnitLinkageRequestSchema","responseSchema":"UnitLinkageResultSchema"}],"consumers":[{"name":"performix","status":"planned"},{"name":"vela","status":"planned"}]},{"slug":"factor-models","schema":"factor_models","contractVersion":"0.6.0","status":"live","contractsTypesPath":"src/spokes/factor-models/contracts/types.ts","contracts":[{"id":"factor-models.health","description":"Per-spoke heartbeat for Postgres `factor_models` reachability.","endpoint":"/api/spokes/factor-models/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"factor-models.models.create","description":"Create a tenant-scoped factor model header (latent factors + outcome) before registering weight versions.","endpoint":"/api/spokes/factor-models/models","method":"POST","requestSchema":"CreateFactorModelRequestSchema","responseSchema":"CreateFactorModelResponseSchema"},{"id":"factor-models.models.get","description":"Fetch the model row including optional currentVersionId pointer.","endpoint":"/api/spokes/factor-models/models/[id]","method":"GET","responseSchema":"FactorModelSchema"},{"id":"factor-models.versions.register","description":"Append an immutable model_version row plus relational factor_weights edges.","endpoint":"/api/spokes/factor-models/models/[id]/versions","method":"POST","requestSchema":"RegisterModelVersionRequestSchema","responseSchema":"RegisterModelVersionResponseSchema"},{"id":"factor-models.versions.validate","description":"Compute holdout correlation / MAE / R² and persist segment fairness snapshots for publish gating.","endpoint":"/api/spokes/factor-models/models/[id]/versions/[versionId]/validate","method":"POST","requestSchema":"ValidateModelVersionRequestSchema","responseSchema":"ValidateModelVersionResponseSchema"},{"id":"factor-models.publish","description":"Advance models.current_version_id only when a passing validation_report exists (409 otherwise).","endpoint":"/api/spokes/factor-models/models/[id]/publish","method":"POST","requestSchema":"PublishModelVersionRequestSchema","responseSchema":"PublishModelVersionResponseSchema"},{"id":"factor-models.scores.compute","description":"Score a subject against the published current version; lazily memoizes `(versionId × subject × factor)` rows for deterministic repeat reads.","endpoint":"/api/spokes/factor-models/scores/[modelId]/[subjectId]","method":"POST","requestSchema":"ScoreSubjectRequestSchema","responseSchema":"ScoreSubjectResponseSchema"},{"id":"factor-models.analytics-plan","description":"PA Instrument — Analytics-Plan Generator: rank candidate models by exec-priority relevance + emit a value-of-information-ranked measurement plan.","endpoint":"/api/spokes/factor-models/analytics-plan","method":"POST","requestSchema":"AnalyticsPlanRequestSchema","responseSchema":"AnalyticsPlanSchema"},{"id":"factor-models.empirical-importance","description":"PA Instrument — Empirical importance from observed-outcome variance (√variance × priority weight, normalized 0–100); feeds calculus.importance-reconcile.","endpoint":"/api/spokes/factor-models/empirical-importance","method":"POST","requestSchema":"EmpiricalImportanceRequestSchema","responseSchema":"EmpiricalImportanceResultSchema"},{"id":"factor-models.program-portfolio","description":"HR program-portfolio prioritization (PAT-177): rank HR programs by weighted outcome-linkage × stakeholder preference, flag low-driver / unreviewed spend as waste, recommend cull/keep/grow + reallocation of the recoverable pool. Service-key gated, stateless. DISTINCT from compensation waste (anycomp).","endpoint":"/api/spokes/factor-models/program-portfolio","method":"POST","requestSchema":"ProgramPortfolioRequestSchema","responseSchema":"ProgramPortfolioResultSchema"},{"id":"factor-models.program-portfolio.scenarios","description":"HR program-budget scenario / optimizer (PAT-177-FU-C): over the prioritized portfolio + recoverable pool, generate a few budget-neutral reallocation scenarios (hold / targeted-cull / aggressive) each with a projected portfolioAlignment lift + moved spend, plus a PAT-171 exec narrative. Service-key gated, stateless. Sibling of the AnyComp scenario layer — HR programs, not pay.","endpoint":"/api/spokes/factor-models/program-portfolio/scenarios","method":"POST","requestSchema":"ProgramScenariosRequestSchema","responseSchema":"ProgramScenariosResultSchema"}],"consumers":[{"name":"performix","status":"in-progress"},{"name":"vela","status":"planned"}]},{"slug":"forecasting","schema":"forecasting","contractVersion":"1.4.0","status":"live","contractsTypesPath":"src/spokes/forecasting/contracts/types.ts","contracts":[{"id":"forecasting.monte-carlo.run","description":"Run a deterministic seeded Monte Carlo over named distributions and a closed-form expression.","endpoint":"/api/spokes/forecasting/monte-carlo/run","method":"POST","requestSchema":"MonteCarloSpecSchema","responseSchema":"MonteCarloRunResponseSchema"},{"id":"forecasting.decision-models.create","description":"Register a reusable decision tree (VOI / EVPI substrate).","endpoint":"/api/spokes/forecasting/decision-models","method":"POST","requestSchema":"RegisterDecisionModelRequestSchema","responseSchema":"DecisionModelRecordSchema"},{"id":"forecasting.decision-models.get","description":"Fetch a stored decision tree by id.","endpoint":"/api/spokes/forecasting/decision-models/[id]","method":"GET","responseSchema":"DecisionModelRecordSchema"},{"id":"forecasting.voi.compute","description":"Compute baseline EV, perfect-information EV, EVPI, and optional discrete EVSI for aligned shared uncertainty.","endpoint":"/api/spokes/forecasting/voi/compute","method":"POST","requestSchema":"VOIComputeRequestSchema","responseSchema":"VOIComputeResponseSchema"},{"id":"forecasting.interval-scoring","description":"PA Instrument — Score interval estimates against realized outcomes (coverage + sharpness).","endpoint":"/api/spokes/forecasting/interval-scoring","method":"POST","requestSchema":"IntervalScoreRequestSchema","responseSchema":"IntervalScoreResultSchema"},{"id":"forecasting.bayesian-combine","description":"PA Instrument — Bayesian combination of multiple estimate sources into a posterior.","endpoint":"/api/spokes/forecasting/bayesian-combine","method":"POST","requestSchema":"BayesianCombineRequestSchema","responseSchema":"BayesianCombineResultSchema"},{"id":"forecasting.measurement-recommend","description":"PA Instrument — Recommend a measurement method given a construct and constraints.","endpoint":"/api/spokes/forecasting/measurement-recommend","method":"POST","requestSchema":"MeasurementRecommendationRequestSchema","responseSchema":"MeasurementRecommendationResultSchema"},{"id":"forecasting.measurement-catalog","description":"PA Instrument — Catalog of available measurement methods and ranges.","endpoint":"/api/spokes/forecasting/measurement-catalog","method":"GET","responseSchema":"MeasurementCatalogResultSchema"}],"consumers":[{"name":"decision-wizard","status":"planned"},{"name":"vela","status":"planned"}]},{"slug":"workforce-planning","schema":"workforce_planning","contractVersion":"0.6.0","status":"live","contractsTypesPath":"src/spokes/workforce-planning/contracts/types.ts","contracts":[{"id":"workforce-planning.health","description":"Per-spoke aggregate heartbeat shim for Postgres reachability.","endpoint":"/api/spokes/workforce-planning/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"workforce-planning.positions.list","description":"List canonical toolbox positions keyed by `(tenant × source × source row id)` plus Greenhouse-aligned status filters.","endpoint":"/api/spokes/workforce-planning/positions","method":"GET","responseSchema":"PositionListResponseSchema"},{"id":"workforce-planning.positions.upsert","description":"Service-key gated batch upsert that writes append-only audit events feeding denormalized `positions` totals.","endpoint":"/api/spokes/workforce-planning/positions","method":"POST","requestSchema":"PositionUpsertBatchRequestSchema","responseSchema":"PositionUpsertBatchResponseSchema"},{"id":"workforce-planning.allocations.list","description":"Read the position-cost / budget envelope: per-allocation rows (native + FX-snapshot reporting amounts) plus an aggregated envelope grouped by reporting currency over the full filtered set.","endpoint":"/api/spokes/workforce-planning/allocations","method":"GET","responseSchema":"AllocationListResponseSchema"},{"id":"workforce-planning.forecast.snapshots.list","description":"Read immutable forecast_snapshots sorted newest-first (`TrailingAverageForecaster` v1; window = 30d|60d|90d JSON field).","endpoint":"/api/spokes/workforce-planning/forecast/snapshots","method":"GET","responseSchema":"ForecastSnapshotsListResponseSchema"},{"id":"workforce-planning.forecast.run","description":"Materialize a persisted forecast_snapshot using rolling-average hires/exits heuristics bounded by toolbox position_events.","endpoint":"/api/spokes/workforce-planning/forecast/run","method":"POST","requestSchema":"ForecastRunRequestSchema","responseSchema":"ForecastRunResponseSchema"},{"id":"workforce-planning.forecast.exits","description":"Segment-aware trailing exit-rate forecast (defaults to ~12-month lookback) with optional regretted attribution from structured position_events taxonomy.","endpoint":"/api/spokes/workforce-planning/forecast/exits","method":"POST","requestSchema":"ForecastRunRequestSchema","responseSchema":"ExitForecastResultSchema"},{"id":"workforce-planning.forecast.funnelThroughput","description":"ATS funnel throughput forward hires from cohort conversion rates (application_status + offer_states) with persisted forecast_snapshot telemetry.","endpoint":"/api/spokes/workforce-planning/forecast/funnel-throughput","method":"POST","requestSchema":"ForecastRunRequestSchema","responseSchema":"FunnelForecastResultSchema"},{"id":"workforce-planning.forecast.projection","description":"Combined head-count balance sheet marrying exit pacing + ATS funnel hires; persists a composite forecast_snapshot envelope.","endpoint":"/api/spokes/workforce-planning/forecast/projection","method":"POST","requestSchema":"ForecastRunRequestSchema","responseSchema":"ProjectedHeadcountResultSchema"},{"id":"workforce-planning.reconciliation.snapshots.list","description":"Historical cross-system deltas (HR filled vs ATS open vs finance budgeted HC JSON per PAT-D1 scout).","endpoint":"/api/spokes/workforce-planning/reconciliation/snapshots","method":"GET","responseSchema":"ReconciliationSnapshotsListResponseSchema"},{"id":"workforce-planning.reconciliation.run","description":"Freezes reconciliation_snapshots capturing HR/Budget/ATS variance using live `positions` grain inputs.","endpoint":"/api/spokes/workforce-planning/reconciliation/run","method":"POST","requestSchema":"ReconciliationRunRequestSchema","responseSchema":"ReconciliationRunResponseSchema"},{"id":"workforce-planning.ats.webhook.greenhouse","description":"Signature-verified Greenhouse webhook ingest that upserts ATS rows + optional hire/exit deltas when JOB→POSITION env map is wired.","endpoint":"/api/spokes/workforce-planning/ats/webhook/greenhouse","method":"POST","requestSchema":"WorkforceGreenhouseWebhookEnvelopeSchema","responseSchema":"WorkforceInboundAckSchema"},{"id":"workforce-planning.matches.propose","description":"PAT-D1-B-FU-C batch Conductor matcher — Beta prior + feature likelihood ratios over open HRIS slots; persists requisition_matches + audit rows.","endpoint":"/api/spokes/workforce-planning/matches/propose","method":"POST","requestSchema":"MatchProposeRequestSchema","responseSchema":"MatchProposeResponseSchema"},{"id":"workforce-planning.matches.get","description":"Read ranked candidates + tenant prior snapshot for one ATS requisition key.","endpoint":"/api/spokes/workforce-planning/matches/[requisitionId]","method":"GET","responseSchema":"MatchDetailResponseSchema"},{"id":"workforce-planning.matches.accept","description":"Operator accepts a ranked slot; flips HRIS lifecycle to reconciled-by-operator + updates conjugate Beta on success ledger insert.","endpoint":"/api/spokes/workforce-planning/matches/[requisitionId]/accept","method":"POST","requestSchema":"MatchAcceptRequestSchema","responseSchema":"MatchAcceptAckSchema"},{"id":"workforce-planning.matches.rejectAndCreateNew","description":"Operator rejects all suggestions and mints `open-newly-created`; ledger bumps Beta \"reject\" atomically once.","endpoint":"/api/spokes/workforce-planning/matches/[requisitionId]/reject-and-create-new","method":"POST","requestSchema":"MatchRejectAndCreateRequestSchema","responseSchema":"MatchRejectCreateAckSchema"},{"id":"workforce-planning.matches.override","description":"Operator binds an off-list toolbox position without diluting conjugate Beta (explicit override semantics + audited reason).","endpoint":"/api/spokes/workforce-planning/matches/[requisitionId]/override","method":"POST","requestSchema":"MatchOverrideRequestSchema","responseSchema":"MatchOverrideAckSchema"},{"id":"workforce-planning.matches.reconcileExpiredExits","description":"Idempotent TTL job — flips stale `open-from-exit` rows to `open-newly-created` when exit_date + exit_ttl_days has elapsed.","endpoint":"/api/spokes/workforce-planning/matches/reconcile-expired-exits","method":"POST","responseSchema":"MatchReconcileExpiredExitsResponseSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"anycomp","schema":"anycomp","contractVersion":"1.61.0","status":"live","contractsTypesPath":"src/spokes/anycomp/contracts/types.ts","contracts":[{"id":"anycomp.models.create","description":"Register a compensation model and its market bands (dimensions × pay mix).","endpoint":"/api/spokes/anycomp/models","method":"POST","requestSchema":"RegisterCompModelRequestSchema","responseSchema":"CompModelSchema"},{"id":"anycomp.models.get","description":"Fetch a comp model with all bands.","endpoint":"/api/spokes/anycomp/models/[id]","method":"GET","responseSchema":"CompModelSchema"},{"id":"anycomp.evaluate","description":"Stateless evaluation: employees × model → recommendations (percentile, target pay, confidence).","endpoint":"/api/spokes/anycomp/evaluate","method":"POST","requestSchema":"CompEvaluateRequestSchema","responseSchema":"CompEvaluateResponseSchema"},{"id":"anycomp.cycles.run","description":"Bulk evaluation with persistence to comp_evaluations (audit trail per cycle).","endpoint":"/api/spokes/anycomp/cycles/run","method":"POST","requestSchema":"CompCycleEvaluationRequestSchema","responseSchema":"CompCycleEvaluationResponseSchema"},{"id":"anycomp.market.labor-rate","description":"Look up a BLS-derived labor-market rate (voluntary attrition / hire / opening / employment) for (socCode, geo, period). Geo/period fallback supplied (PAT-18-FU-A; donor market-data-backend).","endpoint":"/api/spokes/anycomp/market/labor-rate","method":"POST","requestSchema":"LaborMarketRateRequestSchema","responseSchema":"LaborMarketRateResponseSchema"},{"id":"anycomp.market.exit-risk-prior","description":"BLS-baseline exit-risk prior for a segment, with optional compensation-percentile opportunity adjustment (PAT-18-FU-A).","endpoint":"/api/spokes/anycomp/market/exit-risk-prior","method":"POST","requestSchema":"ExitRiskPriorRequestSchema","responseSchema":"ExitRiskPriorResponseSchema"},{"id":"anycomp.market.tier-classify","description":"Classify a value into Low / Mid / High tier using 33rd / 66th cohort-percentile thresholds (BLS labor metrics; PAT-18-FU-A).","endpoint":"/api/spokes/anycomp/market/tier-classify","method":"POST","requestSchema":"MarketTierClassificationRequestSchema","responseSchema":"MarketTierClassificationResponseSchema"},{"id":"anycomp.market-movement.history.ingest","description":"PAT-147-G — Batch append canonical or tenant-overlay market midpoint history for (job family, job level); tenant context required.","endpoint":"/api/spokes/anycomp/market-movement/history/ingest","method":"POST","requestSchema":"MarketReferenceHistoryIngestRequestSchema","responseSchema":"Record written count"},{"id":"anycomp.market-movement.fit","description":"PAT-147-G — YoY derivation + lag surrogate fit (pooled fallback &lt;10 rows) persisted to calculus.surrogate_models.","endpoint":"/api/spokes/anycomp/market-movement/fit","method":"POST","requestSchema":"MarketMovementFitHttpRequestSchema","responseSchema":"SurrogateModel"},{"id":"anycomp.market-movement.forecast","description":"PAT-147-G — MC envelope + surrogate mean CI forward movement percentiles for configured horizon.","endpoint":"/api/spokes/anycomp/market-movement/forecast","method":"POST","requestSchema":"MarketMovementForecastHttpRequestSchema","responseSchema":"MarketMovementForecastSchema"},{"id":"anycomp.engines.merit.run","description":"PAT-147-B CompEngine merit matrix on shared enriched population; optional per-cycle JSON config persistence.","endpoint":"/api/spokes/anycomp/engines/merit/run","method":"POST","requestSchema":"MeritEngineRunRequestSchema","responseSchema":"MeritEngineRunResponseSchema"},{"id":"anycomp.engines.variable-pay.run","description":"PAT-147-B variable-pay / annual incentive engine (Mode A v0; Mode B placeholder) with per-unit aggregates.","endpoint":"/api/spokes/anycomp/engines/variable-pay/run","method":"POST","requestSchema":"VariablePayEngineRunRequestSchema","responseSchema":"VariablePayEngineRunResponseSchema"},{"id":"anycomp.engines.equity.run","description":"PAT-147-B equity pool allocator — proportional split of per–decision-unit budgets by rating multipliers.","endpoint":"/api/spokes/anycomp/engines/equity/run","method":"POST","requestSchema":"EquityEngineRunRequestSchema","responseSchema":"EquityEngineRunResponseSchema"},{"id":"anycomp.engines.discretionary.run","description":"PAT-147-B discretionary cash engine keyed by rating with optional population-status adjustments.","endpoint":"/api/spokes/anycomp/engines/discretionary/run","method":"POST","requestSchema":"DiscretionaryEngineRunRequestSchema","responseSchema":"DiscretionaryEngineRunResponseSchema"},{"id":"anycomp.eib.generate","description":"PAT-147-E — Build Workday-style EIB CSV from persisted CompEngine outputs (merit / variable-pay / equity / discretionary). Optional download=1 as text/csv attachment.","endpoint":"/api/spokes/anycomp/eib/generate","method":"POST","requestSchema":"EibGenerateRequestSchema","responseSchema":"EibGenerateResponseSchema"},{"id":"anycomp.eib.diff","description":"PAT-147-E — Compare two prior Workday EIB CSV strings and summarize added / removed / changed award lines (employeeId or lineKey join).","endpoint":"/api/spokes/anycomp/eib/diff","method":"POST","requestSchema":"EibDiffRequestSchema","responseSchema":"EibDiffResponseSchema"},{"id":"anycomp.analytics.vs-plan","description":"Consulting vs.Plan variance: merges area × function × geo actual increments vs budgets (+ optional FY merit % targets) with rollup totals.","endpoint":"/api/spokes/anycomp/analytics/vs-plan","method":"POST","requestSchema":"VsPlanRequestSchema","responseSchema":"VsPlanResponseSchema"},{"id":"anycomp.analytics.pool-metrics","description":"Pool merit / promo / adj spend versus payroll denominator with optional weighted geo-average splits.","endpoint":"/api/spokes/anycomp/analytics/pool-metrics","method":"POST","requestSchema":"PoolMetricsRequestSchema","responseSchema":"PoolMetricsResponseSchema"},{"id":"anycomp.analytics.hr-finance-crossover","description":"Tenant-config HR↔finance bridge ratios (comp per FTE, comp % revenue proxy, comp % EBITDA) from explicit payroll + FP&A assumptions.","endpoint":"/api/spokes/anycomp/analytics/hr-finance-crossover","method":"POST","requestSchema":"HrFinanceCrossoverRequestSchema","responseSchema":"HrFinanceCrossoverResponseSchema"},{"id":"anycomp.analytics.comp-lifecycle","description":"Seven-column comp lifecycle workbook vector (hourly detect ×2080, pre/post merit TC vs band-mid promo-isolated ratios).","endpoint":"/api/spokes/anycomp/analytics/comp-lifecycle","method":"POST","requestSchema":"CompLifecycleComputationRequestSchema","responseSchema":"CompLifecycleComputationResponseSchema"},{"id":"anycomp.analytics.cr-drift-histogram","description":"Fine-grained comp-ratio histogram with paired employee pre/post counts and configurable bucket windows.","endpoint":"/api/spokes/anycomp/analytics/cr-drift-histogram","method":"POST","requestSchema":"CrDriftHistogramRequestSchema","responseSchema":"CrDriftHistogramResponseSchema"},{"id":"anycomp.analytics.dual-nine-box","description":"Perf × Pay-Equity dual nine-box matrices (pre/post) + movement arcs using segmentation-stable bucket IDs.","endpoint":"/api/spokes/anycomp/analytics/dual-nine-box","method":"POST","requestSchema":"Dual9BoxRequestSchema","responseSchema":"Dual9BoxResponseSchema"},{"id":"anycomp.scenarios.generate","description":"Decision layer (PAT-AC1): priority weights + budget → several distinct scenarios scored on every three-value measure, plus a tradeoff radar (the 'never one option' loop).","endpoint":"/api/spokes/anycomp/scenarios","method":"POST","requestSchema":"GenerateScenariosRequestSchema","responseSchema":"ScenarioBundleSchema"},{"id":"anycomp.engagements.run","description":"Persisted engagement: save strategy + priorities, run the decision loop, persist scenarios + impacts + audit in one transaction; returns the bundle.","endpoint":"/api/spokes/anycomp/engagements","method":"POST","requestSchema":"EngagementRunRequestSchema","responseSchema":"EngagementResponseSchema"},{"id":"anycomp.engagements.get","description":"Reload a persisted engagement (strategy + its scenarios/impacts) by strategyId, tenant-scoped.","endpoint":"/api/spokes/anycomp/engagements/[strategyId]","method":"GET","responseSchema":"EngagementGetResponseSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"metrics-catalog","schema":"metrics_catalog","contractVersion":"1.1.0","status":"live","contractsTypesPath":"src/spokes/metrics-catalog/contracts/types.ts","contracts":[{"id":"metrics-catalog.list","description":"List canonical HR metric definitions (6 categories, 102 metrics). Optional ?categoryId=&limit=&offset= for filtering / pagination.","endpoint":"/api/spokes/metrics-catalog/metrics","method":"GET","responseSchema":"MetricListResultSchema"},{"id":"metrics-catalog.lookup","description":"Fetch a single MetricDefinition by stable composite id 'hr-metric.<category-slug>.<metric-slug>'.","endpoint":"/api/spokes/metrics-catalog/metrics/[id]","method":"GET","responseSchema":"MetricDefinitionSchema"},{"id":"metrics-catalog.search","description":"Case-insensitive substring search across name / description / slug. Optional ?categoryId=&limit= (default 20, max 100).","endpoint":"/api/spokes/metrics-catalog/metrics/search","method":"GET","responseSchema":"MetricsCatalogSearchMcpOutputSchema"},{"id":"metrics-catalog.list-categories","description":"List the 6 catalog categories (workforce-composition, compensation-benefits, talent-acquisition, performance-development, engagement-retention, workforce-planning).","endpoint":"/api/spokes/metrics-catalog/categories","method":"GET","responseSchema":"MetricCategoryListResultSchema"}],"consumers":[{"name":"calculus","cardId":"PAT-40-phase-3","status":"live"},{"name":"performix","status":"planned"}]},{"slug":"org-graph","schema":"org_graph","contractVersion":"1.1.0","status":"live","contractsTypesPath":"src/spokes/org-graph/contracts/types.ts","contracts":[{"id":"org-graph.health","description":"Per-spoke heartbeat for Postgres reachability on `org_graph`.","endpoint":"/api/spokes/org-graph/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"org-graph.graph.build","description":"Idempotent graph rebuild — materializes org nodes + typed temporal edges for `(tenantId, snapshotId)` from worker-resolution rows.","endpoint":"/api/spokes/org-graph/graph/build","method":"POST","requestSchema":"BuildGraphRequestSchema","responseSchema":"BuildGraphResponseSchema"},{"id":"org-graph.query.resolve-ancestor","description":"As-of supervisory (or typed hierarchy) parent chain for a single worker node.","endpoint":"/api/spokes/org-graph/query/resolve-ancestor","method":"POST","requestSchema":"ResolveAncestorRequestSchema","responseSchema":"ResolveAncestorResponseSchema"},{"id":"org-graph.query.ancestor-chains","description":"Memoized ancestor stacks for many leaf nodes in one call.","endpoint":"/api/spokes/org-graph/query/ancestor-chains","method":"POST","requestSchema":"AncestorChainsRequestSchema","responseSchema":"AncestorChainsResponseSchema"},{"id":"org-graph.elt.substring-match","description":"Stateless substring roster match for ELT workbook-style HRIS strings.","endpoint":"/api/spokes/org-graph/elt/substring","method":"POST","requestSchema":"EltSubstringRequestSchema","responseSchema":"EltSubstringResponseSchema"},{"id":"org-graph.inference.dominant-dept","description":"Dominant dept→ELT empirical edges with fractional confidence.","endpoint":"/api/spokes/org-graph/inference/dominant-dept","method":"POST","requestSchema":"DominantDeptInferenceRequestSchema","responseSchema":"DominantDeptInferenceResponseSchema"},{"id":"org-graph.consistency.report","description":"Orphans, cycles, multi-parent clashes, dangling manager edges.","endpoint":"/api/spokes/org-graph/consistency/report","method":"POST","requestSchema":"ConsistencyReportRequestSchema","responseSchema":"ConsistencyReportSchema"},{"id":"org-graph.snapshot.diff","description":"Diff two snapshots — mover map, subtree graft heuristic, span-of-control deltas with optional magnitude threshold.","endpoint":"/api/spokes/org-graph/snapshot/diff","method":"POST","requestSchema":"DiffRequestSchema","responseSchema":"DiffResponseSchema"},{"id":"org-graph.rollup.leader-metrics","description":"Leader-per-layer rollup of leaf measures mirroring workbook leader-metrics passes.","endpoint":"/api/spokes/org-graph/rollup/leaders","method":"POST","requestSchema":"LeaderAggregationRequestSchema","responseSchema":"LeaderAggregationResponseSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"persona-library","schema":"persona_library","contractVersion":"0.2.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/persona-library/contracts/types.ts","contracts":[{"id":"persona-library.generate-and-store","description":"GTM-TOOLBOX-1 (G0). Generate buyer persona(s) from text/research via the live pa-site Bicycle generator, persist to the toolbox persona library, return the stored records. Service-key gated. MCP: persona-library.generate-and-store.","endpoint":"/api/spokes/persona-library/generate-and-store","method":"POST","requestSchema":"GenerateAndStoreInputSchema","responseSchema":"StoredPersonaSchema"},{"id":"persona-library.list","description":"List stored personas (portfolio visibility), filter by vertical/role. MCP: persona-library.list.","endpoint":"/api/spokes/persona-library/list","method":"GET","responseSchema":"StoredPersonaSchema"},{"id":"persona-library.get","description":"Fetch one stored persona by slug or id. MCP: persona-library.get.","endpoint":"/api/spokes/persona-library/get","method":"GET","responseSchema":"StoredPersonaSchema"}],"consumers":[{"name":"peopleanalyst-site","status":"planned"},{"name":"benchmark-outreach","cardId":"PAT-JFE-NICHE-3-OUTREACH","status":"live"}]},{"slug":"gtm-studio","schema":"gtm_studio","contractVersion":"0.4.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/gtm-studio/contracts/types.ts","contracts":[{"id":"gtm-studio.create-artifact","description":"GTM-TOOLBOX-1 (PAT-GTM-6). Persist any GTM tool artifact (positioning · message · segment · offer · channel · content · experiment · northstar) + append a tool_runs ledger entry. The shared artifact/commerce seam for the GTM tools. Service-key gated. MCP: gtm-studio.create-artifact.","endpoint":"/api/spokes/gtm-studio/artifacts","method":"POST","requestSchema":"CreateArtifactInputSchema","responseSchema":"StoredArtifactSchema"},{"id":"gtm-studio.list-artifacts","description":"List stored GTM artifacts (portfolio visibility), filter by tool/persona. MCP: gtm-studio.list-artifacts.","endpoint":"/api/spokes/gtm-studio/artifacts","method":"GET","responseSchema":"StoredArtifactSchema"},{"id":"gtm-studio.get-artifact","description":"Fetch one stored GTM artifact by id. MCP: gtm-studio.get-artifact.","endpoint":"/api/spokes/gtm-studio/artifacts/[id]","method":"GET","responseSchema":"StoredArtifactSchema"},{"id":"gtm.positioning.compose","description":"T1 Positioning & Differentiation Wizard. Offer + buyer + competitive set → positioning statement + differentiation map + one-liner. Free: statement; paid: full map + variants. MCP: gtm.positioning.compose.","endpoint":"/api/surfaces/gtm-positioning/compose","method":"POST","requestSchema":"ComposePositioningInputSchema","responseSchema":"PositioningArtifactSchema"},{"id":"gtm.message.build","description":"T2 StoryBrand / Message Builder. Customer + problem + guide + plan + stakes → an SB7 brandscript (universal contract, verbatim) + website one-liner + elevator pitch. MCP: gtm.message.build.","endpoint":"/api/surfaces/gtm-message/compose","method":"POST","requestSchema":"ComposeMessageInputSchema","responseSchema":"MessageArtifactSchema"},{"id":"gtm.offer.compose","description":"T4 Offer & Value-Prop Composer. Product + segment + price + pain → value-prop + offer structure (bonuses/risk-reversal/guarantee) + value-vs-price framing. Paid WTP carries a VoI bridge. MCP: gtm.offer.compose.","endpoint":"/api/surfaces/gtm-offer/compose","method":"POST","requestSchema":"ComposeOfferInputSchema","responseSchema":"OfferArtifactSchema"},{"id":"gtm.channel.plan","description":"T5 Channel-Mix & Distribution Planner. Segment + budget + product type + attention → ranked channel shortlist + starter paid/owned/earned mix + start-here channel. MCP: gtm.channel.plan.","endpoint":"/api/surfaces/gtm-channel/compose","method":"POST","requestSchema":"ComposeChannelInputSchema","responseSchema":"ChannelArtifactSchema"},{"id":"gtm.content.generate","description":"T6 Content Engine. Buyer + positioning → content pillars + editorial calendar + drafted pieces. Free: pillars + 7-day starter; paid: 30-day + drafts. MCP: gtm.content.generate.","endpoint":"/api/surfaces/gtm-content/compose","method":"POST","requestSchema":"ComposeContentInputSchema","responseSchema":"ContentPlanArtifactSchema"},{"id":"gtm.experiment.design","description":"T7 Growth-Experiment & Funnel Designer (flagship). AARRR stage that hurts + known stage rates → diagnosed bottleneck + ICE-ranked, falsifiable pass/fail experiment backlog, each with a value-of-information bridge. MCP: gtm.experiment.design.","endpoint":"/api/surfaces/gtm-experiment/compose","method":"POST","requestSchema":"ComposeExperimentInputSchema","responseSchema":"ExperimentArtifactSchema"},{"id":"gtm.northstar.recommend","description":"T8 North-Star Metric & Measurement Scorer. Business model + funnel → North Star metric + 3-4 input metrics + a flying-blind gap read (each gap paired with value-at-risk + cheapest close). MCP: gtm.northstar.recommend.","endpoint":"/api/surfaces/gtm-northstar/compose","method":"POST","requestSchema":"ComposeNorthStarInputSchema","responseSchema":"NorthStarArtifactSchema"}],"consumers":[{"name":"gtm-toolbox surfaces (T1·T2·T4·T5·T6·T7·T8)","status":"live"},{"name":"peopleanalyst-site","status":"planned"}]},{"slug":"job-family-agent","schema":"job_family_agent","contractVersion":"1.21.0","status":"live","contractsTypesPath":"src/spokes/job-family-agent/contracts/types.ts","contracts":[{"id":"job-family-agent.soc.list","description":"Paginated list of canonical SOC codes (O*NET 28.3 / SOC 2018). 1,016 occupations across 23 SOC major groups; default 100/page, max 500.","endpoint":"/api/spokes/job-family-agent/soc/list","method":"GET","responseSchema":"SocListResponseSchema"},{"id":"job-family-agent.soc.lookup","description":"Fetch a single SOC code by canonical id (e.g., '15-1252.00'). Accepts compact ('15-1252') or full forms.","endpoint":"/api/spokes/job-family-agent/soc/[code]","method":"GET","responseSchema":"SocLookupResponseSchema"},{"id":"job-family-agent.families.list","description":"List 23 canonical job families with hierarchy + alternative strings + resolved SOC codes (by major-group alignment).","endpoint":"/api/spokes/job-family-agent/families/list","method":"GET","responseSchema":"JobFamilyListResponseSchema"},{"id":"job-family-agent.families.lookup","description":"Fetch a single job family by stable id (e.g., 'jf.computer-mathematical') with resolved SOC codes.","endpoint":"/api/spokes/job-family-agent/families/[id]","method":"GET","responseSchema":"JobFamilyLookupResponseSchema"},{"id":"job-family-agent.functions.list","description":"List 26 canonical job functions with parent-family links + alternative strings + SOC codes (parsed from source definitions).","endpoint":"/api/spokes/job-family-agent/functions/list","method":"GET","responseSchema":"JobFunctionListResponseSchema"},{"id":"job-family-agent.functions.lookup","description":"Fetch a single job function by stable id (e.g., 'jfn.engineering') with parent family + alt-strings + SOC codes.","endpoint":"/api/spokes/job-family-agent/functions/[id]","method":"GET","responseSchema":"JobFunctionLookupResponseSchema"},{"id":"job-family-agent.classify","description":"Token-overlap heuristic classifier: free text → up to 8 SOC matches with confidence + best-guess job family + job function. Direct SOC matches detected in text override the heuristic. Stateless; public + IP-rate-limited at 100 req/min.","endpoint":"/api/spokes/job-family-agent/classify","method":"POST","requestSchema":"ClassifyRequestSchema","responseSchema":"ClassifyResponseSchema"},{"id":"job-family-agent.resolve-title","description":"JobFrame canon (PAT-JF1): resolve a messy observed title to ranked Family×Focus×Level profile candidates (profileKey e.g. 'SWE.GEN.P6') with confidence band, evidence, and recommendedAction. Alias-exact in MVP; public + also an MCP tool.","endpoint":"/api/spokes/job-family-agent/resolve-title","method":"GET","requestSchema":"ResolveTitleRequestSchema","responseSchema":"ResolveTitleResponseSchema"},{"id":"job-family-agent.construct","description":"JobFrame canon: assemble a draft profile top-down from family/focus/level (+ context modifiers) — no blank-page JD. Returns a canonical_job_profile draft.","endpoint":"/api/spokes/job-family-agent/construct","method":"GET","responseSchema":"CanonicalProfileSchema"},{"id":"job-family-agent.export","description":"JobFrame canon: export a canonical profile as JSON or Markdown (?profileKey=&format=). Plus HRIS bulk-mapping + single-JD analysis + mapping-decision (tenant-overlay) write routes — see the spoke README surface table.","endpoint":"/api/spokes/job-family-agent/export","method":"GET","responseSchema":"JobExportSchema"},{"id":"job-family-agent.level-equivalency","description":"Map external comp-source levels to the canonical JobFrame universal level by pay (preferred) or ordinal signal — the stateless core of the survey mapper. Honest 3-state (confident/review/no_match); no_match abstains with a null canonicalLevel, never a fabricated equivalence (PAT-JFE-PAY-5 #1a).","endpoint":"/api/spokes/job-family-agent/level-equivalency","method":"POST","requestSchema":"LevelEquivalencyRequestSchema","responseSchema":"LevelEquivalencyResponseSchema"},{"id":"job-family-agent.source-level-mappings.propose","description":"Survey-mapper persistence (#1b): propose source→canonical level mappings (runs the #1a equivalency per item) into the review queue (`source_level_mappings`, review_status=needs_review). Crosswalk-licensing enforced — a LICENSED source's mappings require a tenantId (tenant-segregated, never the shared canon). Service-key gated.","endpoint":"/api/spokes/job-family-agent/source-level-mappings/propose","method":"POST","requestSchema":"ProposeMappingsRequestSchema","responseSchema":"ProposeMappingsResponseSchema"},{"id":"job-family-agent.source-level-mappings.query","description":"Survey-mapper review queue (#1b): gated list of source→canonical level mappings filtered by tenant (+ global canon), source, and review status. Service-key gated (tenant-scoped licensed mappings are sensitive).","endpoint":"/api/spokes/job-family-agent/source-level-mappings/query","method":"POST","requestSchema":"ListMappingsRequestSchema","responseSchema":"ListMappingsResponseSchema"},{"id":"job-family-agent.source-level-mappings.review","description":"Survey-mapper review-correct loop (#1b): confirm or reject a proposed source→canonical level mapping (optional canonical-level override on confirm). Service-key gated.","endpoint":"/api/spokes/job-family-agent/source-level-mappings/[id]/review","method":"POST","requestSchema":"ReviewMappingRequestSchema","responseSchema":"ReviewMappingResponseSchema"},{"id":"job-family-agent.crosswalk-licensing.gate","description":"The IP-clean crosswalk guard over HTTP: honest 3-state READ gate per source (open|licensed|not_licensed, never a fabricated match) + a WRITE cleanliness check over candidate crosswalk rows. Enforces the §33 storage rule (licensed survey-house structures stay tenant-segregated, never in the shared canon).","endpoint":"/api/spokes/job-family-agent/crosswalk-licensing/gate","method":"POST","requestSchema":"CrosswalkGateRequestSchema","responseSchema":"CrosswalkGateResponseSchema"},{"id":"job-family-agent.crosswalk","description":"PAT-JFE-ENT-15 — IP-clean public-standards crosswalk: a canonical profile (FAMILY.FOCUS.LEVEL) → its equivalents in the OPEN occupation standards (ESCO · Lightcast LOT/Open Skills · O*NET/SOC), each with confidence + a 3-state band (confident/review/not_mapped) + an auditable open `via` basis. The computed coordinate position is ours; only open codes are stored as join keys (PAT-203). For global benchmarking + EU compliance interop.","endpoint":"/api/spokes/job-family-agent/crosswalk","method":"GET","responseSchema":"CrosswalkLookupResponseSchema"},{"id":"job-family-agent.crosswalk.reverse","description":"PAT-JFE-ENT-15 — reverse public-standards crosswalk: position a public-standard occupation (ESCO/Lightcast/SOC) onto OUR canon, returning candidate profiles on the shared OPEN anchor with a 3-state band. Service-key gated (positions external input). Honest not_mapped when no open anchor resolves.","endpoint":"/api/spokes/job-family-agent/crosswalk","method":"POST","requestSchema":"CrosswalkReverseRequestSchema","responseSchema":"CrosswalkReverseResponseSchema"}],"consumers":[{"name":"performix","cardId":"PFX-5","status":"in-progress"},{"name":"vela","status":"planned"}]},{"slug":"manager-effectiveness","schema":"manager_effectiveness","contractVersion":"1.2.0","status":"live","contractsTypesPath":"src/spokes/manager-effectiveness/contracts/types.ts","contracts":[{"id":"manager-effectiveness.health","description":"Per-spoke Postgres reachability shim on `manager_effectiveness` (heartbeat + tenant weight profile table presence).","endpoint":"/api/spokes/manager-effectiveness/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"manager-effectiveness.composite.compute","description":"Nine-domain hierarchical Manager Effectiveness Index (MEI) composite (0–100) with optional measure ladder payload, flight-risk penalty, and tenant-persisted pillar weights.","endpoint":"/api/spokes/manager-effectiveness/composite","method":"POST","requestSchema":"CompositeComputeRequestSchema","responseSchema":"MeiCompositeScoreSchema"},{"id":"manager-effectiveness.tenant.weights.get","description":"Return merged MEI pillar weights for a tenant (Postgres profile when present, otherwise toolbox defaults mirroring the FiveTran MQI mix).","endpoint":"/api/spokes/manager-effectiveness/weights","method":"GET","responseSchema":"TenantWeightsResponseSchema"},{"id":"manager-effectiveness.tenant.weights.upsert","description":"UPSERT the nine canonical pillar weights per tenant (service key; sum-to-one validation via Zod).","endpoint":"/api/spokes/manager-effectiveness/weights","method":"POST","requestSchema":"TenantWeightsUpsertSchema","responseSchema":"TenantWeightsResponseSchema"},{"id":"manager-effectiveness.tenant.weights.recalibrate","description":"Blend pooled Q2-derived per-domain explanatory mass with FiveTran-informed priors, UPSERT merged MEI pillar weights per tenant, and append an analyst-facing audit row.","endpoint":"/api/spokes/manager-effectiveness/weights/recalibrate","method":"POST","requestSchema":"RecalibrationRequestSchema","responseSchema":"RecalibrationResponseSchema"},{"id":"manager-effectiveness.archetype.classify","description":"Classify team staffing archetype from net growth, exit rate, and headcount (defaults align with toolbox workforce analytics cut points).","endpoint":"/api/spokes/manager-effectiveness/archetype","method":"GET","responseSchema":"ArchetypeClassifyResponseSchema"}],"consumers":[{"name":"performix","status":"planned"},{"name":"vela","status":"planned"}]},{"slug":"company-intelligence","schema":"company_intelligence","contractVersion":"0.2.0","status":"live","contractsTypesPath":"src/spokes/company-intelligence/contracts/types.ts","contracts":[{"id":"company-intelligence.companies.search","description":"Search the canonical company-master by signal tag (category:listId), sector, list, or name; returns companies with accumulated list memberships + intelligence.","endpoint":"/api/spokes/company-intelligence/companies","method":"GET","responseSchema":"CompaniesQueryResponseSchema"},{"id":"company-intelligence.cohort.get","description":"Benchmarking peer cohort — companies sharing a list, category, or sector (the peer set for comp / HR-metric / survey comparison).","endpoint":"/api/spokes/company-intelligence/cohort","method":"GET","responseSchema":"CohortResponseSchema"},{"id":"company-intelligence.cohort.compare","description":"How a benchmarking cohort's companies differ / what they share: shared + cross-recognition + distinctive list memberships, sector composition, and (when enriched) hiring-focus prevalence + comp signal.","endpoint":"/api/spokes/company-intelligence/cohort/compare","method":"GET","responseSchema":"CohortComparisonResponseSchema"},{"id":"company-intelligence.lists","description":"The list catalog (fast-growing / funding / innovation / employer / excellence / scale) with per-list member counts.","endpoint":"/api/spokes/company-intelligence/lists","method":"GET","responseSchema":"ListsResponseSchema"},{"id":"company-intelligence.ingest","description":"Upsert catalog entries + companies + list memberships (service-key).","endpoint":"/api/spokes/company-intelligence/ingest","method":"POST","responseSchema":"IngestResponseSchema"},{"id":"company-intelligence.health","description":"Per-spoke Postgres reachability shim on `company_intelligence` (heartbeat probe).","endpoint":"/api/spokes/company-intelligence/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"anycomp","status":"planned"},{"name":"job-family-agent","status":"planned"}]},{"slug":"knowledge-graph","schema":"knowledge_graph","contractVersion":"0.1.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/knowledge-graph/contracts/types.ts","contracts":[{"id":"knowledge-graph.entities.search","description":"GTM-HKG (PAT-GTM-6). Search graph entities (company · person · role · topic · keyword · content · competitor · market) by kind + name within a tenant. MCP: knowledge-graph.entity.lookup.","endpoint":"/api/spokes/knowledge-graph/entities","method":"GET","responseSchema":"EntitySearchResponseSchema"},{"id":"knowledge-graph.resolve","description":"Resolve a name/alias to the best-matching entity + candidates (the identity resolver across sources).","endpoint":"/api/spokes/knowledge-graph/resolve","method":"GET","responseSchema":"ResolveResponseSchema"},{"id":"knowledge-graph.neighborhood","description":"The core traverse: center + neighbor entities + typed/weighted edges to depth ≤3, with type + min-weight filters. The grounding/gap-analysis call. MCP: knowledge-graph.entity.neighbors.","endpoint":"/api/spokes/knowledge-graph/neighborhood","method":"GET","responseSchema":"NeighborhoodResponseSchema"},{"id":"knowledge-graph.entities.upsert","description":"Upsert entities — idempotent by (tenant,kind,slug) or (tenant,sourceNamespace,canonicalRef); reference nodes federate to canonical graphs and may not copy canonical-owned attributes. Service-key. MCP: knowledge-graph.entity.upsert.","endpoint":"/api/spokes/knowledge-graph/entities/upsert","method":"POST","requestSchema":"EntityUpsertRequestSchema","responseSchema":"UpsertResponseSchema"},{"id":"knowledge-graph.relationships.upsert","description":"Upsert typed directed edges between existing entities — idempotent by (tenant,type,from,to,effectiveFrom). Service-key. MCP: knowledge-graph.relationship.upsert.","endpoint":"/api/spokes/knowledge-graph/relationships/upsert","method":"POST","requestSchema":"RelationshipUpsertRequestSchema","responseSchema":"UpsertResponseSchema"},{"id":"knowledge-graph.health","description":"Per-spoke Postgres reachability shim on `knowledge_graph` (heartbeat probe).","endpoint":"/api/spokes/knowledge-graph/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"seo","status":"planned"},{"name":"ai-inbound","status":"planned"},{"name":"content-development","status":"planned"},{"name":"competitive-intelligence","status":"planned"}]},{"slug":"seo","schema":"seo","contractVersion":"0.1.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/seo/contracts/types.ts","contracts":[{"id":"seo.keywords.search","description":"GTM-HSEO (PAT-GTM-6). Search researched/tracked keywords by niche/geo/intent/phrase. Volumes are null unless a real provider/GSC supplied them (never fabricated). MCP: seo.keywords.search.","endpoint":"/api/spokes/seo/keywords","method":"GET","responseSchema":"KeywordSearchResponseSchema"},{"id":"seo.rank-trend","description":"Rank + clicks/impressions time series for a tracked site (optionally one keyword) — the instrumentation behind a market-inventory Spot's pitch. MCP: seo.rank.trend.","endpoint":"/api/spokes/seo/rank-trend","method":"GET","responseSchema":"RankTrendResponseSchema"},{"id":"seo.sites.query","description":"List tracked sites (a Spot directory · client · portfolio), incl. the Spot a site backs (spotId).","endpoint":"/api/spokes/seo/sites","method":"GET","responseSchema":"SitesQueryResponseSchema"},{"id":"seo.audits.get","description":"Fetch a completed audit report + findings by id.","endpoint":"/api/spokes/seo/audits/[auditId]","method":"GET","responseSchema":"AuditReportSchema"},{"id":"seo.keywords.research","description":"Generate + upsert keyword candidates from a seed/niche/geo (honest — unvolumed until a provider/GSC is wired). Service-key. MCP: seo.keywords.research.","endpoint":"/api/spokes/seo/keywords/research","method":"POST","requestSchema":"KeywordResearchRequestSchema","responseSchema":"KeywordResearchResponseSchema"},{"id":"seo.sites.upsert","description":"Register/upsert a tracked site + its pages (link a market-inventory Spot via spotId). Service-key.","endpoint":"/api/spokes/seo/sites","method":"POST","requestSchema":"SiteUpsertRequestSchema","responseSchema":"SiteUpsertResponseSchema"},{"id":"seo.rankings.ingest","description":"Append rank/GSC observations (batch, idempotent on site×keyword×day×source×device). GSC = measured truth; provider/scrape = estimated. Service-key.","endpoint":"/api/spokes/seo/rankings/ingest","method":"POST","requestSchema":"RankIngestRequestSchema","responseSchema":"RankIngestResponseSchema"},{"id":"seo.audits.run","description":"Run a technical/on-page audit on a registered site → structural findings + a 0-100 score. Service-key. MCP: seo.audit.run.","endpoint":"/api/spokes/seo/audits/run","method":"POST","requestSchema":"AuditRunRequestSchema","responseSchema":"AuditReportSchema"},{"id":"seo.health","description":"Per-spoke Postgres reachability shim on `seo` (heartbeat probe).","endpoint":"/api/spokes/seo/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"content-development","status":"planned"},{"name":"ai-inbound","status":"planned"},{"name":"gtm market-inventory Spots","status":"planned"}]},{"slug":"marketing-analytics","schema":"marketing_analytics","contractVersion":"0.4.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/marketing-analytics/contracts/types.ts","contracts":[{"id":"marketing-analytics.mmm","description":"MKTG-SCI-1. Marketing Mix Modeling: per-channel spend + outcome series → channel contribution, average + marginal ROI, bootstrap uncertainty intervals, and a marginal-ROI budget reallocation (honest abstain on thin data). Adstock + Hill saturation + ridge. MCP: marketing-analytics.mmm.","endpoint":"/api/spokes/marketing-analytics/mmm","method":"POST","requestSchema":"MmmRequestSchema","responseSchema":"MmmResponseSchema"},{"id":"marketing-analytics.attribution","description":"MKTG-SCI-2. Multi-touch attribution: conversion journeys → credit by 7 methods (5 heuristics + Markov removal-effect + Shapley) with the recommended causal credit, bootstrap intervals, and an explicit last-touch-vs-causal divergence. Honest abstain on thin paths. MCP: marketing-analytics.attribution.","endpoint":"/api/spokes/marketing-analytics/attribution","method":"POST","requestSchema":"AttributionRequestSchema","responseSchema":"AttributionResponseSchema"},{"id":"marketing-analytics.properties.list","description":"GTM-HMA (PAT-GTM-6). List connected analytics properties (GA4 / GSC / internal), incl. the Spot a property backs. MCP: marketing-analytics.properties.list.","endpoint":"/api/spokes/marketing-analytics/properties","method":"GET","responseSchema":"PropertiesQueryResponseSchema"},{"id":"marketing-analytics.metrics.query","description":"Query daily metric rollups (sessions/conversions/gsc_clicks/gsc_position/…). GA4 sampling flagged; nothing fabricated. MCP: marketing-analytics.metrics.query.","endpoint":"/api/spokes/marketing-analytics/metrics","method":"GET","responseSchema":"MetricsQueryResponseSchema"},{"id":"marketing-analytics.spots.performance","description":"The HONEST market-inventory Spot traffic number — null + honest:false until real GA4/GSC data is ingested for the Spot's property. MCP: marketing-analytics.spot.performance.","endpoint":"/api/spokes/marketing-analytics/spots/[spotId]/performance","method":"GET","responseSchema":"SpotPerformanceSchema"},{"id":"marketing-analytics.properties.connect","description":"Register/connect a GA4 or GSC property (stores a connection ref, never raw tokens). Service-key.","endpoint":"/api/spokes/marketing-analytics/properties/connect","method":"POST","requestSchema":"PropertyConnectRequestSchema","responseSchema":"PropertyConnectResponseSchema"},{"id":"marketing-analytics.ingest.ga4","description":"Ingest GA4 daily metric rollups (idempotent). Service-key.","endpoint":"/api/spokes/marketing-analytics/ingest/ga4","method":"POST","requestSchema":"MetricIngestRequestSchema","responseSchema":"MetricIngestResponseSchema"},{"id":"marketing-analytics.ingest.gsc","description":"Ingest GSC clicks/impressions/position rollups — the MEASURED truth source the SEO spoke reads. Service-key.","endpoint":"/api/spokes/marketing-analytics/ingest/gsc","method":"POST","requestSchema":"MetricIngestRequestSchema","responseSchema":"MetricIngestResponseSchema"},{"id":"marketing-analytics.conversions.ingest","description":"Mirror commerce-till / signals conversions (honest join, idempotent on sourceRef). Service-key.","endpoint":"/api/spokes/marketing-analytics/conversions/ingest","method":"POST","requestSchema":"ConversionIngestRequestSchema","responseSchema":"ConversionIngestResponseSchema"},{"id":"marketing-analytics.health","description":"Per-spoke Postgres reachability shim on `marketing_analytics` (heartbeat probe).","endpoint":"/api/spokes/marketing-analytics/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"seo","status":"planned"},{"name":"gtm north-star (T8)","status":"planned"},{"name":"gtm market-inventory Spots","status":"planned"}]},{"slug":"competitive-intelligence","schema":"competitive_intelligence","contractVersion":"0.1.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/competitive-intelligence/contracts/types.ts","contracts":[{"id":"competitive-intelligence.competitors","description":"GTM-HCI (PAT-GTM-6). List tracked competitors (references the company-intelligence master by key; isSelf marks our own properties). MCP: competitive-intelligence.competitors.list.","endpoint":"/api/spokes/competitive-intelligence/competitors","method":"GET","responseSchema":"CompetitorsQueryResponseSchema"},{"id":"competitive-intelligence.movement","description":"Longitudinal SERP diff for a competitor between two captures (gains/losses/new/dropped). Positions observed or null, never imputed. MCP: competitive-intelligence.movement.","endpoint":"/api/spokes/competitive-intelligence/competitors/[key]/movement","method":"GET","responseSchema":"MovementResponseSchema"},{"id":"competitive-intelligence.gaps","description":"The ranked opportunity list — keywords a competitor ranks for that we don't, by priority (feeds SEO + Content). MCP: competitive-intelligence.gaps.list.","endpoint":"/api/spokes/competitive-intelligence/gaps","method":"GET","responseSchema":"GapsQueryResponseSchema"},{"id":"competitive-intelligence.competitors.register","description":"Register a competitor + monitoring profile (references the company-intelligence master). Service-key.","endpoint":"/api/spokes/competitive-intelligence/competitors/register","method":"POST","requestSchema":"RegisterCompetitorRequestSchema","responseSchema":"RegisterCompetitorResponseSchema"},{"id":"competitive-intelligence.observations.ingest","description":"Append a capture's observations (SERP/positioning/hiring) from the connector. Append-only longitudinal store. Service-key.","endpoint":"/api/spokes/competitive-intelligence/observations/ingest","method":"POST","requestSchema":"IngestObservationsRequestSchema","responseSchema":"IngestObservationsResponseSchema"},{"id":"competitive-intelligence.gaps.recompute","description":"Recompute keyword gaps for a competitor set vs our own (self) ranked keywords. Service-key. MCP: competitive-intelligence.gaps.recompute.","endpoint":"/api/spokes/competitive-intelligence/gaps/recompute","method":"POST","requestSchema":"GapsRecomputeRequestSchema","responseSchema":"GapsRecomputeResponseSchema"},{"id":"competitive-intelligence.health","description":"Per-spoke Postgres reachability shim on `competitive_intelligence` (heartbeat probe).","endpoint":"/api/spokes/competitive-intelligence/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"seo","status":"planned"},{"name":"content-development","status":"planned"},{"name":"knowledge-graph","status":"planned"},{"name":"company-intelligence","status":"planned"}]},{"slug":"ai-inbound","schema":"ai_inbound","contractVersion":"0.1.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/ai-inbound/contracts/types.ts","contracts":[{"id":"ai-inbound.aeo.audits","description":"GTM-HAI (PAT-GTM-6). List citability/AEO audits (0-100 score + structured-data/entity/answerability subscores + recommendations). MCP: ai-inbound.aeo.audit (write).","endpoint":"/api/spokes/ai-inbound/aeo/audits","method":"GET","responseSchema":"AeoAuditsQueryResponseSchema"},{"id":"ai-inbound.citation-trend","description":"Cited-share over answer-engine probe runs — HONEST 3-state (citedShare of observed + explicit unknownShare; never a fabricated citation). MCP: ai-inbound.citation.trend.","endpoint":"/api/spokes/ai-inbound/answer-engine/citation-trend","method":"GET","responseSchema":"CitationTrendResponseSchema"},{"id":"ai-inbound.llms-txt","description":"The generated AEO answer-feed (llms.txt) for a property — the machine-readable file answer engines fetch. Public.","endpoint":"/api/spokes/ai-inbound/llms.txt","method":"GET","responseSchema":"text/plain"},{"id":"ai-inbound.leads","description":"List captured inbound leads (filter by status/intent). MCP: ai-inbound.leads.list.","endpoint":"/api/spokes/ai-inbound/inbound/leads","method":"GET","responseSchema":"LeadsQueryResponseSchema"},{"id":"ai-inbound.aeo.audit","description":"Run a citability/AEO audit of a URL from its signals → score + findings + recommendations. Service-key.","endpoint":"/api/spokes/ai-inbound/aeo/audit","method":"POST","requestSchema":"AeoAuditRequestSchema","responseSchema":"AeoAuditSchema"},{"id":"ai-inbound.answer-engine.probe-run","description":"Store a 3-state citation probe batch (engine × query → cited/not-cited/unknown) → citedShare + unknownShare. Service-key.","endpoint":"/api/spokes/ai-inbound/answer-engine/probe-run","method":"POST","requestSchema":"ProbeRunRequestSchema","responseSchema":"ProbeRunResponseSchema"},{"id":"ai-inbound.inbound.qualify","description":"One conversational capture turn: classify intent, reply, emit a qualified lead (visitor text PII-redacted). Service-key. MCP: ai-inbound.inbound.qualify.","endpoint":"/api/spokes/ai-inbound/inbound/qualify","method":"POST","requestSchema":"QualifyRequestSchema","responseSchema":"QualifyResponseSchema"},{"id":"ai-inbound.health","description":"Per-spoke Postgres reachability shim on `ai_inbound` (heartbeat probe).","endpoint":"/api/spokes/ai-inbound/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"knowledge-graph","status":"planned"},{"name":"content-development","status":"planned"},{"name":"marketing-analytics","status":"planned"},{"name":"gtm market-inventory Spots","status":"planned"}]},{"slug":"content-development","schema":"content_development","contractVersion":"0.1.0","status":"live","cluster":"gtm-toolbox","contractsTypesPath":"src/spokes/content-development/contracts/types.ts","contracts":[{"id":"content-development.briefs","description":"GTM-HCD (PAT-GTM-6). GET: list content briefs. POST: create a brief (intake of the governed lifecycle; grounds on KG topics/entities, consumes T6/SEO/CI sources — never re-ingests the library). MCP: content-development.briefs.create.","endpoint":"/api/spokes/content-development/briefs","method":"GET","responseSchema":"BriefsQueryResponseSchema"},{"id":"content-development.pieces","description":"GET: list content pieces + lifecycle status. POST: promote a brief → piece + first draft (drafting→review). MCP: content-development.pieces.list.","endpoint":"/api/spokes/content-development/pieces","method":"GET","responseSchema":"PiecesQueryResponseSchema"},{"id":"content-development.pieces.get","description":"A piece's full detail: immutable versions + optimization checks + publications. MCP: content-development.pieces.get.","endpoint":"/api/spokes/content-development/pieces/[id]","method":"GET","responseSchema":"PieceDetailSchema"},{"id":"content-development.briefs.create","description":"Create a content brief. Service-key.","endpoint":"/api/spokes/content-development/briefs","method":"POST","requestSchema":"CreateBriefRequestSchema","responseSchema":"CreateBriefResponseSchema"},{"id":"content-development.pieces.promote","description":"Promote a brief → content piece + a first deterministic draft (the lifecycle's drafting step; T6/LLM grounding is the enhancement). Service-key.","endpoint":"/api/spokes/content-development/pieces","method":"POST","requestSchema":"PromoteBriefRequestSchema","responseSchema":"PromoteBriefResponseSchema"},{"id":"content-development.pieces.checks","description":"Run the optimization gate (seo/aeo/editorial/fact-grounding/originality/readability) on a piece's current version → optimized if it passes. Service-key.","endpoint":"/api/spokes/content-development/pieces/[id]/checks","method":"POST","responseSchema":"RunChecksResponseSchema"},{"id":"content-development.pieces.publish","description":"Publish an OPTIMIZED piece to a URL (HITL gate). Service-key. MCP: content-development.pieces.publish.","endpoint":"/api/spokes/content-development/pieces/[id]/publish","method":"POST","requestSchema":"PublishRequestSchema","responseSchema":"PublishResponseSchema"},{"id":"content-development.health","description":"Per-spoke Postgres reachability shim on `content_development` (heartbeat probe).","endpoint":"/api/spokes/content-development/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"seo","status":"planned"},{"name":"knowledge-graph","status":"planned"},{"name":"ai-inbound","status":"planned"},{"name":"marketing-analytics","status":"planned"},{"name":"gtm market-inventory Spots","status":"planned"}]},{"slug":"wage-benchmark","schema":"wage_benchmark","contractVersion":"0.5.0","status":"live","contractsTypesPath":"src/spokes/wage-benchmark/contracts/types.ts","contracts":[{"id":"wage-benchmark.benchmark.query","description":"Median hourly wage + p10/p25/p75/p90 + a confidence interval for an SOC × geography. National cells are observed (BLS OEWS, tight CI); sub-national cells are projected from the national anchor with an honestly wide CI until OEWS metro/state tables are ingested. Flags: basis / confidence / observedForCell.","endpoint":"/api/spokes/wage-benchmark/benchmark","method":"GET","responseSchema":"BenchmarkQueryResponseSchema"},{"id":"wage-benchmark.benchmark.coverage","description":"Honest dataset coverage: occupation count, data year, observed vs. projected geo levels, sources, and the widest-error-bars-first widening roadmap.","endpoint":"/api/spokes/wage-benchmark/coverage","method":"GET","responseSchema":"BenchmarkCoverageResponseSchema"},{"id":"wage-benchmark.health","description":"Per-spoke Postgres reachability shim on `wage_benchmark` (heartbeat probe).","endpoint":"/api/spokes/wage-benchmark/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"wage-benchmark.fairness-monitor.train","description":"Single-model fairness monitor — TRAIN. Fits ONE logistic classifier with a fairness-aware loss (accuracyLoss + λ·disparity, demographic-parity or equalized-odds). No second/monitoring model, no pseudo-unbiased corpus (US11922435B2 design-around). Returns a FairnessModel (weights + bias).","endpoint":"/api/spokes/wage-benchmark/fairness-monitor/train","method":"POST","requestSchema":"FairnessTrainRequestSchema","responseSchema":"FairnessModelSchema"},{"id":"wage-benchmark.fairness-monitor.audit","description":"Single-model fairness monitor — AUDIT. Measures protected-class disparity post-hoc on an external held-out cohort of ONE model's decisions; never compares a second classifier (US11922435B2 design-around). Returns a DisparityReport with a boundary attestation.","endpoint":"/api/spokes/wage-benchmark/fairness-monitor/audit","method":"POST","requestSchema":"FairnessAuditRequestSchema","responseSchema":"DisparityReportSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"wage-compliance","schema":"wage_compliance","contractVersion":"0.21.0","status":"live","contractsTypesPath":"src/spokes/wage-compliance/contracts/types.ts","contracts":[{"id":"wage-compliance.jurisdictions.resolve","description":"Resolve a work-location address into its hierarchical jurisdiction chain with precision tier + ambiguity flags + rooftop-pending indicator (PAT-89 future).","endpoint":"/api/spokes/wage-compliance/jurisdictions/resolve","method":"POST","requestSchema":"ResolveJurisdictionRequestSchema","responseSchema":"ResolveJurisdictionResponseSchema"},{"id":"wage-compliance.jurisdictions.rules","description":"Return the active applied rule_version for a known jurisdiction_id + rule family + classification + evaluation date.","endpoint":"/api/spokes/wage-compliance/jurisdictions/[id]/rules","method":"GET","responseSchema":"RuleLookupResponseSchema"},{"id":"wage-compliance.evaluate.single","description":"Stateless single-worker compliance evaluation: pass/fail/warning/unknown with full evaluation trace + jurisdiction chain + applied rule.","endpoint":"/api/spokes/wage-compliance/evaluate/single","method":"POST","requestSchema":"EvaluateSingleRequestSchema","responseSchema":"EvaluateSingleResponseSchema"},{"id":"wage-compliance.evaluate.bulk","description":"Stateless bulk compliance evaluation (≤10,000 workers) with per-worker results + aggregate pass/fail/warning/unknown counts.","endpoint":"/api/spokes/wage-compliance/evaluate/bulk","method":"POST","requestSchema":"EvaluateBulkRequestSchema","responseSchema":"EvaluateBulkResponseSchema"},{"id":"wage-compliance.evaluate.offer","description":"PAT-90 — Stateless single-offer (ATS / pre-hire) compliance evaluation. Resolves the candidate's location, looks up the applicable rule, returns pass/warning/fail/unknown plus a `recommendedHourlyWage` (required + 1¢ buffer) when failing. Writes an `api`-source row to wage_compliance.offer_evaluations_audit (fire-and-forget).","endpoint":"/api/spokes/wage-compliance/evaluate/offer","method":"POST","requestSchema":"OfferEvaluationRequestSchema","responseSchema":"OfferEvaluationResponseSchema"},{"id":"wage-compliance.evaluate.posting","description":"PAT-100 — Stateless pay-transparency posting / offer-letter validation. Resolves the jurisdiction (id or location), looks up the applicable `pay-transparency` rule_version, and returns pass/fail + `missingFields[]`. `noObligation=true` when the jurisdiction has no transparency rule on file (outcome still `pass`).","endpoint":"/api/spokes/wage-compliance/evaluate/posting","method":"POST","requestSchema":"EvaluatePostingRequestSchema","responseSchema":"EvaluatePostingResponseSchema"},{"id":"wage-compliance.evaluate.paid-leave","description":"PAT-99-FU-A — Stateless paid-leave accrual + eligibility evaluation. Given a rule_version id (from the PAT-99 seed) + worker YTD hours-worked + employment start date + optional carryover, returns a `PaidLeaveFinding` (accrued hours, available balance, days-until-eligible, paid / job-protected / FMLA-compatible flags). Supports per-hour / front-load / fixed-bank accrual methods.","endpoint":"/api/spokes/wage-compliance/evaluate/paid-leave","method":"POST","requestSchema":"PaidLeaveEvaluationRequestSchema","responseSchema":"PaidLeaveEvaluationResponseSchema"},{"id":"wage-compliance.worker-classification.evaluate","description":"PAT-97 — Advisory FLSA + state heuristic classifier for industry-specific exemption / tipped / prevailing-wage / independent-contractor patterns. Stateless; optional `industry` selects layered rulesets (generic default). Does not substitute for legal advice.","endpoint":"/api/spokes/wage-compliance/worker-classification","method":"POST","requestSchema":"WorkerClassificationEvaluationRequestSchema","responseSchema":"WorkerClassificationEvaluationResponseSchema"},{"id":"wage-compliance.alerts.list","description":"List compliance alerts (law change / new failure / expiring rule / conflict / refresh failure). Filterable by organizationId, status, severity, alertType. v0 read surface; PAT-87 temporal diff agent populates rows.","endpoint":"/api/spokes/wage-compliance/alerts","method":"GET","responseSchema":"ListAlertsResponseSchema"},{"id":"wage-compliance.alerts.acknowledge","description":"Acknowledge a compliance alert — flip status from `open` to `reviewed` or `resolved`. Idempotent.","endpoint":"/api/spokes/wage-compliance/alerts/[id]/acknowledge","method":"POST","requestSchema":"AcknowledgeAlertRequestSchema","responseSchema":"AcknowledgeAlertResponseSchema"},{"id":"wage-compliance.rule-changes.recent","description":"Temporal diff feed of rule-version changes (increase / decrease / correction / expiration / override). Filterable by `since` + `changeType`. v0 read surface; PAT-87 temporal diff agent populates rows.","endpoint":"/api/spokes/wage-compliance/rule-changes/recent","method":"GET","responseSchema":"ListRuleChangesResponseSchema"},{"id":"wage-compliance.review-queue.create","description":"PAT-94 — Create a review-queue item from an existing compliance_evaluation row. Writes a 'created' audit event. Persistent; pairs with stateless evaluate.single / evaluate.bulk to land specific results into the operator review workflow.","endpoint":"/api/spokes/wage-compliance/review-queue","method":"POST","requestSchema":"CreateReviewQueueItemRequestSchema","responseSchema":"CreateReviewQueueItemResponseSchema"},{"id":"wage-compliance.review-queue.list","description":"PAT-94 — List review-queue items for an organization. Filterable by status + assigned_to; cursor-paginated newest-first.","endpoint":"/api/spokes/wage-compliance/review-queue","method":"GET","responseSchema":"ListReviewQueueItemsResponseSchema"},{"id":"wage-compliance.review-queue.get","description":"PAT-94 — Fetch a single review-queue item with embedded recent notes + recent audit events. One call powers the operator item-detail view.","endpoint":"/api/spokes/wage-compliance/review-queue/[id]","method":"GET","responseSchema":"GetReviewQueueItemResponseSchema"},{"id":"wage-compliance.review-queue.assign","description":"PAT-94 — Assign (or unassign with `assigneeId: null`) a review-queue item to an operator. Writes an 'assigned' / 'unassigned' audit event. Idempotent.","endpoint":"/api/spokes/wage-compliance/review-queue/[id]/assign","method":"POST","requestSchema":"AssignReviewQueueItemRequestSchema","responseSchema":"AssignReviewQueueItemResponseSchema"},{"id":"wage-compliance.review-queue.set-status","description":"PAT-94 — Transition a review-queue item's status (new / under_review / approved / exported / resolved / dismissed). Writes a 'status_changed' (or 'exported') audit event capturing the previous status.","endpoint":"/api/spokes/wage-compliance/review-queue/[id]/status","method":"POST","requestSchema":"SetReviewQueueItemStatusRequestSchema","responseSchema":"SetReviewQueueItemStatusResponseSchema"},{"id":"wage-compliance.review-queue.add-note","description":"PAT-94 — Append a free-text note to a review-queue item; atomically bumps notes_count and writes a 'note_added' audit event referencing the new note id.","endpoint":"/api/spokes/wage-compliance/review-queue/[id]/notes","method":"POST","requestSchema":"AddReviewQueueNoteRequestSchema","responseSchema":"AddReviewQueueNoteResponseSchema"},{"id":"wage-compliance.review-queue.audit","description":"PAT-94 — Paginated audit history for a single review-queue item (created / assigned / unassigned / status_changed / note_added / exported). Newest-first.","endpoint":"/api/spokes/wage-compliance/review-queue/[id]/audit","method":"GET","responseSchema":"GetReviewQueueAuditResponseSchema"},{"id":"wage-compliance.exports.generate","description":"PAT-91 — Generate a payroll-vendor export pack (ADP / UKG / Paychex) for a set of compliance_evaluation rows. Uploads CSV to Vercel Blob with a 7-day signed-URL TTL, writes a row to wage_compliance.exports_audit, and (when reviewQueueId is provided) a companion 'exported' audit event to review_queue_audit. Vendor is part of the path: /api/spokes/wage-compliance/exports/[vendor].","endpoint":"/api/spokes/wage-compliance/exports/[vendor]","method":"POST","requestSchema":"ExportRequestSchema","responseSchema":"ExportResponseSchema"},{"id":"wage-compliance.diff-agent.run","description":"PAT-87 — Run the temporal diff agent. Scans pending `rule_versions` added in the lookback window, classifies the change vs the current canonical version, emits one `rule_change_events` row per change + tiered `compliance_alerts` per affected organization (informational ≥90d / warning ≥30d / critical ≥7d / immediate <7d or active). Scheduled daily at 09:00 UTC via vercel.ts; MCP tool is the manual trigger.","endpoint":"/api/cron/wage-compliance/run-diff-agent","method":"GET","responseSchema":"DiffAgentRunResultSchema"},{"id":"wage-compliance.jurisdiction-discovery.scan","description":"PAT-102 — Jurisdiction-discovery AI agent (third toolbox AI consumer). Scans curated US government sources for new minimum-wage ordinances or statutes not yet represented in `wage_compliance.jurisdictions`. Official-domain trust scoring (.gov / state.xx.us → high; HR aggregators → medium; everything else → low). Persists every candidate to `wage_compliance.discovery_candidates`; high-trust + confidence ≥ 0.9 candidates auto-escalate to the PAT-94 review queue. Scheduled weekly at 10:00 UTC Tuesdays via vercel.ts; MCP tool is the operator override for ad-hoc scans.","endpoint":"/api/cron/wage-compliance/jurisdiction-discovery","method":"GET","responseSchema":"JurisdictionDiscoveryScanResultSchema"},{"id":"wage-compliance.rules.get","description":"PAT-84-FU-B — Drill-down read of a single rule_version: version row + jurisdiction_rule + rule_family + full jurisdiction chain + source citations.","endpoint":"/api/spokes/wage-compliance/rules/[ruleVersionId]","method":"GET","responseSchema":"GetRuleVersionResponseSchema"},{"id":"wage-compliance.jurisdictions.list","description":"PAT-84-FU-B-LIST — Paginated jurisdictions hierarchy fetch. Filterable by parentJurisdictionId, jurisdictionType, stateCode; cursor-paginated (canonical_name asc).","endpoint":"/api/spokes/wage-compliance/jurisdictions","method":"GET","responseSchema":"ListJurisdictionsResponseSchema"},{"id":"wage-compliance.alerts.assign","description":"PAT-84-FU-C — Assign a compliance_alert to an operator. Writes to wage_compliance.alert_assignments; fire-and-forget audit to mcp.mcp_audit.","endpoint":"/api/spokes/wage-compliance/alerts/[id]/assign","method":"POST","requestSchema":"AssignAlertRequestSchema","responseSchema":"AssignAlertResponseSchema"},{"id":"wage-compliance.alerts.add-note","description":"PAT-84-FU-C — Append a free-text note (≤10,000 chars) to a compliance_alert. Writes to wage_compliance.alert_notes; fire-and-forget audit to mcp.mcp_audit.","endpoint":"/api/spokes/wage-compliance/alerts/[id]/notes","method":"POST","requestSchema":"AddAlertNoteRequestSchema","responseSchema":"AddAlertNoteResponseSchema"},{"id":"wage-compliance.evaluations.aggregate","description":"PAT-84-FU-D — Dashboard KPI aggregate. Returns total/failure/pending-review/upcoming-rule-change counts, estimated annual payroll exposure (|discrepancy| × 2080), per-state failure + exposure rollup, and the last 10 compliance_alerts for an organization. Counts + aggregates only — no PII.","endpoint":"/api/spokes/wage-compliance/evaluations/aggregate","method":"GET","responseSchema":"EvaluationsAggregateResponseSchema"},{"id":"wage-compliance.conflicts.list","description":"PAT-95-FU-A — List source-citation conflicts: tuples (jurisdictionId × ruleFamilyId × effectiveStart) where ≥2 rule_versions exist. Returns candidate rule_versions, their citations, and the wage disagreement span.","endpoint":"/api/spokes/wage-compliance/conflicts","method":"GET","responseSchema":"ListConflictsResponseSchema"},{"id":"wage-compliance.conflicts.resolve","description":"PAT-95-FU-B — Resolve a source-citation conflict. Flips the accepted rule_version to `validated`, supersedes siblings on the same (jurisdictionId × ruleFamilyId × effectiveStart) tuple, writes an audit row to wage_compliance.conflict_resolutions.","endpoint":"/api/spokes/wage-compliance/rules/[ruleVersionId]/resolve-conflict","method":"POST","requestSchema":"ResolveConflictRequestSchema","responseSchema":"ResolveConflictResponseSchema"},{"id":"wage-compliance.ai-source-validation.scan","description":"PAT-103 — Source-validation AI agent. Re-scores wage_compliance.data_sources rows on the high/medium/low trust ladder using a deterministic domain heuristic (`.gov` → high, aggregators → medium) plus AI judgment for the unclassified tail. Writes audit rows to `source_validations` and updates `data_sources.trust_level` in place. Weekly cron + MCP operator tool.","endpoint":"/api/cron/wage-compliance/source-validation","method":"GET","requestSchema":"ValidateDataSourcesRequestSchema","responseSchema":"ValidateDataSourcesResponseSchema"},{"id":"wage-compliance.ai-conflict-detection.scan","description":"PAT-104 — Conflict-detection AI agent. Reads the PAT-95-FU-A conflict list and writes one draft resolution per conflict tuple to `conflict_resolution_drafts` for operator approval. Drafts never mutate rule_versions directly — committing routes through PAT-95-FU-B. Weekly cron + MCP operator tool.","endpoint":"/api/cron/wage-compliance/ai-conflict-detection","method":"GET","requestSchema":"DetectConflictsRequestSchema","responseSchema":"DetectConflictsResponseSchema"},{"id":"wage-compliance.ai-confidence-scoring.score","description":"PAT-105 — Confidence-scoring agent. 4-factor model (0.40 source / 0.20 extraction / 0.20 temporal / 0.20 cross-source) over each rule_version; writes `rule_versions.confidence_score` in place. Daily cron + inline hook from PAT-85 refresh + MCP operator tool.","endpoint":"/api/cron/wage-compliance/ai-confidence-scoring","method":"GET","requestSchema":"ScoreRuleVersionConfidenceRequestSchema","responseSchema":"ScoreRuleVersionConfidenceResponseSchema"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"worker-resolution","schema":"worker_resolution","contractVersion":"1.0.0","status":"live","contractsTypesPath":"src/spokes/worker-resolution/contracts/types.ts","contracts":[{"id":"worker-resolution.resolve","description":"Two-Pass Self-Healing join: learning index fortification followed by deterministic merge with HRIS vault, ladder matching, lineage, admissions policy, aliases learned, failures roster.","endpoint":"/api/spokes/worker-resolution/resolve","method":"POST","requestSchema":"ResolveRequestSchema","responseSchema":"ResolveResponseSchema"},{"id":"worker-resolution.health","description":"Per-spoke Postgres heartbeat shim on `worker_resolution`.","endpoint":"/api/spokes/worker-resolution/health","method":"GET","responseSchema":"SpokeHealth"}],"consumers":[{"name":"performix","status":"planned"},{"name":"vela","status":"planned"}]},{"slug":"principia-connector","schema":"principia_connector","contractVersion":"0.12.0","status":"live","contractsTypesPath":"src/spokes/principia-connector/contracts/types.ts","contracts":[{"id":"principia-connector.health","description":"Per-spoke heartbeat shim for Postgres reachability on `principia_connector`.","endpoint":"/api/spokes/principia-connector/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"principia-connector.priors.get","description":"Look up Principia's synthesized Bayesian prior for `from --predicate--> to`. Returns the typed three-state PriorResult (found/none/error) — distribution + r/CI + k + n + grade + provenance/effects URLs. Never fabricates: 'no prior available' is first-class.","endpoint":"/api/spokes/principia-connector/priors/{from}/{predicate}/{to}","method":"GET","responseSchema":"PriorResult"},{"id":"principia-connector.posterior.fuse","description":"Fuse a published Principia prior with a new observation into a posterior (conjugate normal-normal on the Fisher-z scale). Three-state PosteriorResult (fused/none/error). Service-key gated; read-only compute.","endpoint":"/api/spokes/principia-connector/posterior","method":"POST","requestSchema":"PosteriorRequest","responseSchema":"PosteriorResult"},{"id":"principia-connector.voi.analyze","description":"Value of Information (EVPI/EVSI/optimal-N) for one prior + a loss function; surfaces a delegationHint when the heavier toolbox voi-framework is needed. Three-state VoiResult (ok/none/error). Service-key gated; read-only compute.","endpoint":"/api/spokes/principia-connector/voi","method":"POST","requestSchema":"VoiRequest","responseSchema":"VoiResult"},{"id":"principia-connector.items.norms","description":"Item norm lookup (PRN-068) — is an item score typical/high/low? Three-state ItemNormResult (found/none/error); norm:null is an honest cold-start, never fabricated.","endpoint":"/api/spokes/principia-connector/items/{id}/norms","method":"GET","responseSchema":"ItemNormResult"},{"id":"principia-connector.relationship-evidence.emit","description":"Emit a primary-deployment construct→outcome effect size to Principia (PRN-065, write-key forwarded). AGGREGATE ONLY — the caller (reincarnation) gates consent + minimum cell size first. Service-key gated.","endpoint":"/api/spokes/principia-connector/relationship-evidence","method":"POST","requestSchema":"RelationshipEvidencePayload","responseSchema":"RelationshipEvidenceResult"},{"id":"principia-connector.methods.response-quality","description":"Insufficient-effort (IER) ingestion gate (PRN-145, HO-059): scores a response set and returns ready-to-filter included/excluded/flagged respondent buckets to drop low-effort responses before metrics compute. Fail-OPEN (Principia down → nothing excluded, checked:false). Service-key gated.","endpoint":"/api/spokes/principia-connector/methods/response-quality","method":"POST","requestSchema":"ResponseQualityReq","responseSchema":"ResponseQualityRes"},{"id":"principia-connector.methods.assemble-battery","description":"Soft-constraint battery assembly (PRN-142, HO-057): construct set + item pool + weights → assembled battery + per-constraint satisfaction (unmet[] flags thin-pool constraints, never a failure). Service-key gated; fail-soft 3-state.","endpoint":"/api/spokes/principia-connector/methods/assemble-battery","method":"POST","requestSchema":"AssembleBatteryReq","responseSchema":"AssembleBatteryRes"},{"id":"principia-connector.methods.local-validity","description":"Local closed-loop validity (PRN-144, HO-073): per predictor, fuses the literature prior with the customer's own predictor→criterion correlation into a posterior LOCAL validity, then flags predictors to prune + flags validation decay (drift / too-small n). Re-implements no stats (Fisher-z stays upstream). REST-entity proxy; service-key gated; fail-soft 3-state. (Blueprint-Library-derived — internal use, never market.)","endpoint":"/api/spokes/principia-connector/methods/local-validity","method":"POST","requestSchema":"LocalValidityReq","responseSchema":"LocalValidityRes"},{"id":"principia-connector.methods.validate-theory","description":"Confirmatory theory validation (PRN-147, HO-068): theory (construct→construct relationships + priors) + a corpus of coded units → per-relationship verdict (supported/refined/contradicted/inconclusive/untested_no_prior) fusing the text-derived association with the published prior (Fisher-z). Absence is signal but coverage is reported. The differentiated capability over commodity theme/sentiment analysis. Service-key gated; fail-soft 3-state. Upstream deploy-pending (returns none/error until principia ships).","endpoint":"/api/spokes/principia-connector/methods/validate-theory","method":"POST","requestSchema":"ValidateTheoryReq","responseSchema":"ValidateTheoryRes"},{"id":"principia-connector.open-text-codings.read","description":"Read batch-produced open-text codings (PRN-143, HO-058): verbatims auto-coded to canonical construct ids. Customer-derived free text → service-key gated even as a GET. Empty until the live scorer batch runs.","endpoint":"/api/spokes/principia-connector/open-text-codings","method":"GET","responseSchema":"OpenTextCodingsResult"}],"consumers":[{"name":"forecasting","status":"planned"},{"name":"anycomp","status":"planned"},{"name":"factor-models","status":"planned"},{"name":"calculus","status":"planned"},{"name":"performix","status":"planned"}]},{"slug":"glass-ox","schema":"glass_ox","contractVersion":"1.0.0","status":"live","contractsTypesPath":"src/spokes/glass-ox/contracts/types.ts","contracts":[{"id":"glass-ox.health","description":"Per-spoke Postgres reachability shim on `glass_ox` (heartbeat probe). Also seeds the reference `companalyst-coding` plan on first hit so the plans list is never empty on a fresh deploy.","endpoint":"/api/spokes/glass-ox/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"glass-ox.runs.list","description":"List persisted `RunReport` summaries, newest-reported-first. Query params: planSlug, overallStatus (ok|warn|halt), organizationId, limit (cap 200), offset.","endpoint":"/api/spokes/glass-ox/runs","method":"GET","responseSchema":"RunSummarySchema"},{"id":"glass-ox.runs.get","description":"Fetch a single persisted RunReport by `runId` — rehydrates the full StepManifest DAG (assertions + field profiles + drops-by-reason + joins).","endpoint":"/api/spokes/glass-ox/runs/[runId]","method":"GET","responseSchema":"RunReportSchema"},{"id":"glass-ox.plans.list","description":"List registered Glass Ox plans. Seeded with the reference `companalyst-coding` plan so the list is never empty on a fresh deploy.","endpoint":"/api/spokes/glass-ox/plans","method":"GET","responseSchema":"PlanSchema"},{"id":"glass-ox.plans.run","description":"Execute a registered plan synchronously, persist its RunReport across the durable tables, and return the rehydrated report (halts honestly when an assertion fires). Service-key-gated.","endpoint":"/api/spokes/glass-ox/plans/[slug]/run","method":"POST","responseSchema":"RunPlanResponseSchema"}],"consumers":[]},{"slug":"enterprise-jobframe","schema":"enterprise_jobframe","contractVersion":"0.3.0","status":"live","contractsTypesPath":"src/spokes/enterprise-jobframe/contracts/types.ts","contracts":[{"id":"enterprise-jobframe.health","description":"Per-spoke Postgres reachability shim on `enterprise_jobframe`.","endpoint":"/api/spokes/enterprise-jobframe/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"enterprise-jobframe.scaffold","description":"Top-down constructor scaffold for a canon profile (family×focus×level): the universal base + accept/reject component suggestions with 'why suggested'. Pillar 7 — choose + remove, never type a JD. Composes the job-family-agent canon.","endpoint":"/api/spokes/enterprise-jobframe/scaffold","method":"GET","responseSchema":"ConstructorScaffoldSchema"},{"id":"enterprise-jobframe.profiles.list","description":"List a tenant's job profiles (tenant-scoped; optional status filter).","endpoint":"/api/spokes/enterprise-jobframe/profiles","method":"GET","responseSchema":"TenantJobProfileSchema"},{"id":"enterprise-jobframe.profiles.create","description":"Create a tenant job profile from constructor decisions over the canon — preserves canon component ids + edit provenance, flags prose-only additions. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/profiles","method":"POST","responseSchema":"CreateTenantProfileRequestSchema"},{"id":"enterprise-jobframe.profiles.get","description":"Fetch one tenant profile + its components + approval-event history.","endpoint":"/api/spokes/enterprise-jobframe/profiles/[id]","method":"GET","responseSchema":"TenantJobProfileWithComponentsSchema"},{"id":"enterprise-jobframe.profiles.action","description":"Apply a lifecycle transition (submit_for_review/approve/reject/publish/archive). approve+publish gate on admin+ role; publish snapshots an immutable version. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/profiles/[id]/action","method":"POST","responseSchema":"ApprovalEventSchema"},{"id":"enterprise-jobframe.profiles.drift","description":"Edit-drift → warn / re-match. Computes how far the tenant profile's components moved from their canon anchor; persists the flag + offers re-match candidates. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/profiles/[id]/drift","method":"POST","responseSchema":"DriftCheckResultSchema"},{"id":"enterprise-jobframe.profiles.versions","description":"The immutable published-version history of a tenant profile.","endpoint":"/api/spokes/enterprise-jobframe/profiles/[id]/versions","method":"GET","responseSchema":"TenantProfileVersionSchema"},{"id":"enterprise-jobframe.profiles.join","description":"The 3-way join indexed BY JOB: this profile + its associated positions (workforce-planning) + people (org-graph).","endpoint":"/api/spokes/enterprise-jobframe/profiles/[id]/join","method":"GET","responseSchema":"JoinByJobSchema"},{"id":"enterprise-jobframe.overlays.list","description":"List a tenant's organizational overlays (philosophy/change/strategy).","endpoint":"/api/spokes/enterprise-jobframe/overlays","method":"GET","responseSchema":"TenantOverlaySchema"},{"id":"enterprise-jobframe.overlays.create","description":"Create an organizational overlay — a tenant-governed capability layer injected by level × function. Never part of global canon. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/overlays","method":"POST","responseSchema":"TenantOverlaySchema"},{"id":"enterprise-jobframe.overlays.catalog","description":"PAT-JFE-OVERLAY-1: list published organizational overlays available to adopt (philosophy/change-objective/strategy), each with its source-tagged capability fragments. The adoption selector.","endpoint":"/api/spokes/enterprise-jobframe/overlays/catalog","method":"GET","responseSchema":"OverlayInstanceSchema"},{"id":"enterprise-jobframe.overlays.adopt","description":"PAT-JFE-OVERLAY-1: adopt an overlay (by key or instance id). Routes to governance + injects fragments into profiles by level × function, composing with the Focus overlay; returns the injection plan + rollout. Never mutates canon. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/overlays/adoptions","method":"POST","responseSchema":"AdoptOverlayRequestSchema"},{"id":"enterprise-jobframe.overlays.adoptions.list","description":"PAT-JFE-OVERLAY-1: a tenant's overlay adoptions with rollout stats (eligible/injected profiles, adoption rate).","endpoint":"/api/spokes/enterprise-jobframe/overlays/adoptions","method":"GET","responseSchema":"TenantOverlayAdoptionSchema"},{"id":"enterprise-jobframe.overlays.adoptions.action","description":"PAT-JFE-OVERLAY-1: set an adoption's status (active re-injects; suspended/retired withdraws injected fragments). Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/overlays/adoptions/[id]/action","method":"POST","responseSchema":"SetAdoptionStatusRequestSchema"},{"id":"enterprise-jobframe.overlays.adoptions.inject","description":"PAT-JFE-OVERLAY-1: run/re-run injection for an adoption — match fragments to profiles by level × function (composing with Focus), record provenance, refresh rollout. Idempotent. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/overlays/adoptions/[id]/inject","method":"POST","responseSchema":"InjectionResultSchema"},{"id":"enterprise-jobframe.overlays.injections.list","description":"PAT-JFE-OVERLAY-1: the injection provenance rows — what overlay fragment landed where, from which source, at what version, and whether it composed with Focus.","endpoint":"/api/spokes/enterprise-jobframe/overlays/injections","method":"GET","responseSchema":"OverlayInjectionSchema"},{"id":"enterprise-jobframe.associations.bySubject","description":"The 3-way join indexed BY POSITION or BY PERSON: which tenant profiles attach to a position/person.","endpoint":"/api/spokes/enterprise-jobframe/associations","method":"GET","responseSchema":"JobAssociationSchema"},{"id":"enterprise-jobframe.associations.create","description":"Associate a tenant profile to a position (workforce-planning) or person (org-graph). Best-effort verifies a position exists via workforce-planning. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/associations","method":"POST","responseSchema":"CreateAssociationRequestSchema"},{"id":"enterprise-jobframe.governance.queue","description":"The Governance Review Console queue — the cross-cutting seam. Open review items for this spoke (profile submissions + canon-promotion proposals), tenant-scoped.","endpoint":"/api/spokes/enterprise-jobframe/governance/queue","method":"GET","responseSchema":"ReviewItemSchema"},{"id":"enterprise-jobframe.promotions.list","description":"List canon-promotion proposals (tenant-scoped; optional status filter).","endpoint":"/api/spokes/enterprise-jobframe/governance/promotions","method":"GET","responseSchema":"CanonPromotionProposalSchema"},{"id":"enterprise-jobframe.promotions.create","description":"Propose a tenant change for promotion into the global canon. A RECORD ONLY — never mutates canon; promotion is a separate governed path. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/governance/promotions","method":"POST","responseSchema":"CreatePromotionProposalRequestSchema"},{"id":"enterprise-jobframe.promotions.decide","description":"Decide a canon-promotion proposal (under_review/accepted/rejected/withdrawn). Even 'accepted' only queues for the separate canon-edit pipeline — never mutates canon. Admin+ gated. Service-key-gated.","endpoint":"/api/spokes/enterprise-jobframe/governance/promotions/[id]","method":"POST","responseSchema":"CanonPromotionProposalSchema"},{"id":"enterprise-jobframe.comp.survey-levels.list","description":"List a tenant's stored survey↔universal level equivalencies (optional source/review-status filter). PAT-JFE-ENT-5.","endpoint":"/api/spokes/enterprise-jobframe/comp/survey-levels","method":"GET","responseSchema":"SurveyLevelEquivalencySchema"},{"id":"enterprise-jobframe.comp.survey-levels.map","description":"Map a comp survey's levels ↔ universal JobFrame levels, storing the mapping basis (pay_anchored/ordinal/title_only). Title-only + low-confidence → needs_review. Composes job-family-agent level-equivalency. Service-key-gated. PAT-JFE-ENT-5.","endpoint":"/api/spokes/enterprise-jobframe/comp/survey-levels","method":"POST","responseSchema":"MapSurveyLevelsResponseSchema"},{"id":"enterprise-jobframe.comp.survey-levels.review","description":"Human review of a low-confidence/high-impact equivalency (confirm/reject + optional universal-level override → basis=manual). Service-key-gated. PAT-JFE-ENT-5.","endpoint":"/api/spokes/enterprise-jobframe/comp/survey-levels/[id]/review","method":"POST","responseSchema":"SurveyLevelEquivalencySchema"},{"id":"enterprise-jobframe.comp.survey-candidates.match","description":"Match a tenant job (anchored to canon) → comp-survey candidates, flagging content-vs-pay-grade mismatch (job content level ≠ survey level's pay-implied level). Service-key-gated. PAT-JFE-ENT-5.","endpoint":"/api/spokes/enterprise-jobframe/comp/survey-candidates","method":"POST","responseSchema":"MatchSurveyCandidatesResponseSchema"},{"id":"enterprise-jobframe.comp.disclosure-policies.list","description":"List a tenant's comp-data disclosure policies. PAT-JFE-ENT-12.","endpoint":"/api/spokes/enterprise-jobframe/comp/disclosure-policies","method":"GET","responseSchema":"CompDisclosurePolicySchema"},{"id":"enterprise-jobframe.comp.disclosure-policies.upsert","description":"Create/update a comp-data disclosure policy (what×conditions×who; one active per tenant; defaultMinN bounds every rule). Service-key-gated. PAT-JFE-ENT-12.","endpoint":"/api/spokes/enterprise-jobframe/comp/disclosure-policies","method":"POST","responseSchema":"CompDisclosurePolicySchema"},{"id":"enterprise-jobframe.comp.disclose","description":"Decide, per artifact, whether a viewer may SEE a job's comp data — through the tenant's active disclosure policy + the min-N privacy floor (individual pay never exposed) + pay-transparency law (range mandated on). Composes org-graph, data-anonymizer, wage-compliance. Service-key-gated. PAT-JFE-ENT-12.","endpoint":"/api/spokes/enterprise-jobframe/comp/disclose","method":"POST","responseSchema":"DiscloseResponseSchema"}],"consumers":[{"name":"job-family-agent","status":"live"},{"name":"wage-benchmark","status":"live"},{"name":"wage-compliance","status":"live"},{"name":"data-anonymizer","status":"live"},{"name":"anycomp","status":"live"},{"name":"workforce-planning","status":"planned"},{"name":"org-graph","status":"planned"}]},{"slug":"hris-mapper","schema":"hris_mapper","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/hris-mapper/contracts/types.ts","contracts":[{"id":"hris-mapper.health","description":"Per-spoke Postgres reachability shim on `hris_mapper`.","endpoint":"/api/spokes/hris-mapper/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"hris-mapper.datasets.list","description":"List a tenant's staged HRIS datasets (tenant-scoped).","endpoint":"/api/spokes/hris-mapper/datasets","method":"GET","responseSchema":"ImportedDatasetRow"},{"id":"hris-mapper.datasets.create","description":"Stage an upload (CSV text or parsed rows): field-type detection + RAW rows stored separately from any mapped projection (the we-do-the-homework audit). Service-key-gated.","endpoint":"/api/spokes/hris-mapper/datasets","method":"POST","responseSchema":"UploadRequestSchema"},{"id":"hris-mapper.field-mappings.set","description":"Confirm the source-column → canonical-field mapping for a dataset (idempotent replace). Service-key-gated.","endpoint":"/api/spokes/hris-mapper/field-mappings","method":"POST","responseSchema":"SetFieldMappingsRequestSchema"},{"id":"hris-mapper.mapping-runs.create","description":"Cluster (by code/title/grade) + predict family/focus/universal-level per cluster with field-level + record-level confidence + evidence + alternatives — ABSTAINING when no canon match clears the floor. Composes job-family-agent resolve-title (HTTP). Service-key-gated.","endpoint":"/api/spokes/hris-mapper/mapping-runs","method":"POST","responseSchema":"MappingRunRequestSchema"},{"id":"hris-mapper.mapping-runs.get","description":"A run's clusters + their ranked candidates (with evidence + field confidence).","endpoint":"/api/spokes/hris-mapper/mapping-runs","method":"GET","responseSchema":"MappingClusterSchema"},{"id":"hris-mapper.review-queue.get","description":"The triage queue for a run: clusters flagged by reason (low_confidence/high_impact/comp_risk/conflict) + a priority score (biggest-leverage first).","endpoint":"/api/spokes/hris-mapper/review-queue","method":"GET","responseSchema":"ReviewQueueItemSchema"},{"id":"hris-mapper.decisions.create","description":"Record a CLUSTER-level decision (accept/correct/reject/defer) — the bulk-correction grain (one decision per cluster, not per row). On correct the chosen canon ids are local truth. Service-key-gated.","endpoint":"/api/spokes/hris-mapper/decisions","method":"POST","responseSchema":"DecideRequestSchema"},{"id":"hris-mapper.export.get","description":"The mapping export for a run (JSON or CSV): one row per cluster with the FINAL mapping (decision over prediction) + confidence + band + decision + exception flag.","endpoint":"/api/spokes/hris-mapper/export","method":"GET","responseSchema":"ExportRowSchema"}],"consumers":[{"name":"job-family-agent","status":"live"},{"name":"segmentation-studio","status":"planned"},{"name":"enterprise-jobframe","status":"planned"}]},{"slug":"jobframe-analytics","schema":"jobframe_analytics","contractVersion":"0.1.0","status":"live","contractsTypesPath":"src/spokes/jobframe-analytics/contracts/types.ts","contracts":[{"id":"jobframe-analytics.health","description":"Per-spoke Postgres reachability shim on `jobframe_analytics`.","endpoint":"/api/spokes/jobframe-analytics/health","method":"GET","responseSchema":"SpokeHealth"},{"id":"jobframe-analytics.analytics","description":"PRD 20 People Analytics — run a confidence + 5-state-provenance-aware dashboard (job-architecture inventory / title proliferation / family-focus-level distribution / role drift / data trust / KSAO heatmap) over a tenant's JobFrame data. Every segment carries its provenance breakdown + a data-anonymizer min-N gate; returns a viz-catalog payload, never a bespoke chart. Service-key-gated.","endpoint":"/api/spokes/jobframe-analytics/analytics","method":"POST","responseSchema":"AnalyticsResultSchema"},{"id":"jobframe-analytics.gap-scan","description":"PRD 21 — scan a tenant's profiles against a data objective (required fields × min provenance state × staleness) → the gaps that fail it, highest-impact first. The first stage of 'ask the fewest'. Service-key-gated.","endpoint":"/api/spokes/jobframe-analytics/gap-scan","method":"POST","responseSchema":"GapScanResultSchema"},{"id":"jobframe-analytics.campaigns.list","description":"List a tenant's clarification campaigns (optional status filter).","endpoint":"/api/spokes/jobframe-analytics/campaigns","method":"GET","responseSchema":"CampaignPlanSchema"},{"id":"jobframe-analytics.campaigns.plan","description":"PRD 21 Clarification Campaign Builder — plan + persist a campaign from an objective: gap-scan → sampling (exception/random/stratified/cluster/census) → route to the people most likely to know (org-graph) → info-gain order (reincarnation) → burden-capped tasks. ?previewOnly=true returns the respondent + burden estimate without persisting. Service-key-gated.","endpoint":"/api/spokes/jobframe-analytics/campaigns","method":"POST","responseSchema":"CampaignPlanSchema"},{"id":"jobframe-analytics.responses.ingest","description":"PRD 21 — ingest clarification responses → update the value's 5-state provenance (confirm → respondent_confirmed; correct → respondent_confirmed-new), route disagreements over human-strong or sensitive values to governance review. Corrections become governed evidence. Service-key-gated.","endpoint":"/api/spokes/jobframe-analytics/responses","method":"POST","responseSchema":"IngestResponsesResultSchema"}],"consumers":[{"name":"calculus","status":"live"},{"name":"segmentation-studio","status":"live"},{"name":"org-graph","status":"live"},{"name":"workforce-planning","status":"live"},{"name":"data-anonymizer","status":"live"},{"name":"survey-orchestrator","status":"live"},{"name":"reincarnation","status":"live"},{"name":"preference-modeler","status":"live"},{"name":"enterprise-jobframe","status":"live"}]}],"crossCutting":[{"id":"insight-player.contract","description":"Canonical Insight Card contract + pure sequencing core (PAT-34). Vendor `src/lib/insight-player/contract.ts` + `sequence.ts` to consume. Bump-via-toolbox is the only path to evolve.","version":"0.5.0","contractsTypesPath":"src/lib/insight-player/contract.ts","schemaNames":["InsightCardSchema","InsightCardVisualSchema","InsightCardVisualKindSchema","InsightCardFreshnessSchema","InsightCardRevealSchema","InsightCardSignalRequestSchema","InsightCardEmitterSchema","InsightCardFocusSchema","BuildPlayerQueueRequestSchema","BuildPlayerQueueResponseSchema"]},{"id":"toolbox.analyses","description":"Analysis Catalog (PAT-42 / Catalog 3 of 7): named, versioned methodology-defined analytical units composing one or more spokes. Each entry encodes 100-250 words of methodology prose with citations. Static typed catalog in v1 (DB-back when entries exceed ~100). MCP tools: `toolbox.analyses.list / lookup / compose`.","version":"0.1.0","contractsTypesPath":"src/lib/analyses/contract.ts","schemaNames":["AnalysisDefinitionSchema","AnalysisCategorySchema","AnalysisInputDescriptorSchema","AnalysisOutputDescriptorSchema","AnalysisCompositionRequestSchema","AnalysisCompositionResultSchema","AnalysisDispatchStepSchema","AnalysisListResultSchema"],"entryCount":20},{"id":"toolbox.viz","description":"Visualization Catalog (PAT-43, Catalog 4 of 7): named visualization templates with declared input shapes + AI-routing tags. Templates back the InsightCard `visual.kind` enum. Three MCP tools: toolbox.viz.list-templates, toolbox.viz.lookup-template, toolbox.viz.infer-template-for-envelope.","version":"0.12.0","contractsTypesPath":"src/lib/visualizations/contract.ts","schemaNames":["VizTemplateSchema","VizPayloadSchema","VizRoutingTagSchema","VizInferenceRequestSchema","VizInferenceResultSchema","VizChartKindSchema","VizIntentSchema","VizDataShapeTagSchema","VizInteractionPatternSchema","VizAccessibilityMetadataSchema","VizColorScaleModeSchema","VizPalettePolicySchema","VizChartTypeRegistryEntrySchema","VizAriaRoleSuggestionSchema"],"entryCount":51},{"id":"toolbox.data-sources","description":"Data Source Catalog (PAT-45 / Catalog 7 of 7): catalog of authoritative People Analytics data sources — BLS / Census / O*NET / EEOC / NAICS / commercial / internal. Records each source's provider, license, freshness, access path, and integration status (connected / partial / planned / blocked). Two MCP tools: toolbox.data-sources.list / lookup.","version":"0.2.0","contractsTypesPath":"src/lib/data-sources/contract.ts","schemaNames":["DataSourceSchema","DataSourceProviderSchema","DataSourceCategorySchema","FreshnessCadenceSchema","LicenseSchema","IntegrationStatusSchema","DataSourceListResultSchema"],"entryCount":26},{"id":"toolbox.etl","description":"Generic ETL connector library (PAT-N4 — Objective 1). JSON / CSV / read-only Postgres / REST ingestion with TenantContext, canonical-field projection, and persistence into `segmentation_studio.workforce_dataset_rows`. HTTP POST `/api/connectors/etl/ingest`; MCP tool `toolbox.etl.ingest`.","version":"0.1.0","contractsTypesPath":"src/lib/connectors/etl/shared/types.ts","schemaNames":["EtlSourceConfigSchema","EtlIngestRequestSchema","EtlIngestResultSchema","EtlIngestRouteResponseSchema"]}],"generatedAt":"2026-06-30T22:00:04.263Z"}