Skip to content

feat(dashboard): make Dashboard the / landing route (v2.13.0) - #545

Closed
seonghobae wants to merge 900 commits into
mainfrom
worktree-dashboard-home-route
Closed

feat(dashboard): make Dashboard the / landing route (v2.13.0)#545
seonghobae wants to merge 900 commits into
mainfrom
worktree-dashboard-home-route

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • / now opens a news-portal Dashboard ranking important posts and important projects by real fast-mlsirm FIPC-calibrated theta (grouping_kind="project", the already-shipped ADR 0003 pipeline), falling back to RankWeave's fused ranking when no project period report has been calibrated yet. No score is invented; TEPP is intentionally not used as an importance source since it has no live HTTP transport yet (ADR 0145).
  • No new backend endpoint — the Dashboard reuses fetchPeriodReportIndex, fetchPeriodReports, and fetchRankings exactly as the existing Period Reports and Rankings panels already do.
  • Board stays one click away as the first Workspace nav item after Dashboard; global search and admin board-tool deep links still route to Board unchanged. An unauthorized ?workspace=admin deep link now falls back to Dashboard (the true home) instead of Board.
  • ko/zh/ja/vi translations for every new string; Storybook stories for loaded/empty/fallback/loading/unavailable states; component tests asserting every rendered score traces to a mocked service call, not a literal.
  • Version bump to 2.13.0 (pyproject.toml + frontend/package.json) with a CHANGELOG.d fragment.

Test plan

  • pnpm exec vitest run — 374/374 tests pass across 37 files (frontend)
  • pnpm run build (tsc -b && vite build) — clean
  • pnpm run lint (oxlint) — clean
  • Manual smoke test in a running dev/demo environment (not run this session)

🤖 Generated with Claude Code

https://claude.ai/code/session_019zL1WPKcHD6DrRVxGj1Mpx


Open in Devin Review

seonghobae and others added 30 commits August 20, 2026 18:48
Forward-only conflict resolution uses protected main as the tree baseline and reapplies the exact twelve-file Event Lineage delta. This preserves current main product/security changes plus direction, dates, evidence, accessibility, Figma/Storybook, i18n, cycle safety, changelog, and stabilization-plan contracts without rewriting history or dropping capability.
…ame-evidence-lineage' into repair/pr258-current
# Conflicts:
#	frontend/src/App.tsx
#	lineageweave/post_summary.py
#	tests/test_post_summary.py
* fix: align buyer lineage shell with UI UX guide

* docs: track post-merge UI UX review gate

* feat: expose authorized account scope and global search

* fix: place locale control in header top menu

* docs: record central hourly merge loop

* fix: refocus buyer search after board load

* refactor: retire "Buyer" terminology across code and living docs

LineageWeave has no explicit buyer actor -- rename BuyerNav/BuyerDestination
to WorkspaceNav/WorkspaceDestination, .buyer-gnb* CSS to .workspace-gnb*,
the "Buyer navigation" i18n key, the "BUYER EVIDENCE" legend label, and
backend _buyer_evidence_kind/_buyer_evidence_text helpers. Replace prose
referring to "the buyer" with "the reader" in AGENTS.md, ARCHITECTURE.md,
docstrings, living docs, and test descriptions/idempotency keys.

Historical ADRs (0002-0118) and CHANGELOG.md/CHANGELOG.d entries keep their
original wording as a point-in-time record; ADR 0119 documents the rename.
Fixture/table content that uses "buyer" as ordinary sales-note prose is
left untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: translate workspace navigation labels

* fix: make buyer search focus one-shot and localize lineage label

* docs: record authenticated UI UX gap evidence

* fix: use lineage evidence terminology

* fix: keep health probe public and settings route covered

* docs: record current health and lineage coverage gaps

* fix: brand the Keycloak login theme and put post-popup analysis first

- Add a custom Keycloak login theme (docker/keycloak/themes/lineageweave)
  extending keycloak.v2 with the app's Noto Sans / brand-blue tokens,
  white background instead of the stock dark polygon image, and a fixed
  !important-vs-!important override so the realm brand text is legible
  (the parent theme's #kc-header-wrapper white-on-dark color otherwise
  renders white-on-white once the background is swapped to white). Set
  displayName/loginTheme on the realm so "LINEAGEWEAVE-DEMO" no longer
  shows as the raw realm slug.
- Reorder the post-detail popup: the Korean summary and 5W1H now render
  immediately after the title/actions in a two-column grid
  (.popup-analysis-grid, single column below 768px), instead of after
  the full raw post body. The raw body and "Original source state" raw
  codes move below the analysis, next to Event Lineage/Keyman -- they
  are supporting evidence, not the first thing a reader needs to see.
- Fix the phone header (<=768px): .app-header-top-menu no longer clips
  the language/search/logout controls off the right edge of a 390px
  viewport. It now wraps onto additional rows instead, so logout stays
  reachable (SS3.2 requires a clear logout path on every page).

Found via a manual visual E2E walkthrough (login -> board -> post popup
-> workspace destinations -> 390px mobile) driven by Playwright against
the local docker compose stack.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: localize Event Lineage labels

* fix: complete lineage locale coverage

* fix: remove duplicate lineage locale keys

* test: reproduce phone header padding override

* fix: bound normalized body search indexes

* fix: preserve phone header padding

* docs(gap): track external lineage and calendar integration

* docs: record search and phone UI gap fixes

* docs: anchor merged gap baseline

* docs: record current runtime evidence

* docs: record source mapping boundary

* test: preserve global search focus behavior

* fix: preserve UI guide shell and exact Event Lineage evidence

* fix: preserve metric scripts and replay tenant settings

* fix: keep lineage boundary evidence accessible

* docs: refresh UI UX and runtime gap evidence

* docs: refresh stacked PR gate status

* fix: preserve lineage edge direction markers

* fix: bump minimum control size to the 44px touch-target floor

--size-control-min was 24px, well under the WCAG 2.5.5 / platform
minimum of 44x44px. It backed three icon-only, high-traffic controls
with no other size constraint: the mobile drawer hamburger trigger, the
main post-popup close button (.popup-close, previously sized only by
its font-size glyph with no box), and the mobile drawer close button.
Bump the token once and give the trigger/popup-close buttons the
flex centering needed so the larger hit area doesn't misalign the
glyph.

Found via the ui-ux-pro-max skill's touch-target checklist, cross-
checked against the live app.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* feat: add a skip-to-main-content link for keyboard users

The authenticated shell puts a sticky header top-menu (user info,
language, search, logout) and a five-item GNB before <main>, so a
keyboard user had to Tab through all of it on every page load with no
way to jump straight to content. Add a standard skip link: visually
hidden until focused, translated in all five locales, and explicitly
focuses #main-content on activation rather than relying on native
anchor-fragment focus (inconsistent across browsers, notably Safari,
and not exercised by jsdom in tests).

Found via the ui-ux-pro-max skill's Accessibility checklist (Skip
Links, priority 1). Also fixes a stacking bug caught while verifying
it live: the skip link initially shared --z-header with the sticky
header, so with equal z-index the header (later in DOM order) painted
over it -- focused but invisible. Added a dedicated --z-skip-link
token above every other layer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* perf: lazy-load and async-decode embedded post images

Posts can carry a dozen-plus embedded base64 images (e.g. the HSWG
technical-diagram post seen during manual walkthrough). None had
loading="lazy" or decoding="async", so opening a popup forced the
browser to synchronously decode every embedded image up front instead
of deferring off-screen ones -- main-thread cost that scales with how
image-heavy a given post is.

Image scaling (max-width:100%/height:auto) and the Noto Sans web font
load (display=swap + preconnect) were already correct; checked both
while auditing this against the ui-ux-pro-max Performance checklist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs: remove stale duplicate gap section reintroduced by a merge

A concurrent session independently resolved the same
feat/lineage-dag-regression <- fix/uiux-standard-guide-v3-postmerge merge
conflict and pushed it first (d0cef47). Their resolution for
docs/product-technical-gap-baseline.md kept both sides of the conflict
instead of dropping the stale one, reintroducing an old, generic
"## 2. LLM Extraction & Knowledge Graph Gaps" / "## 3. General
Architecture Gaps" section -- duplicating the "## 2" heading number and
sitting stale content (Entity Resolution/Searxng, Base64 Image
Omni-modal, DB Architecture, Zotero, PII masking, LLM Orchestration)
ahead of the detailed, current traceability table that already tracks
every one of those same topics with live-corpus evidence.

Verified equivalent (already-pushed tip matches everywhere else this
worktree's merge resolution touched: workspace-gnb naming, the
skip-link CSS, and the mobile lineage-dag-evidence rules are all
present), then reset this local branch to the pushed tip and removed
just the reintroduced stale section, restoring sequential ## numbering.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: enforce canonical database identifiers

* docs: record final local quality evidence

* docs: anchor final exact audit head

* fix: close mobile navigation and preserve search focus

* docs: refresh acceptance evidence after UI fix

* docs: record mobile navigation review fixes

* fix: use inline SVG icons instead of raw glyphs for menu/close buttons

The mobile drawer trigger ("☰"), drawer close ("×"), and main popup
close (PopupCloseButton, "&times;") all rendered raw font glyphs. A
glyph's shape, weight, and baseline vary by OS/browser font stack --
inconsistent with the design system's rendered chrome and a known
anti-pattern (SVG icons, no emoji/glyph icons is a Must-Have per
ui-ux-pro-max's Style Selection checklist). Added two small inline SVG
icons (MenuIcon, CloseIcon; no new dependency -- native SVG covers it)
using currentColor so they inherit each button's existing color token,
and swapped all three usages. aria-labels are unchanged so no
accessible-name regression.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* test: model mobile drawer navigation flow

* docs: anchor drawer acceptance evidence

* feat: resolve source bodies from verified MHTML artifacts

* fix: floor form-control font-size at 16px to stop iOS auto-zoom

The base font scales down at narrower breakpoints (16px -> 15px -> 14px
at 768px, SS2.1.2), and the existing "Base Form & Input Standards"
block (SS3.1.4) inherited that scale verbatim on every input/select/
textarea. Any focused control under 16px makes iOS Safari zoom the
whole viewport -- a well-known WebKit behavior unrelated to the body-
text density tuning that rule exists for. Floor it at
`max(16px, 1em)` so it still respects an explicitly larger font-size
where one is set, but never drops below 16px. The one place with its
own smaller explicit size (.language-switcher select at 0.82rem) gets
the same floor for the same reason -- select focus triggers the same
WebKit zoom.

Found via the ui-ux-pro-max Typography & Color checklist ("Base 16px").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: respect prefers-reduced-motion and use transform for skip-link

Nothing in the app respected prefers-reduced-motion: reduce -- every
transition/animation played at full motion regardless of the user's OS
setting, an explicit anti-pattern on the ui-ux-pro-max Animation
checklist. Add the standard global override (near-zero duration
instead of fully removing the transition, so state changes stay
perceptible without the motion itself).

Also switch the skip-link's reveal-on-focus from animating `top`
(layout-triggering) to `transform: translateY()` (compositor-only) --
the same category of fix as the checklist's "animating width/height"
anti-pattern, free to make while touching this rule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs: refresh source mapping acceptance evidence

* fix: clear stale search focus on navigation

* fix: improve post popup action layout

* docs: record navigation focus acceptance

* fix: label chat and ticket inputs

* docs: anchor accessibility acceptance head

* feat: model operational vocabularies in ontology

* fix: preserve popup history navigation

* fix: name lineage DAG node kind for screen readers and tooltips

Root/branch/current status was only conveyed by stroke color and
border width. Add the same legend wording used visually to each
node's aria-label and title tooltip so it reaches screen reader
and colorblind users too.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs: refresh product gap evidence baseline

* fix: preserve search focus request boundaries

* fix: add send affordance to ask actions

* docs: anchor baseline to final UI head

* feat: add desktop site map utility

* fix: improve desktop evidence popup layout

* docs: record site map and popup gap evidence

* feat: turn Ask Agent into an evidence conversation

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Live query against the seeded stack shows /api/customer-master's
entity list is scoped to account_affiliation grants only (the
account's own employer plus explicit grants), with no schema
signal separating "own company" from "granted customer entity."
Counterparty entities ADR 0010's auto-creation resolves are never
linked via account_affiliation, so the "Harbor Group -> Harbor
Devices Korea" customer-affiliate tree ADR 0004/0010 describe
cannot reach this endpoint regardless of corpus size. Needs an
ADR before implementation, not a guessed schema change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Live query against the seeded stack shows /api/customer-master's
entity list is scoped to account_affiliation grants only (the
account's own employer plus explicit grants), with no schema
signal separating "own company" from "granted customer entity."
Counterparty entities ADR 0010's auto-creation resolves are never
linked via account_affiliation, so the "Harbor Group -> Harbor
Devices Korea" customer-affiliate tree ADR 0004/0010 describe
cannot reach this endpoint regardless of corpus size. Needs an
ADR before implementation, not a guessed schema change.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
5W1H had zero custom CSS -- the browser default <dl>/<details>
layout gave every value's evidence-source disclosure its own
full-width line, so e.g. 9 "누가" entries meant 18 stacked lines
where R&R conveys the same kind of evidence on one compact line
per entry. .semantic-provenance is shared with the Projects/
semantic evidence section, so it gets the same fix.

R&R now reads organization, then team, then person (PROV-O's
broader/narrower direction, ADR 0004) instead of raw LLM
extraction order, grouped by affiliated organization within each
tier so one org's people don't interleave with another's.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
seonghobae and others added 27 commits August 24, 2026 04:07
* fix: require explicit location evidence in 5W1H

* refactor: stop loading unused 5W1H counterparties

* refactor: remove stale 5W1H location lookup
…e last page

total_count came from count(*) over(), a window function that only
rides along on rows surviving the query's own OFFSET/LIMIT. Once the
offset skipped past every matching row, the query returned zero rows
and total_count silently fell back to 0 even though matches existed --
a routine "user paged past the end" or "a filter change shrank the
result set" scenario. A paginator relying on total_count to detect the
overshoot would instead see "0 results" and could wrongly conclude
nothing matched.

Extracted the query's ~170-line predicate into a shared
_list_posts_predicate_sql variable (byte-identical to the inline text
it replaces) so a small fallback count(*) query -- used only when the
main page comes back empty -- can reuse it without duplicating that
much SQL. Renumbers the shared predicate's $10/$11 to $7/$8 since the
fallback has no offset/limit/sort parameters of its own.

Regression test confirmed RED (reported 0 instead of the real count)
before GREEN. Also updated the repo's static SQL-suppression count
contract (37 -> 38) for the new reviewed nosemgrep site.

Found by an Explore agent hunting for a different bug class after
the "unfiltered-then-filtered ABAC leak" well ran dry this session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011EP69xAyLaJxa6oaF6D9eq
A key-set diff of i18n.ts's four non-English locale blocks found 117
keys added for Korean that were never mirrored into zh/ja/vi -- t()
silently falls back to the raw English key when a translation is
missing, and no test catches it since the existing i18n test only
checks curated key lists a component's keys have to be manually added
to (AdminPanel's never were).

Closed the 20 keys AdminPanel.tsx actually uses (control center,
endpoint catalog, tenant settings, board/calendar/entity navigation,
and related copy) with zh/ja/vi translations matching this file's
established terminology (Tenant, Workspace, Board, Admin), and added a
curated adminPanelLabels parity test following the exact pattern the
existing workspace/Event Lineage label tests already use. Confirmed
RED (falls back to the English key) before GREEN.

The remaining 97 ko-only keys (used by components not yet audited)
are intentionally not touched here -- translating 97 keys x 3 locales
without a dedicated review pass risks shipping worse translations than
the visible-gap status quo, and is tracked as a separate follow-up in
the gap baseline rather than forced through this checkpoint.

Found by an Explore agent hunting for a non-ABAC-leak bug class.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011EP69xAyLaJxa6oaF6D9eq
* fix: gate image summaries on persisted vision evidence

* fix: bind summaries to current source evidence

* fix: fence post content worker claims

* fix: fence current vision projections

* fix: serialize summary catalog writes

* fix: separate vision proposals from row locks

* fix: reuse prepared sibling organization aliases

* fix: keep prepared hierarchy aliases distinct
The previous checkpoint closed the 20 keys AdminPanel.tsx references
as literal t("...") calls, but missed 33 more: its endpoint-catalog
and navigation-group metadata (ADMIN_LNB_GROUPS, ADMIN_OPERATIONS) is
defined as label/description/note fields on data arrays, rendered via
t(item.label) -- a literal-string grep can't see through the variable
indirection. Two of the 33 (Rankings, Workspace) were written as
unquoted object keys and weren't even in Korean yet.

Found this second slice by grepping the component's own data arrays
directly instead of its t("...") call sites. Translated all 33 into
zh/ja/vi matching the file's established terminology, and extended the
adminPanelLabels parity test to all 53 of AdminPanel's live keys.
Confirmed RED (falls back to English) before GREEN.

~64 other pre-existing ko-only keys (mostly in App.tsx) remain a
separate, tracked, not-yet-closed gap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011EP69xAyLaJxa6oaF6D9eq
ADR 0049 leftover pair copy names the post and criterion only.
Saved IRT scores stay visible when the evaluation channel is down.
Post-content worker tests pass factory callables without lambda wrappers.
Record exact continuation head 154a13e, leftover next-action close,
leftover-map TypeScript repairs, and the current open-PR SHA listing.
* feat: remember login return path before OIDC redirect (v2.12.19)

Unauthenticated Log in now stores a validated same-origin return
path (ADR 0119 / 0109) before signinRedirect, so a shared /?post=
link still opens that post after callback. Tenant admin settings
stay off the signed-out login shell so tsc -b type-checks.

Independent of leftover-map PRs. Do not invent a leftover score
or a theta. Synthetic fixtures only.

* docs: reuse OIDC deep-link decision

* fix: remember login return path on every OIDC start

Stack onto the workspace branch without force-push. Persist a validated
same-origin path before redirect so a shared post link survives callback
when OIDC state is missing. Admin settings stay unmounted until login.

---------

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
…ions

read_customer_master (GET /api/customer-master, ADR 0125) passed
entity_ids -- the endpoint's broad Customer Master listing, which also
includes entities the account merely *observes* (mentioned in a
visible post, never actually affiliated with) -- into
fetch_relationship_network as its ABAC scope parameter.

fetch_relationship_network's SQL treats corporate_entity_ids exactly
like _can_see_post's `post.corporate_entity_id = any($1)` clause, so
passing the broader observed-inclusive listing let a private post
owned by one of those observed-only entities leak its counterparty
classification into relationship_network -- a real cross-tenant data
leak, not just an over-broad display list.

The pre-existing giant Customer Master contract test
(test_customer_master_returns_authorized_catalog_contract) did not
catch this: its `"Private Other Corp" not in network` assertion passed
only incidentally, because the demo-vs-real-data source-context
eligibility heuristic (SOURCE_POST_ELIGIBILITY_SQL) happened to already
exclude the relevant fixture post for an unrelated reason.

Fix: scope the call to account.corporate_entity_ids (the account's own
real affiliations), net of the same synthetic-only/stale-demo-grant
exclusion (fetch_demo_corporate_entity_ids) the entity tree query just
above it already applies once real source context exists. An initial
fix using the raw account.corporate_entity_ids list (without that
exclusion) still let a stale demo grant leak back in -- caught by the
existing giant contract test failing after the fix, corrected before
this commit.

Added a new focused regression test that deliberately defeats the
demo-vs-real eligibility heuristic (giving both the mentioning and the
mentioned posts real source context) to isolate the ABAC-scoping
behavior being tested, independent of the heuristic. Verified RED
against pre-fix code (both the scope-widening leak and the
observed-corp capture assertion failed), GREEN after. Full suite:
1032 passed, 17 skipped, no regressions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011EP69xAyLaJxa6oaF6D9eq
SourceResearchPanel's load callback had no request-id guard on its
fetchPostSourceResearch call. Switching posts quickly (or the
runResearch -> load refresh racing a still-in-flight initial load)
could let an earlier post's response resolve after the panel had
already moved to a newer post, rendering the wrong post's persisted
source research.

Added the same requestIdRef counter/compare guard already used
elsewhere in App.tsx (historyRequestIdRef, relatedRequest,
postsRequest): each call to load() claims a new request id, and every
state-setting branch (success, error, and the loading finally) checks
it's still current before applying.

Found by the same lineageweave-bug-sweep Workflow finder that surfaced
the Customer Master ABAC leak fixed in the previous commit. Added a
regression test that starts a slow post-1 fetch, switches to post-2
before it resolves, then resolves the stale post-1 response and
asserts its lead never renders. Confirmed RED against pre-fix code
(the stale lead rendered), GREEN after. Full frontend suite: 361
passed, lint clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011EP69xAyLaJxa6oaF6D9eq
Root-caused the reader-reported Event Lineage entanglement bug:
reconstruct_group_key's process_unit_id fallback creates a
multi-thousand-post mega-group, and channels.py's text_similarity_score
is difflib character-overlap rather than embeddings, so temporally-close
but topically-unrelated posts clear the 0.3 min_fused_score floor when
no AdjudicationClient is configured. Independent of the open PR wiring
AdjudicationClient into rebuild_lineage(); both causes above remain open
after that PR merges.
The Source Detail popup's "Source lineage combination" panel -- the
combination-code badge, the four-field presence list, and the nine
commercial_context_code labels plus four SOURCE_LINEAGE_FIELDS labels
computed in frontend/src/sourceLineageHints.ts -- was translated only
into Korean. zh/ja/vi silently fell back to the raw English key for
all 29 of this panel's keys, since t() has no missing-translation
warning and the existing i18n test only checks curated key lists a
feature's keys must be manually added to (same root cause as the
Admin Panel gap fixed earlier this session).

A per-locale re-run of the key-diff (missing-from-ko per individual
locale, not "missing from all three at once") confirmed zh, ja, and
vi are missing the identical 68-key set -- no per-locale asymmetry to
track separately. Scoped this checkpoint to the 29 keys belonging to
this one panel (Catalog hint, Combination code, Field combination,
Present/Not present, Inferred from field presence, Lifecycle vector,
the nine commercial-context labels, the four SOURCE_LINEAGE_FIELDS
labels, and related Source * field-hint keys); the other ~39 ko-only
keys are a separate Board/R&R/customer-identity-search slice, not
attempted here.

Added zh/ja/vi translations matching this file's established
terminology (来源/原典/nguồn for "Source", 谱系/系譜/dòng for
"lineage", 客户/顧客/khách hàng for "customer") and a new curated
sourceLineageHintLabels parity test following the same pattern as
adminPanelLabels/eventLineageLabels. Confirmed RED (all three locales
fell back to raw English) before GREEN. Full frontend suite: 365
passed, lint clean, tsc clean.

Found by the same lineageweave-bug-sweep Workflow finder that
surfaced the Customer Master ABAC leak and SourceResearchPanel race
fixed earlier this checkpoint.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011EP69xAyLaJxa6oaF6D9eq
Second gap-baseline i18n slice: 22 keys used by the Board hand-off
prompt, R&R semantic-relationship predicates (Responsible for,
Supports, Organization member/unit of, Sub-organization of), the
evidence workspace, and AdminPanel's Account/Permissions/routes
fields were ko-only, silently falling back to the raw English key
in zh/ja/vi. Extends the i18n.test.ts parity check the same way the
prior AdminPanel slice did. Source-lineage-hints-panel keys are a
separate concurrent slice on this branch, not touched here.
Peer's source-lineage-hints i18n slice landed concurrently on this
branch and independently translated "Lifecycle vector" (it belongs
to that panel per post.source_lineage_hints.lifecycle_vector,
App.tsx:3182). Dropped the duplicate copy from this checkpoint's
Board/R&R slice, keeping the peer's entry as the single source of
truth for that key in zh/ja/vi.
Documents the third i18n gap-baseline checkpoint (22 Board/R&R keys)
and how it landed alongside a peer session's concurrent 30-key
source-lineage-hints slice on the same branch, including the one
duplicate-key resolution. 18 keys remain, all in the source-lineage
panel's remaining surface -- not claimed closed here.
PR #538 (ADR 0190) wires embedding_client.py into reconstruct()'s text
channel, stacked on PR #434's adjudication-client wiring. The grouping-key
architecture question (process_unit_id fallback) remains open by design.
Repo convention pairs every component with a .stories.tsx (anti-ui-
slop / ui-ux-pro-max review process). A sweep of frontend/src/components
found AdminPanel.tsx, FiveW1H.tsx, and icons.tsx shipped without one.
AdminPanel and FiveW1H stories cover their real states (loading,
grounded evidence, all-dimensions-empty, no affiliations, tenant
settings) with play-function assertions matching this repo's existing
story pattern; the settings-save button is deliberately left unclicked
since it performs a real network call this story doesn't mock. icons.tsx
is three prop-less SVG glyphs, so it gets one gallery story rather than
a dedicated unit test -- there is no logic to assert on.

SourceResearchPanel.tsx is still missing a story but is mid-edit by a
concurrent session's i18n slice on this branch; left untouched to avoid
a collision. LeftoverPairButton.tsx's missing test belongs to the
leftover-map PR stack another session already owns.
`/` now opens a news-portal Dashboard ranking important posts and
important projects by real fast-mlsirm FIPC-calibrated theta (the
already-shipped ADR 0003 pipeline, grouping_kind="project"), falling
back to RankWeave's fused ranking when no project period report has
been calibrated yet. No score is invented anywhere on the page, and
TEPP is intentionally not used as an importance source since it has
no live HTTP transport yet (ADR 0145).

No new backend endpoint: the Dashboard reuses fetchPeriodReportIndex,
fetchPeriodReports, and fetchRankings exactly as the existing Period
Reports panel and Rankings panel already do. The Board stays one
click away as the first Workspace nav item after Dashboard; global
search and admin board-tool deep links still route to Board
unchanged. Unauthorized admin deep links now fall back to Dashboard
(the true home) instead of Board.

Ships with ko/zh/ja/vi translations, Storybook stories covering
loaded/empty/fallback/loading/unavailable states, and component
tests asserting every rendered score traces back to a mocked
service call rather than a literal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019zL1WPKcHD6DrRVxGj1Mpx
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 314 files, which is 214 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 95287349-112a-47ec-b6bf-50787c02c916

📥 Commits

Reviewing files that changed from the base of the PR and between ef6f5a5 and c941e33.

⛔ Files ignored due to path filters (2)
  • frontend/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (314)
  • .dockerignore
  • .github/workflows/repair-global-ask-pnpm-v2.yml
  • .github/workflows/tests.yml
  • AGENTS.md
  • ARCHITECTURE.md
  • CHANGELOG.d/2.12.19-oidc-login-return-remember.md
  • CHANGELOG.d/2.12.6-frontend-build-gate.md
  • CHANGELOG.d/2.12.6-provider-error-boundary.md
  • CHANGELOG.d/2.12.6-related-posts-unavailable.md
  • CHANGELOG.d/2.12.6-remove-self-modifying-repair-workflows.md
  • CHANGELOG.d/2.12.6-temporal-semantic-order.md
  • CHANGELOG.d/2.12.7-lineage-dag-evidence.md
  • CHANGELOG.d/2.16.1-planned-facility-relation.md
  • CHANGELOG.d/dashboard-home-route.md
  • CHANGELOG.d/fivew1h-empty-evidence-guidance.md
  • CHANGELOG.d/global-ask-history-compose-replay.md
  • CHANGELOG.d/image-evidence-queue.md
  • CHANGELOG.d/post-content-explicit-retry.md
  • CHANGELOG.d/source-identity-eligibility.md
  • CHANGELOG.d/synthetic-seed-source-context.md
  • CHANGELOG.md
  • add_translations.py
  • backend/Dockerfile
  • backend/app/analysis_run_ingestion.py
  • backend/app/analysis_run_start.py
  • backend/app/auth.py
  • backend/app/config.py
  • backend/app/corporate_entity_ingestion.py
  • backend/app/customer_hint_ingestion.py
  • backend/app/demo_scope.py
  • backend/app/entity_relationship_ingestion.py
  • backend/app/five_w1h_ingestion.py
  • backend/app/global_ask_history.py
  • backend/app/issue_ticket_ingestion.py
  • backend/app/keyman_ingestion.py
  • backend/app/knowledge_graph.py
  • backend/app/lineage_ingestion.py
  • backend/app/main.py
  • backend/app/organization_name_resolution_ingestion.py
  • backend/app/post_ask_history.py
  • backend/app/post_chat_ingestion.py
  • backend/app/post_content_queue.py
  • backend/app/post_content_worker.py
  • backend/app/post_eligibility.py
  • backend/app/post_evaluation_ingestion.py
  • backend/app/post_summary_ingestion.py
  • backend/app/ranking_ingestion.py
  • backend/app/report_ingestion.py
  • backend/app/source_research_ingestion.py
  • backend/tests/test_api.py
  • backend/tests/test_auth_jwks.py
  • docker-compose.yml
  • docker/keycloak/Dockerfile
  • docker/keycloak/realm-export.json
  • docker/keycloak/themes/lineageweave/login/resources/css/lineageweave.css
  • docker/keycloak/themes/lineageweave/login/theme.properties
  • docker/postgres-init/migrate.sh
  • docker/searxng/settings.yml
  • docs/adr/0002-figma-access-boundary.md
  • docs/adr/0003-fast-mlsirm-report-integration.md
  • docs/adr/0018-related-nodes-team-org-walk.md
  • docs/adr/0022-authorized-tepp-start.md
  • docs/adr/0040-source-state-provenance.md
  • docs/adr/0042-source-hints-before-customer-binding.md
  • docs/adr/0049-leftover-pair-report-ui.md
  • docs/adr/0052-plain-orchestrator-semantic-evidence.md
  • docs/adr/0063-third-normal-form-bookmarks.md
  • docs/adr/0090-global-ask-lineage-timeline-expansion.md
  • docs/adr/0098-valkey-backed-post-content-ingestion.md
  • docs/adr/0105-mathematical-script-semantic-normalization.md
  • docs/adr/0109-oidc-deep-link-state-recovery.md
  • docs/adr/0114-stale-summary-buyer-continuity.md
  • docs/adr/0115-explicit-terminal-content-retry.md
  • docs/adr/0119-retire-buyer-terminology.md
  • docs/adr/0120-two-word-database-identifiers.md
  • docs/adr/0121-mhtml-source-body-resolution.md
  • docs/adr/0123-provider-error-boundary.md
  • docs/adr/0124-operational-controlled-vocabulary-semantic-layer.md
  • docs/adr/0125-customer-master-scope-facets.md
  • docs/adr/0126-global-ask-conversation-history.md
  • docs/adr/0127-role-affiliation-catalog-identity.md
  • docs/adr/0128-source-grounded-quantitative-observations.md
  • docs/adr/0129-standards-aligned-event-clue-ontology-profile.md
  • docs/adr/0130-source-commercial-context-hints.md
  • docs/adr/0131-explicit-organization-project-relations.md
  • docs/adr/0132-tenant-identity-metadata.md
  • docs/adr/0133-source-reference-research-agent.md
  • docs/adr/0134-token-backed-exception-messages.md
  • docs/adr/0135-analysis-result-kind-exact-next-actions.md
  • docs/adr/0136-post-ask-conversation-history.md
  • docs/adr/0137-cross-post-customer-identity.md
  • docs/adr/0141-catalog-unresolved-diagnosability.md
  • docs/adr/0142-planned-facility-project-evidence.md
  • docs/adr/0143-lineage-isolation-reason.md
  • docs/adr/0144-superseded-index-migration-replay.md
  • docs/adr/0145-dashboard-home-route.md
  • docs/doctoring/CUSTOMER_MASTER_SCOPE_REFERENCES.md
  • docs/doctoring/DESIGN_TOKEN_REFERENCES.md
  • docs/image-content-schema.md
  • docs/lineage-bi-research-notes.md
  • docs/ontology/lineageweave-kg.ttl
  • docs/ontology/lineageweave-shapes.ttl
  • docs/product-technical-gap-baseline.md
  • docs/storybook-inventory.md
  • docs/superpowers/plans/2026-08-21-forward-only-fast-stabilization.md
  • frontend/.dockerignore
  • frontend/.gitignore
  • frontend/index.html
  • frontend/package.json
  • frontend/src/App.css
  • frontend/src/App.test.tsx
  • frontend/src/App.tsx
  • frontend/src/AskAgentPanel.stories.tsx
  • frontend/src/ChatPanel.stories.tsx
  • frontend/src/KnowledgeGraph.css
  • frontend/src/KnowledgeGraph.stories.tsx
  • frontend/src/KnowledgeGraph.test.tsx
  • frontend/src/KnowledgeGraph.tsx
  • frontend/src/LineageDag.css
  • frontend/src/LineageDag.css.test.ts
  • frontend/src/LineageDag.stories.tsx
  • frontend/src/LineageDag.test.tsx
  • frontend/src/LineageDag.tsx
  • frontend/src/PostBody.test.tsx
  • frontend/src/PostBody.tsx
  • frontend/src/analysisEvidenceDiagnosis.test.ts
  • frontend/src/analysisEvidenceDiagnosis.ts
  • frontend/src/analysisRunGuidance.test.ts
  • frontend/src/analysisRunGuidance.ts
  • frontend/src/api.test.ts
  • frontend/src/api.ts
  • frontend/src/components/AdminPanel.css
  • frontend/src/components/AdminPanel.stories.tsx
  • frontend/src/components/AdminPanel.test.tsx
  • frontend/src/components/AdminPanel.tsx
  • frontend/src/components/AnalysisRunNextAction.stories.tsx
  • frontend/src/components/AnalysisRunNextAction.test.tsx
  • frontend/src/components/AnalysisRunNextAction.tsx
  • frontend/src/components/BuyerNav.tsx
  • frontend/src/components/CitationChip.test.tsx
  • frontend/src/components/CutoffKnownBody.stories.tsx
  • frontend/src/components/Dashboard.stories.tsx
  • frontend/src/components/Dashboard.test.tsx
  • frontend/src/components/Dashboard.tsx
  • frontend/src/components/FiveW1H.stories.tsx
  • frontend/src/components/FiveW1H.test.tsx
  • frontend/src/components/FiveW1H.tsx
  • frontend/src/components/GlobalSearch.stories.tsx
  • frontend/src/components/GlobalSearch.test.tsx
  • frontend/src/components/GlobalSearch.tsx
  • frontend/src/components/LeftoverPairButton.stories.tsx
  • frontend/src/components/LeftoverPairButton.tsx
  • frontend/src/components/LineageDag.stories.tsx
  • frontend/src/components/PopupCloseButton.test.tsx
  • frontend/src/components/PopupCloseButton.tsx
  • frontend/src/components/RoleEvidence.stories.tsx
  • frontend/src/components/RoleEvidence.test.tsx
  • frontend/src/components/RoleEvidence.tsx
  • frontend/src/components/SourceResearchPanel.test.tsx
  • frontend/src/components/SourceResearchPanel.tsx
  • frontend/src/components/SummaryStatus.stories.tsx
  • frontend/src/components/SummaryStatus.test.tsx
  • frontend/src/components/SummaryStatus.tsx
  • frontend/src/components/WorkspaceNav.stories.tsx
  • frontend/src/components/WorkspaceNav.test.tsx
  • frontend/src/components/WorkspaceNav.tsx
  • frontend/src/components/icons.stories.tsx
  • frontend/src/components/icons.tsx
  • frontend/src/components/roleEvidenceUtils.ts
  • frontend/src/graphLabel.test.ts
  • frontend/src/graphLabel.ts
  • frontend/src/i18n.test.ts
  • frontend/src/i18n.ts
  • frontend/src/index.css
  • frontend/src/indexHtml.test.ts
  • frontend/src/knowledgeGraphCss.test.ts
  • frontend/src/leftoverPairGuidance.test.ts
  • frontend/src/leftoverPairGuidance.ts
  • frontend/src/lineageDagI18n.test.ts
  • frontend/src/lineageDagI18n.ts
  • frontend/src/lineageLayout.test.ts
  • frontend/src/lineageLayout.ts
  • frontend/src/main.test.tsx
  • frontend/src/mobileHeaderCss.test.ts
  • frontend/src/oidcReturnUrl.test.ts
  • frontend/src/popupLayoutCss.test.ts
  • frontend/src/postBodyDisplay.test.ts
  • frontend/src/postBodyDisplay.ts
  • frontend/src/productExceptionCopy.test.ts
  • frontend/src/productExceptionCopy.ts
  • frontend/src/sourceLineageHints.test.ts
  • frontend/src/sourceLineageHints.ts
  • frontend/src/styles/tokens.css
  • frontend/src/styles/tokens.test.ts
  • frontend/vite.config.ts
  • lineageweave/adjudication_client.py
  • lineageweave/affiliate_tree.py
  • lineageweave/caldav_client.py
  • lineageweave/chunking.py
  • lineageweave/commitment_extraction.py
  • lineageweave/corporate_hierarchy_inference.py
  • lineageweave/customer_hint_resolution.py
  • lineageweave/customer_identity_judgment.py
  • lineageweave/entity_relationship_classification.py
  • lineageweave/five_w1h.py
  • lineageweave/http_client.py
  • lineageweave/image_content.py
  • lineageweave/keyman_extraction.py
  • lineageweave/knowledge_graph.py
  • lineageweave/ontology.py
  • lineageweave/organization_name_resolution.py
  • lineageweave/post_chat.py
  • lineageweave/post_content_persistence.py
  • lineageweave/post_evaluation.py
  • lineageweave/post_structure.py
  • lineageweave/post_summary.py
  • lineageweave/rankweave_client.py
  • lineageweave/semantic_hints.py
  • lineageweave/server.py
  • lineageweave/source_artifacts.py
  • lineageweave/source_lineage_hints.py
  • lineageweave/source_research.py
  • lineageweave/synthetic_seed_cleanup.py
  • lineageweave/tepp_client.py
  • lineageweave/voc_evidence.py
  • migrations/0001_initial_schema.sql
  • migrations/0008_post_summary_result.sql
  • migrations/0018_analysis_run_registry.sql
  • migrations/0031_semantic_project_mentions.sql
  • migrations/0035_body_search_prefix.sql
  • migrations/0036_normalized_body_search.sql
  • migrations/0043_bookmark.sql
  • migrations/0044_member_locale_preference.sql
  • migrations/0103_tenant_settings.sql
  • migrations/0104_two_word_database_identifiers.sql
  • migrations/0105_global_ask_conversation_history.sql
  • migrations/0106_account_affiliation_scope_facet.sql
  • migrations/0107_role_affiliation_catalog_identity.sql
  • migrations/0108_post_summary_quantitative_observation.sql
  • migrations/0109_post_summary_source_fact.sql
  • migrations/0110_role_responsibility_software_agent.sql
  • migrations/0111_post_summary_semantic_relationship.sql
  • migrations/0112_event_clue_semantic_projection.sql
  • migrations/0113_broad_source_fact_types.sql
  • migrations/0114_semantic_relationship_standard_predicates.sql
  • migrations/0130_source_commercial_context.sql
  • migrations/0133_source_reference_research.sql
  • migrations/0134_catalog_unresolved_reason.sql
  • migrations/0136_post_ask_conversation_history.sql
  • migrations/0137_cross_post_customer_identity.sql
  • migrations/0138_planned_facility_relation_predicate.sql
  • migrations/0139_post_summary_input_binding.sql
  • migrations/0176_tenant_identity_metadata.sql
  • migrations/rollback/0104_two_word_database_identifiers.sql
  • migrations/rollback/0105_global_ask_conversation_history.sql
  • migrations/rollback/0106_account_affiliation_scope_facet.sql
  • migrations/rollback/0134_catalog_unresolved_reason.sql
  • migrations/rollback/0138_planned_facility_relation_predicate.sql
  • migrations/rollback/0139_post_summary_input_binding.sql
  • pyproject.toml
  • scripts/backfill_post_content.py
  • scripts/backfill_post_keymen.py
  • scripts/backfill_post_summaries.py
  • scripts/import_postgresql_posts.py
  • scripts/queue_post_content_backfill.py
  • scripts/requeue_failed_post_content.py
  • scripts/seed_demo_data.py
  • tests/test_adaptive_orchestration_defaults.py
  • tests/test_analysis_run_start.py
  • tests/test_chat_request_validation.py
  • tests/test_chunking.py
  • tests/test_customer_hint_ingestion.py
  • tests/test_customer_identity_judgment.py
  • tests/test_five_w1h.py
  • tests/test_global_ask_history.py
  • tests/test_global_ask_sources.py
  • tests/test_http_client.py
  • tests/test_http_client_edges.py
  • tests/test_import_postgresql_posts.py
  • tests/test_ingestion_transaction_contracts.py
  • tests/test_knowledge_graph.py
  • tests/test_lineage_ingestion.py
  • tests/test_llm_context.py
  • tests/test_migration_replay.py
  • tests/test_ontology.py
  • tests/test_organization_name_resolution_ingestion.py
  • tests/test_period_report.py
  • tests/test_person_mention_projection.py
  • tests/test_post_ask_history.py
  • tests/test_post_chat.py
  • tests/test_post_chat_ingestion.py
  • tests/test_post_content_api_readiness.py
  • tests/test_post_content_normalization.py
  • tests/test_post_content_persistence.py
  • tests/test_post_content_queue.py
  • tests/test_post_content_worker.py
  • tests/test_post_eligibility.py
  • tests/test_post_summary.py
  • tests/test_public_docstrings.py
  • tests/test_queue_post_content_backfill.py
  • tests/test_rankweave_client.py
  • tests/test_schema.py
  • tests/test_semantic_author_provenance.py
  • tests/test_semantic_hints.py
  • tests/test_source_artifacts.py
  • tests/test_source_lineage_hints.py
  • tests/test_source_research.py
  • tests/test_source_research_knowledge_graph.py
  • tests/test_source_research_security.py
  • tests/test_stale_summary_continuity.py
  • tests/test_static_sql_review_contracts.py
  • tests/test_synthetic_seed_cleanup.py
  • tests/test_tepp_client.py
  • tests/test_tied_organization_no_create.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Closing as out of lane. Buyer GNB is locked to 주시판 / 고객 마스터 / 달력 / Ask Agent. Dashboard as / landing is a fifth home. Unique slice remains #258.

@seonghobae seonghobae closed this Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant