From cf9e57f6251ab468e19b396f0395c5625cfe2f94 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 17 Aug 2026 20:11:41 +0900 Subject: [PATCH] feat: name the first Ask after landed chat (v2.5.0) Opening Public post from Demo Corp members now names the first seeded Ask after landed chat. Home list opens do not add that copy. --- .../2.5.0-name-first-ask-after-landed-chat.md | 4 +++ CHANGELOG.md | 9 +++++++ frontend/package.json | 2 +- frontend/src/App.test.tsx | 15 +++++++++++ frontend/src/App.tsx | 26 +++++++++++++++++-- lineageweave/__init__.py | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 8 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 CHANGELOG.d/2.5.0-name-first-ask-after-landed-chat.md diff --git a/CHANGELOG.d/2.5.0-name-first-ask-after-landed-chat.md b/CHANGELOG.d/2.5.0-name-first-ask-after-landed-chat.md new file mode 100644 index 000000000..63b074c87 --- /dev/null +++ b/CHANGELOG.d/2.5.0-name-first-ask-after-landed-chat.md @@ -0,0 +1,4 @@ +# 2.5.0 Name the first Ask after landed chat + +Open Public post from the landed Demo Corp members and the first +seeded Ask is named after landed chat. Home list opens do not. diff --git a/CHANGELOG.md b/CHANGELOG.md index 9427e849c..c4318d5ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.5.0] - 2026-08-17 + +### Added + +- Opening Public post from the landed Demo Corp members now names the + first Ask after landed chat: What happened between these events, + then read that answer. Home list opens do not add that copy. No + TEPP theta is invented. No cutoff body is invented (ADR 0016). + ## [2.4.0] - 2026-08-17 ### Added diff --git a/frontend/package.json b/frontend/package.json index 49a7db4f0..511fd79db 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "2.4.0", + "version": "2.5.0", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index b9ea8ab7e..784a047a6 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -1490,6 +1490,7 @@ describe("App, authenticated", () => { expect(screen.queryByRole("status", { name: "Keyman next action" })).not.toBeInTheDocument(); expect(screen.queryByRole("status", { name: "Related next action" })).not.toBeInTheDocument(); expect(screen.queryByRole("status", { name: "Ask next action" })).not.toBeInTheDocument(); + expect(screen.queryByRole("status", { name: "Ask seed next action" })).not.toBeInTheDocument(); expect(screen.queryByText("Related to Ada West")).not.toBeInTheDocument(); expect(screen.queryByText("Related to Priya Nair")).not.toBeInTheDocument(); const popup = document.querySelector(".popup-panel"); @@ -2384,6 +2385,17 @@ describe("App, authenticated", () => { const ask = within(popup as HTMLElement).getByRole("heading", { name: "Ask about this lineage" }); expect(askNext.compareDocumentPosition(ask) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); expect(ask.compareDocumentPosition(affiliate) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); + const askSeed = await screen.findByRole("status", { name: "Ask seed next action" }); + expect(askSeed).toHaveTextContent( + "What happened between these events? is the first Ask. Read that answer next.", + ); + expect(ask.compareDocumentPosition(askSeed) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); + expect(askSeed.compareDocumentPosition(affiliate) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); + expect( + within(popup as HTMLElement).getByRole("button", { + name: "Ask seeded question: What happened between these events?", + }), + ).toHaveAttribute("aria-current", "true"); await waitFor(() => expect(document.getElementById("post-ask")).toHaveFocus()); } finally { HTMLElement.prototype.scrollIntoView = originalScrollIntoView; @@ -2669,6 +2681,9 @@ describe("App, authenticated", () => { const askNext = screen.getByRole("status", { name: "Ask next action" }); expect(askNext.compareDocumentPosition(ask) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); expect(ask.compareDocumentPosition(affiliate) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(0); + expect(await screen.findByRole("status", { name: "Ask seed next action" })).toHaveTextContent( + "What happened between these events? is the first Ask. Read that answer next.", + ); await waitFor(() => expect(document.getElementById("post-ask")).toHaveFocus()); }); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 736e84a0d..c71270e89 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -156,7 +156,15 @@ function ChatCitations({ ); } -function ChatPanel({ postId, accessToken }: { postId: string; accessToken: string }) { +function ChatPanel({ + postId, + accessToken, + nameFirstAsk, +}: { + postId: string; + accessToken: string; + nameFirstAsk?: boolean; +}) { const [question, setQuestion] = useState(""); const [exchanges, setExchanges] = useState([]); const [answer, setAnswer] = useState(null); @@ -206,6 +214,11 @@ function ChatPanel({ postId, accessToken }: { postId: string; accessToken: strin

Ask about this lineage

+ {nameFirstAsk && exchanges[0] ? ( +

+ {firstAskNextAction(exchanges[0].question_text)} +

+ ) : null} {!seededOnly && (
{ if (seededOnly) return; setQuestion(exchange.question_text); @@ -290,6 +308,10 @@ function relatedNodesCurrentNextAction(personName: string): string { return `Related nodes for ${personName} are current. Ask about this lineage next.`; } +function firstAskNextAction(questionText: string): string { + return `${questionText} is the first Ask. Read that answer next.`; +} + function EventLineageSection({ lineage, graph, @@ -931,7 +953,7 @@ function KeymanPanel({

) : null} {afterList && landFirstRelated && landedRelatedName && landedRelated !== null ? ( - + ) : null} ); diff --git a/lineageweave/__init__.py b/lineageweave/__init__.py index 5c7a3147c..f452eceaa 100644 --- a/lineageweave/__init__.py +++ b/lineageweave/__init__.py @@ -55,4 +55,4 @@ "sentence_excerpts", ] -__version__ = "2.4.0" +__version__ = "2.5.0" diff --git a/pyproject.toml b/pyproject.toml index 5e7a86ed7..cf5ffc76f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lineageweave" -version = "2.4.0" +version = "2.5.0" description = "Reconstructs git-branch-style lineage DAGs from scattered short records using multi-channel score fusion and LLM adjudication." readme = "README.md" license = { text = "MIT" } diff --git a/uv.lock b/uv.lock index a78413e90..c90a770a2 100644 --- a/uv.lock +++ b/uv.lock @@ -454,7 +454,7 @@ wheels = [ [[package]] name = "lineageweave" -version = "2.4.0" +version = "2.5.0" source = { virtual = "." } dependencies = [ { name = "certifi" },