webui: dependency-layered graph and legible instrument chrome - #428
Conversation
Replace the index-order node grid with a dependency-layered architecture layout (surfaces left, foundations right, isolated modules in a band below, kernel ownership frame, directional edges with arrowheads, fit-to-stage scaling). Selection highlights in/out edges and dims non-neighbours at a readable floor; no auto-selection on first visit. Evidence rail: blueprint tab scopes to the selected node's declaration with an expand toggle and full-height pane; Facts kv grid tightened; lineage restyled to one row per artefact. Chrome: shell fills wide viewports, single labelled Kind/State filter groups, deduplicated status bezel with a compact drift annunciator, channel bar rebuilt as compact severity-sorted rows with collapse toggle and colour-coded severity. Restrained motion section gated behind prefers-reduced-motion. app.js split into app-data, canvas-nav, and graph-layout modules to hold the 500-line gate. Verified headlessly at 1568x962, 1440x900, and 390px against the embedded binary: no console errors, no raw copy keys, no overflow.
Move the landing page from docs/landing/index.html to docs/index.html (and _headers alongside) so Pages serves it directly instead of through a redirect. Update the a11y and design-token gates, their tests, and doc references to the new path. Also a copy pass on README and the landing page: removed the stale "See it" screenshot section (to be re-added with a capture of the new Graph Explorer), replaced telemetry-negation phrasing with plain local-first wording, and reworked flagged template-cadence sentences.
|
Warning Review limit reached
Next review available in: 40 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThis PR replaces the landing-page redirect with a full marketing page, updates the design system, and refactors the WebUI around shared data, graph-layout, navigation, evidence, channel, and status components. ChangesLanding surface
Design-system refresh
Frontend data and graph pipeline
Instrument interaction surfaces
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant QueryRail
participant app
participant GraphWorkspace
participant EvidenceRail
User->>QueryRail: change query or filter
QueryRail->>app: invoke filter or clear handler
app->>GraphWorkspace: update visible nodes and selection
User->>GraphWorkspace: select graph node
GraphWorkspace->>app: invoke onSelect
app->>EvidenceRail: load and render node artefacts
Possibly related PRs
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Tap targets: query segments and the channel toggle meet --tap-min on narrow viewports. Mobile keeps the ratified bounded shell; the channel bar defaults collapsed on compact and its tab strip wraps to a 2x2 grid under 640px instead of scrolling offscreen. Match count now reflects selectable cards (containers render as frames, not cards), fixing the palette scenario's count invariant. Harness actions updated for the redesigned lineage rows and match indicator; dead mobile stage token removed. ux_defect_score=0 across all 11 scenarios locally.
There was a problem hiding this comment.
Actionable comments posted: 13
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/_headers`:
- Around line 1-3: Remove the Referrer-Policy and X-Content-Type-Options entries
from docs/_headers and configure both headers in the GitHub Pages hosting layer
instead, using the repository’s existing deployment configuration.
In `@docs/design-system/components.css`:
- Around line 369-371: The shared dependency-arrow marker uses currentColor,
preventing arrowheads from inheriting each dependency link’s direction-specific
color. Update the marker path styling in docs/design-system/components.css lines
369-371 and src/ui_assets/style.css lines 121-123 to use context-stroke with the
required Safari fallback, or implement synchronized direction-specific marker
copies in both files.
In `@docs/design-system/tokens.css`:
- Around line 144-146: Update the token definitions in the dark root and the
[data-theme="light"] override so --error uses a distinct blocking accent instead
of resolving through --drift to --ci-amber, while --warning remains amber.
Ensure --error and --warning resolve to different colours in both themes,
preserving the existing severity consumer mappings.
In `@docs/index.html`:
- Around line 813-821: Update the reduced-motion handling and animation toggle
logic around the hero autoplay video, reveal effects, variant animations, and
the state.anim switch so reduced motion pauses the video and suppresses all
animation, while state.anim === "off" produces the same behavior instead of only
setting an unused data-anim attribute. Ensure the video is paused and
animation/reveal styles are disabled for either condition, while normal
animation remains unchanged otherwise.
- Around line 19-21: Remove the page-local design-system declarations from the
styles in docs/index.html, including typography, spacing, radii, motion,
buttons, cards, panels, and hardcoded shadows. Link and consume the canonical
docs/design-system/components.css and tokens.css instead, moving any genuinely
reusable definitions into those files. Update the design-system reference and
README to document the canonical additions, while preserving the page’s existing
visual behavior through shared tokens and components.
- Around line 931-969: Update the provenance and authority diagrams to preserve
the canonical Source → Research → Decision and Decision → Blueprint → Contract →
Code flows. Remove the “synthesis” node and reroute the research connection
directly to the Decision hinge, and replace any “layer” labels with the
established pluggable-domain/reconciler terminology in both diagram occurrences.
Do not introduce a flattened architectural stack.
- Around line 115-166: Update the responsive styles for nav.site so narrow
screens provide an accessible mobile layout instead of relying on a single
non-wrapping row clipped by body overflow. Adjust the navigation and its child
selectors, including .brand, .links, .version, and .cta, to fit or scroll within
the viewport while preserving access to all links, the CTA, and version
indicator.
In `@README.md`:
- Line 31: Update the exit-cleanup promise in the README paragraph to include
removing the pasted Cairn section from the agent instructions, alongside
deleting the listed repository files. Preserve the existing local-first and
cleanup guidance while ensuring all setup changes are covered.
In `@src/ui_assets/canvas-nav.js`:
- Around line 84-92: Update the source and candidate selection logic around the
current selection lookup so the first node is only used as a navigation target
when there is no active selection, not treated as the already-selected source.
Preserve the existing behavior for an active currentSelectionId while allowing
arrow-key navigation to include the first node and select it in both single-node
and larger graphs.
In `@src/ui_assets/evidence-rail.js`:
- Around line 125-144: Update LineagePlate so artefacts.sources remains a
distinct Sources/provenance section rather than being assigned to
lineage-authority or labeled as authority. Preserve the separate “Source →
Research → Decision” provenance chain and “Decision → Blueprint → Contract →
Code” authority chain; if authority data is needed, model and render it
independently instead of reusing authority.
In `@src/ui_assets/status-bezel.js`:
- Around line 32-44: Update DriftIndicator so the status summary is shown
whenever any finding count exists, including info-only findings, rather than
gating it solely on drift. Preserve the existing severity tone and clean-state
behavior for zero counts, and use the existing counts/parts values.
In `@src/ui_assets/style.css`:
- Around line 130-135: Update the min-height declaration in
.graph-stage.is-empty to use an existing defined spacing token from --s-1
through --s-12, or an appropriate fixed value, instead of the undefined --s-20.
In `@src/ui_assets/utils.js`:
- Around line 75-79: Update the copy() API in the surrounding utility to accept
a caller-provided fallback value, and return that fallback when copy loading has
not completed instead of always returning an empty string. Update the
runtime-not-ready error path in app.js to pass a non-empty fallback so critical
pre-load errors remain visible, while preserving existing behavior for loaded
copy and missing-key cases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2f93c88b-9bf8-44e2-8c4e-ecadeac3392d
📒 Files selected for processing (33)
AGENTS.mdREADME.mddocs/_headersdocs/design-system/README.mddocs/design-system/components.cssdocs/design-system/copy.tomldocs/design-system/index.htmldocs/design-system/tokens.cssdocs/index.htmldocs/landing/index.htmlharness/fixtures/assets/copy.jsonmap.jsonscripts/check-a11y.shscripts/check-design-tokens.shsrc/ui/mod.rssrc/ui/server.rssrc/ui_assets/app-data.jssrc/ui_assets/app.jssrc/ui_assets/canvas-nav.jssrc/ui_assets/channel-bar.jssrc/ui_assets/evidence-rail.jssrc/ui_assets/graph-layout.jssrc/ui_assets/graph-workspace.jssrc/ui_assets/node-module.jssrc/ui_assets/query-rail.jssrc/ui_assets/status-bezel.jssrc/ui_assets/style.csssrc/ui_assets/utils.jstests/check_a11y.rstests/check_design_tokens.rstests/graph_explorer.rstests/landing_assets.rstests/phase_7_7_ux_foundation.rs
💤 Files with no reviewable changes (1)
- docs/landing/index.html
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 13
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/_headers`:
- Around line 1-3: Remove the Referrer-Policy and X-Content-Type-Options entries
from docs/_headers and configure both headers in the GitHub Pages hosting layer
instead, using the repository’s existing deployment configuration.
In `@docs/design-system/components.css`:
- Around line 369-371: The shared dependency-arrow marker uses currentColor,
preventing arrowheads from inheriting each dependency link’s direction-specific
color. Update the marker path styling in docs/design-system/components.css lines
369-371 and src/ui_assets/style.css lines 121-123 to use context-stroke with the
required Safari fallback, or implement synchronized direction-specific marker
copies in both files.
In `@docs/design-system/tokens.css`:
- Around line 144-146: Update the token definitions in the dark root and the
[data-theme="light"] override so --error uses a distinct blocking accent instead
of resolving through --drift to --ci-amber, while --warning remains amber.
Ensure --error and --warning resolve to different colours in both themes,
preserving the existing severity consumer mappings.
In `@docs/index.html`:
- Around line 813-821: Update the reduced-motion handling and animation toggle
logic around the hero autoplay video, reveal effects, variant animations, and
the state.anim switch so reduced motion pauses the video and suppresses all
animation, while state.anim === "off" produces the same behavior instead of only
setting an unused data-anim attribute. Ensure the video is paused and
animation/reveal styles are disabled for either condition, while normal
animation remains unchanged otherwise.
- Around line 19-21: Remove the page-local design-system declarations from the
styles in docs/index.html, including typography, spacing, radii, motion,
buttons, cards, panels, and hardcoded shadows. Link and consume the canonical
docs/design-system/components.css and tokens.css instead, moving any genuinely
reusable definitions into those files. Update the design-system reference and
README to document the canonical additions, while preserving the page’s existing
visual behavior through shared tokens and components.
- Around line 931-969: Update the provenance and authority diagrams to preserve
the canonical Source → Research → Decision and Decision → Blueprint → Contract →
Code flows. Remove the “synthesis” node and reroute the research connection
directly to the Decision hinge, and replace any “layer” labels with the
established pluggable-domain/reconciler terminology in both diagram occurrences.
Do not introduce a flattened architectural stack.
- Around line 115-166: Update the responsive styles for nav.site so narrow
screens provide an accessible mobile layout instead of relying on a single
non-wrapping row clipped by body overflow. Adjust the navigation and its child
selectors, including .brand, .links, .version, and .cta, to fit or scroll within
the viewport while preserving access to all links, the CTA, and version
indicator.
In `@README.md`:
- Line 31: Update the exit-cleanup promise in the README paragraph to include
removing the pasted Cairn section from the agent instructions, alongside
deleting the listed repository files. Preserve the existing local-first and
cleanup guidance while ensuring all setup changes are covered.
In `@src/ui_assets/canvas-nav.js`:
- Around line 84-92: Update the source and candidate selection logic around the
current selection lookup so the first node is only used as a navigation target
when there is no active selection, not treated as the already-selected source.
Preserve the existing behavior for an active currentSelectionId while allowing
arrow-key navigation to include the first node and select it in both single-node
and larger graphs.
In `@src/ui_assets/evidence-rail.js`:
- Around line 125-144: Update LineagePlate so artefacts.sources remains a
distinct Sources/provenance section rather than being assigned to
lineage-authority or labeled as authority. Preserve the separate “Source →
Research → Decision” provenance chain and “Decision → Blueprint → Contract →
Code” authority chain; if authority data is needed, model and render it
independently instead of reusing authority.
In `@src/ui_assets/status-bezel.js`:
- Around line 32-44: Update DriftIndicator so the status summary is shown
whenever any finding count exists, including info-only findings, rather than
gating it solely on drift. Preserve the existing severity tone and clean-state
behavior for zero counts, and use the existing counts/parts values.
In `@src/ui_assets/style.css`:
- Around line 130-135: Update the min-height declaration in
.graph-stage.is-empty to use an existing defined spacing token from --s-1
through --s-12, or an appropriate fixed value, instead of the undefined --s-20.
In `@src/ui_assets/utils.js`:
- Around line 75-79: Update the copy() API in the surrounding utility to accept
a caller-provided fallback value, and return that fallback when copy loading has
not completed instead of always returning an empty string. Update the
runtime-not-ready error path in app.js to pass a non-empty fallback so critical
pre-load errors remain visible, while preserving existing behavior for loaded
copy and missing-key cases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2f93c88b-9bf8-44e2-8c4e-ecadeac3392d
📒 Files selected for processing (33)
AGENTS.mdREADME.mddocs/_headersdocs/design-system/README.mddocs/design-system/components.cssdocs/design-system/copy.tomldocs/design-system/index.htmldocs/design-system/tokens.cssdocs/index.htmldocs/landing/index.htmlharness/fixtures/assets/copy.jsonmap.jsonscripts/check-a11y.shscripts/check-design-tokens.shsrc/ui/mod.rssrc/ui/server.rssrc/ui_assets/app-data.jssrc/ui_assets/app.jssrc/ui_assets/canvas-nav.jssrc/ui_assets/channel-bar.jssrc/ui_assets/evidence-rail.jssrc/ui_assets/graph-layout.jssrc/ui_assets/graph-workspace.jssrc/ui_assets/node-module.jssrc/ui_assets/query-rail.jssrc/ui_assets/status-bezel.jssrc/ui_assets/style.csssrc/ui_assets/utils.jstests/check_a11y.rstests/check_design_tokens.rstests/graph_explorer.rstests/landing_assets.rstests/phase_7_7_ux_foundation.rs
💤 Files with no reviewable changes (1)
- docs/landing/index.html
🛑 Comments failed to post (13)
docs/_headers (1)
1-3: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -eu # Inspect whether the workflow explicitly processes docs/_headers. fd -a -t f '^pages\.yml$' .github/workflows \ --exec sh -c 'echo "### $1"; sed -n "1,240p" "$1"' sh {} # Verify the actual deployed response. curl -sSI https://cairn-framework.github.io/cairn/ | grep -iE '^(referrer-policy|x-content-type-options):' || trueRepository: cairn-framework/cairn
Length of output: 1030
Move these headers into the Pages hosting layer
docs/_headersis deployed as a static file here, so it won't setReferrer-PolicyorX-Content-Type-Optionson GitHub Pages responses.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/_headers` around lines 1 - 3, Remove the Referrer-Policy and X-Content-Type-Options entries from docs/_headers and configure both headers in the GitHub Pages hosting layer instead, using the repository’s existing deployment configuration.docs/design-system/components.css (1)
369-371: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Which browsers support CSS context-stroke and context-fill for SVG marker fill?💡 Result:
As of July 18, 2026, the CSS values context-fill and context-stroke are supported in the following major browser engines: - Chromium-based browsers (Chrome, Edge, Opera, etc.): Supported since version 124 (released in April 2024) [1][2][3]. - Firefox: Supported since version 111 (released in March 2023) [1][2][4]. These features are currently not supported in Safari (or any WebKit-based browser) [1][5][2]. The context-fill and context-stroke values are part of the SVG 2 specification [6][4]. They allow SVG elements—specifically those instantiated via markers or the use element—to dynamically inherit the fill and stroke properties from the element that references them, rather than requiring static or pre-defined colors [6][3][7]. This is particularly useful for creating scalable markers that automatically match the color of the path or shape they are attached to [6][8][7].
Citations:
- 1: https://caniuse.com/wf-context-fill-stroke
- 2: web-platform-dx/developer-signals#199
- 3: https://developer.chrome.com/release-notes/124
- 4: WebKit/standards-positions#331
- 5: https://web-platform-dx.github.io/web-features-explorer/features/context-fill-stroke/
- 6: https://www.w3.org/TR/SVG2/painting.html
- 7: https://svgwg.org/svg2-draft/painting.html
- 8: https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/fill
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '== relevant files ==\n' git ls-files 'docs/design-system/components.css' 'src/ui_assets/style.css' 'src/ui_assets/*.js' 'src/ui_assets/*.ts' 'src/ui_assets/*.tsx' 'docs/design-system/*.html' 'docs/design-system/*.md' | sed 's#^`#-` #' printf '\n== marker rules ==\n' grep -RIn --line-number --context=2 'marker path' docs/design-system/components.css src/ui_assets/style.css || true printf '\n== dependency arrow usage ==\n' grep -RIn --line-number --context=3 '`#dependency-arrow`\|dependency-link\|context-stroke\|context-fill' src docs/design-system || trueRepository: cairn-framework/cairn
Length of output: 7666
🏁 Script executed:
#!/bin/bash set -euo pipefail ast-grep outline src/ui_assets/graph-workspace.js --view expanded || true printf '\n== marker defs and arrow usage ==\n' sed -n '1,180p' src/ui_assets/graph-workspace.js | cat -nRepository: cairn-framework/cairn
Length of output: 8928
Directional arrowheads use a single color. The shared
#dependency-arrowmarker is filled withcurrentColor, but it does not inherit each.dependency-linkcolor, sois-out,is-in, andis-dimmededges all reuse the same arrowhead color. Usecontext-strokewhere supported, with a Safari fallback, or split the marker by direction and keep both CSS copies aligned.
docs/design-system/components.css#L369-L371src/ui_assets/style.css#L121-L123🧰 Tools
🪛 Stylelint (17.14.0)
[error] 370-370: Expected "currentColor" to be "currentcolor" (value-keyword-case)
(value-keyword-case)
📍 Affects 2 files
docs/design-system/components.css#L369-L371(this comment)src/ui_assets/style.css#L121-L123🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/design-system/components.css` around lines 369 - 371, The shared dependency-arrow marker uses currentColor, preventing arrowheads from inheriting each dependency link’s direction-specific color. Update the marker path styling in docs/design-system/components.css lines 369-371 and src/ui_assets/style.css lines 121-123 to use context-stroke with the required Safari fallback, or implement synchronized direction-specific marker copies in both files.docs/design-system/tokens.css (1)
144-146: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
--errorand--warningresolve to the same colour, so severity coding is not distinguishable.
--error: var(--drift)and--drift: var(--ci-amber)(Line 136), while--warning: var(--ci-amber)(Line 145). Both therefore resolve to#d99a2b. Every consumer that pairs them (.status-severity.error/.warning,.channel-severity,.channel-item.tone-error/.tone-warning) uses the same base colour and identical opacities, soErrorandWarningrender pixel-identically and only the text label differentiates them. This undercuts the PR's severity-coding goal.Consider mapping
--errorto the blocking accent so it reads as more urgent than the amber warning. Note the light theme also needs a distinct value because--block: var(--drift)there (Line 294), so error would still collapse onto warning under[data-theme="light"].🎨 Proposed change (dark root) plus a light-theme override
- --error: var(--drift); + --error: var(--block); --warning: var(--ci-amber); --info: var(--ink-aged);[data-theme="light"] { ... --block: var(--drift); + --error: color-mix(in oklab, var(--ci-amber) 70%, `#7a2f1a`); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/design-system/tokens.css` around lines 144 - 146, Update the token definitions in the dark root and the [data-theme="light"] override so --error uses a distinct blocking accent instead of resolving through --drift to --ci-amber, while --warning remains amber. Ensure --error and --warning resolve to different colours in both themes, preserving the existing severity consumer mappings.docs/index.html (4)
19-21: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Do not create a page-local design system.
The page redeclares typography, spacing, radii, motion, buttons, cards, panels, and hardcoded shadows instead of consuming the canonical tokens and components. Move reusable definitions into
tokens.css/components.css, linkcomponents.css, and update the design-system reference and README.As per coding guidelines, UI changes must use tokens from
docs/design-system/tokens.css, reusecomponents.css, and update the canonical design-system files and references when adding tokens or components.Also applies to: 29-60, 225-258, 643-680, 717-774, 1274-1286
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/index.html` around lines 19 - 21, Remove the page-local design-system declarations from the styles in docs/index.html, including typography, spacing, radii, motion, buttons, cards, panels, and hardcoded shadows. Link and consume the canonical docs/design-system/components.css and tokens.css instead, moving any genuinely reusable definitions into those files. Update the design-system reference and README to document the canonical additions, while preserving the page’s existing visual behavior through shared tokens and components.Source: Coding guidelines
115-166: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Add a narrow-screen navigation layout.
The brand, five links, CTA, and version remain in one non-wrapping flex row while
bodyclips horizontal overflow. On mobile, navigation items will extend beyond the viewport and become inaccessible.Example responsive treatment
nav.site .cta:hover { background: var(--stone-3); color: var(--ink-char); } + +@media (max-width: 760px) { + nav.site { + flex-wrap: wrap; + gap: var(--s-3); + } + nav.site .links { + order: 3; + width: 100%; + margin-left: 0; + flex-wrap: wrap; + gap: var(--s-4); + } + nav.site .version { + margin-left: auto; + } +}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.nav.site { padding: var(--s-5) 0; display: flex; align-items: center; gap: var(--s-6); font-family: var(--font-sans); font-size: var(--t-small); color: var(--ink-faded); letter-spacing: 0.03em; } nav.site .brand { display: flex; align-items: center; gap: var(--s-3); color: var(--ink-char); font-weight: 500; letter-spacing: 0.01em; } nav.site .brand svg { display: block; } nav.site .links { margin-left: auto; display: flex; gap: var(--s-6); } nav.site .links a { color: var(--ink-aged); text-transform: lowercase; border: 0; transition: color var(--fast) var(--ease); } nav.site .links a:hover { color: var(--ink-char); } nav.site .version { color: var(--ink-mist); border: 1px solid var(--seam-thin); padding: 2px var(--s-2); border-radius: var(--r-edge); font-family: var(--font-mono); font-size: var(--t-micro); letter-spacing: 0.05em; } nav.site .cta { color: var(--ink-char); border: 1px solid var(--seam-clear); padding: 4px var(--s-3); border-radius: var(--r-edge); font-family: var(--font-sans); font-size: var(--t-micro); letter-spacing: 0.12em; text-transform: uppercase; transition: background var(--fast) var(--ease), color var(--fast) var(--ease); } nav.site .cta:hover { background: var(--stone-3); color: var(--ink-char); } `@media` (max-width: 760px) { nav.site { flex-wrap: wrap; gap: var(--s-3); } nav.site .links { order: 3; width: 100%; margin-left: 0; flex-wrap: wrap; gap: var(--s-4); } nav.site .version { margin-left: auto; } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/index.html` around lines 115 - 166, Update the responsive styles for nav.site so narrow screens provide an accessible mobile layout instead of relying on a single non-wrapping row clipped by body overflow. Adjust the navigation and its child selectors, including .brand, .links, .version, and .cta, to fit or scroll within the viewport while preserving access to all links, the CTA, and version indicator.
813-821: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Honor reduced motion for the autoplay video and make “off” functional.
The media query disables CSS animation only, so the looping hero video continues playing. The tweak switch merely sets an unused
data-animattribute. Pause the video and suppress reveal/variant animation when either reduced motion orstate.anim === "off"applies.Also applies to: 877-882, 1204-1206, 1252-1268
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/index.html` around lines 813 - 821, Update the reduced-motion handling and animation toggle logic around the hero autoplay video, reveal effects, variant animations, and the state.anim switch so reduced motion pauses the video and suppresses all animation, while state.anim === "off" produces the same behavior instead of only setting an unused data-anim attribute. Ensure the video is paused and animation/reveal styles are disabled for either condition, while normal animation remains unchanged otherwise.
931-969: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Restore the canonical provenance and domain terminology.
- Remove
synthesisand connectresearchdirectly to the Decision hinge.- Replace the “layer” labels with domain/reconciler terminology; these are pluggable domains, not a flattened architectural stack.
As per coding guidelines, preserve
Source → Research → DecisionandDecision → Blueprint → Contract → Code, and do not flatten Cairn’s model into layers.Also applies to: 1099-1121
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/index.html` around lines 931 - 969, Update the provenance and authority diagrams to preserve the canonical Source → Research → Decision and Decision → Blueprint → Contract → Code flows. Remove the “synthesis” node and reroute the research connection directly to the Decision hinge, and replace any “layer” labels with the established pluggable-domain/reconciler terminology in both diagram occurrences. Do not introduce a flattened architectural stack.Source: Coding guidelines
README.md (1)
31-31: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Include the agent-instruction cleanup in this exit promise.
Lines 86 and 92 establish that users must also remove the pasted Cairn section from their agent instructions. Without that step, the repository is not restored as claimed.
Proposed clarification
-If you ever want out, delete `.cairn/`, `cairn.blueprint`, `cairn.config.yaml`, and the generated map files, and your repo is back to how it was. +If you ever want out, delete `.cairn/`, `cairn.blueprint`, `cairn.config.yaml`, and the generated map files, then remove the pasted Cairn section from your agent instructions.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.You do almost nothing. Your agent drafts the first map in one command, and keeps it in sync as part of the work you already asked for. The map and all of its notes are plain text in your repo, plus a blueprint file and a small config file. Cairn is local-first, so your project data stays on your machine. If you ever want out, delete `.cairn/`, `cairn.blueprint`, `cairn.config.yaml`, and the generated map files, then remove the pasted Cairn section from your agent instructions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` at line 31, Update the exit-cleanup promise in the README paragraph to include removing the pasted Cairn section from the agent instructions, alongside deleting the listed repository files. Preserve the existing local-first and cleanup guidance while ensuring all setup changes are covered.src/ui_assets/canvas-nav.js (1)
84-92: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Select the first node when the canvas has no active selection.
The app now starts unselected, but this fallback treats the first node as selected and immediately removes it from the candidates. A single-node graph therefore cannot be selected with arrow keys, while larger graphs skip the first option.
Proposed fix
- const source = nodes.find((node) => node.id === currentSelectionId) || nodes.find((node) => node.id === visibleIds[0]) || nodes[0]; + const source = nodes.find((node) => node.id === currentSelectionId); if (!source) { - return null; + return nodes.find((node) => node.id === visibleIds[0])?.id || nodes[0]?.id || null; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const source = nodes.find((node) => node.id === currentSelectionId); if (!source) { return nodes.find((node) => node.id === visibleIds[0])?.id || nodes[0]?.id || null; } const candidates = nodes.filter((node) => node.id !== source.id); if (!candidates.length) { return null; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/ui_assets/canvas-nav.js` around lines 84 - 92, Update the source and candidate selection logic around the current selection lookup so the first node is only used as a navigation target when there is no active selection, not treated as the already-selected source. Preserve the existing behavior for an active currentSelectionId while allowing arrow-key navigation to include the first node and select it in both single-node and larger graphs.src/ui_assets/evidence-rail.js (1)
125-144: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Do not present source artefacts as the authority chain.
artefacts.sourcesis provenance data, but it is renamed and displayed aslineage-authority. Label this section as Sources, or model the actual authority sequence separately.As per coding guidelines, preserve the distinct provenance chain “Source → Research → Decision” and authority chain “Decision → Blueprint → Contract → Code”; do not flatten them into layers.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/ui_assets/evidence-rail.js` around lines 125 - 144, Update LineagePlate so artefacts.sources remains a distinct Sources/provenance section rather than being assigned to lineage-authority or labeled as authority. Preserve the separate “Source → Research → Decision” provenance chain and “Decision → Blueprint → Contract → Code” authority chain; if authority data is needed, model and render it independently instead of reusing authority.Source: Coding guidelines
src/ui_assets/status-bezel.js (1)
32-44: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Show the summary for info-only findings.
partsincludes informational counts, but the summary is gated ondrift, so an info-only result displays “clean” with no count.Proposed fix
- ${drift ? html`<span class="status-annunciator-summary">${parts.join(" · ")}</span>` : null} + ${parts.length ? html`<span class="status-annunciator-summary">${parts.join(" · ")}</span>` : null}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.function DriftIndicator({ counts }) { const drift = counts.errors + counts.warnings; const parts = []; if (counts.errors) parts.push(`${counts.errors} ${copy("webui.findings-errors")}`); if (counts.warnings) parts.push(`${counts.warnings} ${copy("webui.findings-warnings")}`); if (counts.infos) parts.push(`${counts.infos} ${copy("webui.findings-infos")}`); const tone = drift ? (counts.errors ? "error" : "warning") : "info"; return html` <p class="status-annunciator status-annunciator-chip" role="status"> <${SeverityChip} tone=${tone}>${copy(drift ? "webui.status-drift" : "webui.status-clean")}</${SeverityChip}> ${parts.length ? html`<span class="status-annunciator-summary">${parts.join(" · ")}</span>` : null} </p>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/ui_assets/status-bezel.js` around lines 32 - 44, Update DriftIndicator so the status summary is shown whenever any finding count exists, including info-only findings, rather than gating it solely on drift. Preserve the existing severity tone and clean-state behavior for zero counts, and use the existing counts/parts values.src/ui_assets/style.css (1)
130-135: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Confirm --s-20 is never defined anywhere. rg -n -- '--s-20\s*:' docs/design-system src/ui_assets || echo "no --s-20 definition found"Repository: cairn-framework/cairn
Length of output: 186
🏁 Script executed:
#!/bin/bash set -euo pipefail printf '\n--- tokens.css spacing definitions ---\n' rg -n -- '--s-[0-9]+' docs/design-system/tokens.css printf '\n--- graph-stage.is-empty usage ---\n' rg -n -- 'graph-stage\.is-empty|--s-20' src/ui_assets/style.css src/ui_assets -nRepository: cairn-framework/cairn
Length of output: 870
Replace
--s-20with a defined spacing token
src/ui_assets/style.css:134
tokens.cssonly defines--s-1through--s-12, sovar(--s-20)is invalid here and the empty-state min-height gets dropped. Use one of the existing spacing tokens or a fixed value instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/ui_assets/style.css` around lines 130 - 135, Update the min-height declaration in .graph-stage.is-empty to use an existing defined spacing token from --s-1 through --s-12, or an appropriate fixed value, instead of the undefined --s-20.src/ui_assets/utils.js (1)
75-79: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Keep critical pre-load errors non-empty.
copy()now returns""before copy loading, so the runtime-not-ready branch inapp.jssets an empty error and renders the normal empty workspace. Support a caller-provided fallback and use it for that branch.Proposed copy API adjustment
-function copy(key) { +function copy(key, pendingFallback = "") { ... - return ""; + return pendingFallback;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/ui_assets/utils.js` around lines 75 - 79, Update the copy() API in the surrounding utility to accept a caller-provided fallback value, and return that fallback when copy loading has not completed instead of always returning an empty string. Update the runtime-not-ready error path in app.js to pass a non-empty fallback so critical pre-load errors remain visible, while preserving existing behavior for loaded copy and missing-key cases.
Bump the workspace to 0.8.0 and write the changelog for the graph explorer relayout round (PRs #428, #429). README: swap the release badge to badgen (the shields.io dynamic release path renders broken), add fresh graph-explorer screenshots (default map and node focus, captured from the 0.8.0 binary at 2x), served via absolute raw URLs so the crates.io render resolves them. copy-lint: 0 em-dashes, 0 AI-tier-1 terms, FK grade 6.5.
What
Second-round webui overhaul driven by a grounded screenshot audit plus an adversarial vision review, addressing: relations not readable from a flat grid, tiny blueprint pane, crowded chrome, invisible findings/backlog, page not filling the viewport.
Graph
Evidence rail
Chrome
--ui-shell-max-width: min(100%, 1720px)).prefers-reduced-motion.Second commit
Serves GitHub Pages from
docs/root (drops the landing redirect), updates gates/tests/references, plus the README/landing copy pass.Verification
cairn scan --strictall green.Known deferred: style.css/components.css still duplicate ~40 component selectors with minor drift (flagged by review; needs a single-authority restructure, separate change).