feat: make Event Lineage directional and evidence-readable - #330
Conversation
…fix/buyer-image-evidence
…m/ContextualWisdomLab/LineageWeave into codex/fix-project-action-parser
…s' into fix/project-bound-summary-actions
…x-project-action-parser
|
Reviewed and corrected against exact current head Finding fixed:
Verification on this exact head:
Merge gate remains intentionally open: the head is current, required checks are queued, and no formal approval is present. |
|
Exact head f9df5ea was revalidated against its current parent. Frontend lint passed, 149 tests passed, Vite build passed, and diff-check passed. Hosted checks and formal approval remain pending; no merge attempted. |
|
@opencode-agent Perform the forward-only stack repair on exact current head |
|
Resolved the current CSS-specificity defect on exact head |
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.
Forward-only conflict resolution preserves the authenticated mobile shell and UI/UX Guide v3 header/navigation work while inheriting PR #330's exact direction, date, evidence, accessibility, i18n, deterministic layout, Figma, Storybook, CSS-regression, and stabilization-plan contracts. No capability is removed and shared history is not rewritten.
There was a problem hiding this comment.
📝 Info: Old empty-state and edge-direction translations are now dead entries
This PR moves the DAG empty-state and edge-description copy into a new lineageDagI18n.ts module and renders the corrected source → target direction inline. The old main-catalog keys "No reconstructed lineage yet. Rebuild after seeding posts." and "{from} follows {to} ({score})" in frontend/src/i18n.ts (e.g. lines 283-284, 305) are no longer referenced by LineageDag.tsx. I confirmed no other component uses them (the "follows" match in App.tsx:2971 is an unrelated related-posts list). These are harmless dead entries, not a bug, but could be cleaned up.
Was this helpful? React with 👍 or 👎 to provide feedback.
| margin: 0 0 0.55rem; | ||
| padding: 0; | ||
| color: var(--color-text); | ||
| font-size: var(--lw-font-size-meta); |
There was a problem hiding this comment.
🟡 Lineage legend, disclosure, and evidence table ignore their intended small font size
The legend, non-causal note, and evidence table request a meta font size through var(--lw-font-size-meta) (LineageDag.css), but that custom property is defined nowhere in the stylesheets, so each declaration is invalid and the text falls back to the surrounding font size instead of the smaller meta size.
Undefined custom property resolution
--lw-font-size-meta is referenced only in LineageDag.css, :99, and :120 and is never declared in frontend/src/index.css or frontend/src/styles/tokens.css (other tokens such as --color-accent-info-background and --radius-control are declared there). A font-size: var(--lw-font-size-meta) with no fallback resolves to the guaranteed-invalid value; because font-size is inherited, the affected elements (.lineage-dag-legend, .lineage-dag-boundary, .lineage-dag-evidence-table) render at the inherited ambient size rather than the intended compact meta size.
Prompt for agents
The stylesheet frontend/src/LineageDag.css references a design token var(--lw-font-size-meta) on lines 9, 99, and 120, but this custom property is not defined anywhere (not in frontend/src/index.css, frontend/src/styles/tokens.css, or App.css). As a result the legend, non-causal boundary note, and evidence table do not get the intended smaller meta font size and instead inherit the ambient size. Either define --lw-font-size-meta in the token files (matching the meta font size used elsewhere in the app, e.g. ~0.85rem which App.css uses for .lineage-dag-group figcaption), or reference an existing font-size token, or provide a fallback like var(--lw-font-size-meta, 0.85rem).
Was this helpful? React with 👍 or 👎 to provide feedback.
| const walk = (id: string, depth: number) => { | ||
| const kids = (children.get(id) ?? []).filter((childId) => byId.has(childId)); | ||
| if (positions.has(id) || visiting.has(id)) return; | ||
| visiting.add(id); | ||
| const kids = (children.get(id) ?? []).filter( | ||
| (childId) => byId.has(childId) && !positions.has(childId) && !visiting.has(childId), | ||
| ); | ||
| if (kids.length === 0) { | ||
| positions.set(id, { x: PAD + depth * COL_W, y: PAD + nextRow * ROW_H }); | ||
| nextRow += 1; | ||
| visiting.delete(id); | ||
| return; | ||
| } | ||
| const startRow = nextRow; | ||
| for (const childId of kids) walk(childId, depth + 1); | ||
| const midRow = (startRow + nextRow - 1) / 2; | ||
| positions.set(id, { x: PAD + depth * COL_W, y: PAD + midRow * ROW_H }); | ||
| visiting.delete(id); | ||
| }; |
There was a problem hiding this comment.
📝 Info: Cycle guard in DAG layout prevents infinite recursion but changes multi-parent layout
The new visiting/positions guards in layoutGroup (lineageLayout.ts) correctly bound recursion for malformed cyclic components (the new test covers this). Note a behavioral side effect for legitimate multi-parent/merge DAGs: the kids filter now excludes children that are already positioned or currently on the recursion stack (lineageLayout.ts), so a node reachable from two parents is positioned only under the first parent encountered; the second parent then sees no remaining children and is placed as a leaf. Previously the shared child was re-positioned (last-writer-wins). Neither behavior crashes; this is purely an aesthetic layout difference for merge-shaped lineages, which are uncommon in the git-branch-style reconstruction. Not flagged as a bug.
Was this helpful? React with 👍 or 👎 to provide feedback.
| )} | ||
| </p> | ||
| <details className="lineage-dag-evidence" open> | ||
| <summary>{t("Evidence trail")}</summary> |
There was a problem hiding this comment.
📝 Info: Evidence-table header 'When' reuses the 5W1H translation key
t("When") for the evidence-table column header (LineageDag.tsx) resolves to the same catalog entry used by the 5W1H panel (e.g. Korean 언제 at i18n.ts). The rendering is semantically acceptable, but note the shared key means any future retranslation of the 5W1H 'When' will also change this column header. Not a bug, but worth awareness if the two contexts ever need to diverge.
Was this helpful? React with 👍 or 👎 to provide feedback.
| .lineage-dag-canvas { | ||
| display: block; | ||
| max-width: none; | ||
| color: color-mix(in srgb, canvastext 55%, transparent); | ||
| } | ||
|
|
||
| .lineage-dag-arrow { | ||
| fill: currentColor; | ||
| } |
There was a problem hiding this comment.
📝 Info: Arrowhead color differs from edge stroke color
The edge path stroke is var(--border) (App.css .lineage-dag-edge), while the arrow marker fills with currentColor inherited from .lineage-dag-canvas { color: color-mix(in srgb, canvastext 55%, transparent) } (frontend/src/LineageDag.css:79,83). The arrowhead therefore renders in a muted mixed color that does not match the edge line color. Cosmetic only, but worth confirming the direction indicator is intended to be a different tone than the edge it terminates.
Was this helpful? React with 👍 or 👎 to provide feedback.
| function edgePath(from: Point, to: Point): string { | ||
| const angle = Math.atan2(to.y - from.y, to.x - from.x); | ||
| const offsetX = Math.cos(angle) * (NODE_RADIUS + EDGE_CLEARANCE); | ||
| const offsetY = Math.sin(angle) * (NODE_RADIUS + EDGE_CLEARANCE); | ||
| const startX = from.x + offsetX; | ||
| const startY = from.y + offsetY; | ||
| const endX = to.x - offsetX; | ||
| const endY = to.y - offsetY; | ||
| const midX = (startX + endX) / 2; | ||
| return `M ${startX} ${startY} C ${midX} ${startY}, ${midX} ${endY}, ${endX} ${endY}`; | ||
| } |
There was a problem hiding this comment.
📝 Info: Arrowhead orientation vs endpoint offset
edgePath (LineageDag.tsx) offsets both the start and end points along the straight-line angle between node centers, but the cubic bezier control points share the endpoint's y (midX, endY), so the curve always enters the target horizontally. With orient="auto" the arrowhead therefore renders horizontally rather than along the straight-line angle. Because the endpoint is placed a constant NODE_RADIUS + EDGE_CLEARANCE (11px) from the target center, the arrow still stops ~4px outside the node circle as intended, so this is cosmetic only and consistent with how the S-curve visually approaches the node. Verified not a functional bug.
Was this helpful? React with 👍 or 👎 to provide feedback.
| .lineage-dag-legend-branch { | ||
| border-color: var(--badge-actor-organization-text); | ||
| background: var(--badge-actor-organization-bg); | ||
| } |
There was a problem hiding this comment.
📝 Info: Legend branch swatch color only loosely matches actual branch node color
The legend branch swatch uses --badge-actor-organization-text/bg (a brown-orange palette, tokens.css:18-19) while the actual branch node circle is styled with literal orange in App.css:867-870. Both are in the orange family so the legend is not misleading, but they are not the same value, so a strict visual match isn't guaranteed across light/dark themes. Minor cosmetic inconsistency, not a correctness bug.
Was this helpful? React with 👍 or 👎 to provide feedback.
| <summary>{t("Evidence trail")}</summary> | ||
| <div className="lineage-dag-evidence-scroll"> | ||
| <table className="lineage-dag-evidence-table"> | ||
| <caption className="visually-hidden">{`${lineageLabel} — ${t("Evidence trail")}`}</caption> | ||
| <thead> | ||
| <tr> | ||
| <th scope="col">{relationLabel}</th> | ||
| <th scope="col">{whenLabel}</th> | ||
| <th scope="col">{evidenceLabel}</th> | ||
| </tr> |
There was a problem hiding this comment.
📝 Info: New user-facing strings have full locale coverage
The evidence table introduces t("Evidence trail"), t("Graph relation"), t("When"), and t("Evidence"). All four keys already exist in every non-English locale in i18n.ts (ko/zh/ja/vi), so these render translated rather than falling back to English. The hardcoded → relation/date strings and the literal (fused_score) suffix are intentionally language-neutral. No missing-translation regression.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const instanceId = useId().replaceAll(":", ""); | ||
| const groups = layoutLineageDag(graph); | ||
| if (graph.nodes.length === 0) { | ||
| return <p className="lineage-empty">{t("No reconstructed lineage yet. Rebuild after seeding posts.")}</p>; | ||
| return ( | ||
| <p className="lineage-empty"> | ||
| {lineageDagText( | ||
| "No reconstructed lineage yet. Add eligible source records, then rebuild Event Lineage.", | ||
| )} | ||
| </p> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <div className="lineage-dag" aria-label={t("Reconstructed lineage")}> | ||
| {groups.map((group) => { | ||
| {groups.map((group, groupIndex) => { | ||
| const byId = Object.fromEntries(group.nodes.map((node) => [node.id, node])); | ||
| const arrowMarkerId = `lineage-dag-arrow-${instanceId}-${groupIndex}`; | ||
| const captionId = `lineage-dag-caption-${instanceId}-${groupIndex}`; | ||
| const lineageLabel = tf("{group} lineage", { group: group.heading }); |
There was a problem hiding this comment.
📝 Info: Marker IDs kept component-local; verified no duplicate-ID or cross-group collision
arrowMarkerId and captionId are derived from useId() (LineageDag.tsx) combined with groupIndex, so multiple LineageDag instances on one page and multiple groups within one instance produce distinct SVG marker IDs. markerEnd={url(#arrowMarkerId)} is referenced only inside the same <svg> that defines the marker, so scoping is correct. No collision risk.
Was this helpful? React with 👍 or 👎 to provide feedback.
| ### Changed | ||
|
|
||
| - Made the buyer Event Lineage DAG explicitly directional with parent-to-child arrowheads whose paths stop outside node circles. | ||
| - Preserved authored graph width behind a keyboard-focusable horizontal scroll region instead of shrinking deep lineages. | ||
| - Added visible event dates, a redundant visual/text legend, and an accessible exact-value evidence table for lineage relations, dates, and fused scores. | ||
| - Added five-locale buyer copy stating that reconstructed continuation edges do not prove causality or authoritative fact. |
There was a problem hiding this comment.
🔍 Changelog version 2.12.7 is below the latest 2.13.1 fragment
This adds 2.12.7-lineage-dag-evidence.md while newer fragments (up to 2.13.1-*) already exist in CHANGELOG.d/. The PR description notes it stacks on codex/normalize-source-indent-semantics, so the lower version may be intentional to slot into an earlier release line, but reviewers should confirm the version fragment is correct for the intended release rather than an accidental regression.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
@opencode-agent Review exact current head |
|
Queue 2026-08-21T15:09 KST: exact head |
# Conflicts: # frontend/src/App.tsx # lineageweave/post_summary.py # tests/test_post_summary.py
|
Current head 336730f is normally restacked on the current #258 provider-boundary stack. The merge conflict was resolved by preserving authenticated-only AdminPanel rendering and the provider-safe summary parser. Verification: backend 768 passed, 16 skipped; frontend 153 passed; lint, Vite build, Storybook build, diff check, and raw-provider audit passed. The PR is now stacked and its required Checks are restarting; independent review remains pending. |
| .lineage-dag-node text.lineage-dag-node-date { | ||
| font-size: 9px; | ||
| opacity: 0.72; | ||
| fill: var(--text); | ||
| } |
There was a problem hiding this comment.
📝 Info: Event-date style depends on App.css selector specificity
.lineage-dag-node text.lineage-dag-node-date (0,2,1) outranks .lineage-dag-node text in frontend/src/App.css:527 (0,1,1), so the 9px date wins without !important. Raising the App.css selector's specificity later would silently regress this.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
@opencode-agent Rapidly stabilize the current Event Lineage DAG without removing or weakening any completed behavior. Preserve parent→child geometry, visible dates, localized legend, non-causal disclosure, exact fused-score evidence, actionable empty state, keyboard interaction, responsive exact-value fallback, Figma frames |
* 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * 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, "×") 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]> * 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 <[email protected]>
aaad6f1
into
feat/analysis-run-name-evidence-lineage
| <WorkspaceNav destination={destination} onChange={changeDestination} /> | ||
| {mobileMenuOpen ? ( | ||
| <div className="mobile-drawer-backdrop" onClick={() => setMobileMenuOpen(false)}> | ||
| <aside | ||
| className="mobile-drawer" | ||
| onClick={(event) => event.stopPropagation()} | ||
| > | ||
| <button | ||
| type="button" | ||
| className="mobile-drawer-close" | ||
| aria-label={t("Close")} | ||
| onClick={() => setMobileMenuOpen(false)} | ||
| > | ||
| <CloseIcon /> | ||
| </button> | ||
| <WorkspaceNav | ||
| id="mobile-workspace-navigation" | ||
| destination={destination} | ||
| onChange={changeDestination} | ||
| drawer | ||
| /> | ||
| </aside> | ||
| </div> | ||
| ) : null} |
There was a problem hiding this comment.
📝 Info: Duplicate navigation landmarks share one accessible name
WorkspaceNav renders with aria-label "Workspace navigation" in the header, again inside the mobile drawer, and again inside SiteMapUtility. When the drawer or site map is open, two navigation landmarks carry the same name, which screen-reader landmark navigation cannot distinguish.
Was this helpful? React with 👍 or 👎 to provide feedback.
| function closeSelectedPost() { | ||
| setSelectedPostId(null); | ||
| setOpenedAfterCutoff(false); |
There was a problem hiding this comment.
📝 Info: Asymmetric popup history: push on open, replace on close
selectPost opens a post with pushState (App.tsx:3724) but closeSelectedPost uses replaceState (App.tsx:3759) instead of navigating back. Opening then closing via the button rewrites the pushed entry rather than popping it, so the button-close and back-button-close paths yield different history stacks. Behavior stays correct in traced flows but the asymmetry can surprise later work on back navigation.
(Refers to this code)
Was this helpful? React with 👍 or 👎 to provide feedback.
| return {} | ||
| fields = {"ontology_iri": str(subject)} | ||
| label = ONTOLOGY.value(subject, RDFS.label) | ||
| label = ONTOLOGY.value(subject, RDFS.label) or ONTOLOGY.value(subject, SKOS.prefLabel) |
There was a problem hiding this comment.
📝 Info: Ontology annotation now resolves operational codes
ontology_annotations and iri_for_lookup_code now resolve codes like public, voc, open to SKOS concepts, where they previously returned empty/None. Current callers pass only node/edge/actor codes, so no payload changes today, but any future caller spreading annotations for an operational lookup code will start emitting an ontology_iri/ontology_label.
Was this helpful? React with 👍 or 👎 to provide feedback.
Forward-only Event Lineage scope
This PR strengthens the reconstructed post/record lineage surface without converting it into a different product or deleting accepted behavior.
source → targetsemantics.fused_scorefor keyboard, touch, print, and audit.!important.Product and design boundary
1Su3lDRmiZdcUs47t1QwIX; desktop frame5:14; mobile frame5:15.Forward stack repair completed
A two-parent merge commit was created without force-push or history rewrite. Protected
main@ef6f5a5ffcb467bd935dc1e53acc0029669b0bd7is now the merge base, and conflict resolution used protected main as the complete tree baseline before reapplying exactly the twelve-file Event Lineage delta. GitHub compare reports behind0and a twelve-file product/documentation delta.Exact current candidate
main@ef6f5a5ffcb467bd935dc1e53acc0029669b0bd7.1fad94ff4ec6007d3d3b732580ed68b586f56061.Protected merge gate
Merge only after exact-head terminal checks, zero unresolved threads, and independent formal approval. Auto-merge is enabled, but no self-approval, force-push, protection bypass, or capability-reducing resolution is allowed.