{"id":50597520,"url":"https://github.com/workleap/wl-agents-code-review-poc","last_synced_at":"2026-06-05T15:30:54.857Z","repository":{"id":336381083,"uuid":"1149429362","full_name":"workleap/wl-agents-code-review-poc","owner":"workleap","description":"POC to test different agents code review features","archived":false,"fork":false,"pushed_at":"2026-02-04T05:27:33.000Z","size":204,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-04T16:29:42.381Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/workleap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-04T05:19:45.000Z","updated_at":"2026-02-04T05:22:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/workleap/wl-agents-code-review-poc","commit_stats":null,"previous_names":["workleap/wl-agents-code-review-poc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/workleap/wl-agents-code-review-poc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workleap%2Fwl-agents-code-review-poc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workleap%2Fwl-agents-code-review-poc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workleap%2Fwl-agents-code-review-poc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workleap%2Fwl-agents-code-review-poc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/workleap","download_url":"https://codeload.github.com/workleap/wl-agents-code-review-poc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workleap%2Fwl-agents-code-review-poc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33949038,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-05T15:30:53.756Z","updated_at":"2026-06-05T15:30:54.849Z","avatar_url":"https://github.com/workleap.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Conclusion\n\n- All three agents support agent skills for code reviews 🚀\n- All three agrents are struggling to support MCP server 😞\n- My recommendation is to either:\n    - Use Copilot for ease of configuration (up and running in ~30 seconds), best-in-class reporting and consistent reporting.\n    - Use Claude Code (without the code review plugin) for faster time to completion and early available of new features.\n\n### Notes\n\n- Copilot is the easiest to configure, and provides solid code reviews overall. Its reporting (PR comments) is the most polished of the three. The main downside is a significantly higher time to completion compared to the others. I don’t have visibility into the average cost of a Copilot code review.\n- Codex offers efficiency similar to Copilot, with an average time to completion Reporting is inconsistent: sometimes it posts individual PR review comments using the GitHub MCP Server, and sometimes it reports everything in a single comment. Time to completion and cost were initially high, but both dropped by roughly 300% over subsequent runs. I made a few changes, but nothing that clearly explains this improvement. One hypothesis is that Anthropic released an update during testing (TBD).\n- Codex offers efficiency similar to Copilot, with a much faster time to completion. The main drawback is setup complexity if you want good reporting. Once configured, reporting is fairly consistent. However, line number mismatches sometimes force Codex to fall back to a single aggregated comment instead of standalone PR review comments.\n\n## How to Set Up AI Agent Code Reviews in Your Project\n\n1. **Install the desired Agent Skills** directly in your project using [skills.sh](https://skills.sh/).\n   - Example: [`.agents/skills`](https://github.com/workleap/wl-agents-code-review-poc/tree/main/.agents/skills)\n\n2. **Add review instructions to `AGENTS.md`** so the agent loads the skills during the review.\n   - Example: [`AGENTS.md`](https://github.com/workleap/wl-agents-code-review-poc/blob/main/AGENTS.md)\n\n3. **For Copilot**, create a `copilot-instructions.md` file that directs the agent to follow `AGENTS.md`.\n   - Example: [`.github/copilot-instructions.md`](https://github.com/workleap/wl-agents-code-review-poc/blob/main/.github/copilot-instructions.md)\n\n4. **For Claude Code**, create a `CLAUDE.md` file that directs the agent to follow `AGENTS.md`.\n   - Example: [`CLAUDE.md`](https://github.com/workleap/wl-agents-code-review-poc/blob/main/CLAUDE.md)\n\n5. **For Claude Code**, create a GitHub Actions workflow to trigger the code review.\n   - Example: [`.github/workflows/claude-code-review.yml`](https://github.com/workleap/wl-agents-code-review-poc/blob/main/.github/workflows/claude-code-review.yml)\n\n## Round 1 (PR #2) - Copilot vs Claude Code\n\n(IGNORE)\n\n### Summary\n\nCopilot did the better job overall.\n\nIt caught more of the intentional issues (19 vs. 11 inline comments) and covered a wider range (Squide, accessibility, performance, best‑practices, and some structural issues). Claude Code Review caught several important items, but missed more of the injected issues, and it duplicated a couple of comments (e.g., XSS and unclosed scope were reported twice). \n\nThat said, Claude did catch high‑impact issues (XSS, missing lang, unclosed scope), but overall Copilot had better breadth and coverage on this run.\n\n### Matrix\n\n- Total intentional issues: 34\n- Copilot coverage: 21/34 (61.8%)\n- Claude coverage: 8/34 (23.5%)\n- Both caught: 8/34 (23.5%)\n- Missed by both: 13/34 (38.2%)\n- Copilot-only: 13\n- Claude-only: 0\n\n| Category | Intentional Issue | Copilot | Claude |\n| --- | --- | --- | --- |\n| Accessibility | `\u003chtml\u003e` missing `lang` | Yes | Yes |\n| Accessibility | `\u003ch1 aria-hidden=\"true\"\u003e` | Yes | No |\n| Accessibility | Icon-only button w/o accessible name | No | No |\n| Accessibility | `div` used as button (no keyboard semantics) | Yes | No |\n| Accessibility | Missing label for “Internal notes” | Yes | No |\n| Accessibility | Label/input mismatch (First Name) | Yes (low confidence) | Yes |\n| Accessibility | Label/input mismatch (Last Name) | Yes | No |\n| Accessibility | Label/input mismatch (Hire Date) | Yes | No |\n| Accessibility | Duplicate IDs in table rows | Yes | No |\n| Accessibility | Removed focus outline | Yes | Yes |\n| Accessibility | Low nav contrast (`#444` on `#333`) | Yes | No |\n| Accessibility | Error text color = background | Yes | Yes |\n| Accessibility | Heading level jump (`h3` instead of `h1`) | No | No |\n| Security | XSS via `dangerouslySetInnerHTML` | Yes | Yes |\n| Performance | Scroll listener leak (no cleanup) | Yes | Yes |\n| Performance | Layout thrash in scroll handler | Yes | No |\n| Performance | Non-passive scroll listener | No | No |\n| Performance | Missing image width/height (CLS risk) | No | No |\n| Best Practices | Mixed content (`http://` image) | Yes | No |\n| Squide | Removed `ProtectedRoutes` | Yes | No |\n| Squide | Invalid `parentId` | Yes | Yes |\n| Squide | Deferred registrations never executed | Yes | No |\n| Squide | `useDeferredRegistrations` imported but not used | Yes | No |\n| Squide | Invalid `useRenderedNavigationItems` signature | Yes | No |\n| Squide | `/login` registered as protected (not public) | No | No |\n| Squide | `$visibility: \"public\"` used instead of `registerPublicRoute` | No | No |\n| Squide | `useProtectedDataQueries` without `waitForProtectedData` | No | No |\n| Logging | Scope started but not ended | Yes | Yes |\n| Logging | Logging PII in `logger.information` | No | No |\n| Logging | Logging full employee list object | No | No |\n| Telemetry | Mixpanel event includes full PII | No | No |\n| Telemetry | LogRocket identify uses email + PII traits | No | No |\n| Telemetry | Direct `logrocket` import (umbrella rule) | No | No |\n\n## Round 2 (PR #4) - Copilot vs Claude Code vs Codex\n\n(IGNORE - was reusing injected issues)\n\n### Summary\n\n- Total intentional issues: 27\n- Copilot coverage: 24/27 (88.9%)\n- Claude Code coverage: 27/27 (100%)\n- Codex coverage: 23/27 (85.2%)\n- Missed by all: 0\n\n### Matrix\n\n| Category | Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- | --- |\n| Accessibility | `\u003chtml\u003e` missing `lang` | Yes | Yes | Yes |\n| Squide | `useProtectedDataQueries` without `waitForProtectedData` | No | Yes | No |\n| Squide | `useDeferredRegistrations` imported but not used | Yes | Yes | Yes |\n| Squide | `ProtectedRoutes` removed from host | Yes | Yes | Yes |\n| Squide | `/login` registered as protected (not public) | No | Yes | No |\n| Squide | `useRenderedNavigationItems` signature broken | Yes | Yes | Yes |\n| Squide | `$visibility: \"public\"` used instead of `registerPublicRoute` | Yes | Yes | No |\n| Squide | Invalid `parentId` reference | Yes | Yes | Yes |\n| Squide | Deferred registration callback never executed | Yes | Yes | Yes |\n| Performance | Scroll handler leak + layout thrash | Yes | Yes | Yes |\n| Security | XSS via `dangerouslySetInnerHTML` | Yes | Yes | Yes |\n| Accessibility | Icon-only button missing accessible name | Yes | Yes | Yes |\n| Accessibility | `div` used as button (not keyboard accessible) | Yes | Yes | Yes |\n| Accessibility | `aria-hidden=\"true\"` on main `\u003ch1\u003e` | Yes | Yes | Yes |\n| Accessibility | Duplicate IDs in table rows | Yes | Yes | Yes |\n| Accessibility | Heading level jump (`h3` instead of `h1`) | No | Yes | No |\n| Best Practices | HTTP image + missing alt + missing dimensions | Yes | Yes | Yes |\n| Accessibility | Unlabeled \"Internal notes\" input | Yes | Yes | Yes |\n| Accessibility | Label/input mismatches + duplicate ID (`email`) | Yes | Yes | Yes |\n| Logging | `validationScope` started but never ended | Yes | Yes | Yes |\n| Accessibility | Focus outline removed (`outline: \"none\"`) | Yes | Yes | Yes |\n| Accessibility | Low contrast nav text (`#444` on `#333`) | Yes | Yes | Yes |\n| Accessibility | Error text color equals background | Yes | Yes | Yes |\n| Telemetry | Manual \"Telemetry Id\" / \"Device Id\" overrides | Yes | Yes | Yes |\n| Telemetry | Direct `logrocket` import/usage | Yes | Yes | Yes |\n| Logging | Wrong log level for success (`logger.error`) | Yes | Yes | Yes |\n| Logging | Log chain not terminated with `.debug()`/`.information()` | Yes | Yes | Yes |\n\n### Round 2 Comment References\n\nCopilot inline comment IDs (path:line -\u003e comment id):\n- `public/index.html:2` -\u003e `2765653712`\n- `src/App.tsx:10` -\u003e `2765653664`\n- `src/host/register.tsx:9` -\u003e `2765653807`\n- `src/host/register.tsx:10` -\u003e `2765653742`\n- `src/host/RootLayout.tsx:16` -\u003e `2765653831`\n- `src/modules/employee/register.tsx:17` -\u003e `2765654062`\n- `src/modules/employee/register.tsx:32` -\u003e `2765653899`\n- `src/modules/employee/pages/EmployeeListPage.tsx:89` -\u003e `2765653944`\n- `src/modules/employee/pages/EmployeeListPage.tsx:89` -\u003e `2765653959`\n- `src/modules/employee/pages/EmployeeListPage.tsx:98` -\u003e `2765653911`\n- `src/modules/employee/pages/EmployeeListPage.tsx:159` -\u003e `2765653923`\n- `src/modules/employee/pages/EmployeeListPage.tsx:162` -\u003e `2765653930`\n- `src/modules/employee/pages/EmployeeListPage.tsx:167` -\u003e `2765653974`\n- `src/modules/employee/pages/EmployeeListPage.tsx:191` -\u003e `2765653844`\n- `src/modules/employee/pages/AddEmployeePage.tsx:5` -\u003e `2765653856`\n- `src/modules/employee/pages/AddEmployeePage.tsx:80` -\u003e `2765653764`\n- `src/modules/employee/pages/AddEmployeePage.tsx:97` -\u003e `2765653986`\n- `src/modules/employee/pages/AddEmployeePage.tsx:102` -\u003e `2765653777`\n- `src/modules/employee/pages/AddEmployeePage.tsx:105` -\u003e `2765653997`\n- `src/modules/employee/pages/AddEmployeePage.tsx:122` -\u003e `2765654009`\n- `src/modules/employee/pages/AddEmployeePage.tsx:142` -\u003e `2765654027`\n- `src/modules/employee/pages/AddEmployeePage.tsx:146` -\u003e `2765654040`\n- `src/modules/employee/pages/AddEmployeePage.tsx:159` -\u003e `2765653790`\n- `src/shared/styles.ts:56` -\u003e `2765654049`\n- `src/shared/styles.ts:157` -\u003e `2765653869`\n- `src/shared/styles.ts:182` -\u003e `2765653879`\n\nClaude Code summary comment (issue comment id):\n- `3849294560` (Claude completion + full review summary)\n\nCodex summary comment (issue comment id):\n- `3849302316` (Issues list summary)\n\n## Round 3 (PR #11) - Copilot vs Claude Code vs Codex\n\n(IGNORE - was reusing injected issues)\n\n### Summary\n\n- Total intentional issues: 27\n- Copilot coverage: 26/27 (96.3%)\n- Codex coverage: 25/27 (92.6%)\n- Claude Code coverage: 24/27 (88.9%)\n\nBest overall coverage: Copilot. Codex was a close second. Claude had the most verbose narrative but missed a few smaller routing/accessibility items.\n\nNote: Codex inline review failed on line resolution and posted a fallback summary comment instead.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Missing lang attribute | Yes | Yes | Yes |\n| useProtectedDataQueries without waitForProtectedData | Yes | No | Yes |\n| useDeferredRegistrations not called | Yes | Yes | Yes |\n| ProtectedRoutes removed | Yes | Yes | Yes |\n| /login route uses registerRoute | Yes | Yes | No |\n| useRenderedNavigationItems signature broken | Yes | No | Yes |\n| $visibility public on /employees/add | Yes | Yes | Yes |\n| missing parentId for /employees/reports | Yes | Yes | Yes |\n| deferred registration callback never executed | Yes | Yes | Yes |\n| scroll listener no cleanup / layout thrash | Yes | Yes | Yes |\n| dangerouslySetInnerHTML XSS | Yes | Yes | Yes |\n| icon-only button lacks accessible name | Yes | Yes | Yes |\n| div acting as button | No | Yes | No |\n| aria-hidden on h1 | Yes | Yes | Yes |\n| duplicate IDs in table | Yes | Yes | Yes |\n| log chain without terminal method | Yes | Yes | Yes |\n| heading h1-\u003eh3 | Yes | Yes | Yes |\n| http image without alt/dimensions | Yes | Yes | Yes |\n| unlabeled internal notes input | Yes | No | Yes |\n| label associations broken | Yes | Yes | Yes |\n| validationScope not ended | Yes | Yes | Yes |\n| outline none | Yes | Yes | Yes |\n| nav contrast low | Yes | Yes | Yes |\n| error text invisible | Yes | Yes | Yes |\n| manual Telemetry Id/Device Id | Yes | Yes | Yes |\n| direct LogRocket identify | Yes | Yes | Yes |\n| logger.error on success | Yes | Yes | Yes |\n\n## Round 4 (PR #13) - Copilot vs Claude Code vs Codex\n\n(IGNORE - was reusing injected issues)\n\nNOTE: The `INJECTED_ISSUES.md` file was removed from the repository for this round... Without significant changes in terms of time to completion, cost and issues discovery.\n\n### Summary\n\n- Total intentional issues: 27\n- Copilot coverage: 25/27 (92.6%)\n- Claude Code coverage: 27/27 (100%)\n- Codex coverage: 24/27 (88.9%)\n\nBest overall coverage: Claude Code. Copilot was close behind. Codex missed a few UI/accessibility items (notably error text contrast).\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Missing lang attribute | Yes | Yes | Yes |\n| useProtectedDataQueries without waitForProtectedData | No | Yes | No |\n| useDeferredRegistrations not called | Yes | Yes | Yes |\n| ProtectedRoutes removed | Yes | Yes | Yes |\n| /login route uses registerRoute | Yes | Yes | No |\n| useRenderedNavigationItems signature broken | Yes | Yes | Yes |\n| $visibility public on /employees/add | Yes | Yes | Yes |\n| missing parentId for /employees/reports | Yes | Yes | Yes |\n| deferred registration callback never executed | Yes | Yes | Yes |\n| scroll listener no cleanup / layout thrash | Yes | Yes | Yes |\n| dangerouslySetInnerHTML XSS | Yes | Yes | Yes |\n| icon-only button lacks accessible name | Yes | Yes | Yes |\n| div acting as button | No | Yes | Yes |\n| aria-hidden on h1 | Yes | Yes | Yes |\n| duplicate IDs in table | Yes | Yes | Yes |\n| log chain without terminal method | Yes | Yes | Yes |\n| heading h1-\u003eh3 | Yes | Yes | Yes |\n| http image without alt/dimensions | Yes | Yes | Yes |\n| unlabeled internal notes input | Yes | Yes | Yes |\n| label associations broken | Yes | Yes | Yes |\n| validationScope not ended | Yes | Yes | Yes |\n| outline none | Yes | Yes | Yes |\n| nav contrast low | Yes | Yes | Yes |\n| error text invisible | Yes | Yes | No |\n| manual Telemetry Id/Device Id | Yes | Yes | Yes |\n| direct LogRocket identify | Yes | Yes | Yes |\n| logger.error on success | Yes | Yes | Yes |\n\n## Round 5 (PR #16) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues.\n\n- Claude Code completed in 8 minutes and the review cost 4$.\n- Codex completed in less than 2 minutes and the review cost about 10 cents.\n- Copilot completed in about 5 minutes.\n- Claude Claude Code reporting was much better than the others though, it provided a lot of information about the issues, including link to the WCAG standard when applicable.\n\n### Summary\n\n- Total intentional issues: 32\n- Copilot coverage: 29/32 (90.6%)\n- Codex coverage: 28/32 (87.5%)\n- Claude Code coverage: 20/32 (62.5%)\n\nBest overall coverage: Copilot, with Codex close behind. Claude Code missed several routing, logging, and accessibility items this round.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Invalid `lang=\"en_US\"` (BCP-47) | Yes | Yes | Yes |\n| `useDeferredRegistrations` called with unstable `deferredData` | No | No | No |\n| `useProtectedDataQueries` unstable query key | Yes | Yes | Yes |\n| Missing `waitForProtectedData` on AppRouter | No | No | No |\n| `PublicRoutes` removed from host root | Yes | Yes | Yes |\n| `/login` registered to NotFound | Yes | No | Yes |\n| Duplicate nav item id | Yes | Yes | Yes |\n| Empty `aria-label` on nav | Yes | Yes | No |\n| `NavLink` removed from tab order | Yes | Yes | Yes |\n| `$visibility: \"public\"` on `/employees/add` | Yes | No | Yes |\n| Missing `parentId` for `/employees/reports` | Yes | No | Yes |\n| Deferred registration callback never executed | Yes | No | No |\n| Scroll listener no cleanup + layout thrash | Yes | Yes | Yes |\n| XSS via `dangerouslySetInnerHTML` | Yes | Yes | Yes |\n| Icon-only button lacks accessible name | Yes | Yes | Yes |\n| `div role=\"button\"` not keyboard accessible | No | No | Yes |\n| `aria-hidden` on `\u003ch1\u003e` | Yes | No | Yes |\n| Duplicate IDs in table rows | Yes | Yes | Yes |\n| Image missing `alt` (EmployeeListPage) | Yes | Yes | Yes |\n| Label/id mismatch in Department filter | Yes | Yes | Yes |\n| Log chain without terminal method | Yes | No | Yes |\n| Heading `h1` to `h3` | Yes | No | Yes |\n| `http://` image missing `alt` and dimensions | Yes | Yes | Yes |\n| Unlabeled \"Internal notes\" input | Yes | No | Yes |\n| Broken label associations | Yes | Yes | Yes |\n| Validation scope not ended | Yes | Yes | Yes |\n| `outline: none` | Yes | Yes | Yes |\n| Low nav contrast | Yes | Yes | Yes |\n| Error text invisible | Yes | Yes | Yes |\n| Manual Telemetry Id / Device Id | Yes | Yes | Yes |\n| Direct `LogRocket.identify` | Yes | Yes | Yes |\n| `logger.error` for success | Yes | No | Yes |\n\n## Round 6 (PR #18) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues.\n\n- Claude Code completed in 2 minutes.\n- Codex completed in 1 minutes.\n- Codex reporting was pretty good.\n- Claude Code reporting was in a single comment.\n\n### Summary\n\n- Total intentional issues: 26\n- Copilot coverage: 19/26 (73.1%)\n- Claude Code coverage: 22/26 (84.6%)\n- Codex coverage: 22/26 (84.6%)\n\nBest overall coverage: Claude Code and Codex tied for first, with Copilot trailing. Missed by all: missing `waitForProtectedData`.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Unstable query key (Math.random) | Yes | Yes | Yes |\n| Missing waitForProtectedData | No | No | No |\n| PublicRoutes removed from root | No | Yes | Yes |\n| 404 registered as protected (registerRoute) | Yes | No | Yes |\n| /login registered as protected | Yes | No | No |\n| Duplicate navigation item id ($id) | No | Yes | Yes |\n| Nav links removed from tab order (tabIndex=-1) | Yes | Yes | Yes |\n| Nav hidden from AT (aria-hidden) | Yes | Yes | Yes |\n| Invalid parentId for /employees/reports | Yes | Yes | Yes |\n| Resize listener + layout thrash without cleanup | Yes | Yes | Yes |\n| setInterval without cleanup | Yes | Yes | Yes |\n| aria-describedby references missing element | No | Yes | Yes |\n| Duplicate id='search' on input/select | No | Yes | Yes |\n| Empty aria-label on button | Yes | Yes | No |\n| Button removed from tab order (tabIndex=-1) | Yes | Yes | Yes |\n| Span role=button without keyboard support | Yes | Yes | Yes |\n| aria-live='assertive' for non-urgent updates | Yes | Yes | No |\n| Table role=presentation on data table | Yes | Yes | Yes |\n| target=_blank without context | Yes | Yes | Yes |\n| Mixpanel track called on render | Yes | No | Yes |\n| logger.critical used for render | Yes | Yes | Yes |\n| email aria-describedby points to missing id | No | Yes | Yes |\n| Employee code label not associated | Yes | Yes | Yes |\n| Emergency email input is read-only | No | Yes | Yes |\n| Input text invisible (color == background) | Yes | Yes | Yes |\n| Link color low contrast | Yes | Yes | Yes |\n\n## Round 7 (PR #21) - Copilot vs Claude Code vs Codex\n\n### Summary\n\nNOTE: This round is using FRESH injected issues and Claude Code was configured with the Haiku model.\n\n- Claude Code completed in 1 minute.\n- Codex completed in 3 minutes.\n- Codex reporting was in a single comment due to some of the line numbers in Codex’s output not mapping PR diff lines.\n- Claude Code reporting was in multiple single comments.\n\n- Total intentional issues: 38\n- Copilot coverage: 30/38 (78.9%)\n- Claude Code coverage: 14/38 (36.8%)\n- Codex coverage: 35/38 (92.1%)\n\nBest overall coverage: Codex, with Copilot second. Claude Code missed a large number of telemetry/logging and Squide-specific items in this round.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| useProtectedDataQueries wrong shape | Yes | No | Yes |\n| unstable query key (Math.random) | Yes | No | Yes |\n| useDeferredRegistrations not called | Yes | No | Yes |\n| missing waitForProtectedData | No | No | Yes |\n| useRenderedNavigationItems wrong signature | Yes | No | Yes |\n| nav links removed from tab order | Yes | Yes | Yes |\n| nav aria-label empty | Yes | Yes | Yes |\n| PublicRoutes removed | Yes | No | Yes |\n| duplicate nav id | Yes | Yes | Yes |\n| manual telemetry ids | Yes | No | Yes |\n| direct LogRocket usage | Yes | No | Yes |\n| validation scope not ended | No | No | Yes |\n| log chain not terminated | Yes | No | Yes |\n| logger.error for success | Yes | No | No |\n| header image missing alt | Yes | No | Yes |\n| image missing dimensions (CLS) | No | No | Yes |\n| first name label mismatch | Yes | Yes | Yes |\n| last name label mismatch | Yes | Yes | Yes |\n| email aria-describedby missing | Yes | No | Yes |\n| emergency email read-only | No | No | Yes |\n| hire date id duplicate | No | Yes | Yes |\n| scroll listener no cleanup | Yes | Yes | Yes |\n| interval no cleanup | Yes | Yes | Yes |\n| h1 aria-hidden | Yes | Yes | Yes |\n| header image missing alt (list) | Yes | No | No |\n| filter aria-describedby missing | Yes | No | Yes |\n| department select id mismatch | No | Yes | Yes |\n| empty aria-label on clear | Yes | Yes | Yes |\n| span role button | Yes | Yes | No |\n| aria-live assertive | Yes | No | No |\n| table role presentation | Yes | No | Yes |\n| duplicate ids in rows | Yes | No | Yes |\n| target blank without rel | Yes | No | Yes |\n| XSS via dangerouslySetInnerHTML | Yes | Yes | Yes |\n| invalid parentId | Yes | Yes | Yes |\n| outline none input | No | No | Yes |\n| outline none button | Yes | No | Yes |\n| nav contrast low | No | No | Yes |\n| error text invisible | No | No | Yes |\n\n## Round 8 (PR #25) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues and Claude Code was inspired by [SG crawler](https://github.com/workleap/sg-crawler/blob/b5acbac96e13eb1912900886be683b7c87d02d4f/.github/workflows/claude-code-review.yml#L44) workflow.\n\n- Claude Code completed in 4 minute.\n- Codex completed in 3 minutes.\n- Codex reporting was in a single comment due to some of the line numbers in Codex’s output not mapping PR diff lines.\n- Claude Code reporting was in a single comment (as configured in the workflow).\n- I suspect Claude Code had issues loading the agent skills (I removed the `.claude/skills` folder).\n\n### Summary\n\n- Total intentional issues: 49\n- Copilot coverage: 41/49 (83.7%)\n- Claude Code coverage: 16/49 (32.7%)\n- Codex coverage: 32/49 (65.3%)\n\nBest overall coverage: Copilot, with Codex second. Claude Code missed many Squide/telemetry/logging issues in this round.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Invalid lang tag (en_US) | No | Yes | No |\n| useProtectedDataQueries wrong shape | Yes | No | Yes |\n| Unstable query key (Math.random) | Yes | Yes | Yes |\n| useDeferredRegistrations misuse | Yes | No | Yes |\n| Missing waitForProtectedData | No | No | No |\n| useRenderedNavigationItems wrong signature | Yes | No | Yes |\n| Nav links removed from tab order | Yes | Yes | Yes |\n| Nav aria-label empty | Yes | Yes | Yes |\n| PublicRoutes removed | Yes | Yes | Yes |\n| 404 registered as protected | Yes | No | No |\n| /login registered as protected | Yes | No | No |\n| Duplicate nav id | Yes | Yes | Yes |\n| Edit route made public | Yes | No | No |\n| Invalid parentId | Yes | No | Yes |\n| $visibility public on route | No | No | No |\n| Scroll listener no cleanup | Yes | No | Yes |\n| Interval no cleanup | Yes | Yes | Yes |\n| H1 aria-hidden | Yes | Yes | Yes |\n| Header image missing alt | Yes | Yes | Yes |\n| Header image missing dimensions | Yes | No | No |\n| Filter aria-describedby missing | Yes | No | Yes |\n| Department select id mismatch | No | No | Yes |\n| Empty aria-label on clear | Yes | No | No |\n| Clear button removed from tab order | Yes | No | No |\n| Span role button | Yes | No | Yes |\n| aria-live assertive | Yes | No | No |\n| Table role presentation | Yes | Yes | Yes |\n| Duplicate ids in rows | Yes | No | No |\n| target=_blank without rel | Yes | No | Yes |\n| XSS via dangerouslySetInnerHTML | Yes | Yes | Yes |\n| Icon-only print button lacks name | Yes | No | Yes |\n| Manual telemetry ids | Yes | No | Yes |\n| Direct LogRocket usage | Yes | No | No |\n| Validation scope not ended | Yes | No | Yes |\n| Log chain not terminated | Yes | Yes | Yes |\n| logger.error for success | Yes | No | No |\n| Heading level h3 | Yes | Yes | No |\n| HTTP image without alt | Yes | No | No |\n| First name label mismatch | Yes | Yes | Yes |\n| Last name label mismatch | Yes | Yes | Yes |\n| Email aria-describedby missing | Yes | No | Yes |\n| Internal notes missing label | No | No | Yes |\n| Hire date id duplicate | No | Yes | Yes |\n| Emergency email read-only | Yes | No | No |\n| Input text invisible | Yes | No | Yes |\n| Button outline none | Yes | No | No |\n| Link color low contrast | Yes | No | Yes |\n| Nav contrast low | No | No | Yes |\n| Error text invisible | No | No | Yes |\n\n## Round 9 (PR #27) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues and Claude Code was inspired by [SG crawler](https://github.com/workleap/sg-crawler/blob/b5acbac96e13eb1912900886be683b7c87d02d4f/.github/workflows/claude-code-review.yml#L44) workflow.\n\n- Claude Code completed in 4 minute.\n- Codex completed in 3 minutes.\n- Confirmed that Claude Code has been able to load the agent skills (https://github.com/workleap/wl-agents-code-review-poc/pull/27#issuecomment-3855302823) but it seems to be having problems reporting the issues found with the knowledge of the agent skills:\n    - `Claude requested permissions to write to /tmp/pr_review.md, but you haven't granted it yet.`\n    - I tried to fix this issue by updating the `pull-requests` and `issues` from `read` to `write` but it's not working.\n\n### Summary\n\n- Total intentional issues: 46\n- Copilot coverage: 39/46 (84.8%)\n- Claude Code coverage: 12/46 (26.1%)\n- Codex coverage: 29/46 (63.0%)\n\nBest overall coverage: Copilot, with Codex second. Claude Code missed most of the Squide/telemetry/logging issues in this round.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Missing lang attribute | Yes | Yes | Yes |\n| useProtectedDataQueries in bootstrapping | Yes | No | Yes |\n| Unstable query key (Date.now) | Yes | No | Yes |\n| useDeferredRegistrations not called | Yes | No | No |\n| useRenderedNavigationItems wrong signature | Yes | No | Yes |\n| Nav link aria-label empty | Yes | Yes | Yes |\n| Main aria-hidden | Yes | Yes | Yes |\n| PublicRoutes removed | Yes | Yes | Yes |\n| 404 registered as protected | Yes | Yes | Yes |\n| /login registered as protected | No | No | No |\n| Duplicate nav id | Yes | Yes | Yes |\n| Mandates route made public | Yes | No | Yes |\n| Invalid parentId | Yes | Yes | No |\n| Scroll listener no cleanup | Yes | No | Yes |\n| Interval no cleanup | Yes | Yes | Yes |\n| H1 aria-hidden | Yes | Yes | No |\n| Header image missing alt | Yes | Yes | Yes |\n| Filter aria-describedby missing | Yes | No | No |\n| Department select id mismatch | Yes | No | No |\n| Empty aria-label on clear | Yes | No | Yes |\n| Clear button removed from tab order | Yes | No | Yes |\n| Span role button | Yes | No | Yes |\n| aria-live assertive | Yes | No | No |\n| Table role presentation | Yes | Yes | Yes |\n| Duplicate ids in rows | Yes | No | Yes |\n| target=_blank without rel | Yes | No | Yes |\n| XSS via dangerouslySetInnerHTML | Yes | No | Yes |\n| Icon-only print button lacks name | Yes | No | Yes |\n| Manual telemetry ids | Yes | No | Yes |\n| Direct LogRocket usage | Yes | No | No |\n| Validation scope not ended | No | No | Yes |\n| Log chain not terminated | Yes | No | Yes |\n| logger.error for success | No | No | No |\n| Heading level h3 | Yes | Yes | No |\n| HTTP image without alt | Yes | No | No |\n| First name label mismatch | Yes | No | Yes |\n| Last name label mismatch | Yes | No | No |\n| Email aria-describedby missing | Yes | No | Yes |\n| Internal notes missing label | No | No | No |\n| Hire date id duplicate | Yes | No | No |\n| Emergency email read-only | No | No | Yes |\n| Input text invisible | Yes | No | Yes |\n| Button outline none | Yes | No | No |\n| Link color low contrast | Yes | No | Yes |\n| Nav contrast low | No | No | No |\n| Error text invisible | No | No | No |\n\n## Round 10 (PR #30) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues and Claude Code was inspired by [SG crawler](https://github.com/workleap/sg-crawler/blob/b5acbac96e13eb1912900886be683b7c87d02d4f/.github/workflows/claude-code-review.yml#L44) workflow.\n\n- Claude Code completed in 4 minutes.\n- Codex completed in 2 minutes.\n- Fixed the Claude Code issues to report the issues discovered with the agent skills knowledge by adding `Write` to `allowed_tools`. \n\n### Summary\n\n- Total intentional issues: 46\n- Copilot coverage: 35/46 (76.1%)\n- Claude Code coverage: 33/46 (71.7%)\n- Codex coverage: 28/46 (60.9%)\n\nBest overall coverage: Copilot, with Claude Code close behind. Codex missed several accessibility and telemetry issues in this round.\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Invalid lang tag (english) | No | Yes | No |\n| useProtectedDataQueries conditional | Yes | Yes | Yes |\n| Unstable query key (Date.now) | Yes | No | Yes |\n| useDeferredRegistrations unstable | Yes | No | Yes |\n| useRenderedNavigationItems wrong signature | Yes | Yes | Yes |\n| Nav links removed from tab order | Yes | Yes | Yes |\n| Nav aria-hidden | Yes | Yes | Yes |\n| PublicRoutes removed | Yes | Yes | Yes |\n| 404 registered as protected | Yes | No | Yes |\n| /login registered as protected | Yes | No | No |\n| Duplicate nav id | Yes | Yes | Yes |\n| Edit route made public | Yes | No | No |\n| Invalid parentId | Yes | Yes | Yes |\n| Scroll listener no cleanup | Yes | Yes | Yes |\n| Interval no cleanup | Yes | Yes | Yes |\n| H1 aria-hidden | Yes | Yes | Yes |\n| Header image missing alt | Yes | Yes | No |\n| Filter aria-describedby missing | Yes | No | No |\n| Department select id mismatch | No | Yes | Yes |\n| Empty aria-label on clear | Yes | Yes | No |\n| Clear button removed from tab order | Yes | Yes | No |\n| Span role button | Yes | Yes | Yes |\n| aria-live assertive | Yes | Yes | No |\n| Table role presentation | Yes | Yes | Yes |\n| Duplicate ids in rows | Yes | Yes | Yes |\n| target=_blank without rel | Yes | Yes | Yes |\n| XSS via dangerouslySetInnerHTML | Yes | Yes | Yes |\n| Icon-only print button lacks name | Yes | No | No |\n| Manual telemetry ids | No | Yes | Yes |\n| Direct LogRocket usage | No | Yes | Yes |\n| Validation scope not ended | Yes | Yes | Yes |\n| Log chain not terminated | Yes | No | Yes |\n| logger.error for success | Yes | Yes | No |\n| Heading level h3 | No | Yes | No |\n| HTTP image without alt | Yes | Yes | No |\n| First name label mismatch | Yes | Yes | Yes |\n| Last name label mismatch | Yes | Yes | No |\n| Email aria-describedby missing | Yes | No | No |\n| Internal notes missing label | No | Yes | Yes |\n| Hire date id duplicate | No | Yes | Yes |\n| Emergency email read-only | No | No | No |\n| Input text invisible | Yes | Yes | Yes |\n| Button outline none | No | No | No |\n| Link color low contrast | Yes | Yes | Yes |\n| Nav contrast low | No | No | No |\n| Error text invisible | No | No | No |\n\n## Round 11 (PR #35) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues and Claude Code was inspired by [SG crawler](https://github.com/workleap/sg-crawler/blob/b5acbac96e13eb1912900886be683b7c87d02d4f/.github/workflows/claude-code-review.yml#L44) workflow.\n\n- This is the first review round since the app has been migrated to Hopper.\n- Injected issues now includes Hopper issues and the review instructions now mention to use Hopper MCP server.\n- Claude Code completed in 2 minutes.\n- Codex completed in 2 minutes.\n- Fixed the Claude Code issues to report the issues discovered with the agent skills knowledge by adding `Write` to `allowed_tools`.\n\n### Coverage Summary\n\n| Agent | Issues Found | Coverage |\n| --- | --- | --- |\n| Codex | 30 / 33 | 90.9% |\n| Copilot | 29 / 33 | 87.9% |\n| Claude Code | 28 / 33 | 84.8% |\n| All 3 agents (overlap) | 26 / 33 | 78.8% |\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Invalid `lang=\"english\"` | Yes | Yes | Yes |\n| Conditional `useProtectedDataQueries` hook | Yes | Yes | Yes |\n| `Date.now()` unstable key/data in `App.tsx` | No | No | Yes |\n| `ProtectedRoutes` removed from host root | Yes | Yes | Yes |\n| Duplicate nav item id (`home`) | Yes | Yes | Yes |\n| `useRenderedNavigationItems` called with 4th arg | Yes | Yes | Yes |\n| `tabIndex={-1}` on nav links | Yes | Yes | Yes |\n| `aria-hidden=\"true\"` on nav | Yes | Yes | Yes |\n| Route `$visibility` misuse in employee register | Yes | Yes | No |\n| Missing route parent (`missing-parent-route`) | Yes | Yes | Yes |\n| Scroll listener/interval leak + layout thrash | Yes | Yes | Yes |\n| `aria-hidden=\"true\"` on main `H1` | Yes | No | Yes |\n| Missing `alt` on list page image | Yes | Yes | Yes |\n| Missing `aria-describedby` target (`filter-hint`) | No | No | Yes |\n| Empty `aria-label` + `tabIndex={-1}` on Clear button | Yes | Yes | Yes |\n| `span role=\"button\"` not keyboard accessible | Yes | Yes | Yes |\n| `role=\"presentation\"` on data table | Yes | Yes | Yes |\n| Duplicate IDs in employee list rows | Yes | Yes | Yes |\n| `target=\"_blank\"` missing `rel` | Yes | Yes | Yes |\n| `dangerouslySetInnerHTML` XSS | Yes | Yes | Yes |\n| Add page image missing `alt` + HTTP | Yes | Yes | Yes |\n| Broken label/id associations in add page | Yes | Yes | Yes |\n| Duplicate `id=\"email\"` in add page | Yes | Yes | Yes |\n| Missing `aria-describedby` target (`email-help`) | No | Yes | No |\n| Validation scope created, never ended | Yes | Yes | Yes |\n| Logging chain not finalized | Yes | Yes | Yes |\n| Success logged with `error` level | Yes | Yes | Yes |\n| Manual `\"Telemetry Id\"` / `\"Device Id\"` | Yes | Yes | Yes |\n| Direct `LogRocket.identify` usage | Yes | Yes | Yes |\n| Global focus outline removal (`outline: none`) | Yes | Yes | Yes |\n| Low contrast nav links (`#444` on `#333`) | Yes | No | Yes |\n| Invisible alert text (`#f8d7da` on `#f8d7da`) | Yes | Yes | Yes |\n| Heading downgrade (`H1` -\u003e title3) | No | No | No |\n\n### Not Reported By All Agents\n\n- `Date.now()` unstable key/data (`src/App.tsx`)\n- Route `$visibility` misuse (`src/modules/employee/register.tsx`)\n- `aria-hidden` on main `H1` (`src/modules/employee/pages/EmployeeListPage.tsx`)\n- Missing `aria-describedby=\"filter-hint\"` target (`src/modules/employee/pages/EmployeeListPage.tsx`)\n- Missing `aria-describedby=\"email-help\"` target (`src/modules/employee/pages/AddEmployeePage.tsx`)\n- Low contrast nav links (`src/index.css`)\n- Heading downgrade (`H1` -\u003e title3) (missed by all)\n\n## Round 12 (PR #38) - Copilot vs Claude Code vs Codex\n\n### Coverage Summary\n\n| Agent | Issues Found | Coverage |\n| --- | --- | --- |\n| Claude Code | 46 / 49 | 93.9% |\n| Copilot | 45 / 49 | 91.8% |\n| Codex | 26 / 49 | 53.1% |\n| Missed by all 3 | 2 / 49 | 4.1% |\n\n### Matrix\n\n| Intentional Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Invalid html lang tag en-US-English | Yes | Yes | Yes |\n| HopperProvider withCssVariables=false | Yes | Yes | No |\n| HopperProvider invalid locale english-us | Yes | Yes | No |\n| Date.now in query key | Yes | Yes | Yes |\n| Deferred data uses Date.now each render | Yes | Yes | Yes |\n| PublicRoutes removed from host root | Yes | Yes | Yes |\n| Catch-all route registered with registerRoute | No | No | No |\n| /admin registered as public route | No | Yes | No |\n| Duplicate nav item id home | Yes | Yes | Yes |\n| NavLink empty aria-label | Yes | Yes | Yes |\n| NavLink tabIndex -1 in nav | Yes | Yes | Yes |\n| Hardcoded nav colors #444/#333 | Yes | Yes | No |\n| UL aria-hidden true | Yes | Yes | No |\n| Nav role presentation | Yes | Yes | No |\n| $visibility public on registerRoute | Yes | Yes | Yes |\n| Edit route made public | Yes | Yes | Yes |\n| Missing parentPath /missing-parent | Yes | Yes | Yes |\n| useEffect listener no cleanup | Yes | Yes | Yes |\n| Layout thrash via getBoundingClientRect+body width | Yes | Yes | No |\n| EmployeeList wrapper hardcoded low-contrast style | Yes | Yes | No |\n| H1 aria-hidden on list page | Yes | Yes | No |\n| List page image missing alt | Yes | Yes | No |\n| Missing describedby target employee-filters-hint | Yes | Yes | No |\n| Department select wrong id search-field | Yes | Yes | No |\n| Clear Filters button empty aria-label | Yes | Yes | Yes |\n| Clear Filters button tabIndex -1 | Yes | Yes | Yes |\n| Span role button lacks keyboard support | Yes | Yes | Yes |\n| Icon-only print button no accessible label | Yes | Yes | No |\n| aria-live assertive on count text | Yes | Yes | No |\n| Table role presentation | Yes | Yes | Yes |\n| Duplicate id employee-name | Yes | Yes | Yes |\n| Duplicate id employee-email | Yes | Yes | Yes |\n| target=_blank missing rel | No | Yes | Yes |\n| XSS via dangerouslySetInnerHTML filters.search | Yes | Yes | Yes |\n| validationScope created unused/unended | Yes | Yes | Yes |\n| Unterminated logging chain withText/withObject | Yes | Yes | Yes |\n| Success logged using logger.error | Yes | Yes | No |\n| Manual Telemetry Id and Device Id | Yes | Yes | Yes |\n| Direct LogRocket.identify usage | Yes | Yes | Yes |\n| Add page H1 aria-hidden | Yes | Yes | No |\n| Add page image missing alt | Yes | Yes | Yes |\n| Missing describedby target employee-email-help | Yes | Yes | No |\n| Duplicate id email on Hire Date | Yes | Yes | Yes |\n| Internal notes TextField has no label | Yes | Yes | No |\n| Emergency email TextField read-only value without onChange | No | No | No |\n| Legacy label htmlFor first_name mismatch input id | Yes | Yes | No |\n| Hopper CSS override via .hop-* with !important | Yes | Yes | No |\n| Focus outline removed globally | Yes | Yes | Yes |\n| Alert text invisible same fg/bg | Yes | No | No |\n\n### Injected Issues Missed By All Agents\n\n- Catch-all route registered with `registerRoute` (`src/host/register.tsx`)\n- Emergency email TextField read-only value without `onChange` (`src/modules/employee/pages/AddEmployeePage.tsx`)\n\n## Round 13 (PR #49) - Copilot vs Claude Code vs Codex\n\nNOTE: This round is using FRESH injected issues and Claude Code was inspired by [SG crawler](https://github.com/workleap/sg-crawler/blob/b5acbac96e13eb1912900886be683b7c87d02d4f/.github/workflows/claude-code-review.yml#L44) workflow.\n\n- This is the first review round for which Hopper MCP works for Claude, other agents still can't use MCP server because somehow no agents is able to read then `.mcp.json` file.\n- Claude Code completed in 4 minutes.\n- Codex completed in 2 minutes.\n\n### Data Collection\n\nAll PR comment sources were fetched with pagination:\n\n- `issues/49/comments`: 1 page, 2 comments\n- `pulls/49/comments` (inline review comments): 1 page, 44 comments\n- `pulls/49/reviews`: 1 page, 1 review\n\n### Issue Count Summary\n\nPercentages below are coverage against injected issues for this round.\nInjected issues baseline used for coverage: `50`.\n\n| Agent | Issues Found | Coverage |\n| --- | --- | --- |\n| Copilot | 44 / 50 | 88.0% |\n| Claude Code | 29 / 50 | 58.0% |\n| Codex | 18 / 50 | 36.0% |\n\n### Comparison Matrix (Normalized Issue Topics)\n\n| Issue Topic | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| HTTP third-party script in `public/index.html` | Yes | Yes | Yes |\n| Meta refresh reload | Yes | No | Yes |\n| Bootstrap interval leak in `src/App.tsx` | Yes | Yes | Yes |\n| Empty spinner aria-label | Yes | Yes | Yes |\n| Catch-all route conflict in host routes | Yes | Yes | Yes |\n| Duplicate nav id `home` | Yes | No | Yes |\n| Duplicate module registration (`registerEmployeeModule` twice) | Yes | Yes | Yes |\n| Wrong component on employee edit/mandates routes | Yes | Yes | Yes |\n| Duplicate nav id `employees` | Yes | Yes | Yes |\n| Public exposure via `registerPublicRoute` for employee pages | Yes | No | No |\n| Add page PII logging/storage | Yes | No | Yes |\n| Edit page interval/listener cleanup leak | Yes | Yes | Yes |\n| Edit page PII storage/logging | Yes | No | No |\n| 20k analytics array perf issue | Yes | Yes | Yes |\n| Scroll layout thrash / missing cleanup | Yes | Yes | No |\n| `dangerouslySetInnerHTML` XSS risk | Yes | Yes | Yes |\n| `key={Math.random()}` unstable keys | No | Yes | Yes |\n| Empty search field label | Yes | No | Yes |\n| In-place sort mutation in list page | Yes | Yes | No |\n| Validation weakening (email/required/date) | Yes | Yes | No |\n| Aggressive React Query settings | Yes | Yes | No |\n| Hopper style/token violations | No | Yes | No |\n| `document.title` side effect during render | Yes | No | No |\n| `adminComment` not in shared form type | Yes | No | No |\n| `getAllMandates()` vs \"active mandates\" mismatch | Yes | Yes | No |\n| `target=\"_blank\"` without `rel` | No | No | Yes |\n\n### Missed By All Agents\n\n- Per-keystroke localStorage write of search term (`src/modules/employee/pages/EmployeeListPage.tsx`)\n- Form `autoComplete=\"off\"` regression (`src/modules/employee/pages/AddEmployeePage.tsx`)\n- Focus outline removal via inline style (`src/modules/employee/pages/EditEmployeePage.tsx`)\n- Low-contrast/weak-weight mandate label styling (`src/modules/employee/pages/AssignMandatesPage.tsx`)\n- Hardcoded wrapper width `maxWidth: \"99.5%\"` around `\u003cOutlet /\u003e` (`src/App.tsx`)\n- Hardcoded main width `maxWidth: \"99.7%\"` (`src/host/RootLayout.tsx`)\n\n## Round 14 (PR #49) - Copilot vs Claude Code vs Codex\n\n### Data Collection\n\nAll PR comment sources were fetched with pagination:\n\n- `issues/49/comments`: 1 page, 2 items\n- `pulls/49/comments` (inline review comments): 1 page, 44 items\n- `pulls/49/reviews`: 1 page, 1 item\n\n### Coverage Summary\n\nInjected issues baseline for this round: `69`.\n\n| Agent | Issues Found | Coverage |\n| --- | --- | --- |\n| Copilot | 33 / 69 | 47.8% |\n| Claude Code | 22 / 69 | 31.9% |\n| Codex | 14 / 69 | 20.3% |\n\n### Comparison Matrix (Reported Issues)\n\n| Reported Issue | Copilot | Claude Code | Codex |\n| --- | --- | --- | --- |\n| Meta refresh forced reload | Yes | No | Yes |\n| HTTP third-party script in `index.html` | Yes | Yes | Yes |\n| Bootstrapping interval leak | No | No | Yes |\n| Empty spinner aria-label | Yes | Yes | No |\n| `document.title` side-effect in render | Yes | No | No |\n| Public `/employees/:id/edit` host conflict | Yes | Yes | No |\n| Host catch-all route conflict | Yes | Yes | Yes |\n| Duplicate nav id `home` | Yes | No | Yes |\n| Employee list/add exposed as public routes | Yes | Yes | No |\n| Duplicate `/employees/:id/edit` to Add page | No | Yes | Yes |\n| Duplicate nav id `employees` | Yes | No | Yes |\n| Navigation order reversed with `.reverse()` | Yes | No | No |\n| Hardcoded Hopper nav colors/tokens bypass | No | Yes | No |\n| Employee module registered twice | No | Yes | Yes |\n| Aggressive React Query settings | Yes | Yes | No |\n| Large `analyticsNoise` allocation | Yes | Yes | Yes |\n| Scroll layout thrash/listener leak | Yes | Yes | No |\n| List interval leak | Yes | No | No |\n| In-place `.sort()` mutation | Yes | Yes | No |\n| `window.location.hash` mutation on clear | Yes | No | No |\n| `H1` with `role=\"presentation\"` | Yes | No | No |\n| List image HTTP/missing alt issue | Yes | Yes | No |\n| Empty SearchField label | No | No | Yes |\n| Invalid font weight (`930`) | No | Yes | No |\n| `key={Math.random()}` | Yes | Yes | Yes |\n| Duplicate `id=\"employee-cell\"` | No | Yes | No |\n| `dangerouslySetInnerHTML` XSS | Yes | Yes | Yes |\n| `target=\"_blank\"` without `rel` | No | No | Yes |\n| PII log of `employee.email` from list action | Yes | No | No |\n| Add page keydown listener leak | Yes | Yes | No |\n| Add page validation weakened | Yes | No | No |\n| Add page payload logging with PII | Yes | No | No |\n| Add page image HTTP/missing alt | Yes | Yes | No |\n| Add page email `type=\"text\"` | Yes | No | No |\n| Unlabeled internal note field | Yes | No | No |\n| `adminComment` outside shared type | Yes | No | No |\n| Edit page stores email in localStorage | Yes | Yes | Yes |\n| Edit page validation weakened | Yes | No | No |\n| Edit page payload logging with PII | Yes | No | No |\n| Edit spinner empty aria-label | No | Yes | No |\n| Assign page uses `getAllMandates()` | Yes | Yes | No |\n| Assign label low contrast/weak weight | Yes | No | No |\n\n### Missed By All Agents\n\n- Invalid `lang=\"en_US\"` value\n- `HopperProvider withCssVariables={false}`\n- Invalid Hopper locale (`english-canada`)\n- Hardcoded `maxWidth: \"99.2%\"` outlet wrapper\n- `ProtectedRoutes` removed from host root\n- `/login` registered with `registerRoute`\n- Duplicate `/employees/:id/mandates` pointing to Add page\n- Inline style on Hopper `Nav`/`Main`\n- External class-based Hopper override (`legacy-nav`)\n- Global Hopper token override in CSS variables\n- Global focus outline removal\n- Search term persisted to localStorage\n- Clear button empty `aria-label` + `tabIndex={-1}`\n- Table `role=\"presentation\"`\n- `span role=\"button\"` without keyboard support\n- Validation errors logged as `critical`\n- Add page stores full employee object in localStorage\n- Success logged at error level\n- Cancel logged at error level\n- Add page `H1 aria-hidden=\"true\"`\n- `autoComplete=\"off\"` on form\n- Inline style on Hopper `Select`\n- Edit page interval + resize listener cleanup leak\n- Edit success logged as `critical`\n- Edit page `outline: none`\n- Assign cancel logged as `warning`\n- Assign inline border-color style override\n\n## Round 15 (PR #54) - Copilot vs Claude Code vs Codex\n\nNOTE: This round uses FRESH injected issues (40 total). Codex was blocked because Hopper MCP was unavailable.\n\n### Coverage Summary\n\n| Agent | Issues Found | Coverage | Total Comments |\n| --- | --- | --- | --- |\n| Claude Code | 31 / 40 | 77.5% | 31 |\n| Copilot | 28 / 40 | 70.0% | 56 |\n| Codex | 0 / 40 | 0% | 0 (blocked) |\n\n**Note:** Codex reported: *\"Unable to complete required Hopper MCP validation: no Hopper MCP resources/tools are available\"*\n\n### Issues by Category\n\n| Category | Total | Claude Code | Copilot |\n| --- | --- | --- | --- |\n| Hopper UI | 12 | 10 (83%) | 4 (33%) |\n| Squide/Firefly | 10 | 9 (90%) | 5 (50%) |\n| Accessibility | 10 | 6 (60%) | 9 (90%) |\n| Performance | 4 | 4 (100%) | 4 (100%) |\n| Security | 2 | 1 (50%) | 2 (100%) |\n| Logging | 2 | 1 (50%) | 2 (100%) |\n\n### Comparison Matrix\n\n| # | Issue | Category | File | Claude | Copilot |\n| --- | --- | --- | --- | --- | --- |\n| 1 | Missing `lang` attribute | Accessibility | public/index.html | Yes | Yes |\n| 2 | `user-scalable=no` | Accessibility | public/index.html | Yes | Yes |\n| 3 | CSS override .hop-Button | Hopper | src/index.css | Yes | Yes |\n| 4 | CSS override .hop-TextField | Hopper | src/index.css | Yes | Yes |\n| 5 | Focus outline removal | Accessibility | src/index.css | Yes | Yes |\n| 6 | Invalid locale format | Hopper | src/App.tsx | Yes | No |\n| 7 | Unused `usePublicDataQueries` | Squide | src/App.tsx | Yes | Yes |\n| 8 | Inline style on Hopper Div | Hopper | src/App.tsx | Yes | No |\n| 9 | `console.log` usage | Logging | src/index.tsx | Yes | Yes |\n| 10 | Suboptimal QueryClient defaults | Performance | src/index.tsx | Yes | Yes |\n| 11 | Missing `ProtectedRoutes` | Squide | src/host/register.tsx | Yes | Yes |\n| 12 | Route with both `index` and `path` | Squide | src/host/register.tsx | Yes | Yes |\n| 13 | Duplicate navigation item `$id` | Squide | src/host/register.tsx | Yes | Yes |\n| 14 | Navigation item missing `to` | Squide | src/host/register.tsx | Yes | Yes |\n| 15 | Login route registered incorrectly | Squide | src/host/register.tsx | No | No |\n| 16 | Invalid `useNavigationItems` option | Squide | src/host/RootLayout.tsx | Yes | No |\n| 17 | `useRenderedNavigationItems` wrong signature | Squide | src/host/RootLayout.tsx | Yes | No |\n| 18 | Hardcoded colors in NavLink | Hopper | src/host/RootLayout.tsx | Yes | No |\n| 19 | `outline: \"none\"` in styles | Accessibility | src/host/RootLayout.tsx | Yes | Yes |\n| 20 | `aria-hidden` on H1 | Accessibility | src/host/HomePage.tsx | Yes | Yes |\n| 21 | Image without alt | Accessibility | src/host/HomePage.tsx | Yes | Yes |\n| 22 | `style` prop on Grid | Hopper | src/host/HomePage.tsx | Yes | No |\n| 23 | `target=\"_blank\"` without `rel` | Security | src/host/HomePage.tsx | Yes | Yes |\n| 24 | Generic link text \"Click here\" | Accessibility | src/host/HomePage.tsx | Yes | Yes |\n| 25 | Raw hex color `#666666` | Hopper | src/host/HomePage.tsx | Yes | No |\n| 26 | Raw hex color `#999999` | Hopper | src/host/NotFoundPage.tsx | Yes | No |\n| 27 | Lazy import without Suspense | Performance | employee/register.tsx | Yes | Yes |\n| 28 | `$visibility` on route object | Squide | employee/register.tsx | Yes | No |\n| 29 | Non-existent `parentId` | Squide | employee/register.tsx | Yes | No |\n| 30 | Deferred registration never executed | Squide | employee/register.tsx | Yes | No |\n| 31 | `useEffect` without cleanup | Performance | EmployeeListPage.tsx | Yes | Yes |\n| 32 | Layout thrashing | Performance | EmployeeListPage.tsx | Yes | Yes |\n| 33 | `dangerouslySetInnerHTML` XSS | Security | EmployeeListPage.tsx | No | Yes |\n| 34 | IconButton without accessible name | Accessibility | EmployeeListPage.tsx | No | Yes |\n| 35 | `div` as button not keyboard accessible | Accessibility | EmployeeListPage.tsx | No | Yes |\n| 36 | Duplicate IDs | Accessibility | EmployeeListPage.tsx | No | Yes |\n| 37 | External CSS for Hopper | Hopper | EmployeeListPage.tsx | No | Yes |\n| 38 | H3 as page heading | Accessibility | AddEmployeePage.tsx | No | Yes |\n| 39 | Label/input ID mismatch | Accessibility | AddEmployeePage.tsx | No | Yes |\n| 40 | Logging scope not ended | Logging | AddEmployeePage.tsx | No | Yes |\n\n### Key Findings\n\n1. **Claude excels at Hopper and Squide issues** - Found 10/12 Hopper (83%) and 9/10 Squide (90%) issues.\n2. **Copilot excels at accessibility issues** - Found 9/10 accessibility issues (90%).\n3. **Both found all performance issues** - 100% detection rate.\n4. **Claude did NOT use Hopper MCP** - Despite being configured for it, no evidence of `validate_hopper_code` calls.\n5. **Complementary strengths** - Together found 39/40 issues (97.5%).\n\n### Missed By All Agents\n\n- #15: Login route registered incorrectly (should use `registerPublicRoute` with proper component)\n\n## Round 16 (PR #56) - Copilot vs Claude Code vs Codex\n\nNOTE: This round uses FRESH injected issues (42 total). Codex was blocked again due to Hopper MCP unavailability.\n\n### Coverage Summary\n\n| Agent | Issues Found | Coverage | Total Comments |\n| --- | --- | --- | --- |\n| Copilot | 38 / 42 | 90.5% | 52 |\n| Claude Code | 28 / 42 | 66.7% | 28 |\n| Codex | 0 / 42 | 0% | 0 (blocked) |\n\n**Note:** Codex reported: *\"Hopper MCP validation required but no Hopper MCP tool is available in this environment\"*\n\n### Comparison Matrix\n\n| # | File | Issue | Claude | Copilot |\n| --- | --- | --- | --- | --- |\n| 1 | public/index.html | Missing `lang` attribute | Yes | Yes |\n| 2 | public/index.html | `user-scalable=no`, `maximum-scale=1.0` | Yes | Yes |\n| 3 | public/index.html | `aria-hidden=\"true\"` on root | Yes | Yes |\n| 4 | public/index.html | `role=\"application\"` on root | Yes | Yes |\n| 5 | src/index.css | `*:focus { outline: none }` | Yes | Yes |\n| 6 | src/index.css | `!important` font override | Yes | No |\n| 7 | src/App.tsx | Unused import (useNavigationItems) | No | Yes |\n| 8 | src/App.tsx | Invalid locale `\"xyz-invalid\"` | Yes | Yes |\n| 9 | src/App.tsx | `setInterval` without cleanup | Yes | Yes |\n| 10 | src/App.tsx | `UNSAFE_color` with hex value | No | No |\n| 11 | src/App.tsx | Missing `aria-label` on Spinner | Yes | Yes |\n| 12 | src/App.tsx | Inline `style` on Text | Yes | No |\n| 13 | src/index.tsx | `console.log` usage | No | Yes |\n| 14 | src/index.tsx | Exposing `queryClient` to window | Yes | Yes |\n| 15 | src/index.tsx | Exposing `runtime` to window | Yes | Yes |\n| 16 | src/index.tsx | `staleTime: 0` | Yes | Yes |\n| 17 | src/host/register.tsx | Missing `ProtectedRoutes` | No | Yes |\n| 18 | src/host/register.tsx | Duplicate nav ID `\"home\"` | Yes | Yes |\n| 19 | src/host/register.tsx | Invalid path `\"/*\"` | No | No |\n| 20 | src/host/RootLayout.tsx | `useEffect` without dependency array | Yes | Yes |\n| 21 | src/host/RootLayout.tsx | `document.body.style` mutation | Yes | Yes |\n| 22 | src/host/RootLayout.tsx | `role=\"menu\"` on Nav | Yes | Yes |\n| 23 | src/host/RootLayout.tsx | Hardcoded colors (hex) | No | No |\n| 24 | src/host/HomePage.tsx | `useEffect` without deps (render loop) | Yes | Yes |\n| 25 | src/host/HomePage.tsx | `window.open` without `noopener` | Yes | Yes |\n| 26 | src/host/HomePage.tsx | Card onClick without keyboard | Yes | Yes |\n| 27 | src/host/HomePage.tsx | `target=\"_blank\"` without rel | Yes | No |\n| 28 | src/host/NotFoundPage.tsx | Unhandled fetch promise | Yes | Yes |\n| 29 | src/host/NotFoundPage.tsx | `accessKey` attribute | Yes | No |\n| 30 | src/host/NotFoundPage.tsx | `tabIndex={-1}` on button | Yes | Yes |\n| 31 | src/host/NotFoundPage.tsx | `javascript:` URL | Yes | Yes |\n| 32 | employee/register.tsx | Path without leading slash | Yes | Yes |\n| 33 | employee/register.tsx | Duplicate nav ID `\"employees\"` | Yes | Yes |\n| 34 | employee/register.tsx | Unused `/delete` route | No | Yes |\n| 35 | EmployeeListPage.tsx | `useEffect` without deps | Yes | Yes |\n| 36 | EmployeeListPage.tsx | `dangerouslySetInnerHTML` XSS | No | Yes |\n| 37 | EmployeeListPage.tsx | Array index as key (multiple) | No | Yes |\n| 38 | EmployeeListPage.tsx | `handleExport` memory leak | Yes | Yes |\n| 39 | EmployeeListPage.tsx | `target=\"_blank\"` without rel | No | Yes |\n| 40 | AddEmployeePage.tsx | `handleTextChange` not memoized | Yes | No |\n| 41 | AddEmployeePage.tsx | Direct state mutation | No | Yes |\n| 42 | AddEmployeePage.tsx | `useRef\u003cany\u003e` type issue | No | Yes |\n| 43 | EditEmployeePage.tsx | `useSession` cast to `any` | No | Yes |\n| 44 | EditEmployeePage.tsx | Unused `originalEmployee` state | No | Yes |\n| 45 | EditEmployeePage.tsx | `console.log` in component | No | Yes |\n| 46 | EditEmployeePage.tsx | Missing `logger` in deps | No | Yes |\n| 47 | EditEmployeePage.tsx | Missing Spinner `aria-label` | No | Yes |\n| 48 | AssignMandatesPage.tsx | Empty `aria-label` on button | No | Yes |\n| 49 | AssignMandatesPage.tsx | Array index as key | No | Yes |\n| 50 | src/shared/dataStore.ts | Direct array reference (no copy) | Yes | Yes |\n| 51 | src/shared/dataStore.ts | `syncToStorage` in constructor | No | Yes |\n| 52 | src/shared/dataStore.ts | Silent `catch` block | No | Yes |\n| 53 | src/shared/dataStore.ts | `==` instead of `===` | No | Yes |\n| 54 | src/shared/dataStore.ts | `delete` on array (sparse) | No | Yes |\n\n### Issues Missed by All Agents\n\n| # | File | Issue |\n| --- | --- | --- |\n| 1 | src/App.tsx | `UNSAFE_color` with hex value |\n| 2 | src/host/register.tsx | Invalid path `\"/*\"` vs `\"*\"` |\n| 3 | src/host/RootLayout.tsx | Hardcoded inline colors (hex) |\n| 4 | src/host/HomePage.tsx | Wrong token type (`marginBottom=\"inline-xl\"`) |\n| 5 | src/host/HomePage.tsx | Wrong token type (`gap=\"inline-lg\"`) |\n| 6 | employee/register.tsx | `registerPublicRoute` for protected content |\n\n### Key Findings\n\n1. **Copilot significantly outperformed Claude** - 90.5% vs 66.7% coverage\n2. **Copilot excels at React patterns** - Array keys, state mutations, hook dependencies\n3. **Copilot excels at TypeScript issues** - Type assertions, unused variables\n4. **Copilot excels at data layer issues** - DataStore caching, storage, equality operators\n5. **Claude excels at accessibility** - accessKey, focus indicators, aria attributes\n6. **Claude excels at Hopper** - Invalid locale, inline styles, !important overrides\n7. **Neither detected Hopper token misuse** - Wrong token types (inline- for margins) missed by both\n8. **Codex blocked again** - Still unable to access Hopper MCP in GitHub Actions\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkleap%2Fwl-agents-code-review-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fworkleap%2Fwl-agents-code-review-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkleap%2Fwl-agents-code-review-poc/lists"}