the ring reads out over ipc as turn decisions (V-564)

Same shape as TickTrace and RecentEvents: a bounded daemon ring, so the store
adapter refuses rather than pretending a table exists. No voice wiring means an
empty list and not an error, because a box with no voice path has had no turns
to arbitrate.
This commit is contained in:
2026-08-06 00:52:48 +04:00
parent 3e6a427e85
commit a5b245dbf5
9 changed files with 70 additions and 0 deletions
+2
View File
@@ -350,6 +350,7 @@ func run(args []string) error {
getMorningStatus: func(ctx context.Context) []ipc.MorningRoutineStatus { return tl.morningStatus(ctx, time.Now()) },
getDayPlan: func(ctx context.Context) ipc.DayPlan { return tl.dayPlan(ctx, time.Now()) },
getEvents: intakeEventsFn(evBus),
getDecisions: turnDecisionsFn(voiceW),
seedStore: seedStoreIfAllowed(st),
nexus: nexusOf(voiceW),
}
@@ -619,6 +620,7 @@ func run(args []string) error {
getMorningStatus: func(ctx context.Context) []ipc.MorningRoutineStatus { return tl.morningStatus(ctx, time.Now()) },
getDayPlan: func(ctx context.Context) ipc.DayPlan { return tl.dayPlan(ctx, time.Now()) },
getEvents: intakeEventsFn(evBus),
getDecisions: turnDecisionsFn(voiceW),
seedStore: seedStoreIfAllowed(st),
}
if voiceW != nil && voiceW.handler != nil {
+12
View File
@@ -23,6 +23,7 @@ type daemonAPI struct {
chatFn func(ctx context.Context, conversation, text string) string
getMCPServers func() []ipc.MCPServerStatus
getEvents func(n int) []ipc.IntakeEvent
getDecisions func(n int) []ipc.TurnDecision
// nexus — the identity client, nil when no nexus block is configured. It
// is what makes ResolveEntity answerable at all; without it the store
// adapter's refusal stands, and a surface that wanted an entity id says so
@@ -118,6 +119,17 @@ func (d *daemonAPI) TickTrace(ctx context.Context) (ipc.TickTrace, error) {
return toIPCTickTrace(*trace), nil
}
// TurnDecisions — the arbitration records of the last few turns (V-564). Nil
// getter means voice was never wired, and that is an empty list rather than an
// error: a box with no voice path has had no turns to arbitrate, which is not a
// fault and renders as an empty table.
func (d *daemonAPI) TurnDecisions(ctx context.Context, n int) ([]ipc.TurnDecision, error) {
if d.getDecisions == nil {
return nil, nil
}
return d.getDecisions(n), nil
}
func (d *daemonAPI) MorningStatus(ctx context.Context) ([]ipc.MorningRoutineStatus, error) {
if d.getMorningStatus == nil {
return nil, errors.New("mavend: morning status not available")