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/1.0.0-analysis-run-opened-report-next-action.md
Original file line number Diff line number Diff line change
@@ -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.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
5 changes: 4 additions & 1 deletion docs/adr/0024-seed-period-report-analysis-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
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": "0.99.0",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
31 changes: 23 additions & 8 deletions frontend/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
Expand Down Expand Up @@ -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();
});
Expand All @@ -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;
Expand Down Expand Up @@ -2408,7 +2418,7 @@ describe("App, authenticated", () => {
stubBackend();
render(<App />);

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);
Expand Down Expand Up @@ -2445,10 +2455,15 @@ describe("App, authenticated", () => {
render(<App />);

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"),
Expand Down
43 changes: 35 additions & 8 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,30 @@ function CalendarPanel({
);
}

const REPORT_GROUPING_LABELS: Record<string, string> = {
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,
Expand Down Expand Up @@ -2124,12 +2148,6 @@ function ReportsPanel({
const [rebuilding, setRebuilding] = useState(false);
const openedComparisonRef = useRef<HTMLButtonElement | null>(null);

const groupingLabels: Record<string, string> = {
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;
Expand Down Expand Up @@ -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"
Expand All @@ -2239,7 +2261,7 @@ function ReportsPanel({
}}
>
<span className="ticket-title">
{groupingLabels[row.grouping_kind] ?? row.grouping_kind}: {row.grouping_label}
{comparisonGroupingTitle(row.grouping_kind, row.grouping_label)}
</span>
<span className="post-badge">mean θ {row.mean_theta.toFixed(2)}</span>
<span className="post-badge">{row.post_count} posts</span>
Expand All @@ -2248,6 +2270,11 @@ function ReportsPanel({
))}
</ul>
)}
{openedGroupingLabel && (
<p className="post-meta" role="status">
{openedReportNextAction(openedGroupingLabel)}
</p>
)}
{index && index.periods.length > 0 && (
<ul className="ticket-list">
{index.periods.map((row) => (
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__ = "0.99.0"
__version__ = "1.0.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 = "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" }
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.