review: match session models on component boundaries, not substrings · Entire

review: match session models on component boundaries, not substrings

cc48964→main·

dipree·1mo ago·2 files·+62 added/-16 removed

reviewRunModelMatches used bidirectional substring matching on a separator-stripped model id, so a configured "gpt-4" (compacted "gpt4") matched a "gpt-4o-mini" session ("gpt4omini"), mis-attributing sessions to workers in multi-model profiles.

Normalize by collapsing non-alphanumeric runs to "-" (preserving component boundaries) instead of stripping them, then match with boundary-padded containment. Aliases/families still match the resolved session model ("sonnet" -> "claude-sonnet-4-5", "anthropic/claude-sonnet:high" -> "claude-sonnet-4-5") but "gpt-4" no longer matches "gpt-4o-mini". Adds table tests covering the regression and the legitimate matches.

Sessions

bb7a16d230a5View transcript

Changes

2

426 unmodified lines

...
...
...
func reviewRunModelMatches(want, got string) bool {
    want = strings.ToLower(strings.TrimSpace(want))
    got = strings.ToLower(strings.TrimSpace(got))
    want = normalizeReviewModelID(want)
    got = normalizeReviewModelID(got)
    if want == "" || got == "" {
        return true
    }
    if want == got {
        return true
    }
    wantCompact := compactReviewModelID(want)
    gotCompact := compactReviewModelID(got)
    if wantCompact == "" || gotCompact == "" {
        return true
    }
    return strings.Contains(gotCompact, wantCompact) || strings.Contains(wantCompact, gotCompact)
}

// Boundary-aware containment...

// compactReviewModelID normalizes...

func compactReviewModelID(s string) string {
}

func normalizeReviewModelID(s string) string {
}

Mcmd/entire/cli/review/manifest.go+31/-16

745 unmodified lines

...
...
...
func TestReviewRunModelMatches(t *testing.T) {
    t.Parallel()
    cases := []struct {
        name string
        want string
        got  string
        ok   bool
    }{
        {"exact", "gpt-4", "gpt-4", true},
        {"empty want matches anything", "", "claude-sonnet-4-5", true},
        {"empty got matches anything", "sonnet", "", true},
        ...
    }
    for _, c := range cases {
        t.Run(c.name, func(t *testing.T) {
            t.Parallel()
            if got := reviewRunModelMatches(c.want, c.got); got != c.ok {
                t.Errorf("reviewRunModelMatches(%q, %q) = %v, want %v", c.want, c.got, got, c.ok)
            }
        })
    }
}

Mcmd/entire/cli/review/manifest_test.go+31