From 536b24be941babb1624488005f468fc1119548a9 Mon Sep 17 00:00:00 2001 From: santoshkumarradha Date: Thu, 17 Sep 2026 20:31:14 -0400 Subject: [PATCH 1/3] crew: pin a bare auto row to the pick word's own catalog answer Co-Authored-By: codeaf --- internal/config/auto_test.go | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/internal/config/auto_test.go b/internal/config/auto_test.go index 0addeb5643..08131c91ab 100644 --- a/internal/config/auto_test.go +++ b/internal/config/auto_test.go @@ -452,6 +452,55 @@ func TestAutoPickWithCarriesThePriorItIsGiven(t *testing.T) { } } +// ── the two seams ─────────────────────────────────────────────────────────── + +// A BARE AUTO ROW AND THE PICK WORD'S OWN SEAT ANSWER ONE CATALOG THE SAME +// WAY. Under `picked from = catalog` both read the catalog's published +// figures alone — the Model Pool's measurements enter neither seat — and +// under `learn` both carry them, on the learned rung. The fixture still +// splits the two answers, asserted rather than assumed, so rows or a prior +// that stop moving the worker pick fail here saying so instead of pinning +// nothing. +func TestABareAutoRowAnswersTheCatalogThePickWordNames(t *testing.T) { + t.Setenv(ModelEnv, "") + t.Setenv(PlanModelEnv, "") + restoreModels, restoreIndex := AutoModels, AutoIndex + defer func() { AutoModels, AutoIndex = restoreModels, restoreIndex }() + AutoModels = func() []catalog.Model { return autoTestRows() } + AutoIndex = func() *index.Index { return mustIndex(t, priorDocument) } + + published, ok := AutoPickWith(ModelTierWorker, DefaultCrewSource, DefaultCrew, autoTestRows(), nil) + if !ok || published == "a/cheap" { + t.Fatalf("the fixture does not split the two answers: the published pick reads %q (ok %t), so the assertions below cannot tell them apart", published, ok) + } + + dir := writeProfileRows(t, map[string]string{ + KeyTierWorkerModel: AutoValue, + KeyCrewPick: CrewPickCatalog, + }) + model, source, preset := autoRow(dir, DefaultCrewSource, ModelTierWorker) + want, _ := pickedModel(ModelTierWorker, DefaultCrewSource, preset, CrewPickCatalog) + if model != want { + t.Fatalf("under picked from = catalog the bare auto row answers %q and the pick word's own seat answers %q — the two seams disagreed about what the catalog means", model, want) + } + if source != SeatComputed { + t.Errorf("under picked from = catalog the bare row's rung reads %q, want computed", source) + } + + dir = writeProfileRows(t, map[string]string{ + KeyTierWorkerModel: AutoValue, + KeyCrewPick: CrewPickLearn, + }) + model, source, preset = autoRow(dir, DefaultCrewSource, ModelTierWorker) + want, _ = pickedModel(ModelTierWorker, DefaultCrewSource, preset, CrewPickLearn) + if model != want || model != "a/cheap" { + t.Errorf("under picked from = learn the bare auto row answers %q and the pick word's own seat answers %q, want the measured pick a/cheap", model, want) + } + if source != SeatLearned { + t.Errorf("under picked from = learn the bare row's rung reads %q, want learned", source) + } +} + // ── the install's own sheet ───────────────────────────────────────────────── // ownCells is the install's own evidence for the prior tests: one cell the From fca3f3bd79cba6ce0f282d1cebee8d251e58b98a Mon Sep 17 00:00:00 2001 From: santoshkumarradha Date: Thu, 17 Sep 2026 20:31:59 -0400 Subject: [PATCH 2/3] crew: a bare auto row under picked from = catalog reads the catalog's figures alone autoRow and pickedModel now decide the prior through one helper, priorFor, so the two seams cannot disagree about what catalog means. AutoPick's only caller was the seam itself; it keeps its always-measured answer for callers beyond this repository and no seat resolves through it. Co-Authored-By: codeaf --- internal/config/auto.go | 48 +++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/internal/config/auto.go b/internal/config/auto.go index 971ec367c7..aae9a9db2c 100644 --- a/internal/config/auto.go +++ b/internal/config/auto.go @@ -65,11 +65,12 @@ var AutoOwnCells func() []crewpick.Cell // crewpick scores a seat on, with one cell per role and model. const PoolQualityMetric = "role_quality" -// AutoPick is the bare `auto` word's own answer for one tier, computed from -// the rows. It is [AutoPickWith] with the measured quality the Model Pool -// holds carried as a prior — the behaviour the bare word has always had — and -// it stays the seam a row that says `auto` resolves through ([autoRow]). The -// pick row's words answer through [AutoPickWith] directly ([pickedSeat]). +// AutoPick is the pick with the measured quality the Model Pool holds ALWAYS +// carried as a prior: [AutoPickWith] with [autoPrior], whatever a profile's +// pick word says. No seat resolves through it any more — the bare `auto` row +// ([autoRow]) and the pick row's words ([pickedModel]) decide the prior +// together in [priorFor] — and it stays for a caller that wants the measured +// computation regardless of the pick word. func AutoPick(tier, family, preset string, models []catalog.Model) (modelID string, ok bool) { return AutoPickWith(tier, family, preset, models, autoPrior(autoIndex())) } @@ -263,14 +264,15 @@ func listHolds(words []string, word string) bool { // never empty. func autoRow(profileDir, family, tier string) (model string, source SeatSource, preset string) { preset = crewPresetUnder(profileDir, family) - // THE RUNG ANSWERS TO THE PICK WORD exactly as a pick-computed seat's does - // ([pickedModel]): the bare word carries the pool's measurements through - // [AutoPick]'s own prior, so a row computed under `learn` is a learned seat - // and says so, while one computed under `catalog` keeps the catalog's rung. - // The decision is shared ([computedRung]) so the two seams cannot name one - // computation two ways. - if id, ok := AutoPick(tier, family, preset, autoCatalogRows()); ok { - return id, computedRung(CrewPickAt(profileDir)), preset + // THE ANSWER IS THE PICK WORD'S OWN ANSWER, computed the way a + // pick-computed seat's is ([pickedModel]): the prior is decided once, in + // [priorFor] — the pool's measurements under `learn`, the published + // figures alone under every other word — so the two seams cannot disagree + // about what `catalog` means, and the rung names the word that ran + // ([computedRung]) so they cannot name one computation two ways either. + pick := CrewPickAt(profileDir) + if id, ok := AutoPickWith(tier, family, preset, autoCatalogRows(), priorFor(pick)); ok { + return id, computedRung(pick), preset } if row, ok := CrewModelsForSource(family, preset); ok { if id := strings.TrimSpace(row[tier]); id != "" { @@ -327,17 +329,27 @@ func pickedSeat(profileDir, family, tier, model string) (Seat, bool) { return Seat{Role: tierSeatRole(tier), Model: id, Source: source, Crew: preset}, true } +// priorFor is the prior a seat computed at the crew's preset carries, read +// from the pick word alone: [autoPrior] under `learn` — the Model Pool's +// measurements and this install's own judged runs — and nil under every other +// word, which leaves each seat on the published figures alone. The bare +// `auto` row ([autoRow]) and the pick word's own seat ([pickedModel]) both +// answer through it, so the two seams cannot disagree again about what +// `catalog` means. +func priorFor(pick string) crewpick.Prior { + if normalCrewPick(pick) == CrewPickLearn { + return autoPrior(autoIndex()) + } + return nil +} + // pickedModel is the pick word's own answer for one tier: the catalog's pick // at the preset, on the rung the word names; and, when nothing can be // computed, the preset's own table row on the table rung — the id a preset // write would have landed, and never `auto` and never empty. func pickedModel(tier, family, preset, pick string) (modelID string, source SeatSource) { pick = normalCrewPick(pick) - var prior crewpick.Prior - if pick == CrewPickLearn { - prior = autoPrior(autoIndex()) - } - if id, ok := AutoPickWith(tier, family, preset, autoCatalogRows(), prior); ok { + if id, ok := AutoPickWith(tier, family, preset, autoCatalogRows(), priorFor(pick)); ok { return id, computedRung(pick) } if row, ok := CrewModelsForSource(family, preset); ok { From 7b7d8a87ddced41b595f50f15db369351254fcc6 Mon Sep 17 00:00:00 2001 From: santoshkumarradha Date: Thu, 17 Sep 2026 20:32:10 -0400 Subject: [PATCH 3/3] changes: a bare auto row under catalog reads the catalog's figures alone Co-Authored-By: codeaf --- ...bare-auto-row-under-catalog-reads-the-catalog-alone.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 docs/changes/unreleased/a-bare-auto-row-under-catalog-reads-the-catalog-alone.md diff --git a/docs/changes/unreleased/a-bare-auto-row-under-catalog-reads-the-catalog-alone.md b/docs/changes/unreleased/a-bare-auto-row-under-catalog-reads-the-catalog-alone.md new file mode 100644 index 0000000000..b603c4bd4a --- /dev/null +++ b/docs/changes/unreleased/a-bare-auto-row-under-catalog-reads-the-catalog-alone.md @@ -0,0 +1,8 @@ +--- +kind: fixed +title: a bare auto row under picked from = catalog reads the catalog's figures alone +surface: [chat, engine] +invalidates: + - "Under `picked from = catalog` a tier row that says `auto` answered with the Model Pool's measurements blended in while its rung said `computed from the catalog`; it now answers the catalog's published figures alone, the same computation the pick word's own seat runs." + - "The prior decision lived in two places — `AutoPick`, which always carried the measurements, and `pickedModel`, which carried them only under `learn`. Both seams now read one helper, `priorFor`, so a bare `auto` row and the pick word's own seat cannot disagree about what `catalog` means again." +---