Fixes two findings from the second independent release review of promotion PR #98 at head 7138721. Maestro task: 4fd737b2-fdcb-48ad-858a-ecdd95595e0c.
MQ-98-04 (HIGH): the household-settings query used TanStack Query's default online network mode, so after a real offline event it paused without data or error; with /me on networkMode: 'always', the onboarding gate could admit a previously verified session and then sit on LoadingScreen, locking the household out of saved pages offline. The gate's settings read now runs while offline so it fails into the documented saved-page path, with a test that emits a genuine offline event before /me fails.
MQ-98-05 (MEDIUM): renaming a pending dinner invalidated its background grounding job but left its previously offered candidates live, so candidate grounding could attach an old recipe to the renamed dinner. Offers are now invalidated on rename and offer acceptance is bound to the state observed when the candidates were produced, with a regression test for the rename case.
Checks: gofmt clean, go vet, go test -race -count=1 ./..., CGO_ENABLED=0 go build ./..., make sqlc-check (no drift), make build, docker build ., web typecheck + 537 tests + build - all pass.
Fixes two findings from the second independent release review of promotion PR #98 at head `7138721`. Maestro task: `4fd737b2-fdcb-48ad-858a-ecdd95595e0c`.
- MQ-98-04 (HIGH): the household-settings query used TanStack Query's default online network mode, so after a real offline event it paused without data or error; with `/me` on `networkMode: 'always'`, the onboarding gate could admit a previously verified session and then sit on `LoadingScreen`, locking the household out of saved pages offline. The gate's settings read now runs while offline so it fails into the documented saved-page path, with a test that emits a genuine offline event before `/me` fails.
- MQ-98-05 (MEDIUM): renaming a pending dinner invalidated its background grounding job but left its previously offered candidates live, so candidate grounding could attach an old recipe to the renamed dinner. Offers are now invalidated on rename and offer acceptance is bound to the state observed when the candidates were produced, with a regression test for the rename case.
Checks: gofmt clean, go vet, go test -race -count=1 ./..., CGO_ENABLED=0 go build ./..., make sqlc-check (no drift), make build, docker build ., web typecheck + 537 tests + build - all pass.
MQ-98-04: the household settings read that OnboardingGate makes before
every page now runs with networkMode 'always', like /me. After the
browser emits an offline event it fails into the saved pages instead of
pausing on the loading screen. A test emits a real offline event before
/me fails.
MQ-98-05: renaming a dinner now clears its candidate offers and makes a
running candidate search stale, and an offer is bound to the normalized
name it was searched for, so a candidate offered before a rename cannot
ground the renamed dinner. Regression tests cover a pending dinner
renamed after candidates were offered, and a rename during a running
search.
Maestro task: 4fd737b2-fdcb-48ad-858a-ecdd95595e0c
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MQ-103-01: offers were bound only to the normalized name and cleared
only when it changed, so "Chicken curry" -> "Quick Chicken curry" kept
the old candidates live, and a search finishing after renames A -> B -> A
committed (before either cleared offers) stored candidates that matched
A again.
Every actual name edit now raises grounding_revision and clears the
dinner's offers. Each offer set records the revision its search read,
and a candidate grounds the dinner only while the dinner is still at
that revision; GroundDinner already requires the observed revision, so
a rename between the check and the write is a conflict. A pending
dinner renamed keeps getting a job at its new revision; recipe_url is
still cleared only when the normalized name changes.
Tests: a same-normalized-name rename refuses the old candidate and
attaches no recipe; an in-flight search finishing between the A -> B -> A
commits and their offer clearing stores candidates that are refused.
Both fail against 3c0a7fd.
Maestro task: 4fd737b2-fdcb-48ad-858a-ecdd95595e0c
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A candidate search that read a dinner after its rename committed could
store fresh offers that the rename's own clear then dropped, so a valid
candidate for the renamed dinner was refused with a 400.
clearOffers now takes the revision below which offers are stale: a rename
passes its committed revision, so it drops only offers and in-flight
searches from earlier revisions, while grounding by hand and archiving
pass math.MaxInt64 and clear everything as before. A search finishing
late at an earlier revision no longer replaces offers already found at a
later one.
Fixes MQ-103-02.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes two findings from the second independent release review of promotion PR #98 at head
7138721. Maestro task:4fd737b2-fdcb-48ad-858a-ecdd95595e0c./meonnetworkMode: 'always', the onboarding gate could admit a previously verified session and then sit onLoadingScreen, locking the household out of saved pages offline. The gate's settings read now runs while offline so it fails into the documented saved-page path, with a test that emits a genuine offline event before/mefails.Checks: gofmt clean, go vet, go test -race -count=1 ./..., CGO_ENABLED=0 go build ./..., make sqlc-check (no drift), make build, docker build ., web typecheck + 537 tests + build - all pass.
Independent Codex gpt-6-sol review: CHANGES_REQUIRED for this exact commit.
Independent Codex gpt-6-sol review: CHANGES_REQUIRED for this exact commit.
Independent Codex gpt-6-sol review: APPROVED for this exact commit.