Assert the reviewer fires exactly once per session

Closes the one coverage gap from the final review: the spec's
'one async call per session' efficiency claim is now directly
verified via the reviewer call count, not just implied. Also drops a
stale CarryForward-preview mention from the Review projection in the
design spec to match the shipped (cleaner) behaviour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-01 09:47:27 -04:00
parent 95e14e6340
commit e3cfe8c70c
2 changed files with 6 additions and 3 deletions
@@ -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
+5 -1
View File
@@ -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) {