Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.d/2.8.0-land-first-cited-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 2.8.0 Land the first cited evidence under the named citation next action

Open Public post from the landed Demo Corp members and the first
cited evidence sits under the citation next action, ahead of the
input. Home list opens still wait for a citation click.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ 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.8.0] - 2026-08-17

### Added

- Opening Public post from the landed Demo Corp members now puts the
first cited evidence immediately under the named citation next
action, ahead of the chat input. Home list opens still wait for a
citation click. No TEPP theta is invented. No cutoff body is
invented (ADR 0016).

## [2.7.2] - 2026-08-17

### Fixed
Expand Down
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ related nodes. After those related nodes land, the popup names Ask
about this lineage as the next read. After that next action, the
popup lands Ask about this lineage. After landed chat, the popup names
the first Ask. After that next action, the popup lands the first Ask
answer. Changing the week first still
answer. After landed first Ask answer, the popup names the first
cited source. After that next action, the popup lands the first cited
evidence. Changing the week first still
focuses the report period field. Mean θ stays on the period-report
panel.
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "frontend",
"private": true,
"version": "2.7.2",
"version": "2.8.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
29 changes: 28 additions & 1 deletion frontend/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,7 @@ describe("App, authenticated", () => {
expect(screen.queryByRole("status", { name: "Ask next action" })).not.toBeInTheDocument();
expect(screen.queryByRole("status", { name: "Ask seed next action" })).not.toBeInTheDocument();
expect(screen.queryByRole("status", { name: "Ask citation next action" })).not.toBeInTheDocument();
expect(screen.queryByRole("complementary", { name: "Evidence" })).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");
Expand Down Expand Up @@ -1547,6 +1548,10 @@ describe("App, authenticated", () => {
expect(homeInput.compareDocumentPosition(homeAnswer) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(
0,
);
expect(screen.queryByRole("complementary", { name: "Evidence" })).not.toBeInTheDocument();
expect(
screen.queryByText("The evidence panel should show exactly this text."),
).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: /ask seeded question: what happened between these events/i })).toBeInTheDocument();
expect(screen.getByRole("button", { name: /ask seeded question: who is involved/i })).toBeInTheDocument();
expect(screen.getByRole("button", { name: /ask seeded question: what is the next commitment/i })).toBeInTheDocument();
Expand Down Expand Up @@ -2462,6 +2467,17 @@ describe("App, authenticated", () => {
expect(
within(popup as HTMLElement).getByRole("button", { name: "Open evidence: Linked post" }),
).toHaveAttribute("aria-current", "true");
const citedEvidence = await screen.findByRole("complementary", { name: "Evidence" });
expect(await within(citedEvidence).findByText("Linked post")).toBeInTheDocument();
expect(
await within(citedEvidence).findByText("The evidence panel should show exactly this text."),
).toBeInTheDocument();
expect(
citedNext.compareDocumentPosition(citedEvidence) & Node.DOCUMENT_POSITION_FOLLOWING,
).not.toBe(0);
expect(
citedEvidence.compareDocumentPosition(askInput) & Node.DOCUMENT_POSITION_FOLLOWING,
).not.toBe(0);
await waitFor(() => expect(document.getElementById("post-ask")).toHaveFocus());
} finally {
HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
Expand Down Expand Up @@ -2820,9 +2836,20 @@ describe("App, authenticated", () => {
expect(firstAskAnswer.compareDocumentPosition(affiliate) & Node.DOCUMENT_POSITION_FOLLOWING).not.toBe(
0,
);
expect(await screen.findByRole("status", { name: "Ask citation next action" })).toHaveTextContent(
const citedNext = await screen.findByRole("status", { name: "Ask citation next action" });
expect(citedNext).toHaveTextContent(
"Linked post is the first cited source. Open that evidence next.",
);
const citedEvidence = await screen.findByRole("complementary", { name: "Evidence" });
expect(
await within(citedEvidence).findByText("The evidence panel should show exactly this text."),
).toBeInTheDocument();
expect(
citedNext.compareDocumentPosition(citedEvidence) & Node.DOCUMENT_POSITION_FOLLOWING,
).not.toBe(0);
expect(
citedEvidence.compareDocumentPosition(affiliate) & Node.DOCUMENT_POSITION_FOLLOWING,
).not.toBe(0);
await waitFor(() => expect(document.getElementById("post-ask")).toHaveFocus());
});

Expand Down
25 changes: 20 additions & 5 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function EvidencePanel({
}: {
postId: string;
accessToken: string;
onClose: () => void;
onClose?: () => void;
}) {
const [post, setPost] = useState<PostDetail | null>(null);

Expand All @@ -118,7 +118,7 @@ function EvidencePanel({

return (
<div className="evidence-panel" role="complementary" aria-label="Evidence">
<PopupCloseButton onClose={onClose} label="Close evidence panel" />
{onClose ? <PopupCloseButton onClose={onClose} label="Close evidence panel" /> : null}
<h3>Evidence</h3>
{!post && <p>Loading source post...</p>}
{post && (
Expand Down Expand Up @@ -183,6 +183,7 @@ function ChatPanel({
setAnswer(null);
setError(null);
setSeededOnly(false);
setEvidencePostId(null);
fetchPostChat(accessToken, postId)
.then((history) => setExchanges(history.exchanges))
.catch(() => setExchanges([]));
Expand Down Expand Up @@ -214,9 +215,12 @@ function ChatPanel({
}
}

const firstCitedPostId =
exchanges[0]?.cited_posts?.[0]?.post_id ?? exchanges[0]?.cited_post_ids[0] ?? null;
const firstCitedTitle =
exchanges[0]?.cited_posts?.[0]?.post_title ??
(exchanges[0]?.cited_post_ids[0] ? exchanges[0].cited_post_ids[0].slice(0, 8) : null);
(firstCitedPostId ? firstCitedPostId.slice(0, 8) : null);
const landedEvidencePostId = nameFirstAsk ? (evidencePostId ?? firstCitedPostId) : null;

return (
<section className="popup-section chat-section">
Expand Down Expand Up @@ -247,6 +251,17 @@ function ChatPanel({
{firstCitedNextAction(firstCitedTitle)}
</p>
) : null}
{nameFirstAsk && landedEvidencePostId ? (
<EvidencePanel
postId={landedEvidencePostId}
accessToken={accessToken}
onClose={
evidencePostId && evidencePostId !== firstCitedPostId
? () => setEvidencePostId(null)
: undefined
}
/>
) : null}
{!seededOnly && (
<div className="chat-input-row">
<input
Expand Down Expand Up @@ -314,13 +329,13 @@ function ChatPanel({
/>
</div>
)}
{evidencePostId && (
{!nameFirstAsk && evidencePostId ? (
<EvidencePanel
postId={evidencePostId}
accessToken={accessToken}
onClose={() => setEvidencePostId(null)}
/>
)}
) : null}
</section>
);
}
Expand Down
2 changes: 1 addition & 1 deletion lineageweave/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@
"sentence_excerpts",
]

__version__ = "2.7.2"
__version__ = "2.8.0"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "lineageweave"
version = "2.7.2"
version = "2.8.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" }
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.