From 3b8ee64eb1e1c6bc3d68798828771827729a59ff Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 17 Aug 2026 11:58:04 +0900 Subject: [PATCH] feat: name the next action on the landed Demo Corp report (v1.0.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After Open period report lands on Demo Corp, the panel says to read its mean θ and member posts. The focused chip uses the visible Corporate entity caption plus the persisted mean θ. --- ...-analysis-run-opened-report-next-action.md | 5 +++ CHANGELOG.md | 11 +++++ CLAUDE.md | 9 ++-- .../0024-seed-period-report-analysis-run.md | 5 ++- frontend/package.json | 2 +- frontend/src/App.test.tsx | 31 +++++++++---- frontend/src/App.tsx | 43 +++++++++++++++---- lineageweave/__init__.py | 2 +- pyproject.toml | 2 +- uv.lock | 2 +- 10 files changed, 88 insertions(+), 24 deletions(-) create mode 100644 CHANGELOG.d/1.0.0-analysis-run-opened-report-next-action.md diff --git a/CHANGELOG.d/1.0.0-analysis-run-opened-report-next-action.md b/CHANGELOG.d/1.0.0-analysis-run-opened-report-next-action.md new file mode 100644 index 000000000..a42a6b538 --- /dev/null +++ b/CHANGELOG.d/1.0.0-analysis-run-opened-report-next-action.md @@ -0,0 +1,5 @@ +# 1.0.0 Name the next action on the landed Demo Corp report + +Open period report 2026-W02 names the opened grouping and puts the +visible Corporate entity caption plus mean θ in the focused chip. +Mean θ stays on the report panel. diff --git a/CHANGELOG.md b/CHANGELOG.md index 328aec876..bd9a3aa06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ 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). +## [1.0.0] - 2026-08-17 + +### Added + +- Opening **Open period report 2026-W02** now names the next action on + the landed Demo Corp report: read its mean θ and member posts, then + open a post. The focused comparison chip uses the visible + `Corporate entity: Demo Corp` caption and the persisted mean θ + (WCAG 2.5.3). Changing the week still focuses the report period + field. Mean θ stays on the report panel. No TEPP theta is invented. + ## [0.99.0] - 2026-08-17 ### Added diff --git a/CLAUDE.md b/CLAUDE.md index 239d659f2..4f9b0b182 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,6 +43,9 @@ the parent-choice digest. After `make seed`, open **Period report · Succeeded · Demo Corp**, then **Open period report 2026-W02**. The home week is already 2026-W02, so the grouping comparison strip lands on Demo Corp. Report -grouping is Corporate entity and Demo Corp is current. Changing the -week first still focuses the report period field. Mean θ stays on the -period-report panel. +grouping is Corporate entity and Demo Corp is current. The focused +chip name contains `Corporate entity: Demo Corp` and the persisted +mean θ. The period-report panel says Demo Corp is the opened grouping +and to read its mean θ and member posts, then open a post. Changing +the week first still focuses the report period field. Mean θ stays on +the period-report panel. diff --git a/docs/adr/0024-seed-period-report-analysis-run.md b/docs/adr/0024-seed-period-report-analysis-run.md index eac3ad477..9e824e7e0 100644 --- a/docs/adr/0024-seed-period-report-analysis-run.md +++ b/docs/adr/0024-seed-period-report-analysis-run.md @@ -50,7 +50,10 @@ rows. Opening it shows the cutoff posts and **Open period report 2026-W02** (the week stored on `scope_key`). That click also switches Report grouping to Corporate entity and marks the Demo Corp grouping current, using the persisted scope grouping key. When the operator is -already on that week, the comparison strip lands on Demo Corp. Mean θ +already on that week, the comparison strip lands on Demo Corp. The +focused chip name contains the visible Corporate entity caption and +the persisted mean θ. The period-report panel names the next action: +read that grouping's mean θ and member posts, then open a post. Mean θ remains on the period-report panel. Re-seed is idempotent on `demo-report-seed-2026-w02`. diff --git a/frontend/package.json b/frontend/package.json index 7095b7fc7..30a383f95 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "0.99.0", + "version": "1.0.0", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index ee9d00ea5..e0335f531 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -746,7 +746,7 @@ describe("App, authenticated", () => { grouping_kind: "corporate_entity", grouping_key: "corp-1", grouping_label: "Demo Corp", - mean_theta: 0.01, + mean_theta: 0.42, post_count: 8, link_method: "fipc", }, @@ -2181,11 +2181,14 @@ describe("App, authenticated", () => { expect(groupingSelect).toHaveValue("corporate_entity"); expect(periodInput).toHaveFocus(); expect( - screen.getByRole("button", { name: "Compare corporate_entity: Demo Corp" }), + screen.getByRole("button", { name: "Compare Corporate entity: Demo Corp, mean θ 0.42" }), ).toHaveAttribute("aria-current", "true"); expect( - screen.getByRole("button", { name: "Compare process_unit: Demo Report High" }), + screen.getByRole("button", { name: "Compare Process unit: Demo Report High, mean θ 0.81" }), ).not.toHaveAttribute("aria-current"); + expect(screen.getByRole("status")).toHaveTextContent( + "Demo Corp is the opened grouping. Read its mean θ and member posts below, then open a post.", + ); expect(await screen.findByText(/Demo Corp: mean θ 0\.42/)).toBeInTheDocument(); expect(screen.queryByText(/corp-1: mean θ/)).not.toBeInTheDocument(); }); @@ -2211,11 +2214,18 @@ describe("App, authenticated", () => { expect(periodInput).toHaveValue("2026-W02"); expect(screen.getByLabelText("Report grouping")).toHaveValue("corporate_entity"); - const demoChip = screen.getByRole("button", { name: "Compare corporate_entity: Demo Corp" }); + const demoChip = screen.getByRole("button", { + name: "Compare Corporate entity: Demo Corp, mean θ 0.42", + }); expect(demoChip).toHaveAttribute("aria-current", "true"); expect(demoChip).toHaveFocus(); + expect(demoChip).toHaveAccessibleName(/Corporate entity: Demo Corp/); + expect(demoChip).toHaveAccessibleName(/mean θ 0\.42/); expect(scrollIntoView).toHaveBeenCalled(); expect(periodInput).not.toHaveFocus(); + expect(screen.getByRole("status")).toHaveTextContent( + "Demo Corp is the opened grouping. Read its mean θ and member posts below, then open a post.", + ); expect(await screen.findByText(/Demo Corp: mean θ 0\.42/)).toBeInTheDocument(); } finally { HTMLElement.prototype.scrollIntoView = originalScrollIntoView; @@ -2408,7 +2418,7 @@ describe("App, authenticated", () => { stubBackend(); render(); - expect(await screen.findByText(/mean θ 0.42/)).toBeInTheDocument(); + expect((await screen.findAllByText(/mean θ 0.42/)).length).toBeGreaterThan(0); expect(screen.getAllByText(/8 posts/).length).toBeGreaterThan(0); expect(screen.getByText(/TEST-PU-REPORT/)).toBeInTheDocument(); expect(screen.getAllByText("shared metric").length).toBeGreaterThan(0); @@ -2445,10 +2455,15 @@ describe("App, authenticated", () => { render(); expect(await screen.findByLabelText("Grouping comparison")).toBeInTheDocument(); - expect(screen.getByRole("button", { name: /compare process_unit: demo report high/i })).toHaveTextContent( - "mean θ 0.81", + expect( + screen.getByRole("button", { name: "Compare Process unit: Demo Report High, mean θ 0.81" }), + ).toHaveTextContent("mean θ 0.81"); + await userEvent.click( + screen.getByRole("button", { name: "Compare Thread group: A-100, mean θ 0.81" }), + ); + expect(screen.getByRole("status")).toHaveTextContent( + "A-100 is the opened grouping. Read its mean θ and member posts below, then open a post.", ); - await userEvent.click(screen.getByRole("button", { name: /compare thread_group: a-100/i })); await waitFor(() => expect(fetchMock).toHaveBeenCalledWith( expect.stringContaining("/api/reports/thread_group/2026-W02"), diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 7c9b02229..921959e03 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2092,6 +2092,30 @@ function CalendarPanel({ ); } +const REPORT_GROUPING_LABELS: Record = { + process_unit: "Process unit", + corporate_entity: "Corporate entity", + thread_group: "Thread group", +}; + +function comparisonGroupingTitle(groupingKind: string, groupingLabel: string): string { + return `${REPORT_GROUPING_LABELS[groupingKind] ?? groupingKind}: ${groupingLabel}`; +} + +function comparisonChipAccessibleName( + groupingKind: string, + groupingLabel: string, + meanTheta: number, +): string { + return `Compare ${comparisonGroupingTitle(groupingKind, groupingLabel)}, mean θ ${meanTheta.toFixed(2)}`; +} + +function openedReportNextAction(groupingLabel: string): string { + return ( + `${groupingLabel} is the opened grouping. Read its mean θ and member posts below, then open a post.` + ); +} + function ReportsPanel({ accessToken, canRebuild, @@ -2124,12 +2148,6 @@ function ReportsPanel({ const [rebuilding, setRebuilding] = useState(false); const openedComparisonRef = useRef(null); - const groupingLabels: Record = { - process_unit: "Process unit", - corporate_entity: "Corporate entity", - thread_group: "Thread group", - }; - function groupingIsOpened(groupingKind: string, groupingKey: string, groupingLabel?: string) { if (groupingKind !== grouping) { return false; @@ -2227,7 +2245,11 @@ function ReportsPanel({ ? openedComparisonRef : undefined } - aria-label={`Compare ${row.grouping_kind}: ${row.grouping_label}`} + aria-label={comparisonChipAccessibleName( + row.grouping_kind, + row.grouping_label, + row.mean_theta, + )} aria-current={ groupingIsOpened(row.grouping_kind, row.grouping_key, row.grouping_label) ? "true" @@ -2239,7 +2261,7 @@ function ReportsPanel({ }} > - {groupingLabels[row.grouping_kind] ?? row.grouping_kind}: {row.grouping_label} + {comparisonGroupingTitle(row.grouping_kind, row.grouping_label)} mean θ {row.mean_theta.toFixed(2)} {row.post_count} posts @@ -2248,6 +2270,11 @@ function ReportsPanel({ ))} )} + {openedGroupingLabel && ( +

+ {openedReportNextAction(openedGroupingLabel)} +

+ )} {index && index.periods.length > 0 && (
    {index.periods.map((row) => ( diff --git a/lineageweave/__init__.py b/lineageweave/__init__.py index 2b38b4fcf..107bfdb6f 100644 --- a/lineageweave/__init__.py +++ b/lineageweave/__init__.py @@ -55,4 +55,4 @@ "sentence_excerpts", ] -__version__ = "0.99.0" +__version__ = "1.0.0" diff --git a/pyproject.toml b/pyproject.toml index 4008b9f77..6510d6e3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lineageweave" -version = "0.99.0" +version = "1.0.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 942b5fe16..7ea52e063 100644 --- a/uv.lock +++ b/uv.lock @@ -454,7 +454,7 @@ wheels = [ [[package]] name = "lineageweave" -version = "0.99.0" +version = "1.0.0" source = { virtual = "." } dependencies = [ { name = "certifi" },