Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/integration/mag_win_probability_integration_test.go |
| Original SHA-256 | 596b4a5efd483b2f6871b25ace7548b2a725df6d9e21e68c5d002bf4f22638dc |
| Git blob SHA | 8af0ca65e7c7210cc2b9d58c382fb1f227f2bab7 |
| Reading-copy SHA-256 | 596b4a5efd483b2f6871b25ace7548b2a725df6d9e21e68c5d002bf4f22638dc |
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/integration/mag_win_probability_integration_test.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / internal/integration/mag_win_probability_integration_test.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓252 lines · 12.3 KB
//go:build integration
// MAG (Model Augmented Generation) win probability integration. Proves at runtime against a REAL Postgres and
// the migrated 0036 coefficient store what the unit tests cannot: the first model backed intent on the closed
// Registry gathers its feature (the advisory bid_win_rate_by_segment base rate) through the guarded
// ExecuteIntent path RLS scoped, loads the prior only v0 champion coefficients from aedt_learned_models, scores
// a CALIBRATED probability in shopspring/decimal, narrates the ordered driver contributions and the prior only
// reliability disclosure through the deterministic fallback (a nil inference client), computes NO candidate
// score, and emits a counts only aedt.ai.model_answered audit carrying model_key, version, output_kind, and
// feature_count and NO value or PII. It also proves the raw ExecuteIntent path rejects the model intent.
//
// Run: go test -tags=integration ./internal/integration/ -run MAGWinProbability -v
// Env: MM_APP_DSN, MM_MIGRATOR_DSN (required). The orchestrator applies migration 0036 (goose v36) first.
package integration
import (
"context"
"strings"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/missionworkforce/missionmatch/internal/modules/ai"
"github.com/missionworkforce/missionmatch/internal/modules/bidoutcomes"
"github.com/missionworkforce/missionmatch/internal/platform/audit"
)
// TestMAGWinProbabilityPriorOnlyReturnsCalibratedBaseRate seeds a segment with decided bid outcomes so the
// advisory base rate is defined, then runs the win probability MAG intent through the orchestrator with a nil
// inference client (so the answer is the deterministic rendering). It asserts the answer carries a calibrated
// probability in [0, 1] near the seeded base rate (prior only, betas zero, so the number is the shrunk market
// base rate), the ordered driver contributions, the prior only reliability disclosure, and NO candidate score,
// and that the audit holds model_key, version, output_kind, and feature_count and NO value or PII.
func TestMAGWinProbabilityPriorOnlyReturnsCalibratedBaseRate(t *testing.T) {
org := seedOrg(t)
run := uuid.NewString()[:8]
agency := "DEPT OF THE NAVY " + run // unique per run so the segment is isolated
// Seed a segment with decided bid outcomes so the base rate is defined: two wins and one loss for the
// agency, so the advisory win rate is 2/3. The prior only v0 model returns the calibrated intercept base
// rate (0.60) regardless, because every learned coefficient is zero; the base rate is the FEATURE, which
// the trace surfaces as a driver.
req := seedRequirementWithAgency(t, org, agency)
svc := bidoutcomes.NewService(appDB, nil)
recordOutcome(t, svc, org, req, bidoutcomes.ResultWin)
recordOutcome(t, svc, org, req, bidoutcomes.ResultWin)
recordOutcome(t, svc, org, req, bidoutcomes.ResultLoss)
orch := ai.NewOrchestrator(appDB, nil, audit.New(appDB))
resp, err := orch.Answer(ctxOrg(org), "", ai.IntentOpportunityWinProbability, []any{agency, ""})
if err != nil {
t.Fatalf("win probability answer: %v", err)
}
// (a) The answer is on the graph route and is not refused for an authenticated tenant.
if resp.Refused {
t.Fatalf("an authenticated win probability question must not be refused, got %+v", resp)
}
if resp.Route != ai.RouteGraph {
t.Errorf("the model intent must dispatch to the graph route, got %q", resp.Route)
}
// (b) The answer carries a calibrated opportunity_score probability near the seeded base rate. Prior only
// v0: the intercept is logit(0.60), betas zero, so the calibrated probability is near 0.60. The answer
// names it as an opportunity_score, never a candidate score.
if !strings.Contains(resp.Answer, "opportunity_score") {
t.Errorf("the answer must name the opportunity_score output kind, got %q", resp.Answer)
}
if !strings.Contains(resp.Answer, "0.6") {
t.Errorf("the prior only calibrated probability must be near 0.60, got %q", resp.Answer)
}
// (c) The ordered driver contributions are present: the intercept (the base) and the segment base rate
// feature.
if !strings.Contains(resp.Answer, "intercept contributes") {
t.Errorf("the answer must carry the ordered intercept driver contribution, got %q", resp.Answer)
}
if !strings.Contains(resp.Answer, "segment_base_rate contributes") {
t.Errorf("the answer must carry the ordered segment base rate driver contribution, got %q", resp.Answer)
}
// (d) The prior only reliability disclosure is present.
if !strings.Contains(resp.Answer, "prior only estimate") {
t.Errorf("the answer must carry the prior only reliability disclosure, got %q", resp.Answer)
}
// (e) The frozen engine path is untouched: no per candidate score, no band, no total_score, and the
// disclosure explicitly names that this is not a per candidate match score.
if !strings.Contains(strings.ToLower(resp.Answer), "not a per candidate match score") {
t.Errorf("the answer must disclose it is not a per candidate match score, got %q", resp.Answer)
}
for _, scoreWord := range []string{"total_score", "band=", "candidatescore", "scorecandidate"} {
if strings.Contains(strings.ToLower(resp.Answer), scoreWord) {
t.Errorf("the win probability answer must report no engine score, leaked %q in %q", scoreWord, resp.Answer)
}
}
// (f) The counts only audit holds model_key, version, output_kind, and feature_count and NO value or PII.
var payloads []string
if err := appDB.RunInTenantTx(ctxOrg(org), func(ctx context.Context, tx pgx.Tx) error {
rows, qerr := tx.Query(ctx,
"SELECT new_values::text FROM audit_logs WHERE organization_id=$1 AND action='aedt.ai.model_answered'", org)
if qerr != nil {
return qerr
}
defer rows.Close()
for rows.Next() {
var p string
if serr := rows.Scan(&p); serr != nil {
return serr
}
payloads = append(payloads, p)
}
return rows.Err()
}); err != nil {
t.Fatalf("read model audit: %v", err)
}
if len(payloads) == 0 {
t.Fatal("a win probability answer must emit an aedt.ai.model_answered audit event")
}
for _, p := range payloads {
if !strings.Contains(p, ai.WinProbabilityModelKey) {
t.Errorf("the model audit must record the model_key, got %q", p)
}
for _, want := range []string{"version", "output_kind", "feature_count", "opportunity_score"} {
if !strings.Contains(p, want) {
t.Errorf("the model audit must record %q, got %q", want, p)
}
}
// NO probability value, NO agency, NO answer text, NO candidate id in the audit payload. The word
// probability legitimately appears inside the model_key opportunity_win_probability, so the leak check
// looks for a decimal value (a probability renders as 0.xxx) and for answer or candidate references,
// not the bare word.
if strings.Contains(p, agency) {
t.Errorf("the model audit must hold no agency, leaked it in %q", p)
}
for _, leak := range []string{"0.", "answer", "candidate"} {
if strings.Contains(p, leak) {
t.Errorf("the model audit must hold no value, answer text, or candidate id, leaked %q in %q", leak, p)
}
}
}
}
// TestMAGWinProbabilityNoBidHistoryStillReturnsPrior proves the prior only floor holds honestly when a segment
// has NO decided bid history: the feature is a zero base rate, but the model still returns the calibrated
// intercept base rate (near 0.60), because the prior is the intercept, not the feature. The answer states the
// no history rationale honestly.
func TestMAGWinProbabilityNoBidHistoryStillReturnsPrior(t *testing.T) {
org := seedOrg(t)
agency := "AGENCY WITH NO BIDS " + uuid.NewString()[:8]
orch := ai.NewOrchestrator(appDB, nil, audit.New(appDB))
resp, err := orch.Answer(ctxOrg(org), "", ai.IntentOpportunityWinProbability, []any{agency, ""})
if err != nil {
t.Fatalf("win probability answer: %v", err)
}
if resp.Refused || resp.Route != ai.RouteGraph {
t.Fatalf("a bound tenant win probability question must answer on the graph route, got %+v", resp)
}
// The prior only base rate is still returned near 0.60 (the intercept), even with a zero base rate feature.
if !strings.Contains(resp.Answer, "0.6") {
t.Errorf("with no bid history the prior only base rate must still be near 0.60, got %q", resp.Answer)
}
// The feature rationale states the no history honestly (via the segment base rate driver line and the
// disclosure). The segment base rate driver contributes zero (coefficient zero), so it is present but zero.
if !strings.Contains(resp.Answer, "segment_base_rate contributes 0") {
t.Errorf("the segment base rate driver must contribute zero with a zero coefficient, got %q", resp.Answer)
}
}
// TestMAGWinProbabilityRejectsRawIntentPath proves the defense in depth guard: the generic ExecuteIntent (the
// raw path that returns database rows verbatim) hard rejects the win probability model intent, so a model
// intent can never run as raw SQL even if a future caller tried it.
func TestMAGWinProbabilityRejectsRawIntentPath(t *testing.T) {
intent, ok := ai.IntentByName(ai.IntentOpportunityWinProbability)
if !ok {
t.Fatalf("the win probability intent %q must be registered", ai.IntentOpportunityWinProbability)
}
_, err := ai.ExecuteIntent(ctxOrg(seedOrg(t)), appDB, intent, []any{"agency", "naics"})
if err == nil {
t.Fatal("ExecuteIntent must reject the win probability model intent on the raw path, got nil error")
}
if !strings.Contains(err.Error(), "ExecuteModelIntent") {
t.Errorf("the raw path rejection of a model intent must name ExecuteModelIntent, got %v", err)
}
}
// TestMAGWinProbabilityNaturalLanguageRoute proves the conservative classifier binds a quoted agency for a
// win probability question and routes it to the model intent, returning the calibrated probability. It uses a
// nil inference client so the answer is deterministic.
func TestMAGWinProbabilityNaturalLanguageRoute(t *testing.T) {
org := seedOrg(t)
run := uuid.NewString()[:8]
agency := "DEPT OF THE ARMY " + run
req := seedRequirementWithAgency(t, org, agency)
svc := bidoutcomes.NewService(appDB, nil)
recordOutcome(t, svc, org, req, bidoutcomes.ResultWin)
recordOutcome(t, svc, org, req, bidoutcomes.ResultLoss)
orch := ai.NewOrchestrator(appDB, nil, audit.New(appDB))
// A free form win probability question that quotes the agency: the classifier binds it and routes to the
// model intent (no explicit intent name).
question := "what is the win probability for \"" + agency + "\""
resp, err := orch.Answer(ctxOrg(org), question, "", nil)
if err != nil {
t.Fatalf("natural language win probability answer: %v", err)
}
if resp.Refused {
t.Fatalf("the natural language win probability question must not be refused, got %+v", resp)
}
if resp.Route != ai.RouteGraph {
t.Errorf("the classified win probability question must dispatch to the graph route, got %q", resp.Route)
}
if !strings.Contains(resp.Answer, "opportunity_score") || !strings.Contains(resp.Answer, "0.6") {
t.Errorf("the classified answer must carry the calibrated opportunity_score near 0.60, got %q", resp.Answer)
}
}
// verifyChampionSeeded is a small guard that the migrator applied the 0036 seed: exactly one champion row for
// the win probability model, with the opportunity_score output kind and the intercept and segment base rate
// coefficients. It reads through the migrator so it sees the global reference tables directly.
func verifyChampionSeeded(t *testing.T) {
t.Helper()
var version int
var outputKind string
if err := migrator.QueryRow(context.Background(),
`SELECT version, output_kind FROM aedt_learned_models WHERE model_key = $1 AND champion = true`,
ai.WinProbabilityModelKey).Scan(&version, &outputKind); err != nil {
t.Fatalf("the 0036 champion seed must be present: %v", err)
}
if outputKind != "opportunity_score" {
t.Errorf("the seeded champion output kind must be opportunity_score, got %q", outputKind)
}
var nCoef int
if err := migrator.QueryRow(context.Background(),
`SELECT count(*) FROM aedt_model_coefficients WHERE model_key = $1 AND version = $2`,
ai.WinProbabilityModelKey, version).Scan(&nCoef); err != nil {
t.Fatalf("read seeded coefficients: %v", err)
}
if nCoef < 2 {
t.Errorf("the seed must carry the intercept and the segment base rate coefficient, got %d rows", nCoef)
}
}
// TestMAGChampionSeeded is the seed guard, run standalone so a missing 0036 seed fails fast with a clear
// message rather than surfacing as a no champion error deep in a serving test.
func TestMAGChampionSeeded(t *testing.T) {
verifyChampionSeeded(t)
}