Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
c7ca106
fix: align buyer lineage shell with UI UX guide
seonghobae Aug 21, 2026
8ec2cd1
docs: track post-merge UI UX review gate
seonghobae Aug 21, 2026
26e61d3
feat: expose authorized account scope and global search
seonghobae Aug 21, 2026
4068bc5
fix: place locale control in header top menu
seonghobae Aug 21, 2026
5b727e7
docs: record central hourly merge loop
seonghobae Aug 21, 2026
483383b
fix: refocus buyer search after board load
seonghobae Aug 21, 2026
67ca679
refactor: retire "Buyer" terminology across code and living docs
seonghobae Aug 21, 2026
0937a98
fix: translate workspace navigation labels
seonghobae Aug 21, 2026
d49c716
fix: make buyer search focus one-shot and localize lineage label
seonghobae Aug 21, 2026
a1eae30
docs: record authenticated UI UX gap evidence
seonghobae Aug 21, 2026
8d429de
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
9d124c8
fix: use lineage evidence terminology
seonghobae Aug 21, 2026
e58c3a2
fix: keep health probe public and settings route covered
seonghobae Aug 21, 2026
f74df9e
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
8d24147
docs: record current health and lineage coverage gaps
seonghobae Aug 21, 2026
c616a11
fix: brand the Keycloak login theme and put post-popup analysis first
seonghobae Aug 21, 2026
a398440
fix: localize Event Lineage labels
seonghobae Aug 21, 2026
c050237
fix: complete lineage locale coverage
seonghobae Aug 21, 2026
c5d8a64
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
525ce57
fix: remove duplicate lineage locale keys
seonghobae Aug 21, 2026
fc04fe3
test: reproduce phone header padding override
seonghobae Aug 21, 2026
ce28033
fix: bound normalized body search indexes
seonghobae Aug 21, 2026
9444a7c
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
35c89cf
fix: preserve phone header padding
seonghobae Aug 21, 2026
32308e1
docs(gap): track external lineage and calendar integration
seonghobae Aug 21, 2026
ff197e0
docs: record search and phone UI gap fixes
seonghobae Aug 21, 2026
1982348
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
e254a2b
docs: anchor merged gap baseline
seonghobae Aug 21, 2026
274b437
docs: record current runtime evidence
seonghobae Aug 21, 2026
a375d53
docs: record source mapping boundary
seonghobae Aug 21, 2026
f0c4d6a
test: preserve global search focus behavior
seonghobae Aug 21, 2026
443908d
fix: preserve UI guide shell and exact Event Lineage evidence
seonghobae Aug 21, 2026
ef7d334
Merge Event Lineage foundation into UI UX guide stack
seonghobae Aug 21, 2026
f0a5b1e
fix: preserve metric scripts and replay tenant settings
seonghobae Aug 21, 2026
eca0fa0
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
344ee14
fix: keep lineage boundary evidence accessible
seonghobae Aug 21, 2026
7d8164d
docs: refresh UI UX and runtime gap evidence
seonghobae Aug 21, 2026
5d0ba46
docs: refresh stacked PR gate status
seonghobae Aug 21, 2026
cf47d7c
fix: preserve lineage edge direction markers
seonghobae Aug 21, 2026
a51f6ff
fix: bump minimum control size to the 44px touch-target floor
seonghobae Aug 21, 2026
b3454bd
feat: add a skip-to-main-content link for keyboard users
seonghobae Aug 21, 2026
77ee1ac
perf: lazy-load and async-decode embedded post images
seonghobae Aug 21, 2026
d0cef47
Merge latest lineage DAG base into UI UX shell
seonghobae Aug 21, 2026
4714fd5
docs: remove stale duplicate gap section reintroduced by a merge
seonghobae Aug 21, 2026
5b8eda8
fix: enforce canonical database identifiers
seonghobae Aug 21, 2026
5d9a43f
docs: record final local quality evidence
seonghobae Aug 21, 2026
694e617
docs: anchor final exact audit head
seonghobae Aug 21, 2026
7ff03df
fix: close mobile navigation and preserve search focus
seonghobae Aug 21, 2026
1fa70b0
docs: refresh acceptance evidence after UI fix
seonghobae Aug 21, 2026
1dd7926
docs: record mobile navigation review fixes
seonghobae Aug 21, 2026
d1e4861
fix: use inline SVG icons instead of raw glyphs for menu/close buttons
seonghobae Aug 21, 2026
b08b406
test: model mobile drawer navigation flow
seonghobae Aug 21, 2026
6d3ae80
docs: anchor drawer acceptance evidence
seonghobae Aug 21, 2026
847e85f
feat: resolve source bodies from verified MHTML artifacts
seonghobae Aug 21, 2026
81af273
fix: floor form-control font-size at 16px to stop iOS auto-zoom
seonghobae Aug 21, 2026
379ee7e
fix: respect prefers-reduced-motion and use transform for skip-link
seonghobae Aug 21, 2026
776b9dc
docs: refresh source mapping acceptance evidence
seonghobae Aug 21, 2026
33e512a
fix: clear stale search focus on navigation
seonghobae Aug 21, 2026
9a708f0
fix: improve post popup action layout
seonghobae Aug 21, 2026
f7558fa
docs: record navigation focus acceptance
seonghobae Aug 21, 2026
93f924a
fix: label chat and ticket inputs
seonghobae Aug 21, 2026
fa6f627
docs: anchor accessibility acceptance head
seonghobae Aug 21, 2026
0747f56
feat: model operational vocabularies in ontology
seonghobae Aug 21, 2026
7fce1da
fix: preserve popup history navigation
seonghobae Aug 21, 2026
d74ed82
fix: name lineage DAG node kind for screen readers and tooltips
seonghobae Aug 21, 2026
c7146e0
docs: refresh product gap evidence baseline
seonghobae Aug 21, 2026
0d13919
fix: preserve search focus request boundaries
seonghobae Aug 21, 2026
4e3e470
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
6e06191
fix: add send affordance to ask actions
seonghobae Aug 21, 2026
9ea90c9
docs: anchor baseline to final UI head
seonghobae Aug 21, 2026
bbcc5e3
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
234300e
feat: add desktop site map utility
seonghobae Aug 21, 2026
57104a7
Merge remote-tracking branch 'origin/fix/uiux-standard-guide-v3-postm…
seonghobae Aug 21, 2026
b897fab
fix: improve desktop evidence popup layout
seonghobae Aug 21, 2026
8724326
docs: record site map and popup gap evidence
seonghobae Aug 21, 2026
819ef87
feat: turn Ask Agent into an evidence conversation
seonghobae Aug 21, 2026
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
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ reimplementing them:
tree assembly (`reconstruct.py`'s `_walk`/`thread_messages` calls).
- [RankWeave](https://github.com/ContextualWisdomLab/RankWeave) for
multi-channel score fusion (`weighted_convex_fuse` in
`reconstruct.py`) and the buyer-facing Rankings port
`reconstruct.py`) and the reader-facing Rankings port
(`rankweave_client.py`) -- never invent a fused score or a theta.
- [TEPP](https://github.com/ContextualWisdomLab/TEPP)'s published wire
contract for calibrated measurement (`tepp_client.py`) -- never
Expand Down Expand Up @@ -127,7 +127,7 @@ contextual-orchestrator owns model discovery and selection.
retaining the original asset and provenance. Recognize image DOM/visual
regions before OCR, descriptions, Keyman extraction, or embeddings. Store
region-level evidence; never show an internal LLM instruction such as
`This post is an image` to a buyer.
`This post is an image` to a reader.

## Source parsing and semantic units

Expand All @@ -146,10 +146,10 @@ contextual-orchestrator owns model discovery and selection.
- Remove presentation-only visual line alignment inside a paragraph (for
example continuation lines manually aligned after `-`, `*`, `1.`, or `.`)
from derived semantic text, while retaining the source body and meaningful
list/heading nesting. A buyer-facing post view must render semantic
list/heading nesting. A reader-facing post view must render semantic
paragraphs, not the authoring application's spacing workaround.
- Image descriptions, OCR text, and region evidence are analysis artifacts,
not buyer-facing prompt instructions. Buyer UI shows the source content and
not reader-facing prompt instructions. The workspace UI shows the source content and
useful captions/evidence only, with provenance where appropriate.

## Pluggable channels: never fake a missing signal
Expand Down
10 changes: 5 additions & 5 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ flowchart LR
| `chunking.py` | Splits a document into meaning-identifiable units (paragraph, sentence, DOM, conversation-turn) plus embedded-image extraction, in document order |
| `embedding_client.py` | Pluggable text-embedding channel (`Null` default, `OpenAiCompatible` real impl) + `chunked_max_similarity` |
| `adjudication_client.py` | Pluggable LLM-judgment channel (`Null` default, `ContextualOrchestrator` real impl) |
| `image_content.py` | Pluggable vision channel: OCR + object recognition/tagging for embedded images (`Null` default, `OpenAiCompatibleVisionClient` real impl). The product popup (`frontend/src/PostBody.tsx`) renders each `data:image` payload in document order so the buyer sees the picture, not the base64 string; GET does not call the vision client. |
| `image_content.py` | Pluggable vision channel: OCR + object recognition/tagging for embedded images (`Null` default, `OpenAiCompatibleVisionClient` real impl). The product popup (`frontend/src/PostBody.tsx`) renders each `data:image` payload in document order so the reader sees the picture, not the base64 string; GET does not call the vision client. |
| `tepp_client.py` | TEPP's published `AnalysisRunRequest` wire contract, pluggable transport |
| `rankweave_client.py` | Fail-closed RankWeave ranking port (`weighted_reciprocal_rank_fuse` in-process; never invent a fused score or a theta) |
| `reconstruct.py` | The pipeline: group → candidate window → score → fuse → thread |
Expand Down Expand Up @@ -326,7 +326,7 @@ Keymen are affiliated with (`lineageweave/affiliate_tree.py`, loaded by
set of those leaves, not the whole company directory -- a sibling the
post never mentions is omitted. People on the tree are buttons that
reuse `GET /api/keymen/{person_id}/related` so the popup Keyman walk
starts from the affiliation the buyer clicked. A resolved organization
starts from the affiliation the reader clicked. A resolved organization
is the same walk via `GET /api/corporate-entities/{id}/related`. An affiliation that did not resolve to
a `corporate_entity` row stays as its own root (`resolved=false`); that
is the same never-guess-a-parent rule
Expand Down Expand Up @@ -467,15 +467,15 @@ truly have no dated open tickets.

## Phase 6-M2: authorized analysis-run evidence (read projection)

Issue #79's first buyer-visible Milestone 2 slice is a source-redacting
Issue #79's first reader-visible Milestone 2 slice is a source-redacting
read of the #89 registry. `GET /api/analysis-runs` and
`GET /api/analysis-runs/{id}` require `post_read` and apply the scope
in SQL: the requester always sees their own run; a corporate-entity or
process-unit scope is visible only to affiliated accounts; a
thread-group scope is visible only when the account can already see a
post in that group; `all_visible` is requester-only. Hidden runs 404. Detail also lists ABAC-visible post titles in the
run's scope whose `created_at` is at or before `knowledge_cutoff`
(ADR 0016) so a buyer can open a post the run was allowed to know
(ADR 0016) so a reader can open a post the run was allowed to know
without seeing later live rows or hidden bodies. Detail also returns
revision and configuration digest prefixes.
`POST /api/analysis-runs` records a Pending lineage run on a new
Expand Down Expand Up @@ -925,7 +925,7 @@ code. Wired into both `keyman_ingestion.py`'s affiliation loop and
## Standards-complete W3C PROV-O provenance layer

ADR 0011 separates standards-complete provenance from the compact
buyer-facing navigation graph. `lineageweave/prov_o.py` validates
reader-facing navigation graph. `lineageweave/prov_o.py` validates
and materializes all 50 normative PROV-O properties, including
literal-valued times/values and qualified Influence resources.
`migrations/0017_prov_o_standard_relations.sql` stores definitions,
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,31 @@ All notable changes to this project are documented here. Format follows

## [Unreleased]

### Changed

- Renamed "Buyer" terminology to reader/workspace naming across the frontend
shell, backend evidence helpers, and living docs (ADR 0119). LineageWeave
has no explicit buyer role, so `BuyerNav`/`BuyerDestination` became
`WorkspaceNav`/`WorkspaceDestination`, `.buyer-gnb*` CSS became
`.workspace-gnb*`, and prose referring to the reading user now says
"reader" instead of "buyer". Historical ADRs and changelog entries keep
their original wording as a point-in-time record.

### Fixed

- `make smoke` and `make seed` now run through the locked project `uv`
environment, so local OIDC and synthetic-data workflows resolve the same
pinned dependencies as CI.
- The workspace Event Lineage global Search action now retries focus after the
board finishes loading, so navigation from Customer master, Calendar, or
Ask Agent lands the cursor in the search box. The handled request is consumed,
so later board navigation does not steal focus, and Search closes an open
mobile drawer like every other destination change.
- Mobile Event Lineage evidence cards now read their translated column labels
from the rendered cells instead of hardcoded English CSS, and the two drawer
close controls have distinct accessible names.
- Event Lineage SVG edges now retain their instance-specific direction markers,
so parent-to-child arrows remain visible when multiple lineage groups render.
- All OpenAI-compatible chat-completion consumers now validate the shared
response envelope before parsing it, preventing malformed provider bodies
from escaping as raw `KeyError` or response-shape details.
Expand Down
6 changes: 3 additions & 3 deletions backend/app/analysis_run_ingestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ async def fetch_outbox_deliveries(
"""Labeled claim/delivery events for one already-visible run.

Missing outbox tables mean migration 0023 is not applied. Stream
entry ids stay off the payload -- they are not buyer evidence.
entry ids stay off the payload -- they are not reader-facing evidence.
"""
try:
rows = await conn.fetch(
Expand Down Expand Up @@ -285,7 +285,7 @@ async def _serialize_runs(
conn: asyncpg.Connection,
rows: list[asyncpg.Record],
) -> list[dict[str, Any]]:
"""Project registry rows into the authorized buyer-facing payload."""
"""Project registry rows into the authorized reader-facing payload."""
if not rows:
return []
count_rows = await _counts_by_run(conn, [str(row["analysis_run_id"]) for row in rows])
Expand Down Expand Up @@ -346,7 +346,7 @@ async def fetch_visible_analysis_runs(
"""Runs the account requested or whose scope they may already walk.

Once real source-import evidence is visible, the synthetic `make seed`
Demo Corp runs stop appearing here -- a buyer must not mistake that
Demo Corp runs stop appearing here -- a reader must not mistake that
fabricated narrative for real evidence (ADR 0001 / ADR 0042).
"""
# Safe SQL: this immutable module query contains only closed schema SQL; request values remain bound below.
Expand Down
2 changes: 1 addition & 1 deletion backend/app/demo_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
something to show. Once an account can see at least one post carrying real
source-import evidence, the synthetic Demo Corp tree is no longer needed to
fill an empty screen and must stop appearing next to real evidence -- a
buyer must never mistake a fabricated contact (e.g. Ada West, Priya Nair)
reader must never mistake a fabricated contact (e.g. Ada West, Priya Nair)
for a real one.
"""

Expand Down
4 changes: 2 additions & 2 deletions backend/app/entity_relationship_ingestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ async def fetch_relationship_network(
can be a customer in one post, a competitor in another (their own
product line competes with ours elsewhere), the customer of our
customer in a third, or a supplier -- Customer Master's per-post
reads never rolled these up, so buyers could only see one role at
reads never rolled these up, so readers could only see one role at
a time and never the entity's whole network. This groups every
visible, eligible post's classifications by counterparty name,
keeping every distinct relationship type observed (not just the
most frequent), so a buyer can see a name marked both Customer and
most frequent), so a reader can see a name marked both Customer and
Competitor and know that reflects the real, mixed relationship
rather than a classification error.

Expand Down
2 changes: 1 addition & 1 deletion backend/app/issue_ticket_ingestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ async def upsert_commitment_ticket(

Re-deriving the same post must not stack duplicate calendar rows --
an existing open ticket with a commitment_summary is updated in place.
A closed ticket is left alone so the buyer can keep the historical
A closed ticket is left alone so the reader can keep the historical
record and still derive a fresh open one.
"""
existing = await conn.fetchrow(
Expand Down
6 changes: 3 additions & 3 deletions backend/app/knowledge_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ async def fetch_person_role_history(
responsibility, in posts at different times (a job change, a title
change, a move between projects). ``post_summary_role`` already
carries this per post; this simply orders it chronologically for
one person instead of leaving a buyer to open every post that
one person instead of leaving a reader to open every post that
mentions them and compare manually.

``visible_post_ids`` must already be ABAC-filtered by the caller
Expand All @@ -590,7 +590,7 @@ async def fetch_person_role_history(
rows = await conn.fetch(
"""
select role.post_id, post.post_title, post.created_at,
role.responsibility, role.affiliated_organization_name
role.responsibility_text, role.affiliated_organization_name
from post_summary_role role
join source_post post on post.post_id = role.post_id
where role.cataloged_person_id = $1
Expand All @@ -605,7 +605,7 @@ async def fetch_person_role_history(
"post_id": str(row["post_id"]),
"post_title": row["post_title"],
"created_at": row["created_at"].isoformat(),
"responsibility": row["responsibility"],
"responsibility": row["responsibility_text"],
"affiliated_organization_name": row["affiliated_organization_name"],
}
for row in rows
Expand Down
Loading