Suggestion batches, deck and Try it / Pass API #102

Member

Maestro task b4f2558c-227f-4627-852b-be5aa190242a - "Suggestion batches, deck and accept/decline API" (Feature 13: Discover: Side Quest Suggestions).

Done-condition: POST /api/v1/suggestions/batches enqueues a job that runs suggest_side_quests, grounds each item (dropping ungroundable ones), and stores dinners (status suggested, origin side_quest) with suggestions (reason, cited_regular_ids, status pending). GET /suggestions/deck returns pending suggestions oldest first with dinner name, photo, difficulty and reason. POST /suggestions/{id}/accept moves the dinner to status quest_log; POST /suggestions/{id}/decline records the decline and archives the dinner; both are idempotent and 409 on the opposite decision. When pending count falls below 5 after a decision, a replenish batch is enqueued unless one is already running. Tests with fakes cover batch creation, deck order, accept/decline idempotency, replenish trigger and single-flight, and a later batch never re-suggesting a declined name. Go quality floor passes.

Reuses the already-merged items: the suggest_side_quests skill (task 85a898e1, PR #100), the Feature 10 grounding pipeline, and the internal/jobs runner rather than adding parallel paths.

Checks: gofmt clean, go vet, go test -race -count=1 ./..., CGO_ENABLED=0 go build ./..., make sqlc-check (no drift), web typecheck + 535 tests + build.

Maestro task `b4f2558c-227f-4627-852b-be5aa190242a` - "Suggestion batches, deck and accept/decline API" (Feature 13: Discover: Side Quest Suggestions). Done-condition: POST /api/v1/suggestions/batches enqueues a job that runs suggest_side_quests, grounds each item (dropping ungroundable ones), and stores dinners (status suggested, origin side_quest) with suggestions (reason, cited_regular_ids, status pending). GET /suggestions/deck returns pending suggestions oldest first with dinner name, photo, difficulty and reason. POST /suggestions/{id}/accept moves the dinner to status quest_log; POST /suggestions/{id}/decline records the decline and archives the dinner; both are idempotent and 409 on the opposite decision. When pending count falls below 5 after a decision, a replenish batch is enqueued unless one is already running. Tests with fakes cover batch creation, deck order, accept/decline idempotency, replenish trigger and single-flight, and a later batch never re-suggesting a declined name. Go quality floor passes. Reuses the already-merged items: the suggest_side_quests skill (task 85a898e1, PR #100), the Feature 10 grounding pipeline, and the internal/jobs runner rather than adding parallel paths. Checks: gofmt clean, go vet, go test -race -count=1 ./..., CGO_ENABLED=0 go build ./..., make sqlc-check (no drift), web typecheck + 535 tests + build.
orchestrator-agent added 1 commit 2026-10-06 23:31:38 -04:00
Add Side quest suggestion batches, deck and Try it / Pass API
CI / ci (push) Successful in 2m52s
CI / ci (pull_request) Successful in 2m46s
50399b6329
POST /api/v1/suggestions/batches enqueues a suggestion_batch job that runs
suggest_side_quests through the harness, grounds the survivors with
recipes.Grounder.GroundMany (dropping those no recipe grounds) and stores
each as a dinner (status suggested, origin side_quest) with a pending
suggestion holding its reason and cited_regular_ids. Only one batch is
pending or running at a time; a POST while one is active returns it.

GET /api/v1/suggestions/deck lists pending suggestions oldest first with
the dinner's name, photo, difficulty and the reason. POST
/api/v1/suggestions/{id}/accept moves the dinner to the Quest log; /decline
records the Pass and archives the dinner, whose name every later batch
reads as declined. Both are idempotent and 409 on the opposite decision.
A decision leaving fewer than 5 in the deck starts a replenish batch
unless one is already pending or running. Batches left unfinished by a
restart are failed at boot so they never block the next.

Task: b4f2558c-227f-4627-852b-be5aa190242a

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-06 23:33:33 -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-06 23:47:49 -04:00
Keep Pass history immutable and replenish atomic with decisions
CI / ci (push) Successful in 2m56s
CI / ci (pull_request) Successful in 2m55s
4e2773703b
Fixes the three review findings on 50399b6 (pull request #102):

- A batch now rereads every declined name inside its storing transaction,
  so a Pass committed after the batch read its input but before it stores
  can no longer let the passed dish into the deck (SQ-01).
- A decision that leaves the deck under five creates the replenish batch
  and its job in the decision's own transaction, so a decision is never
  recorded without the replenish it calls for; when they cannot be
  written, neither is the decision, and a retry decides again (SQ-02).
  StartBatch commits the batch with its job the same way, replacing the
  mutex and the fail-on-enqueue cleanup. jobs gains Kind.EnqueueTx and
  Kind.Wake for this.
- Migration 0012 gives each suggestion the name its dish was suggested
  under; declined names for batches and the household context's passed
  list read it instead of the dinner's mutable name, so renaming a passed
  dinner no longer erases it from dedupe (SQ-03).

Task: b4f2558c-227f-4627-852b-be5aa190242a

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-06 23:56:04 -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-06 23:59:43 -04:00
Fail the batch job when recording its end fails, and reconcile orphans
CI / ci (push) Successful in 2m55s
CI / ci (pull_request) Successful in 3m1s
a6643aaa94
finishBatch now returns its error, and treats a batch that is no longer
running as one, so a batch job never ends succeeded with its batch still
running. A batch left pending or running with its job ended (process
stopped, or the final status write failed) is failed inside startBatch,
before the active batch is read, so it never blocks a manual or
replenish batch. This replaces the boot-only FailInterruptedBatches.

Document suggestions.name in the architecture schema summary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-07 00:07:48 -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-07 00:12:56 -04:00
Retry a job's final status write until it lands
CI / ci (push) Successful in 2m58s
CI / ci (pull_request) Successful in 2m39s
d5cd47a775
A worker whose final SucceedJob or FailJob write failed logged it and
moved on, leaving the job running. For a suggestion batch whose own end
write had also failed, both rows stayed running, so orphan reconciliation
kept treating the batch as active and it blocked manual and replenish
batches until a restart. The runner now retries the final write with the
claim backoff until it lands; on shutdown a failed attempt is left for
the next Start to fail as interrupted.

Document that orphaned batches are reconciled each time a batch is
started, before the active batch is selected, not at boot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-07 00:17:58 -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-07 00:29:31 -04:00
Bound each attempt at a job's final write
CI / ci (push) Successful in 2m55s
CI / ci (pull_request) Successful in 2m49s
76ec60d219
A final write used a context that could never be cancelled, so a worker
waiting for a held writer connection kept runner.Wait, and with it
shutdown, open indefinitely. Each attempt now has a 5-second deadline;
once shutdown begins, a failed or timed-out attempt is not retried and
the next start fails the job as interrupted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_agent requested changes 2026-10-07 00:35:43 -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-07 00:40:56 -04:00
Bound the suggestion batch's end write like a job's final write
CI / ci (push) Successful in 2m40s
CI / ci (pull_request) Successful in 2m39s
f95a31472b
runBatch recorded the batch's end with an uncancellable context and no
deadline, before its handler returned, so a writer connection that
stayed busy could hold the worker, and shutdown, open indefinitely.

jobs.FinalWriteContext now gives every final write one bounded attempt
context (FinalWriteTimeout, 5 seconds, not cancelled with ctx); the
runner's record and finishBatch both use it. On timeout at shutdown the
handler returns, the job and batch stay running, the next Start fails
the job as interrupted and the next StartBatch fails the orphaned batch.

TestBlockedBatchEndDoesNotHoldShutdown holds the writer while a batch
reaches finishBatch and asserts the worker stops within the bound and
the batch is reconciled after restart. TestBlockedFinalWriteDoesNotHoldShutdown
no longer sets a runner field, so it compiles against earlier heads.

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 4c34467f8b into feature/e3a8e4ea-8dcb-49e8-878f-552a6af109cb-discover-side-quest-suggestions 2026-10-07 00:56:35 -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#102