mavend: group the recall fields into one wiring struct (V-433)

The review comment asked for basic DI. The answer is the idiom voice.go
already had for capabilities — a cohesive *Wiring struct — applied to a
group that is not a capability toggle, plus the decision written down so
it is a rule and not a habit.

recallWiring holds the embedder, the vector store, the personal boundary
and the two numbers that gate an answer. They sat in three places on
reactiveHandler, with the gate numbers a hundred lines from the store
they gate. Its zero value means no recall, so it is a value, not a
pointer like the optional-capability groups.

dataStore stays out of it. patterns.go, ecosystem_acts.go and confirm.go
use it, so it is not part of this cluster.

docs/handler-wiring.md records the choice, rejects a container or a
wire-style generator outright, defers narrow per-handler interfaces to
the package split that would justify them, and states the constraint the
task named: a wiring change does not ride a feature PR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 05:57:24 +04:00
parent 246db4e609
commit ed491e23fc
15 changed files with 173 additions and 84 deletions
+2 -4
View File
@@ -26,11 +26,10 @@ func TestReactiveNotesReminders(t *testing.T) {
h := &reactiveHandler{
api: api,
embedder: emb,
recall: recallWiring{embedder: emb, memStore: memory.NewInMemoryStore()},
router: rtr,
replier: voice.NewStubReplier(),
now: func() time.Time { return now },
memStore: memory.NewInMemoryStore(),
dataStore: st,
}
@@ -101,11 +100,10 @@ func TestSpokenTaskCaptureFilesATask(t *testing.T) {
matcher := tool.NewMatcher(api)
h := &reactiveHandler{
api: api,
embedder: emb,
recall: recallWiring{embedder: emb, memStore: memory.NewInMemoryStore()},
router: buildRouter(emb, matcher, 0.55, nil),
replier: voice.NewStubReplier(),
now: func() time.Time { return now },
memStore: memory.NewInMemoryStore(),
dataStore: st,
}