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 00000000..63b074c8 --- /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 9427e849..c4318d5e 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 49a7db4f..511fd79d 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 b9ea8ab7..784a047a 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 736e84a0..c71270e8 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 5c7a3147..f452ecea 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 5e7a86ed..cf5ffc76 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 a78413e9..c90a770a 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" },