From 3537948a74fa13fb2f0aa7b21f976459f64b3e5d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 26 Aug 2026 03:39:53 +0900 Subject: [PATCH 1/6] fix(ui): clarify ontology node types with tokens --- CHANGELOG.d/ontology-node-readability.md | 5 ++ docs/product-technical-gap-baseline.md | 61 ++++++++++++------- docs/storybook-inventory.md | 1 + frontend/src/App.css | 21 ++++++- .../src/components/OntologyExplorer.test.tsx | 17 ++++++ frontend/src/components/OntologyExplorer.tsx | 13 +++- frontend/src/styles/tokens.css | 13 ++++ frontend/src/styles/tokens.test.ts | 30 +++++++++ 8 files changed, 137 insertions(+), 24 deletions(-) create mode 100644 CHANGELOG.d/ontology-node-readability.md diff --git a/CHANGELOG.d/ontology-node-readability.md b/CHANGELOG.d/ontology-node-readability.md new file mode 100644 index 000000000..50ca29ad4 --- /dev/null +++ b/CHANGELOG.d/ontology-node-readability.md @@ -0,0 +1,5 @@ +### Changed + +- Ontology neighborhood nodes now reuse light/dark design tokens for distinct + Post, Person, Organization, and Team surfaces while retaining shape, text, + keyboard controls, and the exact-value table as the authoritative cues. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 9a65c2eb6..8513a2ebb 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -1,7 +1,7 @@ # Product & Technical Gap Baseline -> Dashboard delivery snapshot: 2026-08-25 21:34 KST. Protected `main` was -> `d7d5eeb310b055b5e138060cf2dfb929b03090a6`. This local branch is not +> Dashboard delivery snapshot: 2026-08-26 03:37 KST. Protected `main` was +> `04e6b610655d0db91d5f7ba9486bdda1440e0b19`. This local branch is not > protected-main release evidence. ## Operations Dashboard PRD/TRD traceability @@ -60,18 +60,16 @@ only aggregate, non-identifying evidence to this repository. ### Exact open-PR boundary -At this snapshot there were 3 open PRs and 11 open issues. Exact observed heads -were `#628 d07d212f` (this branch's observed parent), `#627 9e0528a6`, and -`#579 1c209c85`. PR #579 is open; its ADR 0211 reservation is why this branch's -filter-option decision is ADR 0212. PRs #612, #614, #615, #616, and #626 -reached protected `main`; the superseded baseline PR #613 closed without merge -and its PRD was recreated on protected main. The open heads remain blocked on -hosted gates and/or independent review. These -observations are not merge readiness. Re-fetch exact heads, -unresolved threads, checks, approvals, rulesets, and merge SHA before any -lifecycle claim. - -> Audit snapshot: 2026-08-25 21:34 KST (refreshed by the autonomous merge +At this snapshot there were 11 open PRs and 10 open issues. Exact observed heads +are recorded in §1. Every PR targets `main` and retains normal auto-merge; +none has the two independent approvals required by ruleset 18156473. #657 +also has unresolved review threads, and +new heads on #632 and #640 invalidate earlier check evidence. These +observations are not merge readiness. Re-fetch exact +heads, unresolved threads, checks, approvals, rulesets, and merge SHA before +any lifecycle claim. + +> Audit snapshot: 2026-08-26 03:37 KST (refreshed by the autonomous merge > loop). This repository records synthetic fixtures and aggregate, > non-identifying runtime evidence only. Open PRs and local checks are not > protected-default-branch release evidence. Identifying post identifiers, @@ -80,17 +78,36 @@ lifecycle claim. ## 1. Exact-head and governance evidence -The protected default branch was `d7d5eeb310b055b5e138060cf2dfb929b03090a6` -when this baseline was refreshed. The live queue contained 3 open PRs and 11 +The protected default branch was `04e6b610655d0db91d5f7ba9486bdda1440e0b19` +when this baseline was refreshed. The live queue contained 11 open PRs and 10 open issues. The exact-head inventory below supersedes older per-PR snapshots elsewhere in this document; those older rows remain useful historical delivery context only. | PR | Exact observed head | Merge/check state at this snapshot | | ---: | --- | --- | -| #628 | `d07d212f` (observed parent) | this row is updated by #628 itself, so its exact head advances after the snapshot is encoded; ADR 0212 combines complete ABAC-visible filter options into one database round trip, while hosted gates and independent review remain required | -| #627 | `9e0528a6` | repairs k6 lifecycle evidence preservation; hosted gates remain required | -| #579 | `1c209c85` | persists leftover interaction-map coordinates and owns ADR 0211; hosted gates and independent review remain required | +| #579 | `689a21b6` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #629 | `4b4d6707` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #631 | `c0022c97` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #632 | `05b640a4` | new exact head invalidates earlier checks/reviews; auto-merge enabled; independent approvals absent | +| #636 | `f7b9a65f` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #639 | `aee02dca` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #640 | `31d05313` | new exact head invalidates earlier checks/reviews; auto-merge enabled; independent approvals absent | +| #643 | `041ec13b` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #644 | `c1018a0a` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | +| #657 | `f4f7f185` | TEPP lifecycle candidate; three unresolved review threads; checks and independent approvals require exact-head revalidation | +| #658 | `bf98ac8a` | Global Ask cutoff candidate; review threads resolved on this new head; checks and independent approvals require exact-head revalidation | + +The open queue also has allocation conflicts that prevent order-independent +merges: #636 and #643 both add ADR 0214; #632 and #644 both add ADR 0215; and +#632 and #640 both add migration 0211 for different schema objects. #657's +migration 0210 collides with #632, while #658 reuses #632's ADR 0216 and +#640's migration 0216 for different work. Shared +0165/0203 migrations in #629, #632, #639, and #640 are inherited stack content, +not four independent allocations. Parent content must reach protected `main` +first; each child then needs a `main` retarget/synchronization and fresh +exact-head evidence. No conflicting child is release-ready merely because its +current standalone checks pass. No row above is merge evidence. Immediately before any lifecycle action, re-fetch the head, unresolved threads, formal reviews, rulesets, and same-head @@ -367,11 +384,11 @@ this file per §3.5 of the prior snapshot). | Shared frontend gate | The ADR 0109 login repair is on protected `main`; eight older branches carried the defect and received the same verified repair this loop (#521–#560) | Keep every future branch cut from post-repair bases; re-verify with frontend lint/test/build before push | | Identifying baseline regression | `main` gap file listed real post identifiers; separately, closed #506 and pre-existing public history contain a private runtime source-table identifier, while current `main` and #507 trees are clean | Land this non-identifying rewrite, then coordinate ADR 0001 history remediation with security/privacy owners; do not reproduce the value, force-push, or delete evidence ad hoc | | Authorized-corpus runtime | Repository tests use synthetic fixtures; private records remain outside git | Authenticated runtime validation returning only aggregate, non-identifying evidence | -| Concurrent web responsiveness | ADR 0204 releases pooled transactions during provider work, and the synthetic Compose boundary has an authenticated k6 E2E harness for Ask enqueue, concurrent reads, and job polling. An older-image local observation found repeated post-filter queries while `/api/posts` exceeded 30 seconds; ADR 0212 combines two authorized filter-option queries into one round trip without narrowing ABAC-visible options. The observation is not exact-head evidence or a product guarantee, and no physical scan reduction is claimed without an exact-head plan | Rebuild an exact-head application image, run `make load-http` with declared environment concurrency/window, and retain raw distributions and resource configuration. Compare the post-list database plan and latency with ADR 0212 while preserving the complete authorized filter set; set no SLO until representative capacity evidence is approved | +| Concurrent web responsiveness | ADR 0204 releases pooled transactions during provider work, and the synthetic Compose boundary has an authenticated k6 E2E harness for Ask enqueue, concurrent reads, and job polling. At exact protected `main@04e6b610`, PostgreSQL/migrations/Valkey/Keycloak/orchestrator became healthy, but backend startup failed before load with a `Settings.tepp_api_key` contract mismatch; the full frontend image independently stopped at pnpm 11's unapproved `esbuild` build script. #629 and #639 contain candidate root repairs, so this branch does not duplicate them. No k6 distribution or bottleneck claim is valid from that failed startup | Land the owning config/container repair through protected `main`, rebuild the exact-head application, run `make load-http` with declared environment concurrency/window, and retain raw distributions and resource configuration. Set no SLO until representative capacity evidence is approved | | Image understanding | Region, OCR, and description work exists across active heads (#405, #419), but current runtime acceptance has not yet proved table-image structure, complete region coverage, or summary/image readiness together | Orchestrator-backed rendered workflow, original/derived asset provenance, region-before-OCR processing, and honest unsupported states; reconcile ADR 0052's image-bearing summary readiness with ADR 0098 before changing sequencing | | Semantic source rendering | Paragraph, table, list, formula, and indentation work exists across stacks (#394, #427, #448–#450); #515 adds synthetic backend/frontend parity for deterministic rows/cells, footnote boundaries, and encoded scripts | Land the #427 → #515 stack, then gather authenticated browser evidence that list nesting, continuation alignment, and formula units render without authoring-layout artifacts | | Event and project semantics | Multi-project mentions, project-bound actions, 5W1H, requester/processor, and semantic relations exist in ADR 0036/0052/0100/0111/0129 and active stacks | Aggregate authenticated evidence must show distinct projects and events, explicit requester/processor and real R&R, normalized relative time, and product/entity relations without promoting attendance or co-occurrence | -| Knowledge Graph readability | The black evidence-node root cause is an undefined-token fallback; the design-token repair and long-label/evidence-table coverage remain only on closed, unmerged #490, not protected `main` | Recreate the token repair on a current base and deliver it through protected `main`, then verify light/dark contrast, keyboard graph navigation, full labels, and evidence tables in the authenticated rendered surface | +| Knowledge Graph readability | Current `main` uses one generic node fill. This branch maps the ADR 0184 Post, Person, CorporateEntity, and Team shapes to existing semantic-family, light/dark design tokens while preserving shape and text as the primary non-color channels; exact-value tables retain full labels | Pass focused token/keyboard regression tests and desktop/mobile Storybook screenshot audit, then deliver through protected `main`; authenticated rendered acceptance remains separate | | Source-code lookup UX | Source state/detail codes remain evidence-bearing machine values and current detail presentation is dense | Catalog-backed display labels with raw-code provenance, compact 5W1H/source-detail hierarchy, keyboard access, and no unsupported customer/project binding | | Calendar / Naruon | #355 delivered the projection contract; v2.17.0 wires operator consumption without forwarding the end-user token. Naruon producer, provider/consumer fixtures, and protected merge remain open (#336) | Verify observed events against the published schema without invented events; keep commitments available when the channel is unwired | | SKOS organization aliases | Catalog binding and chip caption live on #480 / #482 | One catalog row per corroborated org; companion caption is hint-only until bound | @@ -382,7 +399,7 @@ this file per §3.5 of the prior snapshot). | Accessibility and responsive UX | #602 delivered base post-detail modal semantics; #605 adds selected-post refocus, collapsed/hidden/inert/CSS-invisible focus exclusion across both modal types, readable evidence separators, focused tests, and desktop/mobile Storybook screenshots | Land #605 through the protected gate, then complete screen-reader and authenticated Playwright acceptance on the exact release head | | Design tokens and repeated objects | Token extraction started; sanitized Figma Event Lineage desktop/mobile frames exist, while other repeated product surfaces remain incomplete | Tokens in CSS + Storybook stories for board, popup, DAG, Ask, calendar, forms, charts; same-viewport Figma/runtime visual comparison before release | | Frontend delivery performance | A current production build succeeds but emits Vite's >500 kB chunk warning (`539.27 kB` minified); raising the warning limit would conceal rather than reduce delivery cost | Measure module contribution on an exact head, split one real route/surface boundary with native dynamic import, then prove the warning is absent and loading/error states remain accessible | -| External integrations | Search, Zotero, calendar, Keyverse, orchestrator, RankWeave, ThreadWeave, TEPP, DiskSage, wardnet | Provider conformance, failure/reconciliation behavior, and provenance-bearing integration evidence | +| External integrations | Search, Zotero, calendar, Keyverse, orchestrator, RankWeave, ThreadWeave, TEPP, `ContextualWisdomLab/disksage`, wardnet | Provider conformance, failure/reconciliation behavior, and provenance-bearing integration evidence | | MSA / modular reuse | LineageWeave must run standalone and as a consumer of org packages | Do not reimplement RankWeave/TEPP/orchestrator/ThreadWeave/Keyverse; fix upstream and PR there | | Product contract authority | This branch recreates the first LineageWeave PRD after superseded #613 closed without merge and records an exact-case ecosystem authority register; TEPP, fast-mlsirm, keyverse, and ThreadWeave have standalone PRDs, while contextual-orchestrator, RankWeave, DiskSage, and wardnet currently rely on product-planning/architecture documents and naruon has only a scoped Topic Intelligence PRD | Land the LineageWeave PRD, keep ADRs normative, and add standalone PRDs in each owning repository before making cross-product release claims beyond its documented boundary | | Release quality | Local focused/full suites have passed on individual PR heads | Repository-wide coverage, docstrings, Storybook, security, browser, and release evidence on one exact head | diff --git a/docs/storybook-inventory.md b/docs/storybook-inventory.md index 3716656cd..7ec497477 100644 --- a/docs/storybook-inventory.md +++ b/docs/storybook-inventory.md @@ -15,6 +15,7 @@ operator-facing control you can click before changing product CSS. | `Lineage/LineageDag` | Open a reconstructed connection to read its inferred channel scores and Allen interval relation, or open the current branch node; compare empty, single-branch, grouped/forked, mobile-scroll, ungrouped, and long-title states before changing graph CSS. On narrow viewports, swipe the named viewport or focus it and use arrow keys to inspect the full lineage. | `--color-accent-background`, `--radius-control`, `--surface`, `--border`, `--color-focus-border`, `--size-control-min`, `LineageDag` | | `Chrome/PopupCloseButton` | Close the evidence panel or post popup. | `--space-close-inset`, `--font-size-close`, `PopupCloseButton` | | `Workspace/WorkspaceCalendar` | Read observed Naruon events, or open a commitment to land on that post. Fail-closed copy stays `이 범위의 일정을 아직 받을 수 없습니다`. | `--color-chip-border`, `WorkspaceCalendar`, `EvidenceStatusMark` | +| `Evidence/OntologyExplorer` | Distinguish Post, Person, Organization, and Team by shape and text, use the token-backed surface as a secondary cue, then open the exact-value table or cited evidence. Compare desktop, narrow, drawer, empty, truncated, denied, stale, and rejected states. | `--ontology-node-*-fill`, `OntologyExplorer` | Repeated web objects must use `frontend/src/styles/tokens.css` and a module under `frontend/src/components/`. Do not add a second Node package manager; diff --git a/frontend/src/App.css b/frontend/src/App.css index eeaa61299..5f910a2de 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1148,11 +1148,30 @@ .ontology-node { cursor: pointer; - fill: var(--color-background); stroke: var(--color-text-heading); stroke-width: 1.5; } +.ontology-node-post { + fill: var(--ontology-node-post-fill); +} + +.ontology-node-person { + fill: var(--ontology-node-person-fill); +} + +.ontology-node-organization { + fill: var(--ontology-node-organization-fill); +} + +.ontology-node-team { + fill: var(--ontology-node-team-fill); +} + +.ontology-node-generic { + fill: var(--ontology-node-generic-fill); +} + .ontology-node text { fill: var(--color-text-heading); stroke: var(--color-background); diff --git a/frontend/src/components/OntologyExplorer.test.tsx b/frontend/src/components/OntologyExplorer.test.tsx index 6c6dbb8e4..9c6480a88 100644 --- a/frontend/src/components/OntologyExplorer.test.tsx +++ b/frontend/src/components/OntologyExplorer.test.tsx @@ -248,6 +248,23 @@ describe("OntologyExplorer", () => { expect(screen.queryByRole("img")).not.toBeInTheDocument(); }); + it("maps known ontology node types to token-backed visual classes", () => { + render( + , + ); + + expect(screen.getByRole("button", { name: "Select node: Post Demo public post" })) + .toHaveClass("ontology-node-post"); + expect(screen.getByRole("button", { name: "Select node: Person Test Person" })) + .toHaveClass("ontology-node-person"); + expect(screen.getByRole("button", { name: "Select node: Organization Demo Corp" })) + .toHaveClass("ontology-node-organization"); + }); + it("names empty, truncated, denied, and rejected next actions", () => { const { rerender } = render( = { node_team: "Team", }; +const NODE_TYPE_CLASS: Record = { + node_post: "ontology-node-post", + node_person: "ontology-node-person", + node_corporate_entity: "ontology-node-organization", + node_team: "ontology-node-team", +}; + const TRUTH_LABEL: Record = { truth_authoritative: "Authoritative", truth_observed: "Observed", @@ -418,7 +425,11 @@ function OntologyGraph({ {layout.nodes.map((node) => ( { } }); + it("defines and consumes ontology node fills in both color schemes", () => { + for (const token of ONTOLOGY_NODE_TOKENS) { + expect(lightBlock, `${token} missing from the light :root block`).toContain(`${token}:`); + expect(darkBlock, `${token} missing from the dark prefers-color-scheme block`).toContain( + `${token}:`, + ); + expect(appCss, `App.css never references var(${token})`).toContain(`var(${token})`); + } + }); + + it("keeps ontology node labels at WCAG AA text contrast in both color schemes", () => { + for (const block of [lightBlock, darkBlock]) { + const label = readToken(block, "--color-text-heading"); + for (const token of ONTOLOGY_TYPED_NODE_TOKENS) { + expect(contrastRatio(label, readToken(block, token)), `${token} label contrast`) + .toBeGreaterThanOrEqual(4.5); + } + } + }); + it("does not dim .post-meta with opacity -- it fails WCAG AA in both themes and carries role=\"status\" next-action text", () => { const match = appCss.match(/\.post-meta\s*\{([^}]*)\}/); expect(match, ".post-meta rule not found in App.css").not.toBeNull(); From 2e3c6f1e928cbae631230e1fda6eb464e11ca7eb Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 26 Aug 2026 03:48:38 +0900 Subject: [PATCH 2/6] test(ui): measure ontology label surface contrast --- frontend/src/styles/tokens.test.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/frontend/src/styles/tokens.test.ts b/frontend/src/styles/tokens.test.ts index 3a8aaee33..435c973ad 100644 --- a/frontend/src/styles/tokens.test.ts +++ b/frontend/src/styles/tokens.test.ts @@ -44,8 +44,6 @@ const ONTOLOGY_NODE_TOKENS = [ "--ontology-node-generic-fill", ]; -const ONTOLOGY_TYPED_NODE_TOKENS = ONTOLOGY_NODE_TOKENS.slice(0, 4); - // Colors this file's dark-mode block replaced -- a regression here would // silently make dark mode as bright as light mode again (ADR 0099). const RETIRED_LIGHT_ONLY_HEX = [ @@ -65,7 +63,10 @@ const RETIRED_LIGHT_ONLY_HEX = [ // WCAG 2.x relative luminance / contrast ratio (SC 1.4.3). function relativeLuminance(hex: string): number { - const rgb = [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16) / 255); + const normalized = hex.length === 4 + ? `#${[...hex.slice(1)].map((digit) => `${digit}${digit}`).join("")}` + : hex; + const rgb = [1, 3, 5].map((i) => parseInt(normalized.slice(i, i + 2), 16) / 255); const [r, g, b] = rgb.map((c) => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4)); return 0.2126 * r + 0.7152 * g + 0.0722 * b; } @@ -86,7 +87,7 @@ function readToken(block: string, token: string): string { // literal passed by the call sites below (e.g. "--color-footer-bg"), and // escapeRegExp() neutralizes any regex metacharacters before // interpolation, so no caller-controlled input reaches RegExp unescaped. - const match = block.match(new RegExp(`${escapeRegExp(token)}:\\s*(#[0-9a-fA-F]{6})`)); // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp + const match = block.match(new RegExp(`${escapeRegExp(token)}:\\s*(#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3})(?![0-9a-fA-F])`)); // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp if (!match) throw new Error(`${token} not found as a hex value`); return match[1]; } @@ -145,11 +146,11 @@ describe("design tokens", () => { } }); - it("keeps ontology node labels at WCAG AA text contrast in both color schemes", () => { + it("keeps ontology labels and their halo at WCAG AA contrast in both color schemes", () => { for (const block of [lightBlock, darkBlock]) { - const label = readToken(block, "--color-text-heading"); - for (const token of ONTOLOGY_TYPED_NODE_TOKENS) { - expect(contrastRatio(label, readToken(block, token)), `${token} label contrast`) + const background = readToken(block, "--color-background"); + for (const token of ["--color-text-heading", "--color-text"]) { + expect(contrastRatio(readToken(block, token), background), `${token} label contrast`) .toBeGreaterThanOrEqual(4.5); } } From 218b1f7f428976dcb8111b79da304ec27bc0ab2c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 26 Aug 2026 03:50:24 +0900 Subject: [PATCH 3/6] docs: refresh exact protected queue snapshot --- docs/product-technical-gap-baseline.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 8513a2ebb..5b35f2c15 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -1,6 +1,6 @@ # Product & Technical Gap Baseline -> Dashboard delivery snapshot: 2026-08-26 03:37 KST. Protected `main` was +> Dashboard delivery snapshot: 2026-08-26 03:49 KST. Protected `main` was > `04e6b610655d0db91d5f7ba9486bdda1440e0b19`. This local branch is not > protected-main release evidence. @@ -60,16 +60,15 @@ only aggregate, non-identifying evidence to this repository. ### Exact open-PR boundary -At this snapshot there were 11 open PRs and 10 open issues. Exact observed heads +At this snapshot there were 13 open PRs and 10 open issues. Exact observed heads are recorded in §1. Every PR targets `main` and retains normal auto-merge; -none has the two independent approvals required by ruleset 18156473. #657 -also has unresolved review threads, and -new heads on #632 and #640 invalidate earlier check evidence. These +none has the two independent approvals required by ruleset 18156473. New heads +on #632, #640, #657, and #658 invalidate earlier check evidence. These observations are not merge readiness. Re-fetch exact heads, unresolved threads, checks, approvals, rulesets, and merge SHA before any lifecycle claim. -> Audit snapshot: 2026-08-26 03:37 KST (refreshed by the autonomous merge +> Audit snapshot: 2026-08-26 03:49 KST (refreshed by the autonomous merge > loop). This repository records synthetic fixtures and aggregate, > non-identifying runtime evidence only. Open PRs and local checks are not > protected-default-branch release evidence. Identifying post identifiers, @@ -79,7 +78,7 @@ any lifecycle claim. ## 1. Exact-head and governance evidence The protected default branch was `04e6b610655d0db91d5f7ba9486bdda1440e0b19` -when this baseline was refreshed. The live queue contained 11 open PRs and 10 +when this baseline was refreshed. The live queue contained 13 open PRs and 10 open issues. The exact-head inventory below supersedes older per-PR snapshots elsewhere in this document; those older rows remain useful historical delivery context only. @@ -89,14 +88,16 @@ context only. | #579 | `689a21b6` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | | #629 | `4b4d6707` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | | #631 | `c0022c97` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | -| #632 | `05b640a4` | new exact head invalidates earlier checks/reviews; auto-merge enabled; independent approvals absent | +| #632 | `dfd2f8b7` | new exact head invalidates earlier checks/reviews; auto-merge enabled; independent approvals absent | | #636 | `f7b9a65f` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | | #639 | `aee02dca` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | -| #640 | `31d05313` | new exact head invalidates earlier checks/reviews; auto-merge enabled; independent approvals absent | +| #640 | `4bed57a7` | new exact head invalidates earlier checks/reviews; auto-merge enabled; independent approvals absent | | #643 | `041ec13b` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | | #644 | `c1018a0a` | required checks terminal-success; auto-merge enabled; two independent approvals and last-push approval absent | -| #657 | `f4f7f185` | TEPP lifecycle candidate; three unresolved review threads; checks and independent approvals require exact-head revalidation | -| #658 | `bf98ac8a` | Global Ask cutoff candidate; review threads resolved on this new head; checks and independent approvals require exact-head revalidation | +| #657 | `64f48679` | receipt-schema review repair and migration-allocation repair pushed; checks and independent approvals require exact-head revalidation | +| #658 | `cd7bee58` | Global Ask cutoff candidate advanced after review repair; checks and independent approvals require exact-head revalidation | +| #659 | `2e3c6f1e` | this ontology-node readability and baseline branch; current-head checks and independent approvals required | +| #660 | `1f1bc3e9` | backend runtime/integration contract repair candidate; current-head checks and independent approvals required | The open queue also has allocation conflicts that prevent order-independent merges: #636 and #643 both add ADR 0214; #632 and #644 both add ADR 0215; and From 0d3a345b52f52cb5c10f14a4ce89245005f91bee Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 26 Aug 2026 03:56:59 +0900 Subject: [PATCH 4/6] docs: record resolved cross-PR allocations --- docs/product-technical-gap-baseline.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 5b35f2c15..46b70ce88 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -99,16 +99,15 @@ context only. | #659 | `2e3c6f1e` | this ontology-node readability and baseline branch; current-head checks and independent approvals required | | #660 | `1f1bc3e9` | backend runtime/integration contract repair candidate; current-head checks and independent approvals required | -The open queue also has allocation conflicts that prevent order-independent -merges: #636 and #643 both add ADR 0214; #632 and #644 both add ADR 0215; and -#632 and #640 both add migration 0211 for different schema objects. #657's -migration 0210 collides with #632, while #658 reuses #632's ADR 0216 and -#640's migration 0216 for different work. Shared -0165/0203 migrations in #629, #632, #639, and #640 are inherited stack content, -not four independent allocations. Parent content must reach protected `main` -first; each child then needs a `main` retarget/synchronization and fresh -exact-head evidence. No conflicting child is release-ready merely because its -current standalone checks pass. +Current heads repair the independently introduced allocation conflicts: #643 +uses ADR 0220 while #636 retains ADR 0214; #644 uses ADR 0221 while #632 +retains ADR 0215; and #632 moved public verification to migration 0218 while +#640 retains operations migration 0211. #657 uses migration 0217. #658 and +#632 intentionally publish the same ADR 0216 decision and the byte-identical +0212 cutoff migration, so merge order cannot create two cutoff schemas. Shared +0165/0203 migrations in #629, #632, #639, and #640 remain inherited stack +content, not four independent allocations. Every repaired head still requires +fresh checks, review, and protected-main merge evidence. No row above is merge evidence. Immediately before any lifecycle action, re-fetch the head, unresolved threads, formal reviews, rulesets, and same-head From e948bd2711a5e89d4449afca6cba436d92dd0f8c Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 26 Aug 2026 04:07:22 +0900 Subject: [PATCH 5/6] fix(ui): honor ontology type label token --- frontend/src/App.css | 2 +- frontend/src/ontologyExplorerCss.test.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index 5f910a2de..acf7651d7 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1180,7 +1180,7 @@ font-size: 0.8rem; } -.ontology-node-type { +.ontology-node text.ontology-node-type { font-size: 0.7rem; fill: var(--color-text); } diff --git a/frontend/src/ontologyExplorerCss.test.ts b/frontend/src/ontologyExplorerCss.test.ts index ad35b8868..612df09a3 100644 --- a/frontend/src/ontologyExplorerCss.test.ts +++ b/frontend/src/ontologyExplorerCss.test.ts @@ -11,4 +11,8 @@ describe("Ontology Explorer CSS contracts", () => { it("defines the ontology node focus-visible rule exactly once", () => { expect(appCss.match(/\.ontology-node:focus-visible\s*\{/g)).toHaveLength(1); }); + + it("lets the node-type label override the shared node text color", () => { + expect(appCss).toContain(".ontology-node text.ontology-node-type {"); + }); }); From 0739b9d71ae2bb5c85709f907e55f90518ba9947 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 26 Aug 2026 05:32:21 +0900 Subject: [PATCH 6/6] fix(ui): make exact values keyboard-scrollable --- frontend/src/App.css | 10 ++++++++++ frontend/src/components/OntologyExplorer.test.tsx | 1 + frontend/src/components/OntologyExplorer.tsx | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index acf7651d7..b4b65dfc8 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1226,7 +1226,17 @@ .ontology-exact-values { margin-top: 1rem; + max-width: 100%; overflow-x: auto; + overscroll-behavior-inline: contain; + scrollbar-gutter: stable; + -webkit-overflow-scrolling: touch; +} + +.ontology-exact-values:focus-visible { + outline: 2px solid var(--color-focus-border); + outline-offset: 2px; + border-radius: var(--radius-control); } .ontology-exact-values table { diff --git a/frontend/src/components/OntologyExplorer.test.tsx b/frontend/src/components/OntologyExplorer.test.tsx index 9c6480a88..4ca22ac4f 100644 --- a/frontend/src/components/OntologyExplorer.test.tsx +++ b/frontend/src/components/OntologyExplorer.test.tsx @@ -236,6 +236,7 @@ describe("OntologyExplorer", () => { expect( screen.getByText(/This is an ontology neighborhood, not Event Lineage/), ).toBeInTheDocument(); + expect(screen.getByRole("region", { name: "Exact values" })).toHaveAttribute("tabindex", "0"); await userEvent.click(screen.getByRole("button", { name: "Select node: Post Demo public post" })); expect(screen.getByRole("heading", { name: "Demo public post" })).toBeInTheDocument(); await userEvent.click(screen.getByRole("button", { name: "Open evidence post" })); diff --git a/frontend/src/components/OntologyExplorer.tsx b/frontend/src/components/OntologyExplorer.tsx index 22247dc87..cd99d97b8 100644 --- a/frontend/src/components/OntologyExplorer.tsx +++ b/frontend/src/components/OntologyExplorer.tsx @@ -479,7 +479,12 @@ function OntologyExactValueTable({ onSelectEdge: (edgeId: string) => void; }) { return ( -
+

{t("Exact values")}

{payload.exact_value_rows.length === 0 ? (

{t("No visible ontology relations for this focus. Open a Keyman or affiliated organization next.")}