{"spokes":[{"slug":"reincarnation","schema":"reincarnation","contractVersion":"1.2.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":"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.2.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.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":"leadership-quality","schema":"leadership_quality","contractVersion":"0.1.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"}],"consumers":[{"name":"performix","cardId":"PFX-79","status":"planned"}]},{"slug":"survey-orchestrator","schema":"survey_orchestrator","contractVersion":"0.4.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.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"}],"consumers":[{"name":"performix","cardId":"PFX-76","status":"planned"},{"name":"performix","cardId":"PFX-77","status":"planned"},{"name":"performix","cardId":"PFX-78","status":"planned"}]},{"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.11.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.14.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"}],"consumers":[{"name":"performix","status":"planned"},{"name":"vela","status":"planned"}]},{"slug":"factor-models","schema":"factor_models","contractVersion":"0.4.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"}],"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.5.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.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.44.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":"job-family-agent","schema":"job_family_agent","contractVersion":"1.2.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"}],"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":"wage-benchmark","schema":"wage_benchmark","contractVersion":"0.4.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"}],"consumers":[{"name":"performix","status":"planned"}]},{"slug":"wage-compliance","schema":"wage_compliance","contractVersion":"0.17.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.0.0","status":"coming-soon","contractsTypesPath":"src/spokes/principia-connector/contracts/types.ts","contracts":[],"consumers":[{"name":"calculus","status":"planned"},{"name":"performix","status":"planned"}]},{"slug":"glass-ox","schema":"glass_ox","contractVersion":"0.1.0","status":"coming-soon","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. POST registration ships in Slice 3; today the table is seeded with the reference `companalyst-coding` plan.","endpoint":"/api/spokes/glass-ox/plans","method":"GET","responseSchema":"PlanSchema"}],"consumers":[]}],"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.2.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.4.0","contractsTypesPath":"src/lib/visualizations/contract.ts","schemaNames":["VizTemplateSchema","VizPayloadSchema","VizRoutingTagSchema","VizInferenceRequestSchema","VizInferenceResultSchema","VizChartKindSchema","VizIntentSchema","VizDataShapeTagSchema","VizInteractionPatternSchema","VizAccessibilityMetadataSchema","VizColorScaleModeSchema","VizPalettePolicySchema","VizChartTypeRegistryEntrySchema","VizAriaRoleSuggestionSchema"],"entryCount":38},{"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-03T12:41:29.635Z"}