Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/ai/mag.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/modules/ai/mag.go |
| Original SHA-256 | e4d6af71b27bf6d821ede0670601dfa79bb46ce988a7596ad741dc630d71611e |
| Git blob SHA | a77acf60b91020462ed969bb9d5d593da73a91f5 |
| Reading-copy SHA-256 | e4d6af71b27bf6d821ede0670601dfa79bb46ce988a7596ad741dc630d71611e |
Every recorded occurrence
These 2 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/modules/ai/mag.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/modules/ai/mag.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓643 lines · 30.8 KB
package ai
// MAG (Model Augmented Generation) is the fourth augmentation class after RAG, TAG, and GraphRAG. A MAG
// intent is a model backed intent in the CLOSED Registry, selected by the planner like any other intent, that
// the model authors ZERO of (no SQL, no params, no coefficients) and that can ONLY emit one of three legal
// OutputKinds (opportunity_score, display_order, confidence), NEVER a per candidate score. That OutputKind
// hard enum is THE mechanism that keeps the frozen decimal engine (internal/modules/matching, ModelVersion
// v1.4.0) the only per candidate scorer by construction: a learned model is structurally incapable of
// emitting a match score.
//
// A learned artifact is stored as interpretable numeric coefficients (aedt_model_coefficients) plus a monotone
// calibration map (aedt_calibration_bins), and served in Go into shopspring/decimal, so serving needs no
// second datastore, no cloud ML service, and no Python at request time. ExecuteModelIntent gathers the model's
// FEATURES by running each declared FeatureIntent through the EXISTING guarded ExecuteIntent path (so RLS, the
// read allowlist, ForbidEEO, and suppression all still hold), reads the champion coefficients, computes
// log odds = intercept + SUM(coefficient_j * feature_j) in decimal, applies the logistic (a single isolated
// float conversion, re quantized to decimal immediately, so every SURFACED number is decimal), applies the
// calibration map, and returns the calibrated probability plus a per feature additive contribution trace
// shaped exactly like engine.ComponentScore. That trace is the citations the existing faithfulness gate grounds
// the narration against.
//
// The first MAG intent is opportunity_win_probability. At v0 it is PRIOR ONLY: the intercept is the logit of a
// defensible federal recompete base rate and every learned coefficient is 0.0, so the model returns the
// calibrated market base rate the day it ships and its learned coefficients light up automatically as decided
// bid labels accrue. It emits opportunity_score, never a candidate score.
import (
"context"
"encoding/json"
"errors"
"fmt"
"math"
"sort"
"strings"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgtype"
"github.com/shopspring/decimal"
"github.com/missionworkforce/missionmatch/internal/platform/tenant"
)
// WinProbabilityModelKey is the model_key of the first MAG intent's champion in aedt_learned_models. It is the
// key ExecuteModelIntent resolves the champion coefficients under; the migration 0036 seed writes the prior
// only v0 champion under this exact key.
const WinProbabilityModelKey = "opportunity_win_probability"
// IntentOpportunityWinProbability is the FIXED registered name of the win probability MAG intent. It is a
// closed Registry entry (so ValidateRegistry asserts its static MAG shape at boot) and an ExecutorModel intent
// (so the raw ExecuteIntent path hard rejects it and the AnswerGraph model fork routes it to
// answerModelIntent). It does NOT run through ExecuteIntent.
const IntentOpportunityWinProbability = "opportunity_win_probability"
// interceptFeatureName is the reserved coefficient row that carries the model's bias term (the log odds base
// rate), distinct from every real feature coefficient. It is not a gathered feature; it is the constant added
// once to the log odds sum.
const interceptFeatureName = "intercept"
// winProbabilityReliabilityDisclosure is the fixed reliability line the win probability answer surfaces so a
// reader knows the number is a prior only market base rate, not a learned per segment signal, until labels
// accrue. It carries no dash.
const winProbabilityReliabilityDisclosure = "Reliability: this is a prior only estimate. It shrinks to the market base rate over the decided bids in the segment; learned per segment signal lights up as more bids are decided. It is an opportunity level probability, not a per candidate match score."
// Contribution is one per feature additive term of a MAG score, shaped exactly like engine.ComponentScore so
// the MAG trace reads like an engine trace: the feature name, its gathered value, the champion coefficient, the
// resulting additive contribution to the log odds (coefficient times value), and a human readable rationale.
// Every numeric field is shopspring/decimal, never float; the contribution is the citation the faithfulness
// gate grounds the prose against.
type Contribution struct {
FeatureName string `json:"feature_name"`
Value decimal.Decimal `json:"value"`
Coefficient decimal.Decimal `json:"coefficient"`
Contribution decimal.Decimal `json:"contribution"`
Rationale string `json:"rationale"`
// Absent marks a feature the gather step could not read for this segment (no decided bid history). The
// scorer imputes the model's stored training mean for an absent feature, so a learned model returns the
// base rate for a no history segment (intercept plus coefficient times the mean) instead of extrapolating
// off a misleading zero. It is not surfaced in the answer JSON.
Absent bool `json:"-"`
}
// ModelResult is the served answer of a MAG intent: the calibrated Value (a probability in [0, 1] for an
// opportunity_score or a confidence), the OutputKind (one of the three legal kinds, NEVER a candidate score),
// the model_key and version that produced it, and the ordered per feature contribution Trace (the citations).
// Value is shopspring/decimal; there is no per candidate score anywhere in this shape by construction.
type ModelResult struct {
Value decimal.Decimal
OutputKind string
ModelKey string
Version int
Trace []Contribution
}
// championModel is the loaded champion row plus its coefficients and calibration bins, read from
// aedt_learned_models, aedt_model_coefficients, and aedt_calibration_bins for a model_key. It is global
// reference data (no org, no PII), so it is loaded with a plain read; the coefficients are keyed by feature
// name (the intercept plus every real feature), all shopspring/decimal.
type championModel struct {
ModelKey string
Version int
OutputKind string
Intercept decimal.Decimal
Coefficients map[string]decimal.Decimal
// FeatureMeans is each feature's training mean, read from the feature_spec. The serve path imputes it for a
// feature with no history (a segment with no decided bids), so a learned model returns the base rate for a
// no history segment (intercept + coefficient times the mean) rather than extrapolating off a misleading
// zero. It is empty for the prior only v0 (whose coefficients are zero, so imputation is moot).
FeatureMeans map[string]decimal.Decimal
Calibration []calibrationBin
}
// featureMean returns the stored training mean for a feature, or decimal zero when none is stored (the prior
// only model stores none, and its zero coefficients make the imputed value moot).
func (m championModel) featureMean(feature string) decimal.Decimal {
if v, ok := m.FeatureMeans[feature]; ok {
return v
}
return decimal.Zero
}
// calibrationBin maps a raw probability in the closed range [Lo, Hi] to an EmpiricalRate. An empty calibration
// set is the identity map (the raw probability passes through). All three figures are decimal, never float.
type calibrationBin struct {
Lo, Hi decimal.Decimal
EmpiricalRate decimal.Decimal
}
// coefficient returns the champion coefficient for a feature name, or decimal zero when the feature has no
// stored coefficient (a prior only feature or a feature the champion does not weight). A missing coefficient
// is a zero contribution, the safe default, never an error.
func (m championModel) coefficient(feature string) decimal.Decimal {
if c, ok := m.Coefficients[feature]; ok {
return c
}
return decimal.Zero
}
// loadChampionModel loads the CHAMPION row for a model_key plus its coefficients and calibration bins from the
// global model tables under a guarded read. The champion is the single row where champion is true (enforced
// unique by the partial index in migration 0036); an error surfaces when no champion is resolvable, so a
// serving path never silently emits an uncalibrated number. It runs inside the caller's tenant tx: the model
// tables are GLOBAL reference (SELECT granted to the app role, no RLS policy), so the org GUC does not filter
// them, exactly like the bls_wages reference read.
func loadChampionModel(ctx context.Context, tx pgx.Tx, modelKey string) (championModel, error) {
var m championModel
m.ModelKey = modelKey
m.Coefficients = map[string]decimal.Decimal{}
m.FeatureMeans = map[string]decimal.Decimal{}
// The champion version, its output kind, and its feature_spec (the single champion row per model_key).
var featureSpec []byte
row := tx.QueryRow(ctx,
`SELECT version, output_kind, feature_spec FROM aedt_learned_models WHERE model_key = $1 AND champion = true`, modelKey)
if err := row.Scan(&m.Version, &m.OutputKind, &featureSpec); err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return championModel{}, fmt.Errorf("ai: no champion model for %q", modelKey)
}
return championModel{}, err
}
if !validOutputKind(m.OutputKind) {
// A stored output kind outside the legal enum can never surface a candidate score: refuse to serve it.
return championModel{}, fmt.Errorf("ai: champion model %q has an illegal output kind %q", modelKey, m.OutputKind)
}
m.FeatureMeans = parseFeatureMeans(featureSpec)
// The coefficients: the intercept plus every real feature, scanned into shopspring/decimal exact.
crows, err := tx.Query(ctx,
`SELECT feature_name, coefficient FROM aedt_model_coefficients WHERE model_key = $1 AND version = $2`,
modelKey, m.Version)
if err != nil {
return championModel{}, err
}
defer crows.Close()
m.Intercept = decimal.Zero
for crows.Next() {
var name string
var coef decimal.Decimal
if err := crows.Scan(&name, &coef); err != nil {
return championModel{}, err
}
if name == interceptFeatureName {
m.Intercept = coef
continue
}
m.Coefficients[name] = coef
}
if err := crows.Err(); err != nil {
return championModel{}, err
}
// The calibration bins, ordered by bin index. An empty set is the identity map.
brows, err := tx.Query(ctx,
`SELECT bin_lo, bin_hi, empirical_rate FROM aedt_calibration_bins WHERE model_key = $1 AND version = $2 ORDER BY bin_index`,
modelKey, m.Version)
if err != nil {
return championModel{}, err
}
defer brows.Close()
for brows.Next() {
var b calibrationBin
if err := brows.Scan(&b.Lo, &b.Hi, &b.EmpiricalRate); err != nil {
return championModel{}, err
}
m.Calibration = append(m.Calibration, b)
}
if err := brows.Err(); err != nil {
return championModel{}, err
}
return m, nil
}
// parseFeatureMeans reads each feature's training mean out of the feature_spec jsonb, keyed by feature name. A
// feature with no stored mean (the prior only v0) is simply absent from the map, so featureMean returns zero,
// which is moot there because the prior only coefficients are zero. A malformed spec yields an empty map, the
// safe default (no imputation), never an error, so a serve path never fails on a spec it cannot read.
func parseFeatureMeans(spec []byte) map[string]decimal.Decimal {
out := map[string]decimal.Decimal{}
if len(spec) == 0 {
return out
}
var parsed struct {
Features []struct {
Name string `json:"name"`
Mean string `json:"mean"`
} `json:"features"`
}
if err := json.Unmarshal(spec, &parsed); err != nil {
return out
}
for _, f := range parsed.Features {
if f.Name == "" || f.Mean == "" {
continue
}
if d, err := decimal.NewFromString(f.Mean); err == nil {
out[f.Name] = d
}
}
return out
}
// featureExtractors maps a FeatureIntent name to the function that runs it (through the existing guarded
// ExecuteIntent path) and extracts the declared scalar feature from its result. The extractor closes over the
// bound args (the segment keys). It is the FIXED, reviewed set of features a MAG intent may read; a feature
// intent with no extractor is refused, so a model can never read a feature the platform did not author an
// extractor for.
type featureExtractor func(ctx context.Context, db *tenant.DB, args []any) (decimal.Decimal, string, error)
// scoreModelIntent is the pure serving math, separated from the database read so it is unit testable with a
// fixed champion, a fixed feature vector, and no DB. It computes log odds = intercept + SUM(coefficient_j *
// value_j) in shopspring/decimal, applies the logistic (a single isolated float conversion, re quantized to
// decimal immediately), applies the calibration map, and returns the calibrated probability plus the ordered
// contribution trace. Every SURFACED number (the value, the coefficient, the contribution, the probability) is
// decimal; the only float is the transient sigmoid argument, which never surfaces.
func scoreModelIntent(model championModel, feats []Contribution) (decimal.Decimal, []Contribution) {
// The additive log odds in decimal: the intercept plus every feature's coefficient times value. Each
// feature carries its own contribution (coefficient times value) as the citation.
logOdds := model.Intercept
trace := make([]Contribution, 0, len(feats)+1)
trace = append(trace, Contribution{
FeatureName: interceptFeatureName,
Value: decimal.NewFromInt(1),
Coefficient: model.Intercept,
Contribution: model.Intercept,
Rationale: "the model bias term, the log odds of the prior base rate before any feature",
})
for _, f := range feats {
coef := model.coefficient(f.FeatureName)
// A feature with no history is imputed at the model's training mean, so a learned model returns the base
// rate for a no history segment (intercept plus coefficient times the mean) rather than extrapolating off
// a misleading zero. The gathered value passes through unchanged when the feature is present.
value := f.Value
rationale := f.Rationale
if f.Absent {
value = model.featureMean(f.FeatureName)
rationale = f.Rationale + "; the feature is imputed at the model training mean " + value.String() + " so a no history segment rests on the base rate"
}
contribution := coef.Mul(value)
logOdds = logOdds.Add(contribution)
trace = append(trace, Contribution{
FeatureName: f.FeatureName,
Value: value,
Coefficient: coef,
Contribution: contribution,
Rationale: rationale,
})
}
// The logistic. This is the single place a float is used: the exponential has no exact decimal form, so
// the log odds decimal is converted to float64 for the sigmoid ONLY, and the result is re quantized to a
// decimal probability immediately. Every surfaced number is decimal; this transient float never surfaces.
raw := sigmoidToDecimal(logOdds)
// The calibration map (identity when the champion carries no bins).
calibrated := applyCalibration(model.Calibration, raw)
return calibrated, trace
}
// sigmoidToDecimal computes the logistic 1 / (1 + exp(-x)) of a decimal log odds and returns a decimal
// probability. The exponential is the one operation with no exact decimal form, so the log odds is converted
// to float64 for the sigmoid ONLY and the float result is re quantized to a decimal rounded to ten places
// (the coefficient scale), so the surfaced probability is decimal and stable. The transient float never
// surfaces.
func sigmoidToDecimal(logOdds decimal.Decimal) decimal.Decimal {
x, _ := logOdds.Float64()
p := 1.0 / (1.0 + math.Exp(-x))
// Re quantize the float result to a decimal at the coefficient scale. This is the boundary: from here on
// the number is decimal.
return decimal.NewFromFloat(p).Round(10)
}
// applyCalibration remaps a raw probability through the champion's monotone calibration bins. A raw probability
// in a bin's closed range [Lo, Hi] maps to that bin's EmpiricalRate. An empty bin set is the identity map (the
// raw probability passes through unchanged), the honest calibration for a prior only model. The result is
// clamped to [0, 1] so a calibrated probability is always a valid probability, all in decimal.
func applyCalibration(bins []calibrationBin, raw decimal.Decimal) decimal.Decimal {
out := raw
for _, b := range bins {
if raw.GreaterThanOrEqual(b.Lo) && raw.LessThanOrEqual(b.Hi) {
out = b.EmpiricalRate
break
}
}
if out.LessThan(decimal.Zero) {
return decimal.Zero
}
if out.GreaterThan(decimal.NewFromInt(1)) {
return decimal.NewFromInt(1)
}
return out
}
// ExecuteModelIntent runs a MAG intent: it confirms the intent is ExecutorModel, loads the champion
// coefficients, gathers each declared FeatureIntent's scalar through the existing guarded ExecuteIntent path,
// scores the calibrated probability in decimal, and returns the ModelResult with its contribution trace. It
// runs inside the caller's tenant tx so the champion read (global reference) and the feature reads (RLS scoped
// through ExecuteIntent) share one authenticated tenant context. It NEVER computes a per candidate score: the
// OutputKind is one of the three legal kinds and the math produces one opportunity level number.
func ExecuteModelIntent(ctx context.Context, db *tenant.DB, intent QueryIntent, args []any) (*ModelResult, error) {
if db == nil {
return nil, errors.New("ai: no database")
}
if intent.Executor != ExecutorModel || intent.Model == nil {
return nil, fmt.Errorf("ai: %q is not a model backed MAG intent", intent.Name)
}
if !validOutputKind(intent.Model.OutputKind) {
return nil, fmt.Errorf("ai: model intent %q has an illegal output kind %q", intent.Name, intent.Model.OutputKind)
}
if len(args) != len(intent.Params) {
return nil, fmt.Errorf("ai: model intent %q expects %d params, got %d", intent.Name, len(intent.Params), len(args))
}
// Gather the features by running each declared FeatureIntent through the existing guarded ExecuteIntent
// path (RLS, ReadAllowlist, ForbidEEO, suppression all hold) and extracting its declared scalar. The
// extractor closes over the bound segment keys.
feats, err := gatherWinProbabilityFeatures(ctx, db, intent, args)
if err != nil {
return nil, err
}
// Load the champion and score, both inside one tenant tx (the champion tables are global reference; the
// feature reads already ran under RLS through ExecuteIntent).
var model championModel
if err := db.RunInTenantTx(ctx, func(ctx context.Context, tx pgx.Tx) error {
m, lerr := loadChampionModel(ctx, tx, intent.Model.ModelKey)
if lerr != nil {
return lerr
}
model = m
return nil
}); err != nil {
return nil, err
}
// The registered output kind and the stored champion output kind must agree, so a drift between the spec
// and the stored model can never surface a candidate score.
if model.OutputKind != intent.Model.OutputKind {
return nil, fmt.Errorf("ai: model intent %q output kind %q disagrees with the champion %q", intent.Name, intent.Model.OutputKind, model.OutputKind)
}
value, trace := scoreModelIntent(model, feats)
return &ModelResult{
Value: value,
OutputKind: model.OutputKind,
ModelKey: model.ModelKey,
Version: model.Version,
Trace: trace,
}, nil
}
// gatherWinProbabilityFeatures gathers the win probability model's features. For v0 the only feature is the
// segment base rate read from the bid_win_rate_by_segment intent: the advisory market win rate for the bound
// agency segment (or the overall rate when no agency binds). It runs that intent through the existing guarded
// ExecuteIntent path and extracts the win_rate scalar for the matching segment. A model may only read a
// feature the platform authored an extractor for; an unrecognized feature intent is refused.
func gatherWinProbabilityFeatures(ctx context.Context, db *tenant.DB, intent QueryIntent, args []any) ([]Contribution, error) {
agency := ""
if len(args) >= 1 {
if s, ok := args[0].(string); ok {
agency = strings.TrimSpace(s)
}
}
var feats []Contribution
for _, fi := range intent.Model.FeatureIntents {
switch fi {
case IntentBidWinRateBySegment:
rate, rationale, absent, err := extractSegmentBaseRate(ctx, db, agency)
if err != nil {
return nil, err
}
feats = append(feats, Contribution{
FeatureName: "segment_base_rate",
Value: rate,
Rationale: rationale,
Absent: absent,
})
default:
return nil, fmt.Errorf("ai: model intent %q declares feature intent %q that has no authored extractor", intent.Name, fi)
}
}
return feats, nil
}
// extractSegmentBaseRate runs the bid_win_rate_by_segment intent through the existing guarded ExecuteIntent
// path and extracts the advisory win rate for the bound agency segment as a decimal in [0, 1]. It matches the
// customer_agency column to the bound agency (case insensitive, trimmed). It returns an absent flag true when no
// agency binds to a segment with decided bids (no matching segment, or a NULL rate); an absent feature is
// imputed at the model training mean by the scorer, so a learned model rests on the base rate for a no history
// segment. A genuine zero rate (a segment with decided bids that were all losses) is present, not absent, real
// signal. The win rate is the intent's own exact numeric ratio scanned into decimal, never recomputed and never
// float.
func extractSegmentBaseRate(ctx context.Context, db *tenant.DB, agency string) (decimal.Decimal, string, bool, error) {
intent, ok := IntentByName(IntentBidWinRateBySegment)
if !ok {
return decimal.Zero, "", false, fmt.Errorf("ai: feature source intent %q is not registered", IntentBidWinRateBySegment)
}
res, err := ExecuteIntent(ctx, db, intent, nil)
if err != nil {
return decimal.Zero, "", false, err
}
// Find the customer_agency and win_rate columns by name (the intent's stable output shape).
agencyCol, rateCol := -1, -1
for i, c := range res.Columns {
switch c {
case "customer_agency":
agencyCol = i
case "win_rate":
rateCol = i
}
}
if agencyCol < 0 || rateCol < 0 {
return decimal.Zero, "", false, fmt.Errorf("ai: feature source %q did not return the expected columns", IntentBidWinRateBySegment)
}
want := strings.ToLower(strings.TrimSpace(agency))
// Match the bound agency segment; when no agency binds, take the first row (the ledger's heaviest segment
// by the intent's ordering) as the overall base rate.
for _, row := range res.Rows {
got := ""
if s, ok := row[agencyCol].(string); ok {
got = strings.ToLower(strings.TrimSpace(s))
}
if want == "" || got == want {
rate, ok := decimalFromCell(row[rateCol])
if !ok {
// A NULL rate (a segment with no decided bids): the feature is absent, imputed at the mean.
return decimal.Zero, segmentBaseRateRationale(agency, decimal.Zero, false), true, nil
}
return rate, segmentBaseRateRationale(agency, rate, true), false, nil
}
}
// No matching segment in the ledger: the feature is absent, imputed at the mean (a learned model rests on
// the base rate, the prior only model returns its intercept base rate).
return decimal.Zero, segmentBaseRateRationale(agency, decimal.Zero, false), true, nil
}
// segmentBaseRateRationale is the human readable rationale for the segment base rate feature, naming the
// segment and whether a decided bid history was found, so the contribution trace (the citations) explains the
// feature honestly to the faithfulness gate. It carries no dash.
func segmentBaseRateRationale(agency string, rate decimal.Decimal, found bool) string {
seg := strings.TrimSpace(agency)
if seg == "" {
seg = "the overall ledger"
}
if !found {
return "the advisory market base rate for " + seg + " has no decided bid history yet, so the feature is zero and the estimate rests on the prior base rate"
}
return "the advisory market base rate for " + seg + " is " + rate.String() + " over the decided bids in the segment"
}
// decimalFromCell coerces a scanned cell into a shopspring/decimal when it is a numeric, returning ok false for
// a NULL (a nil cell) so a NULL rate becomes an honest zero base rate feature rather than an error. It accepts
// the shapes pgx scans a numeric ratio into, never a float64 that would lose precision. On the generic
// ExecuteIntent path (rows.Values()) the app pool registers only the pgvector codecs, not a decimal codec, so a
// numeric column arrives as a pgtype.Numeric; that case is handled exactly via its big.Int coefficient and
// exponent, which is what makes a learned segment_base_rate coefficient actually see the gathered win rate at
// serve time (before this case a numeric cell fell through to ok false and the feature read as zero).
func decimalFromCell(v any) (decimal.Decimal, bool) {
switch n := v.(type) {
case nil:
return decimal.Zero, false
case decimal.Decimal:
return n, true
case *decimal.Decimal:
if n == nil {
return decimal.Zero, false
}
return *n, true
case pgtype.Numeric:
// An invalid (NULL) or non finite numeric is an honest ok false; a finite one is value = Int * 10^Exp.
if !n.Valid || n.NaN || n.InfinityModifier != pgtype.Finite || n.Int == nil {
return decimal.Zero, false
}
return decimal.NewFromBigInt(n.Int, n.Exp), true
case string:
d, err := decimal.NewFromString(n)
if err != nil {
return decimal.Zero, false
}
return d, true
case fmt.Stringer:
d, err := decimal.NewFromString(n.String())
if err != nil {
return decimal.Zero, false
}
return d, true
default:
return decimal.Zero, false
}
}
// answerModelIntent runs a MAG intent and narrates its calibrated probability plus the ordered driver
// contributions behind the faithfulness gate, the structured model path. It mirrors AnswerGraph: it runs the
// EEO and protected attribute guards FIRST on the question and refuses on either, looks the intent up, confirms
// it is ExecutorModel, runs ExecuteModelIntent (which gathers features through the guarded path and scores in
// decimal), builds a DETERMINISTIC rendering of the probability and the contribution trace plus the reliability
// disclosure, and narrates through o.generate and o.finalize over the Trace CITATIONS so the model prose ships
// ONLY when the faithfulness gate confirms it against the contributions, else the deterministic rendering. It
// computes NO per candidate score: the answer is one opportunity level probability. It emits a counts only
// aedt.ai.model_answered audit carrying the route, model_key, version, output_kind, and feature_count, and NO
// value, NO PII, and NO candidate id.
func (o *Orchestrator) answerModelIntent(ctx context.Context, question, intentName string, args []any) (*Response, error) {
if ForbidEEO(question) != nil || MentionsProtectedAttribute(question) {
return o.refuse(ctx, RouteGraph, "the question references prohibited demographic data")
}
intent, ok := IntentByName(intentName)
if !ok {
return nil, fmt.Errorf("%w: %q", ErrUnknownIntent, intentName)
}
if intent.Executor != ExecutorModel {
return nil, fmt.Errorf("ai: %q is not a model backed MAG intent", intentName)
}
result, err := ExecuteModelIntent(ctx, o.db, intent, args)
if err != nil {
return nil, err
}
// The citations are the per feature contributions plus the calibrated probability: the deterministic
// evidence the faithfulness gate grounds the prose against.
citations := modelCitations(result)
deterministic := renderModelAnswer(result)
rendered, _ := json.Marshal(map[string]any{
"output_kind": result.OutputKind,
"probability": result.Value.String(),
"contributions": result.Trace,
"disclosure": winProbabilityReliabilityDisclosure,
})
model, genErr := o.generate(ctx,
"State the opportunity win probability plainly from the model evidence: report the calibrated probability exactly as given, then the ordered driver contributions exactly as the trace gives them, then the reliability disclosure. This is an opportunity level probability, NOT a per candidate match score: never compute or state a candidate score or a band. Do not invent a driver, a coefficient, or a number the trace does not contain.",
"INTENT: "+intent.Description+"\n\nMODEL EVIDENCE:\n"+string(rendered))
resp, aerr := o.finalize(ctx, RouteGraph, model, genErr, deterministic, citations)
if aerr != nil {
return nil, aerr
}
// Counts only audit: the route, the model_key, the version, the output_kind, and the feature count. It
// carries NO probability value, NO agency, NO candidate id, and NO answer text.
if err := o.audit(ctx, "aedt.ai.model_answered", map[string]any{
"route": RouteGraph,
"model_key": result.ModelKey,
"version": result.Version,
"output_kind": result.OutputKind,
"feature_count": len(result.Trace),
}); err != nil {
return nil, err
}
return resp, nil
}
// modelCitations builds the citation strings the faithfulness gate grounds the prose against: one line per
// contribution (the feature, its value, its coefficient, and its additive contribution, all decimal) plus the
// calibrated probability line and the reliability disclosure. No candidate id and no score appears; the trace
// is the additive explanation of an opportunity level probability.
func modelCitations(result *ModelResult) []string {
cites := make([]string, 0, len(result.Trace)+2)
cites = append(cites, "calibrated "+result.OutputKind+" = "+result.Value.String())
for _, c := range result.Trace {
cites = append(cites, fmt.Sprintf("%s: value=%s coefficient=%s contribution=%s (%s)",
c.FeatureName, c.Value.String(), c.Coefficient.String(), c.Contribution.String(), c.Rationale))
}
cites = append(cites, winProbabilityReliabilityDisclosure)
return cites
}
// renderModelAnswer builds the deterministic model answer the MAG path ships when the model prose is withheld:
// the calibrated probability, the ordered driver contributions (the intercept first, then each feature by
// contribution magnitude descending with a name tiebreaker), and the reliability disclosure. Every number is
// the trace's exact decimal, never recomputed; it names no candidate and states no match score.
func renderModelAnswer(result *ModelResult) string {
var b strings.Builder
b.WriteString("Calibrated ")
b.WriteString(result.OutputKind)
b.WriteString(" for the segment: ")
b.WriteString(result.Value.String())
b.WriteString(". Drivers (additive log odds contributions): ")
// Order the drivers deterministically: the intercept first (the base), then the features by absolute
// contribution descending with a feature name tiebreaker, so the strongest driver reads first and the
// order is byte stable.
ordered := make([]Contribution, len(result.Trace))
copy(ordered, result.Trace)
sort.SliceStable(ordered, func(i, j int) bool {
if ordered[i].FeatureName == interceptFeatureName {
return true
}
if ordered[j].FeatureName == interceptFeatureName {
return false
}
ai := ordered[i].Contribution.Abs()
aj := ordered[j].Contribution.Abs()
if !ai.Equal(aj) {
return ai.GreaterThan(aj)
}
return ordered[i].FeatureName < ordered[j].FeatureName
})
parts := make([]string, 0, len(ordered))
for _, c := range ordered {
parts = append(parts, fmt.Sprintf("%s contributes %s (coefficient %s times value %s)",
c.FeatureName, c.Contribution.String(), c.Coefficient.String(), c.Value.String()))
}
b.WriteString(strings.Join(parts, "; "))
b.WriteString(". ")
b.WriteString(winProbabilityReliabilityDisclosure)
return b.String()
}
Mathematical records from this source
010203
mag · log odds
This relation defines log odds in the source section “mag · log odds”. It specifies the displayed relationship between the named quantities or parameters. Its interpretation…
func decimalFromCell(v any) (decimal.Decimal, bool) · An invalid (NULL) or non finite numeric is an honest ok false; a finite one is value
This relation defines An invalid (NULL) or non finite numeric is an honest ok false; a finite one is value in the source section “func decimalFromCell(v any) (decimal.Decimal,…
Linear log-odds score before logistic conversion
The model adds an intercept to the sum of each coefficient times its corresponding feature. Applying a logistic transform converts that log-odds score into a value between zero…