Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/platform/magstore/rerank.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/platform/magstore/rerank.go |
| Original SHA-256 | f35784a13441fcec104b4754ffcecc67ad5d5c3f12feb82a98e117bda94c2d98 |
| Git blob SHA | 7a17d6ce7389bb35707d737c71a00d549783070c |
| Reading-copy SHA-256 | f35784a13441fcec104b4754ffcecc67ad5d5c3f12feb82a98e117bda94c2d98 |
Every recorded occurrence
These 10 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/platform/magstore/rerank.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / internal/platform/magstore/rerank.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓277 lines · 11.2 KB
package magstore
import (
"context"
"fmt"
"sort"
"strings"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/missionworkforce/missionmatch/internal/platform/learn"
)
// RankTolerance is the slack the ranking quality gate allows so a tiny held out set or a floating point tie does
// not fail a genuinely equal challenger. The challenger passes when its pairwise accuracy is within this of the
// champion (better or equal).
const RankTolerance = 0.02
// RerankModelKey is the model_key of the learned slate display order re ranker (migration 0037 seeds the prior
// only v1 whose coefficients are the frozen engine component weights, so it reproduces the engine order until a
// challenger is fitted and promoted).
const RerankModelKey = "slate_display_order"
// RerankFeatureOrder is the FIXED feature order the display order re ranker trains and serves on, the frozen
// engine's six sub scores. Training, ordering, and the coefficient store all use this exact order so a fitted
// coefficient pairs with its sub score. NONE is a protected attribute or a proxy.
var RerankFeatureOrder = []string{"clearance_score", "skills_score", "certs_score", "customer_score", "experience_score", "location_score"}
// SlateMember is one decided slate member for the re ranker: its slate and candidate ids, its six frozen engine
// sub score features (aligned to RerankFeatureOrder), and whether the human approved it. The ids carry NO
// demographic data; they are the only thing that crosses to the eeo compliance path for the fairness gate.
type SlateMember struct {
SlateID string
CandidateID string
Features []float64
Approved bool
}
// SlateGroup is one slate's decided members, the ranking group the pairwise re ranker learns within. OrgID
// carries the owning tenant so the fairness gate can recompute the four fifths ratio per org (a tenant scoped
// EEO measure) under a challenger ranking.
type SlateGroup struct {
SlateID string
OrgID string
Members []SlateMember
}
// ReadSlateGroups reads every decided slate member (approved or rejected) POOLED across tenants, grouped by
// slate, with the six frozen engine sub scores as float features. It reads ONLY the frozen sub scores and the
// decision, never a demographic attribute (the eeo schema is unreachable from here); the demographic join for
// the fairness gate happens separately through the compliance pool keyed only by candidate id. Ordered
// deterministically by slate then candidate.
func ReadSlateGroups(ctx context.Context, pool *pgxpool.Pool) ([]SlateGroup, error) {
const q = `
SELECT slate_id::text, organization_id::text, candidate_id::text, decision,
clearance_score::float8, skills_score::float8, certs_score::float8,
customer_score::float8, experience_score::float8, location_score::float8
FROM slate_members
WHERE decision IN ('approved', 'rejected')
ORDER BY slate_id, candidate_id`
rows, err := pool.Query(ctx, q)
if err != nil {
return nil, err
}
defer rows.Close()
var groups []SlateGroup
var cur *SlateGroup
for rows.Next() {
var slateID, orgID, candidateID, decision string
f := make([]float64, len(RerankFeatureOrder))
if err := rows.Scan(&slateID, &orgID, &candidateID, &decision, &f[0], &f[1], &f[2], &f[3], &f[4], &f[5]); err != nil {
return nil, err
}
if cur == nil || cur.SlateID != slateID {
groups = append(groups, SlateGroup{SlateID: slateID, OrgID: orgID})
cur = &groups[len(groups)-1]
}
cur.Members = append(cur.Members, SlateMember{
SlateID: slateID,
CandidateID: candidateID,
Features: f,
Approved: decision == "approved",
})
}
return groups, rows.Err()
}
// toRankGroups projects the slate groups into the pure learn ranking groups (features plus the approved label),
// dropping the ids the numerical core does not need.
func toRankGroups(groups []SlateGroup) []learn.RankGroup {
out := make([]learn.RankGroup, 0, len(groups))
for _, g := range groups {
items := make([]learn.RankItem, 0, len(g.Members))
for _, m := range g.Members {
items = append(items, learn.RankItem{Features: m.Features, Approved: m.Approved})
}
out = append(out, learn.RankGroup{Items: items})
}
return out
}
// RerankTrainResult summarizes a re ranker training run.
type RerankTrainResult struct {
Skipped bool
SkipReason string
Version int
Groups int
Pairs int
FeatureNames []string
Coeffs []float64 // raw utility weights, aligned to RerankFeatureOrder
}
// TrainReranker reads the decided slates, fits a pairwise learning to rank model over the frozen sub score
// features (approved should rank above rejected within a slate), and writes a CHALLENGER version of the display
// order re ranker. It refuses to fit below the pair floor, leaving the prior only engine order champion in
// force. It NEVER flips champion. The learned utility weights order candidates; a display order model emits an
// ORDERING, never a per candidate score, and stores no calibration bins.
func TrainReranker(ctx context.Context, pool *pgxpool.Pool, modelKey string, l2 float64, minPairs int, dryRun bool) (RerankTrainResult, error) {
groups, err := ReadSlateGroups(ctx, pool)
if err != nil {
return RerankTrainResult{}, err
}
x, y := learn.PairwiseDataset(toRankGroups(groups))
res := RerankTrainResult{Groups: len(groups), Pairs: len(x), FeatureNames: RerankFeatureOrder}
if minPairs <= 0 {
minPairs = 20 * len(RerankFeatureOrder) // twenty pairs per feature, the ranking analogue of the events floor
}
if len(x) < minPairs {
res.Skipped = true
res.SkipReason = fmt.Sprintf("%d approved over rejected pairs is below the floor of %d", len(x), minPairs)
return res, nil
}
model, err := learn.FitLogistic(x, y, l2)
if err != nil {
return RerankTrainResult{}, err
}
// The utility weights: the raw space coefficients. The intercept is irrelevant to an ordering (it is a
// constant across candidates), so it is not stored as a weight; the display order is the utility descending.
res.Coeffs = make([]float64, len(RerankFeatureOrder))
for j := range RerankFeatureOrder {
res.Coeffs[j] = model.Coeffs[j] / model.Scales[j]
}
if dryRun {
return res, nil
}
notes := fmt.Sprintf("Challenger pairwise learning to rank fit by cmd/train-model over %d decided slates (%d approved over rejected pairs) pooled across tenants, ridge l2=%v. OutputKind display_order, never a candidate score; the frozen v1.4.0 engine stays the only per candidate scorer and a human approves every member. champion=false until cmd/eval-model passes the ranking and four fifths gates and a human promotes it.", len(groups), len(x), l2)
version, err := WriteChallenger(ctx, pool, modelKey, Challenger{
Family: "pairwise_logistic",
OutputKind: "display_order",
FeatureNames: RerankFeatureOrder,
Intercept: 0, // an ordering is invariant to the intercept
Coeffs: res.Coeffs,
Notes: notes,
})
if err != nil {
return RerankTrainResult{}, err
}
res.Version = version
return res, nil
}
// RerankCoeffs extracts a loaded model's utility weights in RerankFeatureOrder, so a stored re ranker (champion
// or challenger) can order a slate or be scored for ranking quality.
func RerankCoeffs(m Model) []float64 {
out := make([]float64, len(RerankFeatureOrder))
for j, name := range RerankFeatureOrder {
out[j] = m.Coeffs[name]
}
return out
}
// OrderMembers returns the slate members in the display order the utility weights imply: the learned utility
// descending, with the frozen engine order (the incoming slice order) as the STABLE tiebreak, so a zero weight
// or a tie preserves the engine order exactly. It emits an ORDERING (a permutation), never a score.
func OrderMembers(coeffs []float64, members []SlateMember) []SlateMember {
out := make([]SlateMember, len(members))
copy(out, members)
sort.SliceStable(out, func(i, j int) bool {
return learn.RankUtility(out[i].Features, coeffs) > learn.RankUtility(out[j].Features, coeffs)
})
return out
}
// RerankQualityResult is the held out ranking comparison of the champion and a challenger re ranker.
type RerankQualityResult struct {
HeldOutGroups int
ChampAccuracy float64
ChalAccuracy float64
Pass bool
}
// EvaluateRerankerQuality reads the decided slates, holds out a deterministic tail fraction as a test split, and
// computes the pairwise ranking accuracy (approved ordered above rejected within a slate) under both the
// champion and the challenger utility weights. The challenger passes when it ranks at least as well as the
// champion (accuracy within RankTolerance). It is pure over the stored weights and the slate read; the fairness
// gate is a separate check the caller runs through the compliance pool.
func EvaluateRerankerQuality(ctx context.Context, pool *pgxpool.Pool, champCoeffs, chalCoeffs []float64, holdout float64) (RerankQualityResult, error) {
groups, err := ReadSlateGroups(ctx, pool)
if err != nil {
return RerankQualityResult{}, err
}
if len(groups) == 0 {
return RerankQualityResult{}, fmt.Errorf("magstore: no decided slates to evaluate")
}
if holdout <= 0 || holdout >= 1 {
holdout = 0.30
}
cut := len(groups) - int(float64(len(groups))*holdout)
if cut >= len(groups) {
cut = len(groups) - 1
}
if cut < 0 {
cut = 0
}
test := toRankGroups(groups[cut:])
res := RerankQualityResult{
HeldOutGroups: len(groups) - cut,
ChampAccuracy: learn.PairwiseAccuracy(test, champCoeffs),
ChalAccuracy: learn.PairwiseAccuracy(test, chalCoeffs),
}
res.Pass = res.ChalAccuracy >= res.ChampAccuracy-RankTolerance
return res, nil
}
// GroupsByOrg buckets the slate groups by owning tenant, so the fairness gate can recompute the four fifths
// ratio per org (a tenant scoped EEO measure) under a challenger ranking.
func GroupsByOrg(groups []SlateGroup) map[string][]SlateGroup {
out := map[string][]SlateGroup{}
for _, g := range groups {
out[g.OrgID] = append(out[g.OrgID], g)
}
return out
}
// CandidateSelection reduces the per slate top k selection to a per candidate set (selected if the ranking
// surfaces the candidate in the top of ANY of their slates), the shape the eeo four fifths recomputation
// consumes. It carries only candidate ids, no demographic data.
func CandidateSelection(coeffs []float64, groups []SlateGroup) map[string]bool {
perSlate := TopKSelection(coeffs, groups)
out := map[string]bool{}
for key := range perSlate {
if i := strings.LastIndex(key, "|"); i >= 0 {
out[key[i+1:]] = true
}
}
return out
}
// TopKSelection marks, per slate, the candidates the ranking would surface as the SELECTION it nudges: the top
// N by the utility weights where N is the number the human actually approved on that slate. It returns a set
// keyed by "slateID|candidateID". This is the selection proxy the fairness gate recomputes the four fifths
// ratio over, so a display order change that would skew who surfaces first is caught. Ties preserve the engine
// order (the stable incoming member order).
func TopKSelection(coeffs []float64, groups []SlateGroup) map[string]bool {
selected := map[string]bool{}
for _, g := range groups {
n := 0
for _, m := range g.Members {
if m.Approved {
n++
}
}
if n == 0 {
continue
}
ordered := OrderMembers(coeffs, g.Members)
for i := 0; i < n && i < len(ordered); i++ {
selected[ordered[i].SlateID+"|"+ordered[i].CandidateID] = true
}
}
return selected
}