[Frontend] Fix lore-proposal discovery: wrong link destination, triple-surfaced UI, and a proposals page reachable by one hidden link #375
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Impact: CRITICAL
Found in the August 2026 session lifecycle review (#319).
What the user experiences
Lore proposals are the payoff of the recording pipeline, and the one link the product gives a GM for this task sends them to the wrong page.
SessionDetail's "Review proposals →" points at the wiki home, not the proposals queue. The actual proposals page (/wiki/proposals) has exactly one inbound link in the entire app, and it lives inside a sidebar that is hidden below 768px — so on a phone the page cannot be reached at all except by typing the URL. Meanwhile a third, divergent copy of the same queue is inlined onCampaignDetail, which only renders when the count is above zero (so a GM never learns the feature exists before it first fires), omits relationship proposals entirely, and truncates proposal bodies where the real page shows them in full. Both proposal fetches swallow errors, so a failed request looks identical to an empty queue.Evidence
webapp/frontend/src/pages/SessionDetail.jsx:233(also referenced at:104-106) — "Review proposals →" links to/campaigns/${session.campaign_id}/wiki, the storyline home, instead of/campaigns/${session.campaign_id}/wiki/proposals.webapp/frontend/src/pages/CampaignStoryline.jsx:272,290-300— the sole inbound link to/wiki/proposals("AI Proposals") lives inside<aside className="hidden md:flex …">.webapp/frontend/src/pages/CampaignDetail.jsx:2665-2768— a second, ~110-line inline implementation of the proposal queue, gated on{isGm && loreProposals.length > 0 && (…)}, omitting relationship proposals and truncating bodies withline-clamp-3(:2741) whereWikiProposals.jsx:381shows them in full.webapp/frontend/src/pages/CampaignDetail.jsx:467-469andwebapp/frontend/src/pages/CampaignStoryline.jsx:160-161— bothfetchLoreProposalscalls are.catch(() => {}), so a fetch failure and an empty queue render identically.CampaignDetail.jsx:2668) is factually wrong, not merely inconsistent — per this repo'sCLAUDE.mdandwebapp/backend/app/services/summary_events.py:78-80, lore proposals are generated by the backend Celery worker; the bot has nothing to do with them.Why it matters for a hosted product
The one link the product offers for the payoff step of its flagship pipeline goes to the wrong place, and the correct page is functionally unreachable on a phone or tablet. A GM who does find it sees a divergent, less complete version depending on which page they happened to land on.
Proposed fix
Fix the one-line destination bug on
SessionDetail.jsx:233. Move the/wiki/proposalsentry link out of thehidden md:flexaside into the main content area, beside "New article" (CampaignStoryline.jsx:340-345), so it is reachable regardless of viewport. Delete the inline proposal queue onCampaignDetail(:2665-2768) in favour of a single always-visible summary row — "N suggested wiki updates → Review" or "No pending suggestions" when empty, so the feature is discoverable before it first fires — linking toWikiProposalsas the one canonical review page. Distinguish a fetch error from an empty queue on both fetch sites. Rename "Bot Proposals" to something accurate, e.g. "Suggested wiki updates" (part of the milestone's broader naming cleanup — see the vocabulary issue in this milestone). This is the audit's P6, P23, C2, and C6.Acceptance criteria
SessionDetail.jsx:233links to/campaigns/:id/wiki/proposals, not/campaigns/:id/wiki./wiki/proposalsentry link is visible below themdbreakpoint (moved out of thehidden md:flexaside).CampaignDetailis removed in favour of a single summary row linking toWikiProposals.Note: the link destination half of this issue has already landed, in the v3.11.5 hotfix (see #417).
SessionDetail.jsxnow pointsReview proposals →at/campaigns/{id}/wiki/proposalsinstead of the wiki home. It was taken early because #417 made that link render for the first time — the status field it depends on was never populated by the API — and shipping a newly-visible link to the wrong page would have been a new defect rather than a fixed one.The rest of this issue's scope is unchanged and still open: the three divergent proposal surfaces that need merging to one, and the fact that
/wiki/proposalshas exactly one inbound link, inside ahidden md:flexaside, making it unreachable below 768 px.Picking this up as v4.3.0 phase 6 (#514), first on the wiki lane (#375 → #385 → #395 → #396; the silent-error sweep #377 runs after every lane has settled). The one-line link fix; the proposals entry link moves out of the phone-hidden aside; the inline queue on the campaign page becomes one always-visible summary row linking to the single review page; both fetch sites distinguish an error from an empty queue. The rename to "Suggested wiki updates" already landed with #379.
Done in PR #527 (auto-merging on green); ships with v4.3.0.
The
SessionDetail.jsxlink named here was already fixed: #417 took it as part of makinglore_generation_statusreach the client, and shipped it as "#375, partial" in v4.2.3. It now has the regression test it never got, and the file is otherwise untouched (another lane owns it this phase).The rest: the wiki front page's only route to the queue was in its
hidden md:flexrail, so there was no route at all from a phone. It now also sits beside "New article" in the main column, with the pending count on it; the rail copy stays, since removing it would be a desktop regression for no gain.CampaignDetail's 105-line inline copy of the queue is gone: it omitted relationship suggestions entirely, clamped every body to three lines, and was gated oncount > 0, so it vanished exactly when a GM was looking for it. In its place, one always-visible row that says which of "N suggested wiki updates" / "No pending suggestions" / "Couldn't load suggested wiki updates." is true, with Review going toWikiProposalsas the single canonical page. BothfetchLoreProposalssites stopped being.catch(() => {}), and both counts now include relationship proposals, becausevocabulary.jsdefines "suggested wiki updates" as entries and relationships, so the old entry-only badge was a half-truth.9 new tests. No backend change. The rename this issue also asked for ("Bot Proposals") landed with #379.