diff --git a/docs/superpowers/specs/2026-06-01-m7-reflection-design.md b/docs/superpowers/specs/2026-06-01-m7-reflection-design.md index 5a50f28..d74ab44 100644 --- a/docs/superpowers/specs/2026-06-01-m7-reflection-design.md +++ b/docs/superpowers/specs/2026-06-01-m7-reflection-design.md @@ -119,8 +119,7 @@ type ReflectionView struct { } ``` -- On **Review**, the view carries `Status` + `Recap` (and the `CarryForward` - preview). +- On **Review**, the view carries `Status` + `Recap`. - On **Planning**, the view carries the `CarryForward` line. Unlike the M6 *profile* (large and private, deliberately kept off the wire), the diff --git a/internal/session/session_test.go b/internal/session/session_test.go index 779288c..7755d69 100644 --- a/internal/session/session_test.go +++ b/internal/session/session_test.go @@ -1076,12 +1076,16 @@ func driveToReview(t *testing.T, c *Controller) { func TestReflectionFetchedOnReview(t *testing.T) { c, _ := newTestController(t) - c.SetReviewer(&fakeReviewer{refl: ai.Reflection{Recap: "held focus", CarryForward: "start in the editor"}}) + rev := &fakeReviewer{refl: ai.Reflection{Recap: "held focus", CarryForward: "start in the editor"}} + c.SetReviewer(rev) driveToReview(t, c) st := waitReflectionStatus(t, c, "ready") if st.Reflection.Recap != "held focus" { t.Fatalf("recap not projected on Review: %+v", st.Reflection) } + if n := atomic.LoadInt32(&rev.calls); n != 1 { + t.Fatalf("reviewer should be called exactly once per session, got %d", n) + } } func TestNoReviewerYieldsIdleReflection(t *testing.T) {