diff --git a/internal/session/roles.go b/internal/session/roles.go index 8e588fb..e639ae1 100644 --- a/internal/session/roles.go +++ b/internal/session/roles.go @@ -181,37 +181,31 @@ func (c *Controller) startKnowledgeFetchLocked() { c.knowledgeStatus = knowledgePending src := c.knowledgeSrc path := c.knowledgePath - go func() { - ctx, cancel := context.WithTimeout(context.Background(), knowledgeTimeout) - defer cancel() - prof, err := src.Load(ctx, path) - - c.mu.Lock() - if gen != c.knowledgeGen || c.runtimeState != domain.RuntimePlanning { - c.mu.Unlock() - return // stale or left planning: discard - } - if err != nil { - c.knowledgeStatus = knowledgeError - c.knowledgeText = "" - c.knowledgeChars = 0 - if prof.Path != "" { + var prof knowledge.Profile + var err error + c.runFetchAsync(knowledgeTimeout, + func(ctx context.Context) { prof, err = src.Load(ctx, path) }, + func() bool { return gen != c.knowledgeGen || c.runtimeState != domain.RuntimePlanning }, + func() { + if err != nil { + c.knowledgeStatus = knowledgeError + c.knowledgeText = "" + c.knowledgeChars = 0 + if prof.Path != "" { + c.knowledgePath = prof.Path + } + } else if prof.Text == "" { + c.knowledgeStatus = knowledgeAbsent + c.knowledgeText = "" + c.knowledgeChars = 0 + c.knowledgePath = prof.Path + } else { + c.knowledgeStatus = knowledgeReady + c.knowledgeText = prof.Text + c.knowledgeChars = len(prof.Text) c.knowledgePath = prof.Path } - } else if prof.Text == "" { - c.knowledgeStatus = knowledgeAbsent - c.knowledgeText = "" - c.knowledgeChars = 0 - c.knowledgePath = prof.Path - } else { - c.knowledgeStatus = knowledgeReady - c.knowledgeText = prof.Text - c.knowledgeChars = len(prof.Text) - c.knowledgePath = prof.Path - } - c.mu.Unlock() - c.notify() - }() + }) } // SetReviewer injects the AI reviewer. A nil reviewer keeps reflection idle and