Skip to content

feat(design-system): add professional finish review loop - #153

Merged
jscraik merged 4 commits into
mainfrom
jscraik/feature/jsc-77-professional-finish-review-loops
Apr 26, 2026
Merged

feat(design-system): add professional finish review loop#153
jscraik merged 4 commits into
mainfrom
jscraik/feature/jsc-77-professional-finish-review-loops

Conversation

@jscraik

@jscraik jscraik commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Pull request checklist

Summary

  • What changed (brief): Added the JSC-77 professional-finish review rubric, wired the exemplar evaluator to enforce the review contract before visual checks, scoped shared focus styling to opt-in design-system focus targets, and stabilized workspace package resolution for generated-source, type-check, widget, and web dev-server paths.
  • Why this change was needed: The exemplar surfaces now need a repeatable professional-finish loop for hierarchy, spacing rhythm, focus consistency, state quality, motion restraint, and gold-standard references instead of relying on ad hoc visual review.
  • Risk and rollback plan: Risk is mostly around focus styling scope and Vite alias resolution for local workspace packages. Roll back by reverting this PR; generated widget manifest hashes return to the previous values and shared focus CSS returns to the prior global behavior.

Checklist

  • I did not push directly to main; this PR is from a dedicated branch.
  • Branch name follows policy (codex/* for agent-created branches).
  • Required local gates run: bash scripts/validate-codestyle.sh, pnpm check, test -f memory.json && jq -e '.meta.version == "1.0" and (.preamble.bootstrap | type == "boolean") and (.preamble.search | type == "boolean") and (.entries | type == "array")' memory.json >/dev/null.
  • CodeRabbit review completed and findings handled (or explicitly waived).
  • CodeRabbit review was performed by an independent reviewer (not the coding agent).
  • Codex review completed and findings handled (or explicitly waived).
  • Any CodeRabbit Semgrep findings were either fixed or explicitly justified when warning-level-only.
  • Merge is blocked until all required checks pass.
  • I will delete branch/worktree after merge.

Testing

  • verification_commands: pnpm validate:tokens; pnpm design-system-guidance:check:ci; pnpm generated-source:check; pnpm typecheck; pnpm test:policy; pnpm test:exemplar-evaluation:list; git diff --check; bash scripts/validate-codestyle.sh; pnpm check; test -f memory.json && jq -e '.meta.version == "1.0" and (.preamble.bootstrap | type == "boolean") and (.preamble.search | type == "boolean") and (.entries | type == "array")' memory.json >/dev/null; pnpm -C platforms/web/apps/web build; git push -u origin jscraik/feature/jsc-77-professional-finish-review-loops (pre-push hook)
  • verification_outcomes: all listed commands passed. pnpm design-system-guidance:check:ci retained existing advisory warnings only. pnpm test:exemplar-evaluation:list retained a nonfatal sharp/libvips duplicate-class warning during web visual listing. The first sandboxed push attempt was blocked by macOS Chromium launch permissions; rerunning the same push outside the sandbox passed the pre-push hook.
  • blocked_steps_reason: none; the sandbox-only Chromium launch denial was resolved by rerunning the push outside the sandbox so the repo pre-push hook could complete.
  • Command: bash scripts/validate-codestyle.sh -> pass
  • Command: pnpm check -> pass
  • Command: test -f memory.json && jq -e '.meta.version == "1.0" and (.preamble.bootstrap | type == "boolean") and (.preamble.search | type == "boolean") and (.entries | type == "array")' memory.json >/dev/null -> pass
  • Any other command(s): pnpm validate:tokens -> pass; pnpm design-system-guidance:check:ci -> pass (existing warnings only); pnpm generated-source:check -> pass; pnpm typecheck -> pass; pnpm test:policy -> pass; pnpm test:exemplar-evaluation:list -> pass (nonfatal sharp/libvips duplicate-class warning during web visual listing); git diff --check -> pass; pnpm -C platforms/web/apps/web build -> pass; git push -u origin jscraik/feature/jsc-77-professional-finish-review-loops -> pass (pre-push hook passed)

Review artifacts

  • CodeRabbit: pending draft PR review
  • Independent reviewer evidence: pending independent CodeRabbit/Codex review
  • Codex: pending independent Codex review
  • CodeRabbit Semgrep: n.a. for this local pre-push run; semgrep:changed reported no changed src/** implementation files.
  • Additional evidence (if any): Commit ffa2b53a; Linear issue JSC-77.

Notes

This PR turns JSC-77 into a concrete review loop: a documented professional-finish rubric, an enforced exemplar precheck, scoped focus-ring behavior, and local workspace resolution repairs so the visual and generated-source gates can exercise the right surfaces. The branch uses the Codex desktop configured jscraik/feature/* prefix, while the repository template still names codex/* for agent-created branches; the checklist keeps that policy mismatch visible for review rather than marking it as satisfied.

Why: JSC-77 needs one canonical professional-finish review loop for hierarchy, state quality, focus consistency, and exemplar reference coverage.

What: add the professional-finish rubric and gold-standard reference set, scope shared focus selectors to opt-in design-system targets, wire the exemplar runner to precheck the contract, and stabilize generated-source/type-check resolution for widget manifest rebuilds.

Impact/Risk: shared CSS no longer applies a bare global :focus-visible ring or global mouse-focus outline suppression. Widget manifest hashes are refreshed from the stabilized build path. Runtime/token builds force project emits so stale build info cannot hide missing declaration files.

Validation: pnpm validate:tokens -> pass
Validation: pnpm design-system-guidance:check:ci -> pass (existing warnings only)
Validation: pnpm generated-source:check -> pass
Validation: pnpm typecheck -> pass
Validation: pnpm test:policy -> pass
Validation: pnpm test:exemplar-evaluation:list -> pass (nonfatal sharp/libvips duplicate-class warning during web visual listing)
Validation: git diff --check -> pass

Co-authored-by: Codex <noreply@openai.com>
@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Added Professional Finish review guide, visual QA rubric/checklist, and a Shared Focus Indicator accessibility contract with navigation.
  • New Features
    • Professional-finish precheck integrated into exemplar evaluation to enforce focus/state quality and review rubric.
    • Dev tooling now resolves workspace packages to local sources for consistent local builds.
  • Updates
    • Focus rings are opt-in via scoped selectors; global focus-outline suppression is disallowed.
    • Widget manifest identifiers refreshed; TypeScript builds now force rebuilds.

Walkthrough

Adds a professional-finish precheck and review loop that gates exemplar evaluation, scopes focus styling to opt-in .ds-focusable selectors, updates TypeScript path/project-reference and Vite workspace aliases for local resolution, regenerates widget manifest hashes, and switches several package build scripts to tsc -b --force.

Changes

Cohort / File(s) Summary
Documentation & Review Policy
FORJAMIE.md, docs/design-system/A11Y_CONTRACTS.md, docs/design-system/PROFESSIONAL_FINISH_REVIEW.md, docs/design-system/PROFESSIONAL_UI_CONTRACT.md
Added Professional Finish Review Loop, Shared Focus Indicator accessibility contract, rubric and enforcement text, updated recent-changes notes and review procedure.
Focus CSS & Usage
packages/tokens/src/enhanced.css, packages/tokens/src/enhanced/focus.ts
Replaced global :focus/:focus-visible rules with scoped opt-in selectors (.ds-focusable, [data-ds-focusable]); updated usage docs/examples.
Exemplar Evaluation Precheck
scripts/policy/run-exemplar-evaluation.mjs
Added precheck that reads review docs and enhanced.css, validates rubric/reference headers and focus CSS rules (forbids bare global :focus/:focus-visible and enforces scoped selectors), generalized check runner, added SERVICE_LOG_TAG logging prefix.
TypeScript & Build Configs
packages/json-render/tsconfig.json, packages/ui/tsconfig.json, packages/runtime/package.json, packages/tokens/package.json
Removed certain rootDir/paths in favor of project references/paths mapping to local packages; switched build scripts to TypeScript project-reference build mode (tsc -b ... --force).
Vite Workspace Aliases
packages/widgets/vite.config.ts, platforms/web/apps/web/vite.config.ts
Added @design-studio/* aliases (including @design-studio/json-render, @design-studio/ui, @design-studio/runtime, @design-studio/tokens, and ui/* subpaths) pointing at local packages/*/src for dev/build resolution.
Widget Manifest Regeneration
packages/cloudflare-template/src/worker/widget-manifest.generated.ts
Regenerated widget manifest entries: updated uri and hash values for all widgets; name and originalPath unchanged.

Sequence Diagram(s)

sequenceDiagram
    participant Runner as Runner (script)
    participant FS as Filesystem (docs, enhanced.css)
    participant Precheck as Precheck/Checker
    participant Evaluator as Exemplar Evaluator
    participant CI as Test Harness

    Runner->>FS: read PROFESSIONAL_FINISH_REVIEW.md
    Runner->>FS: read packages/tokens/src/enhanced.css
    Runner->>Precheck: invoke checks (function or command)
    Precheck->>FS: validate rubric headers, reference set, focus selectors
    alt precheck passes
        Runner->>Evaluator: run `pnpm test:exemplar-evaluation`
        Evaluator->>CI: produce screenshots/results
        CI->>Runner: evaluation outcome
    else precheck fails
        Precheck->>Runner: return failure (abort)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(design-system): add professional finish review loop' directly and concisely summarizes the main change: introducing the professional finish review loop for the design system.
Description check ✅ Passed The description is clearly related to the changeset, detailing what changed (review rubric, exemplar evaluator wiring, scoped focus styling, workspace resolution), why it was needed, and testing outcomes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jscraik/feature/jsc-77-professional-finish-review-loops

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/tokens/src/enhanced/focus.ts (1)

96-116: ⚠️ Potential issue | 🟠 Major

Scope mouse-focus outline suppression to opt-in targets only.

The exported CSS still applies :focus:not(:focus-visible) globally, which conflicts with the new scoped focus contract and can remove native outlines from non-opted-in elements.

Proposed fix
-  :focus:not(:focus-visible) {
+  .ds-focusable:focus:not(:focus-visible),
+  [data-ds-focusable]:focus:not(:focus-visible) {
     outline: none;
   }

As per coding guidelines **: Use repository evidence first... Treat contradictions between code, docs, and workflow policy as review-worthy even when code changes look reasonable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/tokens/src/enhanced/focus.ts` around lines 96 - 116, The global rule
":focus:not(:focus-visible)" in the focusVisibleCSS string removes native
outlines for all elements; limit this suppression to opt-in elements by
replacing that global selector with the same scoped selectors used above (e.g.,
".ds-focusable:focus:not(:focus-visible)" and
"[data-ds-focusable]:focus:not(:focus-visible)") so only elements using the
ds-focusable contract lose outlines when focused by mouse; update the
focusVisibleCSS constant accordingly.
docs/design-system/PROFESSIONAL_FINISH_REVIEW.md (1)

86-87: 🧹 Nitpick | 🔵 Trivial

Add trailing newline.

The file ends at line 86 without a trailing newline. Most style guides and tools expect files to end with a newline character.

📄 Proposed fix
 - Update this reference set when a protected exemplar is renamed, removed, or superseded.
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/design-system/PROFESSIONAL_FINISH_REVIEW.md` around lines 86 - 87, The
file ends without a trailing newline; open
docs/design-system/PROFESSIONAL_FINISH_REVIEW.md and add a single newline
character at the end of the file so the final line "Update this reference set
when a protected exemplar is renamed, removed, or superseded." is terminated by
a newline (ensure the file now ends with '\n').
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/design-system/A11Y_CONTRACTS.md`:
- Around line 30-35: Add a generated Table of Contents near the top of the
A11Y_CONTRACTS.md file (just below the main title/header) that lists the
top-level sections (e.g., "Shared Focus Indicator", any other H2/H3 headers)
with Markdown anchor links; update the TOC whenever headers change and follow
the project's Markdown TOC style for other docs matching **/*.md so users can
navigate large docs easily.

In `@packages/json-render/tsconfig.json`:
- Around line 5-7: The tsconfig path mapping for the module identifier
"@design-studio/ui" points to a non-existent declaration file
"packages/ui/dist/index.d.ts"; update the "paths" entry in the JSON "paths"
section of tsconfig.json so that "@design-studio/ui" maps to the package source
(packages/ui/src/index.ts) to match other dev package mappings and restore
successful type-checking.

In `@scripts/policy/run-exemplar-evaluation.mjs`:
- Around line 63-67: The assertIncludes function throws a generic Error when
needle is not found; enhance the message by including the source identifier plus
a short snippet or truncated preview of content to aid debugging. Update
function assertIncludes(content, needle, source) to construct an error string
that contains source, the missing needle, and either a content.slice(0, N)
preview or the index position (content.indexOf(needle)) so the thrown Error
carries more context for locating the problem during tests.

---

Outside diff comments:
In `@docs/design-system/PROFESSIONAL_FINISH_REVIEW.md`:
- Around line 86-87: The file ends without a trailing newline; open
docs/design-system/PROFESSIONAL_FINISH_REVIEW.md and add a single newline
character at the end of the file so the final line "Update this reference set
when a protected exemplar is renamed, removed, or superseded." is terminated by
a newline (ensure the file now ends with '\n').

In `@packages/tokens/src/enhanced/focus.ts`:
- Around line 96-116: The global rule ":focus:not(:focus-visible)" in the
focusVisibleCSS string removes native outlines for all elements; limit this
suppression to opt-in elements by replacing that global selector with the same
scoped selectors used above (e.g., ".ds-focusable:focus:not(:focus-visible)" and
"[data-ds-focusable]:focus:not(:focus-visible)") so only elements using the
ds-focusable contract lose outlines when focused by mouse; update the
focusVisibleCSS constant accordingly.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 66b8efe3-8df6-42df-a152-2b2bfec7fa21

📥 Commits

Reviewing files that changed from the base of the PR and between 2a888da and ffa2b53.

⛔ Files ignored due to path filters (1)
  • packages/widgets/src/sdk/generated/widget-manifest.js is excluded by !**/generated/**
📒 Files selected for processing (14)
  • FORJAMIE.md
  • docs/design-system/A11Y_CONTRACTS.md
  • docs/design-system/PROFESSIONAL_FINISH_REVIEW.md
  • docs/design-system/PROFESSIONAL_UI_CONTRACT.md
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
  • packages/json-render/tsconfig.json
  • packages/runtime/package.json
  • packages/tokens/package.json
  • packages/tokens/src/enhanced.css
  • packages/tokens/src/enhanced/focus.ts
  • packages/ui/tsconfig.json
  • packages/widgets/vite.config.ts
  • platforms/web/apps/web/vite.config.ts
  • scripts/policy/run-exemplar-evaluation.mjs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (macos-latest)
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Biome (biome.json) for JS/TS formatting and keep files formatted via pnpm format

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{js,ts,tsx,jsx,py,rs,mjs,cjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{js,ts,tsx,jsx,py,rs,mjs,cjs}: Fabricated data/entropy (Math.random() without injected seed), hard-coded mock responses, TODO/FIXME/HACK comments, placeholder stubs, disabled features, or fake metrics MUST NOT exist in production code paths
Functions SHOULD be <= 40 LOC; split if readability suffers
No ambient randomness/time in core logic; inject seeds/clocks/IDs
Never swallow errors; add context and route to logging layer
Constants: UPPER_SNAKE_CASE
No hard-coded secrets; use env injection/secret manager; validate/sanitize all external inputs

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{js,ts,tsx,jsx,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Apps/binaries/services MUST include service identity in outputs, error messages, and logs (service:"<service_name>")

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{js,ts,tsx,jsx,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Long-running work MUST accept cancellation (AbortSignal in JS/TS; cancellation tokens/channels in Rust)

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{js,ts,tsx,jsx,mjs,json}

📄 CodeRabbit inference engine (CODESTYLE.md)

Packages MUST target the repo baseline Node version (pinned in .mise.toml and compat.json)

Files:

  • packages/widgets/vite.config.ts
  • packages/json-render/tsconfig.json
  • packages/tokens/src/enhanced/focus.ts
  • packages/tokens/package.json
  • packages/ui/tsconfig.json
  • packages/runtime/package.json
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{ts,tsx,mts,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

JSON imports MUST use import attributes (import data from "./foo.json" with { type: "json" })

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,tsx}: Explicit types at all public API boundaries (functions, modules, React props)
Use concrete types or unknown + narrowing instead of any (forbidden pattern: : any, as any, Promise, Record<string, any>)
Unsafe type assertions (value as unknown as T) forbidden; use type guards or schema validation instead
// @ts-ignore and // @ts-nocheck are forbidden; use // @ts-expect-error -- reason + ticket instead
Unsafe 'as SomeType' without runtime guard is forbidden; use guard function or schema validator
JSON.parse() and Response.json() return any; boundary mitigation MUST use schema validation (Zod/Valibot) or typed parser helper

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{js,ts,tsx,jsx,mjs,cjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{js,ts,tsx,jsx,mjs,cjs}: ESLint-disable comments MUST include reason and ticket; expiry date optional
JavaScript/TypeScript variables/functions: camelCase

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,tsx,js,mjs}: Exported async APIs that perform I/O or long work MUST accept AbortSignal
JSON inputs at boundaries in JS/TS MUST be schema-validated

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{rs,ts,tsx}

📄 CodeRabbit inference engine (CODESTYLE.md)

Tauri UI-facing state MUST be deterministic and testable

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{ts,tsx,jsx,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Types/components: PascalCase

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{ts,tsx,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

CLI/TUI: --plain / --no-color modes required

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{ts,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,js,py,rs,mjs}: OpenTelemetry SHOULD be used where services/CLIs exist; logs SHOULD be structured and include service at app boundaries
Streaming: default token delta streaming for CLIs, optional aggregated mode, JSON event streaming optional if supported
MCP adapters/helpers MUST not hard-code user-specific paths; health checks MUST be scriptable; egress/network policies MUST be explicit

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.{js,ts,tsx,jsx,md,mdx,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Waivers across ESLint, Vale, Semgrep, Clippy, CI checks MUST include: rule ID, reason, ticket/issue reference, expiry (date) OR ADR reference; expired waivers MUST fail CI

Files:

  • packages/widgets/vite.config.ts
  • packages/tokens/src/enhanced/focus.ts
  • docs/design-system/A11Y_CONTRACTS.md
  • docs/design-system/PROFESSIONAL_FINISH_REVIEW.md
  • FORJAMIE.md
  • docs/design-system/PROFESSIONAL_UI_CONTRACT.md
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**

⚙️ CodeRabbit configuration file

**: Use repository evidence first: package scripts, tracked docs, harness contracts, and validation wrappers over assumptions.
Treat contradictions between code, docs, and workflow policy as review-worthy even when code changes look reasonable.
Prioritize behavioral risk, missing validation, and governance drift over style-only feedback.

Files:

  • packages/widgets/vite.config.ts
  • packages/json-render/tsconfig.json
  • packages/tokens/src/enhanced/focus.ts
  • docs/design-system/A11Y_CONTRACTS.md
  • packages/tokens/package.json
  • packages/ui/tsconfig.json
  • packages/runtime/package.json
  • docs/design-system/PROFESSIONAL_FINISH_REVIEW.md
  • FORJAMIE.md
  • docs/design-system/PROFESSIONAL_UI_CONTRACT.md
  • packages/tokens/src/enhanced.css
  • scripts/policy/run-exemplar-evaluation.mjs
  • platforms/web/apps/web/vite.config.ts
  • packages/cloudflare-template/src/worker/widget-manifest.generated.ts
**/*.json

📄 CodeRabbit inference engine (AGENTS.md)

Always verify JSON syntax with jq or similar tool before declaring JSON fixes complete

JSON MUST be valid UTF-8; prefer machine-generated JSON for large files; minimize hand-edited large JSON

Files:

  • packages/json-render/tsconfig.json
  • packages/tokens/package.json
  • packages/ui/tsconfig.json
  • packages/runtime/package.json
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Add a Table of Contents for documentation files

Files:

  • docs/design-system/A11Y_CONTRACTS.md
  • docs/design-system/PROFESSIONAL_FINISH_REVIEW.md
  • FORJAMIE.md
  • docs/design-system/PROFESSIONAL_UI_CONTRACT.md
**/*.{md,mdx,adoc,rst}

📄 CodeRabbit inference engine (CODESTYLE.md)

All docs and long-form prose MUST be linted with Vale (scope: **/.md, **/.mdx, **/.adoc, **/.rst)

Files:

  • docs/design-system/A11Y_CONTRACTS.md
  • docs/design-system/PROFESSIONAL_FINISH_REVIEW.md
  • FORJAMIE.md
  • docs/design-system/PROFESSIONAL_UI_CONTRACT.md
FORJAMIE.md

📄 CodeRabbit inference engine (AGENTS.md)

Maintain a detailed FORJAMIE.md at the repo root explaining the whole project in plain language for future reference

Files:

  • FORJAMIE.md
**/*.{tsx,jsx,html,css}

📄 CodeRabbit inference engine (CODESTYLE.md)

Tailwind: avoid "magic numbers" when theme tokens exist

Files:

  • packages/tokens/src/enhanced.css
🔍 Remote MCP Linear

JSC-77 Issue Context and Requirements

Core Objective

The PR addresses JSC-77: "Add professional-finish review loops with focus consistency, visual QA, and gold-standard references", which is part of the larger JSC-72 audit backlog focused on improving agent-generated UI quality based on the March 2026 audit findings.

Original Requirements (JSC-77 "Done when" criteria)

  1. Focus behavior has one clear canonical pattern — The PR delivers this by scoping all focus styling to opt-in selectors (.ds-focusable / [data-ds-focusable]), eliminating contradictory guidance.
  2. Reviewers and agents have a shared rubric for professional finish — The PR introduces PROFESSIONAL_FINISH_REVIEW.md with a multi-dimension rubric covering hierarchy, spacing rhythm, focus quality, state quality, and motion restraint.
  3. Visual QA covers more than pixel drift — The PR adds run-exemplar-evaluation.mjs precheck logic that validates rubric adherence and reference alignment, treating screenshot parity as insufficient.

Supporting Audit Context (JSC-72)

The parent issue indicates the March 2026 audit identified that "the biggest gap is not missing tokens" but rather that "design-system integrity, semantic-slot discipline, accessibility guidance, composition rules, and review loops are not yet encoded strongly enough." This PR directly addresses the review-loop and composition-rules gaps.

Risk Profile

  • Primary risks: Focus styling scope changes (global to scoped) and Vite/TypeScript workspace alias resolution for local development consistency.
  • Rollback mechanism: Reverting the PR reverts generated widget manifest hashes and focus CSS to prior global behavior.

Issue Status

  • Current state: Todo (unstarted in Linear, but PR #153 is open/draft)
  • Labels: Agent, Docs, Improvement
  • Assigned: jscraik
  • Linked PR: GitHub PR #153 attached as supporting artifact
🔇 Additional comments (13)
packages/tokens/package.json (1)

34-34: Build-script update looks correct.

Switching to tsc -b ... --force is consistent with project-reference builds and helps prevent stale incremental state from hiding missing declaration output.

packages/widgets/vite.config.ts (1)

62-65: Alias additions are aligned with actual widget imports.

These entries correctly close the local workspace-resolution gap for @design-studio/json-render and @design-studio/ui.

platforms/web/apps/web/vite.config.ts (1)

12-64: Workspace alias coverage is solid.

The expanded alias map matches real import patterns in the web app and should improve local source resolution consistency.

packages/runtime/package.json (1)

20-20: Runtime build-script change is appropriate.

Using tsc -b ... --force here is consistent with monorepo reference builds and deterministic emit behavior.

packages/cloudflare-template/src/worker/widget-manifest.generated.ts (1)

9-137: Generated manifest hash refresh looks consistent.

The update preserves widget identity/path metadata while rotating generated build hashes as expected.

packages/tokens/src/enhanced.css (1)

97-117: Well-designed scoped focus pattern.

The focus styling is now properly scoped to opt-in selectors, preventing double-ring conflicts with component-owned focus styles. The implementation correctly:

  1. Uses both class (.ds-focusable) and data attribute ([data-ds-focusable]) patterns for flexibility
  2. Scopes the inset variant for inputs consistently
  3. Restricts mouse-focus suppression to the same scoped elements, preserving native outlines elsewhere

This is a breaking change for any components that previously relied on the global :focus-visible styling. Existing focusable elements will now need to add .ds-focusable or data-ds-focusable to receive the design-system focus ring.

FORJAMIE.md (1)

193-195: Clear documentation of the professional-finish review loop.

The changelog entry accurately documents the JSC-77 changes including the contract precheck, scoped focus selectors, and workspace resolution updates. This maintains the detailed project map required by the coding guidelines.

docs/design-system/PROFESSIONAL_FINISH_REVIEW.md (1)

49-66: Gold-standard reference set alignment verified.

The 11 references in this document match the GOLD_STANDARD_REFERENCES constant in scripts/policy/run-exemplar-evaluation.mjs. The script validates that each reference appears in this document, creating a bidirectional contract between documentation and enforcement.

Minor observation: The last reference row combines "template browser page" and "template widget page" in a single cell, while the script lists them as separate entries. This works because the script uses includes() to check presence, but consider splitting them into separate rows for clarity and to match the script's array structure.

scripts/policy/run-exemplar-evaluation.mjs (2)

135-155: Clean runner refactor to support both function and command checks.

The check runner correctly handles both synchronous run functions and spawnSync commands with proper error handling. The result = { status: 0 } initialization and conditional update pattern is clear.


89-93: Regex correctly detects bare :focus-visible rules.

The regex /(^|[\s,{]):focus-visible\s*\{/ effectively prevents bare global :focus-visible rules and is working as intended. Testing against the actual enhanced.css confirms all :focus-visible selectors are properly scoped (.ds-focusable:focus-visible, [data-ds-focusable]:focus-visible, etc.) and the regex correctly identifies zero bare violations. The pattern's use of \s covers whitespace edge cases including newlines, and the implementation is sound.

docs/design-system/PROFESSIONAL_UI_CONTRACT.md (2)

131-147: Consistent contract updates for focus scoping and professional finish review.

The Focus Contract expansion (lines 131-133) properly documents the mouse-only focus suppression scoping requirement and points to the canonical implementation. The new Professional Finish Review Loop section (lines 135-147) correctly delegates to the detailed rubric document while establishing the key constraint that "screenshot diff parity" is insufficient.

These additions align with the code changes in packages/tokens/src/enhanced.css and the validation in scripts/policy/run-exemplar-evaluation.mjs.


191-192: Enforcement inputs properly updated.

The contract correctly documents that professional finish is enforced by coupling the browser gate with the precheck (line 191-192), and pnpm test:exemplar-evaluation is added to the enforcement inputs list (line 205). This creates a clear audit trail from contract to executable validation.

Also applies to: 205-205

packages/ui/tsconfig.json (1)

7-10: [rewritten comment]
[classification tag]

Comment thread docs/design-system/A11Y_CONTRACTS.md
Comment thread packages/json-render/tsconfig.json
Comment thread scripts/policy/run-exemplar-evaluation.mjs
@jscraik
jscraik marked this pull request as ready for review April 25, 2026 19:09
@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 4 file(s) based on 3 unresolved review comments.

Files modified:

  • docs/design-system/A11Y_CONTRACTS.md
  • packages/json-render/tsconfig.json
  • packages/ui/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs

Commit: c42c6c4441ddc25303e10e002cceb1b3c5ea46f2

The changes have been pushed to the jscraik/feature/jsc-77-professional-finish-review-loops branch.

Time taken: 8m 47s

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ffa2b53a22

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +13 to +14
"@design-studio/runtime": path.resolve(__dirname, "../../../../packages/runtime/src"),
"@design-studio/tokens": path.resolve(__dirname, "../../../../packages/tokens/src"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep manualChunks matching aliased runtime/tokens paths

These aliases switch @design-studio/runtime and @design-studio/tokens to source-folder resolution, but manualChunks in the same file still keys off id.includes("@design-studio/runtime") and id.includes("@design-studio/tokens"). In Vite/Rollup builds, id is the resolved absolute path (for example /packages/runtime/src/...), so those chunk rules stop matching and runtime/tokens code falls into default chunks, which regresses chunk isolation and cache behavior for production web builds.

Useful? React with 👍 / 👎.

Fixed 4 file(s) based on 3 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/ui/tsconfig.json`:
- Around line 8-9: Remove the hard-coded "paths" entries in
packages/ui/tsconfig.json that point to ../../packages/runtime/dist/index.d.ts
and ../../packages/tokens/dist/index.d.ts; instead rely on the root TypeScript
project references so TypeScript resolves `@design-studio/runtime` and
`@design-studio/tokens` from their source projects. Specifically, delete the
"paths" block in packages/ui/tsconfig.json (the entries referencing runtime and
tokens), confirm the root tsconfig.json includes project references for runtime
and tokens, and ensure packages/ui package.json lists `@design-studio/runtime` and
`@design-studio/tokens` as workspace dependencies so the composite project
build/resolution works without prebuilt dist .d.ts artifacts.

In `@scripts/policy/run-exemplar-evaluation.mjs`:
- Around line 4-6: The new log/output and error messages related to
PROFESSIONAL_FINISH_DOC and ENHANCED_CSS must include the service identity tag;
update any console.log/console.error or thrown Error text introduced near those
constants and the later lines around the block referenced (around the output at
142-148) to append or embed service:"run-exemplar-evaluation" (or the canonical
service name) into the message strings so every emitted message includes
service:"<service_name>" for compliance; search for usages of
PROFESSIONAL_FINISH_DOC, ENHANCED_CSS, and the output/error statements in that
module and modify their message formatting to include the service identity.
- Around line 93-101: The current precheck in run-exemplar-evaluation.mjs guards
against a bare global :focus-visible rule but misses rules that remove native
outlines such as a global ":focus:not(:focus-visible) { outline: none; }";
update the validation around enhancedCss (and the ENHANCED_CSS constant) to also
detect and reject patterns that target :focus:not(:focus-visible) or global
:focus selectors combined with "outline: none" (e.g., via a regex that looks for
/:focus\s*:\s*not\s*\(\s*:focus-visible\s*\)\s*\{[^}]*outline\s*:\s*none/ or
global :focus rules setting outline:none) and throw an Error with the same
style/message as the existing check; ensure assertIncludes usage remains to
validate the required .ds-focusable and [data-ds-focusable] selectors.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 899527e2-fd65-4995-9ed8-b14f7cf2d231

📥 Commits

Reviewing files that changed from the base of the PR and between ffa2b53 and c42c6c4.

📒 Files selected for processing (4)
  • docs/design-system/A11Y_CONTRACTS.md
  • packages/json-render/tsconfig.json
  • packages/ui/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: Analyze (javascript)
🧰 Additional context used
📓 Path-based instructions (15)
**/*.json

📄 CodeRabbit inference engine (AGENTS.md)

Always verify JSON syntax with jq or similar tool before declaring JSON fixes complete

JSON MUST be valid UTF-8; prefer machine-generated JSON for large files; minimize hand-edited large JSON

Files:

  • packages/ui/tsconfig.json
  • packages/json-render/tsconfig.json
**/*.{js,ts,tsx,jsx,mjs,json}

📄 CodeRabbit inference engine (CODESTYLE.md)

Packages MUST target the repo baseline Node version (pinned in .mise.toml and compat.json)

Files:

  • packages/ui/tsconfig.json
  • packages/json-render/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs
**

⚙️ CodeRabbit configuration file

**: Use repository evidence first: package scripts, tracked docs, harness contracts, and validation wrappers over assumptions.
Treat contradictions between code, docs, and workflow policy as review-worthy even when code changes look reasonable.
Prioritize behavioral risk, missing validation, and governance drift over style-only feedback.

Files:

  • packages/ui/tsconfig.json
  • docs/design-system/A11Y_CONTRACTS.md
  • packages/json-render/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Add a Table of Contents for documentation files

Files:

  • docs/design-system/A11Y_CONTRACTS.md
**/*.{md,mdx,adoc,rst}

📄 CodeRabbit inference engine (CODESTYLE.md)

All docs and long-form prose MUST be linted with Vale (scope: **/.md, **/.mdx, **/.adoc, **/.rst)

Files:

  • docs/design-system/A11Y_CONTRACTS.md
**/*.{js,ts,tsx,jsx,md,mdx,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Waivers across ESLint, Vale, Semgrep, Clippy, CI checks MUST include: rule ID, reason, ticket/issue reference, expiry (date) OR ADR reference; expired waivers MUST fail CI

Files:

  • docs/design-system/A11Y_CONTRACTS.md
  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,py,rs,mjs,cjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{js,ts,tsx,jsx,py,rs,mjs,cjs}: Fabricated data/entropy (Math.random() without injected seed), hard-coded mock responses, TODO/FIXME/HACK comments, placeholder stubs, disabled features, or fake metrics MUST NOT exist in production code paths
Functions SHOULD be <= 40 LOC; split if readability suffers
No ambient randomness/time in core logic; inject seeds/clocks/IDs
Never swallow errors; add context and route to logging layer
Constants: UPPER_SNAKE_CASE
No hard-coded secrets; use env injection/secret manager; validate/sanitize all external inputs

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Apps/binaries/services MUST include service identity in outputs, error messages, and logs (service:"<service_name>")

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Long-running work MUST accept cancellation (AbortSignal in JS/TS; cancellation tokens/channels in Rust)

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,mts,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

JSON imports MUST use import attributes (import data from "./foo.json" with { type: "json" })

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,mjs,cjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{js,ts,tsx,jsx,mjs,cjs}: ESLint-disable comments MUST include reason and ticket; expiry date optional
JavaScript/TypeScript variables/functions: camelCase

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,tsx,js,mjs}: Exported async APIs that perform I/O or long work MUST accept AbortSignal
JSON inputs at boundaries in JS/TS MUST be schema-validated

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,jsx,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Types/components: PascalCase

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

CLI/TUI: --plain / --no-color modes required

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,js,py,rs,mjs}: OpenTelemetry SHOULD be used where services/CLIs exist; logs SHOULD be structured and include service at app boundaries
Streaming: default token delta streaming for CLIs, optional aggregated mode, JSON event streaming optional if supported
MCP adapters/helpers MUST not hard-code user-specific paths; health checks MUST be scriptable; egress/network policies MUST be explicit

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
🔍 Remote MCP Linear

Relevant Linear issue context (JSC-77)

  • Title: Add professional-finish review loops with focus consistency, visual QA, and gold-standard references.
  • Goal: add review mechanisms to catch the last ~20% of quality issues in agent-generated UI (focus, hierarchy, spacing, state, motion).
  • Deliverables: reconcile canonical focus-ring strategy; add a visual/design review rubric; add a gold‑standard reference set of exemplar screens/stories.
  • Done-when criteria: (1) single canonical focus behavior, (2) shared rubric for professional finish, (3) visual QA beyond pixel drift.
  • Current status: In Progress / started (startedAt: 2026-04-25T19:09:29.572Z). Branch name: jscraik/jsc-77-add-professional-finish-review-loops-with-focus-consistency.
  • Priority/labels/assignee: Medium priority; labels: Agent, Docs, Improvement; assignee: jscraik.
  • Linked PR: feat(design-system): add professional finish review loop — #153 (attached to the Linear issue).
🔇 Additional comments (4)
docs/design-system/A11Y_CONTRACTS.md (2)

5-56: TOC addition looks good and improves navigability.

This is clear and complete for the current section set.

As per coding guidelines **/*.md: Add a Table of Contents for documentation files.


82-88: Shared Focus Indicator contract is clear and testable.

The requirements are specific enough to be enforced by policy checks and component-level review.

scripts/policy/run-exemplar-evaluation.mjs (1)

63-71: Better assertion diagnostics here.

Including a preview in failure output materially improves debugging when contract markers are missing.

packages/json-render/tsconfig.json (1)

5-7: Good fix: @design-studio/ui now resolves to the workspace source entrypoint.

This aligns with the available packages/ui/src/index.ts export surface and avoids the prior missing-dist declaration failure mode.

Comment thread packages/ui/tsconfig.json Outdated
Comment thread scripts/policy/run-exemplar-evaluation.mjs
Comment thread scripts/policy/run-exemplar-evaluation.mjs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c42c6c4441

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

__dirname,
"../../../../packages/ui/src/components/ui/base",
),
"@design-studio/ui/chat": path.resolve(__dirname, "../../../../packages/ui/src/app/chat"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match chat chunking to aliased source path

This alias points @design-studio/ui/chat at packages/ui/src/app/chat, but the manualChunks logic in the same Vite config still only recognizes chat modules under /src/components/ui/chat/ (or /dist/chat.js), so chat code imported from the new alias path will no longer land in the design-studio-chat chunk. In production web builds that means the intended chat chunk split is silently lost, increasing chunk churn and weakening cache locality for chat-only changes.

Useful? React with 👍 / 👎.

assertIncludes(reviewDoc, reference, PROFESSIONAL_FINISH_DOC);
}

if (/(^|[\s,{]):focus-visible\s*\{/.test(enhancedCss)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect bare :focus-visible in comma selector lists

The contract check regex only flags bare selectors written as :focus-visible { ... }, so a prohibited global selector can slip through as part of a list like :focus-visible, .ds-focusable:focus-visible { ... } without failing the precheck. Because this script is meant to enforce the focus-scope contract in CI, that blind spot allows a real policy regression to pass undetected.

Useful? React with 👍 / 👎.

jscraik and others added 2 commits April 26, 2026 01:36
Why: CodeRabbit review found the professional-finish precheck needed service-tagged output and stronger native outline suppression detection, and the UI package should not hard-code dist declaration paths for runtime/token packages.

What: add service identity to exemplar evaluation output/errors, reject bare global :focus outline suppression in the professional-finish contract, and replace UI dist path overrides with references to runtime/token build configs.

Impact/Risk: local UI type-check now relies on build-config project references instead of package-local dist aliases. The exemplar precheck will fail closed if a global focus outline reset returns.

Validation: jq . packages/ui/tsconfig.json >/dev/null -> pass

Validation: pnpm -C packages/ui type-check -> pass

Validation: pnpm test:exemplar-evaluation:list -> pass

Validation: pnpm test:policy -> pass

Validation: pnpm typecheck -> pass

Validation: git diff --check -> pass

Co-authored-by: Codex <noreply@openai.com>
Why: the remote branch advanced with CodeRabbit autofix changes while the local review follow-up commit was ready to push.

What: merge the A11Y contract documentation addition and combine the missing-marker preview with service-tagged exemplar-evaluation errors. Keep json-render on its existing dist declaration mapping because the remote source-path mapping fails package type-checking.

Impact/Risk: preserves the professional-finish review fixes while retaining the working json-render type-check contract.

Validation: jq . packages/ui/tsconfig.json >/dev/null -> pass

Validation: jq . packages/json-render/tsconfig.json >/dev/null -> pass

Validation: pnpm typecheck -> pass

Validation: pnpm test:exemplar-evaluation:list -> pass

Validation: pnpm test:policy -> pass

Validation: git diff --check -> pass

Co-authored-by: Codex <noreply@openai.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/json-render/tsconfig.json (1)

5-7: ⚠️ Potential issue | 🟠 Major

Avoid dist-only TS alias for @design-studio/ui in json-render.

This mapping reintroduces build-artifact coupling and can drift from workspace source resolution (for example, widget Vite aliases @design-studio/ui to packages/ui/src).

♻️ Proposed fix
   "compilerOptions": {
     "outDir": "./dist",
     "paths": {
-      "@design-studio/ui": ["packages/ui/dist/index.d.ts"]
+      "@design-studio/ui": ["packages/ui/src/index.ts"]
     }
   },

Run this to verify artifact coupling and alias mismatch:

#!/bin/bash
set -euo pipefail

echo "== Validate JSON syntax =="
jq . packages/json-render/tsconfig.json >/dev/null

echo "== Current json-render alias target =="
jq -r '.compilerOptions.paths["@design-studio/ui"][]' packages/json-render/tsconfig.json

echo "== Does mapped dist file exist now? =="
TARGET="$(jq -r '.compilerOptions.paths["@design-studio/ui"][0]' packages/json-render/tsconfig.json)"
if [ -f "$TARGET" ]; then
  echo "FOUND: $TARGET"
else
  echo "MISSING: $TARGET"
fi

echo "== Compare with workspace runtime alias usage =="
rg -n --type=ts -C2 '"@design-studio/ui"' packages/widgets/vite.config.ts

As per coding guidelines **: Use repository evidence first: package scripts, tracked docs, harness contracts, and validation wrappers over assumptions. Treat contradictions between code, docs, and workflow policy as review-worthy even when code changes look reasonable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/json-render/tsconfig.json` around lines 5 - 7, The tsconfig paths in
packages/json-render currently map the module alias "@design-studio/ui" to the
built artifact (packages/ui/dist/index.d.ts), causing build-artifact coupling
and mismatches with runtime/vite aliases; update the mapping for
"@design-studio/ui" in packages/json-render's compilerOptions.paths to point to
the workspace source (e.g., packages/ui/src entry) or to a workspace-aware alias
(or remove the override so TypeScript resolves the package via project
references), ensuring the change is made to the "@design-studio/ui" paths entry
so json-render resolves the same source as widgets/vite.config.ts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/policy/run-exemplar-evaluation.mjs`:
- Around line 159-161: The caught-error logging currently emits Error instances
raw (via error.message) and can omit the required service identity tag; update
the console.error call in run-exemplar-evaluation.mjs to always prefix the
message with SERVICE_LOG_TAG and then the error text (e.g., use SERVICE_LOG_TAG
+ the error.message for Error instances or String(error) otherwise), ensuring
every emitted error includes the service:"<service_name>" identity.

---

Duplicate comments:
In `@packages/json-render/tsconfig.json`:
- Around line 5-7: The tsconfig paths in packages/json-render currently map the
module alias "@design-studio/ui" to the built artifact
(packages/ui/dist/index.d.ts), causing build-artifact coupling and mismatches
with runtime/vite aliases; update the mapping for "@design-studio/ui" in
packages/json-render's compilerOptions.paths to point to the workspace source
(e.g., packages/ui/src entry) or to a workspace-aware alias (or remove the
override so TypeScript resolves the package via project references), ensuring
the change is made to the "@design-studio/ui" paths entry so json-render
resolves the same source as widgets/vite.config.ts.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7bb521d-d02e-41ca-ad4e-688b1c3335b9

📥 Commits

Reviewing files that changed from the base of the PR and between c42c6c4 and 7f46caa.

📒 Files selected for processing (4)
  • FORJAMIE.md
  • packages/json-render/tsconfig.json
  • packages/ui/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (ubuntu-latest)
🧰 Additional context used
📓 Path-based instructions (16)
**/*.json

📄 CodeRabbit inference engine (AGENTS.md)

Always verify JSON syntax with jq or similar tool before declaring JSON fixes complete

JSON MUST be valid UTF-8; prefer machine-generated JSON for large files; minimize hand-edited large JSON

Files:

  • packages/json-render/tsconfig.json
  • packages/ui/tsconfig.json
**/*.{js,ts,tsx,jsx,mjs,json}

📄 CodeRabbit inference engine (CODESTYLE.md)

Packages MUST target the repo baseline Node version (pinned in .mise.toml and compat.json)

Files:

  • packages/json-render/tsconfig.json
  • packages/ui/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs
**

⚙️ CodeRabbit configuration file

**: Use repository evidence first: package scripts, tracked docs, harness contracts, and validation wrappers over assumptions.
Treat contradictions between code, docs, and workflow policy as review-worthy even when code changes look reasonable.
Prioritize behavioral risk, missing validation, and governance drift over style-only feedback.

Files:

  • packages/json-render/tsconfig.json
  • packages/ui/tsconfig.json
  • scripts/policy/run-exemplar-evaluation.mjs
  • FORJAMIE.md
**/*.{js,ts,tsx,jsx,py,rs,mjs,cjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{js,ts,tsx,jsx,py,rs,mjs,cjs}: Fabricated data/entropy (Math.random() without injected seed), hard-coded mock responses, TODO/FIXME/HACK comments, placeholder stubs, disabled features, or fake metrics MUST NOT exist in production code paths
Functions SHOULD be <= 40 LOC; split if readability suffers
No ambient randomness/time in core logic; inject seeds/clocks/IDs
Never swallow errors; add context and route to logging layer
Constants: UPPER_SNAKE_CASE
No hard-coded secrets; use env injection/secret manager; validate/sanitize all external inputs

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Apps/binaries/services MUST include service identity in outputs, error messages, and logs (service:"<service_name>")

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Long-running work MUST accept cancellation (AbortSignal in JS/TS; cancellation tokens/channels in Rust)

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,mts,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

JSON imports MUST use import attributes (import data from "./foo.json" with { type: "json" })

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,mjs,cjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{js,ts,tsx,jsx,mjs,cjs}: ESLint-disable comments MUST include reason and ticket; expiry date optional
JavaScript/TypeScript variables/functions: camelCase

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,tsx,js,mjs}: Exported async APIs that perform I/O or long work MUST accept AbortSignal
JSON inputs at boundaries in JS/TS MUST be schema-validated

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,jsx,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Types/components: PascalCase

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,tsx,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

CLI/TUI: --plain / --no-color modes required

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{ts,js,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

**/*.{ts,js,py,rs,mjs}: OpenTelemetry SHOULD be used where services/CLIs exist; logs SHOULD be structured and include service at app boundaries
Streaming: default token delta streaming for CLIs, optional aggregated mode, JSON event streaming optional if supported
MCP adapters/helpers MUST not hard-code user-specific paths; health checks MUST be scriptable; egress/network policies MUST be explicit

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
**/*.{js,ts,tsx,jsx,md,mdx,py,rs,mjs}

📄 CodeRabbit inference engine (CODESTYLE.md)

Waivers across ESLint, Vale, Semgrep, Clippy, CI checks MUST include: rule ID, reason, ticket/issue reference, expiry (date) OR ADR reference; expired waivers MUST fail CI

Files:

  • scripts/policy/run-exemplar-evaluation.mjs
  • FORJAMIE.md
FORJAMIE.md

📄 CodeRabbit inference engine (AGENTS.md)

Maintain a detailed FORJAMIE.md at the repo root explaining the whole project in plain language for future reference

Files:

  • FORJAMIE.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Add a Table of Contents for documentation files

Files:

  • FORJAMIE.md
**/*.{md,mdx,adoc,rst}

📄 CodeRabbit inference engine (CODESTYLE.md)

All docs and long-form prose MUST be linted with Vale (scope: **/.md, **/.mdx, **/.adoc, **/.rst)

Files:

  • FORJAMIE.md
🔍 Remote MCP Linear

Relevant context found

  • Linear issue JSC-77 (title, goal, deliverables, done-when, branch) — status: In Progress; branch: jscraik/jsc-77-add-professional-finish-review-loops-with-focus-consistency.

  • Issue comment by author summarizing the implemented work, validation steps, and notes:

    • Confirms added files and key changes: PROFESSIONAL_FINISH_REVIEW.md, run-exemplar-evaluation.mjs gating, scoped focus CSS (.ds-focusable / [data-ds-focusable]), workspace path/alias stabilizations, and regenerated widget manifest.
    • Lists validation commands that passed (typecheck, policy tests, exemplar-evaluation listing, builds, pre-push hook) and notes one non-fatal sharp/libvips duplicate-class warning during web visual listing.
    • Notes sandboxed push initially failed due to macOS Chromium launch permissions; retry outside sandbox succeeded.
    • PR remains draft pending independent CodeRabbit/Codex reviews.
🔇 Additional comments (3)
packages/ui/tsconfig.json (1)

8-11: Good shift to project references for runtime/tokens resolution.

This removes fragile dist-path coupling in UI type resolution and better matches composite build linkage.

scripts/policy/run-exemplar-evaluation.mjs (1)

94-113: Professional-finish focus checks are well enforced here.

The precheck now blocks bare global focus selectors and requires scoped design-system focus selectors before visuals run.

FORJAMIE.md (1)

195-196: Nice documentation update for JSC-77 enforcement details.

These entries clearly capture the policy gate, focus-scope contract, and follow-up hardening in one place.

Comment on lines +159 to +161
console.error(
error instanceof Error ? error.message : `${SERVICE_LOG_TAG} ${String(error)}`,
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Prefix all caught error messages with service identity.

error.message is emitted raw for Error instances, so some failures (for example ENOENT) will miss the required service tag.

🔧 Proposed fix
     } catch (error) {
       result = { status: 1 };
+      const message = error instanceof Error ? error.message : String(error);
       console.error(
-        error instanceof Error ? error.message : `${SERVICE_LOG_TAG} ${String(error)}`,
+        message.includes(SERVICE_LOG_TAG) ? message : `${SERVICE_LOG_TAG} ${message}`,
       );
     }

As per coding guidelines **/*.{js,ts,tsx,jsx,py,rs,mjs}: Apps/binaries/services MUST include service identity in outputs, error messages, and logs (service:"<service_name>").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/policy/run-exemplar-evaluation.mjs` around lines 159 - 161, The
caught-error logging currently emits Error instances raw (via error.message) and
can omit the required service identity tag; update the console.error call in
run-exemplar-evaluation.mjs to always prefix the message with SERVICE_LOG_TAG
and then the error text (e.g., use SERVICE_LOG_TAG + the error.message for Error
instances or String(error) otherwise), ensuring every emitted error includes the
service:"<service_name>" identity.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7f46caa6dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +98 to +99
.ds-focusable:focus-visible,
[data-ds-focusable]:focus-visible {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve fallback focus ring for existing outline-none controls

Scoping the shared ring to only .ds-focusable / [data-ds-focusable] removes keyboard-visible focus from existing controls that already set focus:outline-none but do not add a local focus-visible:ring-* (for example, packages/ui/src/app/chat/compose/ComposeInstructionsPanel/ComposeInstructionsPanel.tsx textarea). Before this change those controls still received the global :focus-visible ring; after it, they can become effectively focus-invisible for keyboard users, which is an accessibility regression in current UI surfaces.

Useful? React with 👍 / 👎.

Comment on lines +101 to +104
/(^|[\s,{]):focus\s*:\s*not\s*\(\s*:focus-visible\s*\)\s*\{[^}]*outline\s*:\s*none/i.test(
enhancedCss,
) ||
/(^|[\s,{]):focus\s*\{[^}]*outline\s*:\s*none/i.test(enhancedCss)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect bare :focus outline suppression in selector lists

The new bare-:focus guard only matches when :focus (or :focus:not(:focus-visible)) is immediately followed by {, so prohibited global selectors can bypass the precheck when they appear in comma lists such as :focus:not(:focus-visible), .x { outline: none; }. That leaves a policy hole where native outlines can be globally suppressed without failing test:exemplar-evaluation.

Useful? React with 👍 / 👎.

@jscraik
jscraik merged commit 10317d7 into main Apr 26, 2026
11 checks passed
@jscraik
jscraik deleted the jscraik/feature/jsc-77-professional-finish-review-loops branch April 26, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant