archive_title skill: title Supply runs on generation (Feature 17) #134

Member

Task

Maestro task fa4b94c9-6623-41ab-8d2a-0ca7d1e6401a — "archive_title skill" (Feature 17, task 3 of 7).

Done-condition

internal/ai/skills implements archive_title v1: input is the week's dinner names in day order, output {title}; validators require 1–48 characters, no emoji, no surrounding quotes. It runs when a list is first generated and stores shopping_lists.title; if it fails, the list is still created with title null and the UI shows the week label instead, and the title is retried on the next generation (title failure never blocks the list). Golden tests with the Fake provider cover a valid title, a too-long title repaired, an emoji rejected, and the failure path leaving the list intact.

Scope

The skill and its wiring into generation. No freeze/archive API (7ac36526), no UI.

Points for review

  • The skill follows the existing pattern (Skill interface, harness Run with its one repair turn, embedded prompt template plus checksums file, golden tests under testdata): confirm no second way to declare a skill and that the validators reject empty, over-48, emoji and quote-wrapped titles through the repair turn rather than by silent truncation.
  • The failure path: a title failure leaves the list created with title null, logs a warning, records the failure in ai_runs, and never blocks the list — and nothing fabricates a title.
  • The retry semantics, which the developer had to define: after its transaction commits, every Generate/GeneratePushed checks whether the stored list is still untitled and titles it if so; the store is conditional (title IS NULL AND status='current' AND frozen_at IS NULL), so a titled list is never re-titled (even after a swap) and two concurrent generations cannot overwrite each other. Confirm that is airtight and that a title is written exactly once.
  • Two things the developer flagged as hand-offs, which deserve your judgement:
    1. The title call is synchronous, so POST /shopping/{weekStart}/generate and the Push to Calendar response now wait for it, bounded by the harness's 60-second default timeout. Judge whether adding up to a minute to the push response is acceptable, or whether it needs to be decoupled/asynchronous.
    2. An untitled list that is frozen into the Supply archive stays untitled forever (generating a frozen list returns ErrFrozen), and the developer suggests task 7ac36526 may want to decide whether to title at freeze time. Say whether that is acceptable or should be recorded for that task.
  • The title call runs outside the transaction, with the harness scope <weekStart>@<plan revision>; confirm it never holds the database writer and that the scope is the right single-flight key.
  • cmd/server/main.go wiring, the shopping.NewService signature change and the updated internal/server/*_test.go call sites: confirm nothing reviewed regressed and no assertion was weakened.
  • No new dependency; no migration; the new SetShoppingListTitle query committed and not hand-edited; no web change.
  • Test adequacy (the developer reports mutations each caught, including titling off and re-titling every generation), maintainability, error handling.

Evidence (orchestrator-run gate at fdfd0123fb)

  • gofmt -l . — empty; go vet ./... — clean
  • go test -race -count=1 ./... — 27 packages ok, 0 failures (skills 26.6s, shopping 9.5s, server 215.9s)
  • CGO_ENABLED=0 go build ./... — ok
  • make sqlc-check SQLC=$(go env GOPATH)/bin/sqlc — no drift
  • cd web && npm run typecheck && npm test && npm run build — PASS (no web change)

Implementation commit: fdfd0123fb12d7cc95ca3a65131dafdf438ec13f

## Task Maestro task `fa4b94c9-6623-41ab-8d2a-0ca7d1e6401a` — "archive_title skill" (Feature 17, task 3 of 7). ## Done-condition `internal/ai/skills` implements `archive_title` v1: input is the week's dinner names in day order, output `{title}`; validators require 1–48 characters, no emoji, no surrounding quotes. It runs when a list is first generated and stores `shopping_lists.title`; if it fails, the list is still created with `title` null and the UI shows the week label instead, and the title is retried on the next generation (title failure never blocks the list). Golden tests with the Fake provider cover a valid title, a too-long title repaired, an emoji rejected, and the failure path leaving the list intact. ## Scope The skill and its wiring into generation. No freeze/archive API (`7ac36526`), no UI. ## Points for review - The skill follows the existing pattern (Skill interface, harness `Run` with its one repair turn, embedded prompt template plus checksums file, golden tests under `testdata`): confirm no second way to declare a skill and that the validators reject empty, over-48, emoji and quote-wrapped titles through the repair turn rather than by silent truncation. - The failure path: a title failure leaves the list created with `title` null, logs a warning, records the failure in `ai_runs`, and never blocks the list — and nothing fabricates a title. - **The retry semantics**, which the developer had to define: after its transaction commits, every `Generate`/`GeneratePushed` checks whether the stored list is still untitled and titles it if so; the store is conditional (`title IS NULL AND status='current' AND frozen_at IS NULL`), so a titled list is never re-titled (even after a swap) and two concurrent generations cannot overwrite each other. Confirm that is airtight and that a title is written exactly once. - **Two things the developer flagged as hand-offs, which deserve your judgement:** 1. **The title call is synchronous**, so `POST /shopping/{weekStart}/generate` **and the Push to Calendar response** now wait for it, bounded by the harness's 60-second default timeout. Judge whether adding up to a minute to the push response is acceptable, or whether it needs to be decoupled/asynchronous. 2. An **untitled list that is frozen** into the Supply archive stays untitled forever (generating a frozen list returns `ErrFrozen`), and the developer suggests task `7ac36526` may want to decide whether to title at freeze time. Say whether that is acceptable or should be recorded for that task. - The title call runs outside the transaction, with the harness scope `<weekStart>@<plan revision>`; confirm it never holds the database writer and that the scope is the right single-flight key. - `cmd/server/main.go` wiring, the `shopping.NewService` signature change and the updated `internal/server/*_test.go` call sites: confirm nothing reviewed regressed and no assertion was weakened. - No new dependency; no migration; the new `SetShoppingListTitle` query committed and not hand-edited; no web change. - Test adequacy (the developer reports mutations each caught, including titling off and re-titling every generation), maintainability, error handling. ## Evidence (orchestrator-run gate at fdfd0123fb12d7cc95ca3a65131dafdf438ec13f) - `gofmt -l .` — empty; `go vet ./...` — clean - `go test -race -count=1 ./...` — 27 packages ok, 0 failures (skills 26.6s, shopping 9.5s, server 215.9s) - `CGO_ENABLED=0 go build ./...` — ok - `make sqlc-check SQLC=$(go env GOPATH)/bin/sqlc` — no drift - `cd web && npm run typecheck && npm test && npm run build` — PASS (no web change) Implementation commit: `fdfd0123fb12d7cc95ca3a65131dafdf438ec13f`
orchestrator-agent added 1 commit 2026-10-08 05:47:10 -04:00
Add the archive_title skill and title Supply runs on generation
CI / ci (pull_request) Successful in 4m53s
CI / ci (push) Successful in 4m48s
fdfd0123fb
archive_title v1 writes a Supply run's post title for the Supply archive
from the week's dinner names in day order. Validation requires 1-48
characters on one line, no emoji and no surrounding quotation marks; a
reply breaking a rule gets the harness's one repair turn.

shopping.Generate and GeneratePushed run it, outside the generation's
transaction, whenever the stored list is still untitled, and store
shopping_lists.title only while the list is untitled and not frozen. A
title failure never fails the generation: the list stays untitled, the
failure is logged and recorded in ai_runs, and the week's next
generation tries again. A titled list keeps its title on remakes.

Maestro task fa4b94c9-6623-41ab-8d2a-0ca7d1e6401a.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-08 05:50:18 -04:00
Dismissed
review_agent left a comment
Member

Independent Codex gpt-6-sol review: CHANGES_REQUIRED for this exact commit.

Independent Codex gpt-6-sol review: CHANGES_REQUIRED for this exact commit.
overseer added 1 commit 2026-10-08 06:23:18 -04:00
Title Supply runs in a job, scoped by their dinner names
CI / ci (push) Successful in 4m52s
CI / ci (pull_request) Successful in 4m55s
1d19fb9545
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>
review_agent left a comment
Member

Independent Codex gpt-6-sol review: APPROVED for this exact commit.

Independent Codex gpt-6-sol review: APPROVED for this exact commit.
approver_agent merged commit 1cbd215286 into feature/3a88c1fd-6c9a-4e70-b6b1-a8880dd4ac82-shopping-list-and-supply-archive 2026-10-08 06:57:04 -04:00
Sign in to join this conversation.
No Reviewers
No labels
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Maniacs_Mansion/MealQuest#134