Remove ROBINS-I manual judgement override; derive judgements like ROB-2 - #522
Conversation
ROBINS-I let reviewers manually override domain/overall judgements (judgementSource: auto | manual) and reconciled judgements as their own pages. Because an auto judgement was computed-but-not-stored, two reviewers who both left a judgement on auto compared as null === null at reconciliation: the UI reported "Reviewers agreed" yet auto-fill no-opped on the null, leaving the Final Judgement "Not set" and blocking save with no way forward. ROB-2 never hit this because it derives judgements and has no judgement reconciliation pages. Align ROBINS-I with ROB-2: judgements are always derived from the signalling answers, and only direction is reconciled. - Editor: judgement is display-only; drop the Auto/Manual toggle and all manual-override handlers. Direction stays editable. - Data model: remove judgementSource from types, schema, create, handler, and migration; getEffectiveDomainJudgement deleted; scoreAllDomains simplified. isROBINSIComplete now derives completion from the answers. - Reconciliation: replace the domain/overall judgement pages with direction pages (judgement shown read-only/derived). Direction is optional and never blocks save (ROBINS-I has no "not applicable" direction option). - Tests: update unit/migration fixtures; the e2e dual-reviewer workflow now passes without manually selecting an agreed judgement. Existing checklists saved with a manual override now show the derived judgement; the stored override is ignored (no migration).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughRemoves ChangesRemove ROBINS-I manual judgement override
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (5)
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsx (1)
40-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winImport the new pages through the
@/alias.Proposed fix
-import { DomainDirectionPage } from './pages/DomainDirectionPage'; -import { OverallDirectionPage } from './pages/OverallDirectionPage'; +import { DomainDirectionPage } from '`@/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage`'; +import { OverallDirectionPage } from '`@/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage`';As per coding guidelines,
packages/web/src/**/*.{ts,tsx}: Path aliases:@/maps topackages/web/src/.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsx` around lines 40 - 41, The imports in adapter.tsx should use the `@/` alias instead of relative paths. Update the DomainDirectionPage and OverallDirectionPage imports in the adapter module to reference their locations through `@/` so they follow the packages/web/src path-alias guideline and stay consistent with the rest of the codebase.Source: Coding guidelines
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx (2)
5-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the web source alias for the local panel import.
Proposed fix
-import { DirectionPanel } from '../panels/DirectionPanel'; +import { DirectionPanel } from '`@/components/project/reconcile-tab/robins-i-reconcile/panels/DirectionPanel`';As per coding guidelines,
packages/web/src/**/*.{ts,tsx}: Path aliases:@/maps topackages/web/src/.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx` at line 5, The local panel import in OverallDirectionPage should use the web source alias instead of a relative path. Update the DirectionPanel import to follow the project’s `@/` alias convention for `packages/web/src/**/*.{ts,tsx}`, keeping the component reference the same while changing only the import source path.Source: Coding guidelines
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDrop useMemo around overall scoring.
This follows the package guidance to let React Compiler handle memoization.
Proposed fix
-import { useMemo } from 'react'; import { CheckIcon, XIcon, InfoIcon } from 'lucide-react'; @@ - const reviewer1Scoring = useMemo(() => scoreAllDomains(checklist1), [checklist1]); - const reviewer2Scoring = useMemo(() => scoreAllDomains(checklist2), [checklist2]); - const finalScoring = useMemo(() => scoreAllDomains(finalChecklist), [finalChecklist]); + const reviewer1Scoring = scoreAllDomains(checklist1); + const reviewer2Scoring = scoreAllDomains(checklist2); + const finalScoring = scoreAllDomains(finalChecklist);As per coding guidelines,
packages/web/src/**/*.{tsx,ts}: AvoiduseMemooruseCallback- let the React Compiler handle memoization.Also applies to: 52-54
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx` at line 1, Remove the manual memoization from OverallDirectionPage by dropping the useMemo import and any useMemo wrapping around the overall scoring logic, since the React Compiler should handle memoization here. Update the component to compute the score directly in OverallDirectionPage (and any related scoring helpers in the same block) without useMemo/useCallback, keeping the existing behavior unchanged while following the packages/web coding guideline.Source: Coding guidelines
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx (2)
9-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the web source alias for the local panel import.
This new import bypasses the configured
@/alias.Proposed fix
-import { DirectionPanel } from '../panels/DirectionPanel'; +import { DirectionPanel } from '`@/components/project/reconcile-tab/robins-i-reconcile/panels/DirectionPanel`';As per coding guidelines,
packages/web/src/**/*.{ts,tsx}: Path aliases:@/maps topackages/web/src/.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx` at line 9, The local panel import in DomainDirectionPage should use the configured web source alias instead of a relative path. Update the DirectionPanel import to come through the `@/` alias so it matches the packages/web/src convention and keeps imports consistent across the web codebase.Source: Coding guidelines
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDrop useMemo around the scoring calls.
These calculations are pure render-derived values, and this package guideline asks React Compiler to handle memoization.
Proposed fix
-import { useMemo } from 'react'; import { CheckIcon, XIcon, InfoIcon } from 'lucide-react'; @@ - const reviewer1Scoring = useMemo( - () => scoreRobinsDomain(domainKey, reviewer1Answers), - [domainKey, reviewer1Answers], - ); - const reviewer2Scoring = useMemo( - () => scoreRobinsDomain(domainKey, reviewer2Answers), - [domainKey, reviewer2Answers], - ); - const finalScoring = useMemo( - () => scoreRobinsDomain(domainKey, finalAnswers), - [domainKey, finalAnswers], - ); + const reviewer1Scoring = scoreRobinsDomain(domainKey, reviewer1Answers); + const reviewer2Scoring = scoreRobinsDomain(domainKey, reviewer2Answers); + const finalScoring = scoreRobinsDomain(domainKey, finalAnswers);As per coding guidelines,
packages/web/src/**/*.{tsx,ts}: AvoiduseMemooruseCallback- let the React Compiler handle memoization.Also applies to: 62-73
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx` at line 1, Remove the useMemo wrapper around the scoring calculations in DomainDirectionPage and let the values be computed directly during render, since they are pure derived values and the package guideline prefers React Compiler memoization. Also drop the useMemo import from the component if it is no longer used, and keep the existing scoring logic/identifiers intact so the calculations remain functionally the same.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/web/e2e/robins-i-workflow.spec.ts`:
- Line 44: The option locator in the e2e workflow test is building a RegExp
directly from raw outcome text, which can mis-match or fail when the text
contains regex metacharacters. Update the locator in the robins-i workflow spec
to escape the outcome value before passing it into page.getByRole('option',
...), so the match is treated as literal text rather than a pattern.
In `@packages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsx`:
- Around line 140-149: The read-only DomainSection still renders interactive
judgement buttons through DomainJudgement by passing a no-op onJudgementChange,
which leaves inert focusable controls. Update the DomainSection usage of
DomainJudgement so the judgement row is hidden or disabled in display-only mode
while preserving the editable direction controls via handleDirectionChange and
the existing direction props. Use the DomainJudgement component’s
judgement-related props and rendering logic to enforce the new display-only
contract instead of relying on an empty callback.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsx`:
- Around line 155-165: The “Use This” flow in adapter.tsx is skipping reviewer
directions when they are null because of truthy checks in the DOMAIN_DIRECTION
and OVERALL_DIRECTION cases. Update the handling in the affected reconciliation
path (including the related logic around the other referenced block) so it
copies the reviewer’s direction whenever the reviewer scope exists, even if that
value is null, and only skips when the reviewer data itself is missing. Use the
existing updateDomainDirection and updateOverallDirection helpers to preserve an
unset final direction instead of leaving stale reconciled data in place.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.ts`:
- Around line 201-214: The current hasNavItemAnswer helper in navbar-utils.ts
treats DOMAIN_DIRECTION and OVERALL_DIRECTION as always answered, which is
mixing completion logic with value presence. Split this into two checks: keep a
completion-focused path for blocking rules, and add a separate helper for
whether a direction actually has a set value. Update the navbar and summary
answer indicators to use the value-presence helper so unset directions do not
render as answered while still remaining non-blocking.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx`:
- Around line 75-95: The agreement status in DomainDirectionPage should be
direction-only, not tied to judgement equality. Update the header logic in
DomainDirectionPage so the green/amber state and icon depend on directionMatch
alone, matching the nav and summary behavior, and keep judgementMatch only for
any separate judgement-specific display if needed. Use the existing
directionMatch and judgementMatch symbols to locate the conditional rendering
and remove judgementMatch from the page status condition.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx`:
- Around line 56-76: The OverallDirectionPage header is using both
directionMatch and judgementMatch to decide the status, but this screen should
be direction-only. Update the status logic in OverallDirectionPage so the header
styling and icon are driven only by directionMatch, and remove or stop using
judgementMatch in this component’s success/failure state. Make sure the
displayed status stays consistent with the OVERALL_DIRECTION evaluation used
elsewhere.
---
Nitpick comments:
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsx`:
- Around line 40-41: The imports in adapter.tsx should use the `@/` alias instead
of relative paths. Update the DomainDirectionPage and OverallDirectionPage
imports in the adapter module to reference their locations through `@/` so they
follow the packages/web/src path-alias guideline and stay consistent with the
rest of the codebase.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx`:
- Line 9: The local panel import in DomainDirectionPage should use the
configured web source alias instead of a relative path. Update the
DirectionPanel import to come through the `@/` alias so it matches the
packages/web/src convention and keeps imports consistent across the web
codebase.
- Line 1: Remove the useMemo wrapper around the scoring calculations in
DomainDirectionPage and let the values be computed directly during render, since
they are pure derived values and the package guideline prefers React Compiler
memoization. Also drop the useMemo import from the component if it is no longer
used, and keep the existing scoring logic/identifiers intact so the calculations
remain functionally the same.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx`:
- Line 5: The local panel import in OverallDirectionPage should use the web
source alias instead of a relative path. Update the DirectionPanel import to
follow the project’s `@/` alias convention for `packages/web/src/**/*.{ts,tsx}`,
keeping the component reference the same while changing only the import source
path.
- Line 1: Remove the manual memoization from OverallDirectionPage by dropping
the useMemo import and any useMemo wrapping around the overall scoring logic,
since the React Compiler should handle memoization here. Update the component to
compute the score directly in OverallDirectionPage (and any related scoring
helpers in the same block) without useMemo/useCallback, keeping the existing
behavior unchanged while following the packages/web coding guideline.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 64809555-21f2-4a8a-993c-0305f70cbbcd
📒 Files selected for processing (40)
packages/shared/README.mdpackages/shared/src/checklists/__tests__/robins-i.test.tspackages/shared/src/checklists/amstar2/score.tspackages/shared/src/checklists/robins-i/answers-schema.tspackages/shared/src/checklists/robins-i/answers.tspackages/shared/src/checklists/robins-i/create.tspackages/shared/src/checklists/robins-i/schema.tspackages/shared/src/checklists/robins-i/scoring.tspackages/shared/src/checklists/types.tspackages/shared/src/errors/types.tspackages/web/e2e/robins-i-workflow.spec.tspackages/web/e2e/shared-steps.tspackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/checklist/ROBINSIChecklist/__tests__/robins-scoring.test.tspackages/web/src/components/checklist/ROBINSIChecklist/scoring/robins-scoring.tspackages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainJudgementPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallJudgementPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/panels/JudgementPanel.tsxpackages/web/src/lib/export-pdf.tspackages/web/src/lib/inter-rater-reliability.tspackages/web/src/primitives/useProject/checklists/handlers/robins-i.tspackages/web/src/primitives/useProject/reactor/migrate.test.tspackages/web/src/primitives/useProject/reactor/migrate.tspackages/web/src/primitives/useProject/reconciliation.tspackages/web/src/project/connectionReducer.tspackages/web/src/routeTree.gen.tspackages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsxpackages/web/src/server/functions/billing.server.tspackages/web/src/server/guards/requireProjectAccess.tspackages/workers/src/durable-objects/__tests__/UserSession.test.tspackages/workers/worker-configuration.d.ts
💤 Files with no reviewable changes (9)
- packages/web/src/primitives/useProject/checklists/handlers/robins-i.ts
- packages/web/src/components/checklist/ROBINSIChecklist/scoring/robins-scoring.ts
- packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallJudgementPage.tsx
- packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainJudgementPage.tsx
- packages/web/src/components/project/reconcile-tab/robins-i-reconcile/panels/JudgementPanel.tsx
- packages/web/src/primitives/useProject/reactor/migrate.ts
- packages/shared/src/checklists/robins-i/create.ts
- packages/shared/src/checklists/robins-i/answers-schema.ts
- packages/web/src/components/checklist/ROBINSIChecklist/tests/robins-scoring.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: checks
🧰 Additional context used
📓 Path-based instructions (8)
**/*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*: NEVER use emojis anywhere - not in code, comments, documentation, plan files, commit messages, or examples. This includes unicode symbols.
Never use emojis or unicode symbols - not in code, comments, docs, or commits
Files:
packages/shared/src/checklists/robins-i/schema.tspackages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsxpackages/workers/src/durable-objects/__tests__/UserSession.test.tspackages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/server/functions/billing.server.tspackages/web/src/primitives/useProject/reactor/migrate.test.tspackages/web/src/server/guards/requireProjectAccess.tspackages/web/src/project/connectionReducer.tspackages/web/src/primitives/useProject/reconciliation.tspackages/shared/README.mdpackages/shared/src/checklists/amstar2/score.tspackages/shared/src/checklists/__tests__/robins-i.test.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/shared/src/errors/types.tspackages/web/src/lib/inter-rater-reliability.tspackages/shared/src/checklists/robins-i/answers.tspackages/web/e2e/shared-steps.tspackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/lib/export-pdf.tspackages/web/e2e/robins-i-workflow.spec.tspackages/shared/src/checklists/types.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/shared/src/checklists/robins-i/scoring.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsxpackages/workers/worker-configuration.d.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For UI icons, use
lucide-reactlibrary or SVGs only (never emojis)
Files:
packages/shared/src/checklists/robins-i/schema.tspackages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsxpackages/workers/src/durable-objects/__tests__/UserSession.test.tspackages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/server/functions/billing.server.tspackages/web/src/primitives/useProject/reactor/migrate.test.tspackages/web/src/server/guards/requireProjectAccess.tspackages/web/src/project/connectionReducer.tspackages/web/src/primitives/useProject/reconciliation.tspackages/shared/src/checklists/amstar2/score.tspackages/shared/src/checklists/__tests__/robins-i.test.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/shared/src/errors/types.tspackages/web/src/lib/inter-rater-reliability.tspackages/shared/src/checklists/robins-i/answers.tspackages/web/e2e/shared-steps.tspackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/lib/export-pdf.tspackages/web/e2e/robins-i-workflow.spec.tspackages/shared/src/checklists/types.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/shared/src/checklists/robins-i/scoring.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsxpackages/workers/worker-configuration.d.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx,js,jsx}: Use import aliases from tsconfig.json
Code comments should explain why something is being done or provide context, not repeat what the code is saying
Use TODO(agent) pattern for incomplete work or flagging items for future attention, with brief description and optional doc reference
Files:
packages/shared/src/checklists/robins-i/schema.tspackages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsxpackages/workers/src/durable-objects/__tests__/UserSession.test.tspackages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/server/functions/billing.server.tspackages/web/src/primitives/useProject/reactor/migrate.test.tspackages/web/src/server/guards/requireProjectAccess.tspackages/web/src/project/connectionReducer.tspackages/web/src/primitives/useProject/reconciliation.tspackages/shared/src/checklists/amstar2/score.tspackages/shared/src/checklists/__tests__/robins-i.test.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/shared/src/errors/types.tspackages/web/src/lib/inter-rater-reliability.tspackages/shared/src/checklists/robins-i/answers.tspackages/web/e2e/shared-steps.tspackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/lib/export-pdf.tspackages/web/e2e/robins-i-workflow.spec.tspackages/shared/src/checklists/types.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/shared/src/checklists/robins-i/scoring.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsxpackages/workers/worker-configuration.d.ts
packages/web/src/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/web/src/**/*.{tsx,ts}: Use lucide-react for the icon library
Use TanStack Query for server state management (useQuery,useMutation)
Import Zustand stores directly from@/stores/instead of prop-drilling shared state
AvoiduseMemooruseCallback- let the React Compiler handle memoization
Prefer newer React primitives where possible, always on the latest version
UseuseEffectEventfor stable event handler references inside effects
UseuseLayoutEffectfor DOM measurements before paint
UsestartTransition/useTransitionfor non-urgent state updates
UseuseDeferredValuefor deferring expensive re-renders
UseuseSyncExternalStorefor external store subscriptions (e.g., Yjs awareness)
UseuseId()for unique IDs on form elements (radio buttons, checkboxes)
Never prop-drill shared state - import Zustand stores directly
Files:
packages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsxpackages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/server/functions/billing.server.tspackages/web/src/primitives/useProject/reactor/migrate.test.tspackages/web/src/server/guards/requireProjectAccess.tspackages/web/src/project/connectionReducer.tspackages/web/src/primitives/useProject/reconciliation.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/lib/inter-rater-reliability.tspackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/lib/export-pdf.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsx
packages/web/src/routes/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use TanStack Router with file-based routing (
createFileRoute)
Files:
packages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsx
packages/web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Path aliases:
@/maps topackages/web/src/
Files:
packages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsxpackages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/server/functions/billing.server.tspackages/web/src/primitives/useProject/reactor/migrate.test.tspackages/web/src/server/guards/requireProjectAccess.tspackages/web/src/project/connectionReducer.tspackages/web/src/primitives/useProject/reconciliation.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/lib/inter-rater-reliability.tspackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/lib/export-pdf.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsx
packages/workers/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/workers/**/*.{ts,tsx}: Use Zod for schema and input validation (backend)
Use Drizzle ORM for ALL database interactions and migrations
Use Better-Auth for authentication and user management
Never bypass Drizzle for database access
Files:
packages/workers/src/durable-objects/__tests__/UserSession.test.tspackages/workers/worker-configuration.d.ts
packages/web/src/components/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use shadcn/ui for UI components (Radix-based, in
@/components/ui/)
Files:
packages/web/src/components/dashboard/LocalAppraisalsSection.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsxpackages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsx
🪛 ast-grep (0.44.0)
packages/web/e2e/robins-i-workflow.spec.ts
[warning] 43-43: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(outcome, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
[warning] 43-43: Do not use variable for regular expressions
Context: new RegExp(outcome, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.
(regexp-non-literal-typescript)
🔇 Additional comments (49)
packages/web/src/routes/_app/_protected/admin/billing.stuck-states.tsx (1)
87-88: LGTM!packages/workers/src/durable-objects/__tests__/UserSession.test.ts (1)
106-106: LGTM!packages/web/src/components/dashboard/LocalAppraisalsSection.tsx (1)
130-131: LGTM!packages/web/src/server/functions/billing.server.ts (1)
458-459: LGTM!packages/shared/src/errors/types.ts (1)
39-44: LGTM!packages/web/src/lib/export-pdf.ts (1)
348-348: LGTM!Also applies to: 529-529, 545-545
packages/web/src/server/guards/requireProjectAccess.ts (1)
18-19: LGTM!packages/web/src/project/connectionReducer.ts (1)
5-6: LGTM!packages/web/src/primitives/useProject/reconciliation.ts (3)
115-116: LGTM!
171-172: LGTM!
235-236: LGTM!packages/shared/README.md (1)
254-255: LGTM!packages/shared/src/checklists/amstar2/score.ts (1)
70-71: LGTM!packages/web/src/lib/inter-rater-reliability.ts (1)
37-38: LGTM!packages/workers/worker-configuration.d.ts (18)
193-194: LGTM!
688-689: LGTM!
920-921: LGTM!
1984-1985: LGTM!
3740-3743: LGTM!
4609-4610: LGTM!
4637-4638: LGTM!
4748-4749: LGTM!
5080-5081: LGTM!
5268-5269: LGTM!
6566-6567: LGTM!
7363-7364: LGTM!
10285-10292: LGTM!
11108-11109: LGTM!
11611-11612: LGTM!
12394-12395: LGTM!
12598-12599: LGTM!
13716-13717: LGTM!packages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.ts (1)
17-21: LGTM!Also applies to: 31-48, 115-116, 134-155, 235-240
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsx (1)
168-177: LGTM!packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx (1)
11-61: LGTM!Also applies to: 96-174
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx (1)
7-51: LGTM!Also applies to: 77-152
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsx (1)
5-7: LGTM!Also applies to: 68-80, 226-234, 250-250, 266-266, 340-360, 373-388
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsx (1)
46-50: LGTM!Also applies to: 65-69, 77-102, 214-216
packages/shared/src/checklists/types.ts (1)
88-88: LGTM!Also applies to: 101-105, 151-154
packages/shared/src/checklists/robins-i/schema.ts (1)
582-582: LGTM!packages/shared/src/checklists/robins-i/scoring.ts (1)
84-86: LGTM!Also applies to: 96-97, 111-137
packages/shared/src/checklists/robins-i/answers.ts (1)
186-201: LGTM!packages/shared/src/checklists/__tests__/robins-i.test.ts (1)
8-31: LGTM!Also applies to: 181-200
packages/web/e2e/robins-i-workflow.spec.ts (1)
4-7: LGTM!Also applies to: 20-43, 45-174
packages/web/e2e/shared-steps.ts (1)
59-136: LGTM!packages/web/src/primitives/useProject/reactor/migrate.test.ts (1)
399-404: LGTM!packages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsx (1)
35-55: LGTM!Also applies to: 90-91
packages/web/src/components/checklist/ROBINSIChecklist/OverallSection.tsx (1)
14-25: LGTM!Also applies to: 68-72, 81-97, 106-117
packages/web/src/components/checklist/ROBINSIChecklist/ScoringSummary.tsx (1)
113-140: LGTM!
| <DomainJudgement | ||
| domainId={domainKey} | ||
| judgement={autoJudgement} | ||
| direction={direction} | ||
| onJudgementChange={() => {}} | ||
| onDirectionChange={handleDirectionChange} | ||
| showDirection={true} | ||
| isDomain1={domainKey === 'domain1a' || domainKey === 'domain1b'} | ||
| disabled={disabled} | ||
| isAutoMode={true} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Do not leave inert judgement buttons in the read-only section.
DomainJudgement still renders the full judgement button row, so passing a no-op onJudgementChange leaves focusable controls that look enabled but cannot do anything. That conflicts with the new display-only contract. Please hide or disable just the judgement row here and keep only the direction controls editable.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsx`
around lines 140 - 149, The read-only DomainSection still renders interactive
judgement buttons through DomainJudgement by passing a no-op onJudgementChange,
which leaves inert focusable controls. Update the DomainSection usage of
DomainJudgement so the judgement row is hidden or disabled in display-only mode
while preserving the editable direction controls via handleDirectionChange and
the existing direction props. Use the DomainJudgement component’s
judgement-related props and rendering logic to enforce the new display-only
contract instead of relying on an empty callback.
…finityBowman/corates into robins-remove-manual-override
…finityBowman/corates into robins-remove-manual-override
…nore routetree.gen.ts
…finityBowman/corates into robins-remove-manual-override
Apply CodeRabbit feedback from PR #522, fixing both ROBINS-I and the ROB-2 mirror files (the same patterns exist on both sides since this PR aligned them): - DomainJudgement: disable the read-only judgement buttons in auto mode so they are no longer inert-but-clickable (ROBINS-I; ROB-2 already did) - adapter: Use This / autofill now copies a reviewer's direction even when unset, so adopting a "Not set" reviewer clears stale final data - navbar-utils: add hasNavItemValue for visual answered indicators, keeping hasNavItemAnswer for non-blocking completion gating, so an unset optional direction no longer renders as filled - direction pages: header agreement status keyed on directionMatch only, consistent with the nav pills and summary - e2e: escape outcome text before building the option locator regex
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx (1)
62-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove the manual memoization for derived scoring.
These values are cheap render-time derivations, and this package's React guideline prefers relying on the React Compiler over
useMemo. A plain assignment keeps this page consistent with the repo standard.As per coding guidelines, "Avoid useMemo or useCallback - let the React Compiler handle memoization."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx` around lines 62 - 72, The three scoring values in DomainDirectionPage are simple derived computations, so remove the manual useMemo wrappers around reviewer1Scoring, reviewer2Scoring, and finalScoring. Replace them with plain assignments that call scoreRobinsDomain directly, keeping the same inputs (domainKey and the corresponding answers) so the page follows the repo guideline of letting the React Compiler handle memoization.Source: Coding guidelines
packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx (1)
52-54: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDrop the
useMemowrappers around the overall scoring.This is derived render data, and the web-package guideline prefers the React Compiler over manual memoization here. Using direct assignments will keep the component aligned with the repo standard.
As per coding guidelines, "Avoid useMemo or useCallback - let the React Compiler handle memoization."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx` around lines 52 - 54, Remove the manual useMemo wrappers in OverallDirectionPage and assign the results of scoreAllDomains(checklist1), scoreAllDomains(checklist2), and scoreAllDomains(finalChecklist) directly to reviewer1Scoring, reviewer2Scoring, and finalScoring. Keep the scoring logic in the same component, but rely on the React Compiler instead of explicit memoization.Source: Coding guidelines
packages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsx (1)
181-200: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRemove these
useMemowrappers.These values are cheap to derive, and this package's React guidance explicitly asks not to use
useMemooruseCallbackhere. Inline them and let the React Compiler handle memoization. As per coding guidelines, "AvoiduseMemooruseCallback- let the React Compiler handle memoization".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsx` around lines 181 - 200, Remove the unnecessary useMemo wrappers in NavbarDomainPill by computing pillStyle and tooltip inline instead of memoizing them. The logic in the pillStyle and tooltip derivations is cheap and should follow the package React guidance to avoid useMemo/useCallback, so keep the same conditional behavior but assign the values directly within the component body.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsx`:
- Around line 188-200: The tooltip fallback in NavbarDomainPill is treating
unset direction pills as mandatory work by showing "Needs reconciliation" for
optional fields. Update the tooltip logic in the useMemo block to special-case
DOMAIN_DIRECTION and OVERALL_DIRECTION so when they are unset and reviewers
differ, the status reads as optional/not set instead of needing reconciliation.
Keep the existing behavior for other item types and preserve the current
branches for isSkipped, hasValue, and agreement.
---
Nitpick comments:
In
`@packages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsx`:
- Around line 181-200: Remove the unnecessary useMemo wrappers in
NavbarDomainPill by computing pillStyle and tooltip inline instead of memoizing
them. The logic in the pillStyle and tooltip derivations is cheap and should
follow the package React guidance to avoid useMemo/useCallback, so keep the same
conditional behavior but assign the values directly within the component body.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsx`:
- Around line 62-72: The three scoring values in DomainDirectionPage are simple
derived computations, so remove the manual useMemo wrappers around
reviewer1Scoring, reviewer2Scoring, and finalScoring. Replace them with plain
assignments that call scoreRobinsDomain directly, keeping the same inputs
(domainKey and the corresponding answers) so the page follows the repo guideline
of letting the React Compiler handle memoization.
In
`@packages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsx`:
- Around line 52-54: Remove the manual useMemo wrappers in OverallDirectionPage
and assign the results of scoreAllDomains(checklist1),
scoreAllDomains(checklist2), and scoreAllDomains(finalChecklist) directly to
reviewer1Scoring, reviewer2Scoring, and finalScoring. Keep the scoring logic in
the same component, but rely on the React Compiler instead of explicit
memoization.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ad9fb220-9d09-4f5d-b16f-b89eda14226a
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (22)
.prettierignoreknip.config.tspackages/shared/src/checklists/rob2/schema.tspackages/web/e2e/rob2-workflow.spec.tspackages/web/e2e/robins-i-workflow.spec.tspackages/web/e2e/shared-steps.tspackages/web/package.jsonpackages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/vite.config.e2e.tspackages/web/vite.config.ts
💤 Files with no reviewable changes (3)
- knip.config.ts
- packages/shared/src/checklists/rob2/schema.ts
- packages/web/package.json
✅ Files skipped from review due to trivial changes (1)
- .prettierignore
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/web/src/components/project/reconcile-tab/robins-i-reconcile/RobinsISummaryView.tsx
- packages/web/src/components/project/reconcile-tab/robins-i-reconcile/adapter.tsx
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: checks
🧰 Additional context used
📓 Path-based instructions (6)
**/*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*: NEVER use emojis anywhere - not in code, comments, documentation, plan files, commit messages, or examples. This includes unicode symbols.
Never use emojis or unicode symbols - not in code, comments, docs, or commits
Files:
packages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/e2e/rob2-workflow.spec.tspackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/vite.config.tspackages/web/e2e/shared-steps.tspackages/web/vite.config.e2e.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/e2e/robins-i-workflow.spec.ts
**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For UI icons, use
lucide-reactlibrary or SVGs only (never emojis)
Files:
packages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/e2e/rob2-workflow.spec.tspackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/vite.config.tspackages/web/e2e/shared-steps.tspackages/web/vite.config.e2e.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/e2e/robins-i-workflow.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx,js,jsx}: Use import aliases from tsconfig.json
Code comments should explain why something is being done or provide context, not repeat what the code is saying
Use TODO(agent) pattern for incomplete work or flagging items for future attention, with brief description and optional doc reference
Files:
packages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/e2e/rob2-workflow.spec.tspackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/vite.config.tspackages/web/e2e/shared-steps.tspackages/web/vite.config.e2e.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.tspackages/web/e2e/robins-i-workflow.spec.ts
packages/web/src/components/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use shadcn/ui for UI components (Radix-based, in
@/components/ui/)
Files:
packages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.ts
packages/web/src/**/*.{tsx,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
packages/web/src/**/*.{tsx,ts}: Use lucide-react for the icon library
Use TanStack Query for server state management (useQuery,useMutation)
Import Zustand stores directly from@/stores/instead of prop-drilling shared state
AvoiduseMemooruseCallback- let the React Compiler handle memoization
Prefer newer React primitives where possible, always on the latest version
UseuseEffectEventfor stable event handler references inside effects
UseuseLayoutEffectfor DOM measurements before paint
UsestartTransition/useTransitionfor non-urgent state updates
UseuseDeferredValuefor deferring expensive re-renders
UseuseSyncExternalStorefor external store subscriptions (e.g., Yjs awareness)
UseuseId()for unique IDs on form elements (radio buttons, checkboxes)
Never prop-drill shared state - import Zustand stores directly
Files:
packages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.ts
packages/web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Path aliases:
@/maps topackages/web/src/
Files:
packages/web/src/components/checklist/ROBINSIChecklist/DomainJudgement.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/ROB2SummaryView.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.tspackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/DomainDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsxpackages/web/src/components/project/reconcile-tab/rob2-reconcile/adapter.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/pages/OverallDirectionPage.tsxpackages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.ts
🪛 ast-grep (0.44.0)
packages/web/e2e/robins-i-workflow.spec.ts
[warning] 45-45: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(escapedOutcome, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
[warning] 45-45: Do not use variable for regular expressions
Context: new RegExp(escapedOutcome, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity. Security best practice.
(regexp-non-literal-typescript)
🔇 Additional comments (7)
packages/web/e2e/robins-i-workflow.spec.ts (1)
45-46: Still use an exact-match locator here.Escaping fixed the metacharacter issue, but this regex still matches substrings, so similarly named outcomes can select the wrong option. The previous review already called out anchoring this with
^and$.packages/web/src/components/project/reconcile-tab/robins-i-reconcile/navbar-utils.ts (1)
218-240: LGTM!packages/web/src/components/project/reconcile-tab/rob2-reconcile/navbar-utils.ts (1)
227-265: LGTM!packages/web/src/components/project/reconcile-tab/robins-i-reconcile/NavbarDomainPill.tsx (1)
6-6: LGTM!Also applies to: 155-158, 168-177, 197-197
packages/web/e2e/rob2-workflow.spec.ts (1)
151-152: LGTM!packages/web/e2e/shared-steps.ts (1)
138-154: LGTM!packages/web/vite.config.ts (1)
14-20: 🎯 Functional CorrectnessNo action needed
Follow-up to the value-presence indicator change: an unset direction where reviewers differ was falling through to the "Needs reconciliation" / "Reviewers disagree" tooltip, making an optional field look mandatory. Special-case DOMAIN_DIRECTION and OVERALL_DIRECTION so an unset one reads as "Optional (not set)" in both the ROB-2 pill tooltip and the shared ROBINS-I tooltip helper.
…alog to all three reconcile screens via shared ResourcesDialog with per-tool link configs, show study name in the reconcile header, give nav pills their own full-width header row to fix clipping, exclude pre-domain items (ROB2 preliminary, ROBINS-I Section B) from the agreement rate, port ROB2 pill slide animation to ROBINS-I, and drop judgement-override copy from resources and tool pages after #522
Summary
ROBINS-I let reviewers manually override domain/overall judgements (
judgementSource: 'auto' | 'manual') and reconciled judgements as their own pages. Because an auto judgement was computed-but-not-stored, two reviewers who both left a judgement on auto compared asnull === nullat reconciliation: the UI reported "Reviewers agreed" yet auto-fill no-opped on thenull, leaving the Final Judgement "Not set" and blocking save with no way forward. ROB-2 never hit this because it derives judgements and has no judgement reconciliation pages.This PR aligns ROBINS-I with ROB-2: judgements are always derived from the signalling answers, and only direction is reconciled.
Changes
Checklist editor — judgement display-only, direction stays editable:
DomainSection.tsx,OverallSection.tsx: removed the Auto/Manual toggle,judgementSource, and manual-override handlers.ScoringSummary.tsx: dropped the manual*indicator.Data model —
judgementSourceremoved everywhere:types.ts,create.ts,answers-schema.ts,scoring.ts(getEffectiveDomainJudgementdeleted,scoreAllDomainssimplified), handler, andmigrate.ts.isROBINSICompletenow derives completion from the answers (it was reading the now-unwritten stored field).Reconciliation — mirrors ROB-2:
DomainDirectionPage/OverallDirectionPage(judgement read-only/derived); deletedDomainJudgementPage,OverallJudgementPage, and the manualJudgementPanel.navbar-utils.ts,adapter.tsx,NavbarDomainPill.tsx,RobinsISummaryView.tsxupdated (judgement nav items -> direction). Direction is non-gating (optional; ROBINS-I has no "not applicable" option, so it can't block save).Tests: updated unit/migration fixtures; the e2e dual-reviewer workflow now passes without manually selecting an agreed judgement, proving the bug is structurally gone.
Breaking change
Any ROBINS-I checklist previously saved with a manual judgement override now shows the derived judgement instead. The stored override is ignored (no migration), per discussion.
Verification
Summary by CodeRabbit