Skip to content

fix: keep catalog first-page failures retryable - #3457

Open
pacocartones wants to merge 2 commits into
openclaw:mainfrom
pacocartones:fix/catalog-first-fetch-retry
Open

fix: keep catalog first-page failures retryable#3457
pacocartones wants to merge 2 commits into
openclaw:mainfrom
pacocartones:fix/catalog-first-fetch-retry

Conversation

@pacocartones

@pacocartones pacocartones commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • keep New, Featured, and Official first-page fetch failures retryable
  • avoid showing a terminal empty-catalog state before a successful empty response
  • preserve Trending's existing unavailable/fallback behavior

Why

The first request used a null cursor. On rejection, the shared error path set the list to done,
which removed Load more and presented the catalog as empty. Returning these non-Trending views
to idle keeps the existing retry control available without changing successful pagination or
later-page failure behavior.

Verification

  • regression cases: 3/3
  • complete SkillsIndex suite: 52/52
  • Trending control suite: 21/21
  • load-more control: 1/1
  • bun run ci:static
  • bunx tsc --noEmit
  • targeted type-aware oxlint and format checks

The aggregate coverage command did not finish inside a 180-second local timebox, so I am not
claiming that gate; the relevant suites and static gates above completed successfully.

No screenshot is attached because the change concerns a transient rejected-request state and the
regression drives the real rendered controls directly: the retry control remains after failure,
issues a second request, and disappears after recovery.

AI assistance

AI-assisted implementation and review were used. I reviewed the state transition, can maintain the
change, and independently verified retry, pagination, stale-response, double-click, and Trending
fallback behavior.

Real behavior proof

The exact live base (faab45ba) and PR head (25db30d2) were run as real ClawHub applications in
Chromium against the same local Convex deployment and seeded repository fixture. Playwright
intercepted the real first /api/query request with HTTP 503 in both lanes.

  • Base: rendered the false terminal No skills found state with no retry control.
  • Candidate: rendered Load more after the identical failure.
  • Recovery: after removing only the route interception and clicking that real button, the second
    Convex request returned 200 and the seeded skill rendered.

Before/after screenshots, metadata and the full methodology are linked in the durable UI proof
comment below. No DOM, application source, HTML or database row was edited to manufacture the UI.

@clawsweeper

clawsweeper Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

@pacocartones is attempting to deploy a commit to the OpenClaw Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 12, 2026
@clawsweeper

clawsweeper Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed August 16, 2026, 12:15 PM ET / 16:15 UTC.

ClawSweeper review

What this changes

The PR keeps New, Featured, and Official catalog tabs retryable after a failed first-page request, while retaining Trending’s dedicated unavailable fallback.

Merge readiness

⚠️ Ready for maintainer review - 2 items remain

Keep this PR open for maintainer merge review: current main still turns a rejected non-Trending first page into a terminal state, while this focused patch preserves retry and has no actionable correctness finding. The remaining ambiguous error presentation is separately tracked in #3473.

Priority: P2
Reviewed head: b23a83ca902877cdb3f0c5ada437cfb347e64af6

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused repair with convincing browser proof and targeted regression coverage; no blocking source defect was found.
Proof confidence 🦞 diamond lobster (5/6) ✨ media proof bonus Sufficient (screenshot): Prepared before/after Chromium screenshots show the false empty state, retained retry control after an injected 503, and successful recovery to a seeded skill; no sensitive details are visible.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (screenshot): Prepared before/after Chromium screenshots show the false empty state, retained retry control after an injected 503, and successful recovery to a seeded skill; no sensitive details are visible.
Evidence reviewed 5 items Current main behavior: Current main’s failure handler records a null-cursor failure as done, while the UI only exposes Load more for idle status; this produces the false terminal empty state the PR addresses.
Focused repair and regression coverage: The candidate keeps only first-page Trending terminal, leaves other failed catalog pages idle, and adds three tab-specific failure/retry/recovery cases.
Rendered recovery proof: The prepared browser screenshots show the baseline’s false “No skills found” state, the candidate’s retained Load more control after the same injected 503, and a seeded skill rendered after retry.
Findings None None.
Security None None.

How this fits together

The Skills catalog maps backend page requests into list results, terminal empty states, and retry controls. This patch changes the first-page failure state for non-Trending catalog tabs so users can make another request.

flowchart LR
  A[Catalog tab] --> B[First page request]
  B --> C{Request outcome}
  C -->|Success| D[Catalog results]
  C -->|Failure| E[List status]
  E --> F[Retry control]
  F --> G[Second request]
  G --> D
Loading

Before merge

Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope production +2/-2, tests +34, 2 files affected The runtime change is limited to one failure-state condition and is covered by three tab-specific recovery cases.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Land the narrow retry-state repair, then address the distinct error-message state in Skills list: first-page fetch failure leaves no error signal, only a bare "Load more" card #3473 without expanding this PR’s failure-recovery boundary.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Land the narrow retry-state repair, then address the distinct error-message state in #3473 without expanding this PR’s failure-recovery boundary.

Do we have a high-confidence way to reproduce the issue?

Yes—source on current main shows a rejected initial non-Trending request reaches the terminal done state, and the supplied browser proof demonstrates the resulting before/after recovery flow.

Is this the best way to solve the issue?

Yes—the status-only change preserves the existing Load more retry path and leaves the separate error-message design to #3473.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 4117154ecac4.

Labels

Label justifications:

  • P2: This repairs a bounded catalog recovery path without evidence of a release-blocking outage.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (screenshot): Prepared before/after Chromium screenshots show the false empty state, retained retry control after an injected 503, and successful recovery to a seeded skill; no sensitive details are visible.
  • proof: sufficient: Contributor real behavior proof is sufficient. Prepared before/after Chromium screenshots show the false empty state, retained retry control after an injected 503, and successful recovery to a seeded skill; no sensitive details are visible.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. Prepared before/after Chromium screenshots show the false empty state, retained retry control after an injected 503, and successful recovery to a seeded skill; no sensitive details are visible.

Evidence

What I checked:

  • Current main behavior: Current main’s failure handler records a null-cursor failure as done, while the UI only exposes Load more for idle status; this produces the false terminal empty state the PR addresses. (src/routes/skills/-useSkillsBrowseModel.ts:300, 4117154ecac4)
  • Focused repair and regression coverage: The candidate keeps only first-page Trending terminal, leaves other failed catalog pages idle, and adds three tab-specific failure/retry/recovery cases. (src/routes/skills/-useSkillsBrowseModel.ts:300, b23a83ca9028)
  • Rendered recovery proof: The prepared browser screenshots show the baseline’s false “No skills found” state, the candidate’s retained Load more control after the same injected 503, and a seeded skill rendered after retry. (25db30d26c88)
  • Area history: Recent catalog-state work is concentrated in the browse model history, including canonical Trending behavior and the recent SSR-loading adjustment. (src/routes/skills/-useSkillsBrowseModel.ts, dc9da89d3b3f)
  • Autoreview environment result: The required structured autoreview helper was invoked for the functional commit but could not start because this review environment does not have TruffleHog installed; no clean helper result is claimed. (72dd2784394b)

Likely related people:

  • Patrick Erichsen: History shows repeated work on canonical Trending availability and catalog discovery behavior that this patch deliberately preserves. (role: catalog behavior contributor; confidence: medium; commits: 725eb2d31e91, a58294361b8f, 21078e6e0d02; files: src/routes/skills/-useSkillsBrowseModel.ts, src/routes/skills/-SkillsResults.tsx)
  • Vyctor H. Brzezowski: The most recent main-branch history entry for the browse model is the canonical Skills SSR loading adjustment. (role: recent area contributor; confidence: medium; commits: dc9da89d3b3f; files: src/routes/skills/-useSkillsBrowseModel.ts, src/routes/skills/index.tsx)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (51 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-15T14:36:05.086Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T14:45:21.877Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T16:05:21.057Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T17:33:57.827Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T18:36:27.391Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T18:47:56.406Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T20:35:02.166Z sha 25db30d :: needs maintainer review before merge. :: none
  • reviewed 2026-08-15T21:46:02.582Z sha 25db30d :: needs maintainer review before merge. :: none

@pacocartones

pacocartones commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

ClawHub UI Proof

Status: passed
Mode: before-after
Scenario: catalog-first-page-failure-retry-recovery
Provider: local-convex-playwright
Baseline: faab45bace675a046b9b628dbc4581008ebbef96
Candidate: 25db30d26c881fd7d9d60956ced543654d1be26b

Base after a simulated first-page 503: false terminal empty state Candidate after the same first-page 503: Load more remains available
Base after a simulated first-page 503: false terminal empty state Candidate after the same first-page 503: Load more remains available
Base has no in-page recovery control Candidate after retry: real seeded skill is rendered
Base has no in-page recovery control Candidate after retry: real seeded skill is rendered

Raw proof files: https://github.com/pacocartones/clawhub/tree/qa-artifacts/clawhub-ui-proof/pr-3457/catalog-first-page-retry

Both lanes ran real ClawHub apps against the same local Convex deployment. Playwright returned a
proof-only HTTP 503 for the real first /api/query; no DOM or application source was modified.
After capturing the candidate retry state, the interception was removed and the visible Load more
button was clicked, producing a 200 Convex query and the rendered seeded skill.

@clawsweeper clawsweeper Bot added proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Aug 12, 2026

@Yigtwxx Yigtwxx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verify pass on 25db30d2 against base faab45ba, returning the favour for the one you ran on #3414.
No blocking findings. Two non-blocking notes at the end.

The state change is exactly one cell of the matrix. Reading the catch block in
src/routes/skills/-useSkillsBrowseModel.ts:292-300 as a table of (catalogTab, pageCursor):

case before after
trending, first page done done
trending, later page idle idle
other, first page done idle
other, later page idle idle

catalogTab === "trending" && !pageCursor ? "done" : "idle" moves the third row and nothing else, so
canonical Trending keeps its unavailable / No 24-hour activity yet terminal state and later-page
failures keep the behaviour they already had. The retry itself lands where it should: loadMore
(:517-527) calls fetchPage(listCursor, …) with the listCursor the catch block restored, which is
null on a first-page failure, and the success path replaces rather than appends when cursor is
falsy (:281), so a recovered first page cannot double up.

Test verification, with the negative control. At the PR head:

bunx vitest run src/__tests__/skills-index.test.tsx
Test Files  1 passed (1)
Tests  52 passed (52)

Then restoring only src/routes/skills/-useSkillsBrowseModel.ts from main and leaving the new test
file in place:

Tests  3 failed | 49 passed (52)
× keeps the new first page retryable after a temporary fetch failure
× keeps the featured first page retryable after a temporary fetch failure
× keeps the official first page retryable after a temporary fetch failure

Exactly the three new cases fail and the other 49 still pass, so the tests are bound to the new
behaviour and do not silently re-describe the old one.

Note 1, non-blocking: after a first-page failure the page carries no failure signal at all. The
empty state is gated on listDoneLoading, which src/routes/skills/index.tsx:407 computes as
!isLoadingSkills && !canLoadMore && !isLoadingMore. With the status now idle, canLoadMore is
true, so listDoneLoading is false and -SkillsResults.tsx:235 skips the empty block; the result
list is empty, so the render at :314-334 produces nothing either. What is left on screen is a bare
Load more card. That is strictly better than the false No skills found this fixes, and I would not
widen the diff for it, but a user who hits a 503 now sees an empty page whose only hint that anything
went wrong is a button. If the maintainers want an error line there, it seems like its own change.

Note 2, cosmetic: the vi.stubGlobal("IntersectionObserver", undefined) in the new cases is inert
canAutoLoad is a hardcoded false at -useSkillsBrowseModel.ts:515, so loadMoreRef is never
attached and no observer is ever constructed. Harmless, and it matches what the neighbouring tests in
the file already do.

@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Aug 13, 2026
@pacocartones
pacocartones requested a review from Yigtwxx August 13, 2026 08:36

@Yigtwxx Yigtwxx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked on the re-request. Nothing has changed that would move the verify pass above.

The head is still 25db30d2, the commit I read on August 12 — no new commits, no force-push, no new comments since. The only movement on the PR was ClawSweeper's rating going from platinum hermit to diamond lobster at 08:30 UTC.

What I did re-check is main drift, because that pass was run against base faab45ba and main has since moved to 60b02c09 (fix: stream legacy skill downloads, #3451). That commit touches convex/, server/, public/api/v1/openapi.json, docs/http-api.md, specs/spec.md and two files under src/components/. Restricting the range to the files my reading depended on:

git log --oneline faab45ba..60b02c09 -- \
  src/routes/skills/-useSkillsBrowseModel.ts \
  src/__tests__/skills-index.test.tsx \
  src/routes/skills/index.tsx \
  src/routes/skills/-SkillsResults.tsx

returns nothing. So the model, the new test file, and the two render paths behind Note 1 are byte-identical to what I read: the (catalogTab, pageCursor) state table, the loadMore cursor argument, and the listDoneLoading gate all still describe current main. The branch is MERGEABLE against it.

Verify pass stands, no blocking findings, and both notes stay non-blocking.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 13, 2026

@Yigtwxx Yigtwxx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked against ClawSweeper's P1 item, the five failed required checks on 25db30d2. They are one failure, and it lands on the production site rather than in this diff.

Four of the five reds ran nothing. static, unit, packages, types-build and e2e-http are test "$PR_GATES_RESULT" = "success" mirrors of pr-gates (.github/workflows/ci.yml:83-151), so a single red job paints six checks red. In pr-gates the steps those four names refer to all passed:

Static checks        success  01:21:13 -> 01:21:39
Unit coverage        success  01:21:39 -> 01:28:47
Package checks       success  01:28:47 -> 01:29:41
Typecheck and build  success  01:29:41 -> 01:30:11
HTTP e2e             failure  01:30:11 -> 01:30:14

The one real failure is a live-prod fetch. ci:e2e-http starts with test:e2e:prod-http, which is e2e/prod-http-smoke.e2e.test.ts, and that file fetches CLAWHUB_E2E_SITE defaulting to https://clawhub.ai (prod-http-smoke.e2e.test.ts:22-33). Three of its four tests failed on the same assertion:

✓ serves the home page shell from prod                          2521ms
× serves SSR skill html for a public skill page                  132ms
× serves the skill og image for the latest published version       1ms
× serves the published SKILL.md file                               0ms

AssertionError: expected false to be true
 ❯ e2e/prod-http-smoke.e2e.test.ts:158:27
 ❯ e2e/prod-http-smoke.e2e.test.ts:181:20

Line 158 is expect(response.ok).toBe(true) inside fetchSkillDetail(), which GETs /api/v1/skills/gifgrep. That promise is memoized, so the 1ms and 0ms tests are the same rejection re-awaited — one bad response, not three. fetchWithRetry only re-attempts 429 and >= 500 (:100, :104), so what came back was a non-retryable 4xx. The only test that does not touch that endpoint, the home page shell, passed, so the site itself was serving.

Nothing in the diff can reach that, and it is green now. This PR is src/routes/skills/-useSkillsBrowseModel.ts (+2/-2) and src/__tests__/skills-index.test.tsx (+34); e2e/prod-http-smoke.e2e.test.ts is byte-identical between 25db30d2 and main. As of now GET https://clawhub.ai/api/v1/skills/gifgrep returns 200, and a local bun run test:e2e:prod-http gives Test Files 1 passed (1) / Tests 4 passed (4).

Verify pass refreshed against current main. My August 13 re-check was pinned to 60b02c09; main is now 4117154e (36b775a6 and 4117154e since). git log 60b02c09..4117154e restricted to -useSkillsBrowseModel.ts, skills-index.test.tsx, skills/index.tsx and -SkillsResults.tsx returns nothing, and git merge-tree --write-tree main 25db30d2 merges without conflict. On a tree at current main with this PR's two files applied, src/__tests__/skills-index.test.tsx is 52/52. Reverting only -useSkillsBrowseModel.ts to main's copy while keeping the new tests puts exactly the three new cases back to red, each rendering No skills found where the test expects Load more, so the two-line change is still load-bearing and the coverage still binds to it on current main.

Verify pass stands, both earlier notes stay non-blocking. What is left is mechanical: the head is three commits behind main and its check set is from August 12, so a rebase onto 4117154e would replace this stale red with a fresh run. @pacocartones, that one is yours to push.

On ClawSweeper's second P1, the unavailable TruffleHog executable: that is its own gate, not a repo check. Scan for Verified Secrets and CodeQL are both green on 25db30d2.

@pacocartones
pacocartones force-pushed the fix/catalog-first-fetch-retry branch from 25db30d to b23a83c Compare August 16, 2026 16:11
@pacocartones

Copy link
Copy Markdown
Contributor Author

Thank you for running it in reverse — restoring only the model and watching exactly the three new
cases fail while the other 49 held is the part I'd have had to take on faith otherwise. That's the
check that separates "the tests pass" from "the tests are about this change".

On the Aug 15 re-check: agreed the red is stale and unreachable from this diff — I've rebased onto
current main (4117154e), so the next check set runs fresh. (Fair disclosure: the local test run
didn't survive my machine today, so the fresh CI is the verification here — your 52/52 on the merge
is the last local pass I can vouch for.)

Note 1 is right and I don't want to hide it in a thread. The PR moves the first-page-failure
state from a lie (No skills found) to a blank with a Load more card, which is better but still
not honest with the user: listDoneLoading can't distinguish "nothing matched" from "the request
failed", because canLoadMore is true in both. Fixing that means giving the model a distinct
error state rather than folding the failure into idle, and I agree that's its own change and not
this diff — widening it here would put a UI decision inside a retryability fix. I've opened it as
#3473 so it doesn't die in this thread; happy to take it if the maintainers want it.

Note 2: correct, the stub is inert — canAutoLoad is a hardcoded false, so no observer is
ever constructed. I kept it because the neighbouring cases carry it and dropping it from three of
them would read as a meaningful difference where there is none. If you'd rather see it gone from
the whole file, that's a clean separate cleanup.

Noted on the main drift re-check too — that's the bit most verify passes skip.

@Yigtwxx Yigtwxx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-verified on the rebased head b23a83ca. The local pass that didn't survive your machine today is below, so the fresh CI isn't the only thing standing behind this.

The rebase carries no change. I diffed the PR against each of its bases and compared the two patches:

git diff faab45ba 25db30d2 > old.diff   # the head I read on Aug 12
git diff 4117154e b23a83ca > new.diff   # the head after the rebase
diff old.diff new.diff                  # no output, exit 0

Byte-identical. The split into 72dd2784 + b23a83ca is bookkeeping: the second commit puts the try/finally back around the console.error spy where the rebased first commit had dropped it, so the resulting tree matches the one I already reviewed. Nothing new to read.

Local run on b23a83ca (Windows, vitest 4.1.10, bunx vitest run src/__tests__/skills-index.test.tsx):

 Test Files  1 passed (1)
      Tests  52 passed (52)

Reverse check, redone against the new base. Same method as last time but with 4117154e instead of faab45ba — restore only src/routes/skills/-useSkillsBrowseModel.ts from the base and leave the test file at the PR's version:

 x keeps the new first page retryable after a temporary fetch failure
 x keeps the featured first page retryable after a temporary fetch failure
 x keeps the official first page retryable after a temporary fetch failure
 Tests  3 failed | 49 passed (52)

The same three, and still only those three; the other 49 held. The coupling between the model change and the new cases survived the move onto current main, which is the part a rebase can quietly break.

Checks. Everything on b23a83ca is green except the Vercel deploy authorization, which is the same maintainer gate sitting on my #3414 — not something either of us can clear. The five reds from Aug 15 are gone with the rebase, as expected.

Note 1 / #3473. Agreed on the reading and on the scoping. Your write-up there is sharper than my note was: canLoadMore being true in both the empty and the failed case is the actual reason listDoneLoading cannot carry the distinction, and ClawSweeper's recommendation to land it as a follow-up after this merges matches what you proposed in the thread. I'd leave it with you rather than open a competing branch.

Note 2. Accepted. Keeping the stub where the neighbouring cases carry it is right; making three of them different to save three lines would cost more than it saves.

Nothing blocking from me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants