Title Supply runs in a job, scoped by their dinner names
archive_title's single-flight scope was <weekStart>@<plan revision>, but
renaming a planned dinner changes the names to title without changing
the plan revision, so two overlapping generations across a rename could
share one model result. The scope is now
<weekStart>@<plan revision>/<sha256 of the ordered dinner names>, the
same list the skill is given, through the harness's own guard.
Push to Calendar and POST /shopping/{weekStart}/generate also waited
for the title call. Generation now enqueues a title_supply_run job
(service-only, in the generation's transaction) for a list still
untitled and returns without waiting; the list reads untitled until the
job stores its title. A failed title still leaves the list untitled, is
logged, recorded in ai_runs, fails the job title_failed, and is retried
by the week's next generation. A titled list enqueues no job.
Maestro task fa4b94c9-6623-41ab-8d2a-0ca7d1e6401a.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ type plansEnv struct {
|
||||
h http.Handler
|
||||
st *store.Store
|
||||
svc *plan.Service
|
||||
runner *jobs.Runner
|
||||
questLog string
|
||||
// google is the fake Google the plan service pushes to; it starts
|
||||
// unconnected.
|
||||
@@ -47,6 +48,13 @@ type plansEnv struct {
|
||||
}
|
||||
|
||||
func newPlansRouter(t *testing.T) plansEnv {
|
||||
t.Helper()
|
||||
return newPlansRouterTitled(t, untitled)
|
||||
}
|
||||
|
||||
// newPlansRouterTitled is newPlansRouter whose Supply runs are titled by
|
||||
// title.
|
||||
func newPlansRouterTitled(t *testing.T, title shopping.Titler) plansEnv {
|
||||
t.Helper()
|
||||
st := newTestStore(t)
|
||||
ctx := t.Context()
|
||||
@@ -80,7 +88,7 @@ func newPlansRouter(t *testing.T) plansEnv {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
shop, err := shopping.NewService(st, untitled, logger)
|
||||
shop, err := shopping.NewService(st, title, runner, logger)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -119,7 +127,7 @@ func newPlansRouter(t *testing.T) plansEnv {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
return plansEnv{h: h, st: st, svc: svc, questLog: dinner("Pad Thai", "quest_log", "stovetop", 35),
|
||||
return plansEnv{h: h, st: st, svc: svc, runner: runner, questLog: dinner("Pad Thai", "quest_log", "stovetop", 35),
|
||||
google: google, gcal: googleSvc, logs: logs}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user