# review: match session models on component boundaries, not substrings

`cc48964`→[main](/content/gh/entireio/cli/commits/main/index.html)·

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

- cmd/entire/cli/review

- Mmanifest.go+31/-16

- Mmanifest_test.go+31

```
426 unmodified lines

...
...
...
```

```go
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

...
...
...
```

```go
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
