M1: broadcast focus updates, expiry uses Expire outcome
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+5
-3
@@ -31,7 +31,9 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(ctrl *session.Controller) *Server {
|
func NewServer(ctrl *session.Controller) *Server {
|
||||||
return &Server{ctrl: ctrl, bcast: NewBroadcaster()}
|
s := &Server{ctrl: ctrl, bcast: NewBroadcaster()}
|
||||||
|
ctrl.SetOnChange(s.broadcast)
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Router() *gin.Engine {
|
func (s *Server) Router() *gin.Engine {
|
||||||
@@ -154,7 +156,7 @@ func (s *Server) armExpiry() {
|
|||||||
d = 0
|
d = 0
|
||||||
}
|
}
|
||||||
s.timer = time.AfterFunc(d, func() {
|
s.timer = time.AfterFunc(d, func() {
|
||||||
if err := s.ctrl.Complete(); err == nil {
|
if err := s.ctrl.Expire(); err == nil {
|
||||||
s.broadcast()
|
s.broadcast()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -179,7 +181,7 @@ func (s *Server) Init() {
|
|||||||
s.armExpiry()
|
s.armExpiry()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := s.ctrl.Complete(); err == nil {
|
if err := s.ctrl.Expire(); err == nil {
|
||||||
s.broadcast()
|
s.broadcast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"antidrift/internal/domain"
|
"antidrift/internal/domain"
|
||||||
|
"antidrift/internal/evidence"
|
||||||
"antidrift/internal/session"
|
"antidrift/internal/session"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -69,3 +70,31 @@ func TestIllegalTransitionReturns409(t *testing.T) {
|
|||||||
t.Fatalf("expected 409, got %d", w.Code)
|
t.Fatalf("expected 409, got %d", w.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestActiveStatePayloadCarriesEvidence(t *testing.T) {
|
||||||
|
s := newTestServer(t)
|
||||||
|
r := s.Router()
|
||||||
|
_ = post(t, r, "/planning", "")
|
||||||
|
body := `{"next_action":"Build web","success_condition":"web tests pass","timebox_secs":1500}`
|
||||||
|
if w := post(t, r, "/commitment", body); w.Code != http.StatusOK {
|
||||||
|
t.Fatalf("/commitment code %d body %s", w.Code, w.Body.String())
|
||||||
|
}
|
||||||
|
// A focus update should appear in the serialized state.
|
||||||
|
s.ctrl.RecordWindow(evidence.WindowSnapshot{Class: "code", Title: "antidrift", Health: evidence.EvidenceHealth{Available: true}})
|
||||||
|
|
||||||
|
js := s.stateJSON()
|
||||||
|
if !strings.Contains(js, `"evidence"`) {
|
||||||
|
t.Fatalf("payload missing evidence object: %s", js)
|
||||||
|
}
|
||||||
|
if !strings.Contains(js, `"class":"code"`) {
|
||||||
|
t.Fatalf("payload missing current window: %s", js)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLockedStateHasNullEvidence(t *testing.T) {
|
||||||
|
s := newTestServer(t)
|
||||||
|
js := s.stateJSON()
|
||||||
|
if !strings.Contains(js, `"evidence":null`) {
|
||||||
|
t.Fatalf("locked payload should have null evidence: %s", js)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user