Skip to content

dashboard fixes#68

Merged
mikepsinn merged 9 commits into
mainfrom
feature/treaty-dashboard-pre-may7-layout
May 9, 2026
Merged

dashboard fixes#68
mikepsinn merged 9 commits into
mainfrom
feature/treaty-dashboard-pre-may7-layout

Conversation

@mikepsinn

@mikepsinn mikepsinn commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • CLAUDE.md + AGENTS.md "Wishonia voice" sections now explicitly forbid the patterns that produced the example you flagged: tautological "X is the Y. The Y is the road that produces X" framings, empty mechanism vocabulary (incentive layer, coordination mechanism, primitive, substrate, kernel of, fundamentally/essentially/literally), stack/rails/off-ramp/pipeline metaphors, corporate-blather openers, stacked abstract-noun lists, sweeping "every X" without numbers.
  • Added the read-aloud test: if a sentence could appear unchanged in a Stripe keynote / Y Combinator launch post / LinkedIn thought-leadership comment, rewrite. Wishonia is an alien mildly disappointed in your civilization, not a founder.
  • Fixed the canonical violation in TreatyContent.tsx: "Next: the enforcement stack. The treaty is the off-ramp. The Court is the road that produces the off-ramp." → concrete, stakes-named alternative pointing to the class action with the 102M-deaths frame.
  • TODO.md: queued two follow-ups so we don't re-investigate the same surface twice — (1) finish the neobrutalist → treaty migration with explicit step-by-step (drop pink/cyan/yellow from BrutalCard/SectionContainer bgColor unions, update getCardColor and other dynamic-color functions, delete unused brutal-* CSS vars, collapse the @theme inline redirect block, optional BrutalCardTreatySection rename, delete dead ARCADE_LABELS); (2) copy audit pass with the four already-found offenders listed inline (TreatyContent, TreasuryAllocationViz:160, WishocracyLinkCard:17, ResourcePromoSection:12).

Test plan

  • pnpm --filter @optimitron/web exec tsc --noEmit clean
  • CI: core-validate + web-validate + visual-review pipeline
  • Visual review: /treaty page renders the new copy where the "enforcement stack" block was

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a prominent "Sign the Treaty" action and many new site pages (Donate, Treaty, Vote, Court, Endorse, People, Plaintiffs, Signatories, Tasks, Privacy, Terms, Feedback, Employees).
  • Improvements

    • Updated treaty CTA and home actions; improved navbar/menu accessibility.
    • More robust task date handling and fresher public task fetches.
    • Enhanced visual-review tooling and automated screenshot/copy review generation.
  • Documentation

    • Strengthened copy-quality and voice rules in agent docs.
  • Chores

    • Tightened CI visual-baseline resolution and expanded seeding steps.

mikepsinn and others added 3 commits May 8, 2026 22:15
CLAUDE.md "Wishonia: Voice of the Site" + AGENTS.md "Copy and Voice"
now spell out the patterns to never write: tautological "X is the Y.
The Y is the road that produces X" framings; empty mechanism
vocabulary (incentive layer, coordination mechanism, primitive,
substrate, kernel of, fundamentally/essentially/literally); stack /
rails / off-ramp / pipeline metaphors; corporate-blather openers;
stacked abstract-noun lists; sweeping "every X" without numbers.
Plus the read-aloud test: if it could appear unchanged in a Y
Combinator launch post or Stripe pitch deck, rewrite. Wishonia is an
alien mildly disappointed in your civilization, not a founder.

TreatyContent.tsx: replace the canonical violation that motivated
this rule. "Next: the enforcement stack. The treaty is the off-ramp.
The Court is the road that produces the off-ramp." → "If your
government refuses to sign / Sign the treaty here. If your government
refuses to ratify it, join the class action and sue them for the 102
million people their refusal has killed." Concrete, stakes-named,
zero infrastructure metaphors.

TODO.md: queues two follow-up tasks so we don't re-investigate.
(1) Finish neobrutalist cleanup — drop pink/cyan/yellow from
BrutalCard/SectionContainer bgColor unions, update dynamic
color-returning functions (getCardColor's "yellow"/"cyan"
non-status branches, step.color data, accentColor / metric.tone
props), delete the now-unused brutal-pink/cyan/yellow CSS vars,
collapse the @theme inline redirect block, optionally rename
BrutalCard → TreatySection and ArcadeTag → Eyebrow, delete dead
ARCADE_LABELS dictionary. (2) Copy audit pass — sweep
packages/web/src/ for the new anti-pattern grep terms and rewrite
each surface to concrete-Cunk-deadpan, with the four already-found
offenders (TreatyContent, TreasuryAllocationViz line 160,
WishocracyLinkCard line 17, ResourcePromoSection line 12) listed
explicitly so the audit doesn't need to re-find them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 9, 2026 17:43
@vercel

vercel Bot commented May 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
optimitron-wishonia Ignored Ignored May 9, 2026 9:25pm

@coderabbitai

coderabbitai Bot commented May 9, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@mikepsinn has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 52 minutes and 3 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 79969e8a-a4c6-4dd8-8367-b01efc5fca47

📥 Commits

Reviewing files that changed from the base of the PR and between bbeb336 and 238bd9a.

📒 Files selected for processing (27)
  • packages/data/src/referendums/court-of-humanity.ts
  • packages/db/prisma/migrations/20260509173000_rename_optimize_earth_root_task/migration.sql
  • packages/db/prisma/migrations/20260509223000_add_person_name_fields/migration.sql
  • packages/db/prisma/schema.prisma
  • packages/db/src/zod/index.ts
  • packages/web/next.config.js
  • packages/web/scripts/build-visual-review.mjs
  • packages/web/scripts/render-pages-to-markdown.ts
  • packages/web/src/app/api/people/[id]/route.test.ts
  • packages/web/src/app/api/people/[id]/route.ts
  • packages/web/src/app/api/referendums/[slug]/represented-people/route.test.ts
  • packages/web/src/app/api/referendums/[slug]/represented-people/route.ts
  • packages/web/src/app/court/page.md
  • packages/web/src/app/legal/page.md
  • packages/web/src/app/people/page.md
  • packages/web/src/app/plaintiffs/manage/page.tsx
  • packages/web/src/app/questions/page.md
  • packages/web/src/components/landing/TreatyPostVoteShareFlow.tsx
  • packages/web/src/components/landing/TreatyVoteFlow.tsx
  • packages/web/src/components/people/ManageRepresentedPeopleClient.tsx
  • packages/web/src/components/people/RepresentedPersonConversionForm.tsx
  • packages/web/src/components/people/RepresentedPersonForm.tsx
  • packages/web/src/lib/__tests__/represented-person-sync.test.ts
  • packages/web/src/lib/person-name.ts
  • packages/web/src/lib/prisma.ts
  • packages/web/src/lib/represented-person-sync.ts
  • packages/web/src/lib/storage.ts
📝 Walkthrough

Walkthrough

This PR tightens CI visual-baseline discovery and seeding, adds a safe SQL migration and removes one-shot scripts, introduces page-render tooling and demo-session minting, ignores generated preview files, establishes terse copy-voice constraints, adds route-review metadata and many new Markdown pages, hardens task date handling and accessibility labels, updates Next/webpack externals, and adds pixel-level visual diffing and related tests.

Changes

CI Visual Baseline Resolution

Layer / File(s) Summary
Job Execution Constraint
.github/workflows/ci.yml
web-validate job if: condition now requires non-push event and github.ref == 'refs/heads/main'.
Seed visual data
.github/workflows/ci.yml, packages/db/package.json
Seed step now runs seed:bootstrap, seed:demo, seed:tasks, and db:seed:triggers; packages/db adds seed:tasks script.
Artifact Discovery & Screenshot Path Detection
.github/workflows/ci.yml
Resolve-main-baseline logic downloads each candidate main-run artifact into main-baseline/run-$run_id, probes run_root/screenshots and run_root/packages/web/screenshots, sets VISUAL_BEFORE_ROOT on first match, replaces packages/web/screenshots with PR screenshots, and cleans up per-run directories.
Visual-review ordering & diffing
packages/web/scripts/build-visual-review.mjs
Adds pixel-diffing (pixelmatch/pngjs), env thresholds, expanded routeOrder, route summary pills, and <details> groups that auto-expand changed routes.

Tooling: page previews & scripts

Layer / File(s) Summary
Render pages to Markdown
packages/web/scripts/render-pages-to-markdown.ts
New Playwright TSX script scrapes routes and writes deterministic page.md / page.authed.md files; supports --routes= and authenticated pass using minted demo session cookie.
Mint demo session
packages/web/scripts/mint-demo-session.ts
Adds mintDemoSessionCookie() to create an offline NextAuth session cookie for demo user and CLI output.
Ignore generated previews
.gitignore
Add ignore rule for generated packages/web/src/app/**/page.authed.md preview files.
Package scripts & overrides
package.json, packages/web/package.json
Root adds db:reassign-personal-tasks and adjusts pnpm.overrides; packages/web adds copy:preview, pins import-in-the-middle to 3.0.0, and adds devDeps pixelmatch/pngjs.

DB migration & script removals

Layer / File(s) Summary
Prisma SQL migration
packages/db/prisma/migrations/20260509173000_rename_optimize_earth_root_task/migration.sql
Adds SQL migration to rename legacy root id/key to canonical optimize-earth, handling only-old, both-present, and only-new cases while preserving/reattaching children.
One-shot script removals
packages/web/scripts/rename-optimize-earth-root.ts, packages/db/src/reassign-personal-tasks.ts
Removed two one-shot Prisma scripts (rename-optimize-earth-root and reassign-personal-tasks); logic replaced by SQL migration or removed.

Copy voice & campaign tracking

Layer / File(s) Summary
Copy voice rules
AGENTS.md, CLAUDE.md, packages/web/AGENTS.md
Add terse editing constraints and explicit "No startup-bro copy" anti-pattern banning infrastructure metaphors, empty mechanism vocabulary, and corporate openers; refine web screenshot-review layout and coverage guidance.
Campaign TODO & copy-audit
TODO.md
Record that optimize-earth rename is implemented by SQL migration; replace neobrutalist→treaty tracking with concrete remaining cleanup steps and add a grep-based copy-audit task aligned to CLAUDE.md rules.
Parameter/snippet updates
packages/data/src/parameters/parameters-calculations-citations.ts
Update manual page links/titles to questions.html and refresh a shareable-snippet markdown and timestamp.

Web app UI & behavior changes

Layer / File(s) Summary
Treaty CTA & Dashboard
packages/web/src/components/treaty/TreatyContent.tsx, packages/web/src/components/site/TreatyTaskDashboardClient.tsx
Court CTA lead-in changed to “If your government refuses to sign”; paragraph updated to reference signing the treaty and joining a class action; treaty dashboard simplified to inline sections and removed disclosure/action-grid logic.
Navbar accessibility
packages/web/src/components/Navbar.tsx
Add getNavItemAriaLabel helper; set title and aria-label on AvatarButton, quick action, primary and collapsed nav items, and profile/settings links.
Task date handling
packages/web/src/components/tasks/*
Introduce getTaskDate/getTaskDateMs helpers; accept `Date
Routes & site nav
packages/web/src/lib/routes.ts, packages/web/src/lib/site.ts
Add route-review API and flags; change treaty/why/dashboard labels and CTAs (e.g., “Sign the Treaty”, “Check the Math”, “Manage Humanity”); remove readTreatyLink and update nav wiring and home actions to action-focused labels.
Next config externals
packages/web/next.config.js
Server externals narrowed to @optimitron/storage/*, @storacha/*, and pinata/*; multiformats externalization removed in favor of delegating resolution to Node/Storacha; allowed dev origins and outputFileTracingRoot adjusted.
Tests
packages/web/src/lib/__tests__/site.test.ts, packages/web/src/lib/tasks/president-management.test.ts
Add Vitest nav-order test and regression test for selectTreatyPresidentManagementTasks handling legacy root id scenarios.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 A rabbit hopped through CI and prose,
Baselines found where quiet artifacts doze,
Pages scraped to markdown, sessions signed for show,
Dates tamed, navs labeled, migrations sewn just so,
Hop — the repo hums, ready to grow.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/treaty-dashboard-pre-may7-layout

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Updates the project’s “Wishonia voice” documentation to explicitly forbid a set of empty/tautological startup-style writing patterns, replaces a canonical offender in the /treaty CTA copy with concrete stakes, and improves CI behavior around web validation and visual baseline resolution.

Changes:

  • Add explicit “anti-pattern” rules + a read-aloud test to CLAUDE.md and AGENTS.md for user-facing copy.
  • Replace /treaty “enforcement stack / off-ramp” copy with concrete class-action framing in TreatyContent.tsx.
  • Adjust CI so web-validate runs on main pushes and make baseline artifact download more robust; expand TODO tracking for remaining migration/copy-audit work.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
TODO.md Updates/expands queued cleanup tasks (migration cleanup + copy audit follow-ups).
packages/web/src/components/treaty/TreatyContent.tsx Rewrites the Court CTA copy on /treaty to remove the tautological metaphor and name concrete stakes.
CLAUDE.md Adds a detailed anti-pattern blacklist + “read-aloud” test for Wishonia voice.
AGENTS.md Mirrors the anti-pattern blacklist + test in agent-facing copy rules.
.github/workflows/ci.yml Runs web-validate on main pushes and improves main-baseline artifact extraction logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/web/src/components/treaty/TreatyContent.tsx Outdated
Comment thread TODO.md Outdated
Comment thread CLAUDE.md Outdated
Comment thread AGENTS.md Outdated
Comment thread CLAUDE.md Outdated
Comment thread AGENTS.md Outdated
@claude

claude Bot commented May 9, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@mikepsinn mikepsinn changed the title Voice docs: anti-startup-bro rule + canonical fix dashboard fixes May 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)

203-209: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don’t require the entire main workflow run to be success when hunting for a visual baseline.

This query ignores any main run where web-validate produced a valid web-visual-review artifact but a later job in the same workflow failed, notably deploy-production. In that case PRs silently lose their freshest before-screenshots even though the baseline artifact exists.

Suggested fix
           mapfile -t run_ids < <(gh run list \
             --workflow CI \
             --branch main \
-            --status success \
             --limit 20 \
-            --json databaseId \
-            --jq '.[].databaseId')
+            --json databaseId,status,conclusion \
+            --jq '.[] | select(.status == "completed") | .databaseId')

Then keep relying on gh run download ... --name web-visual-review as the real proof that a usable baseline exists.

🤖 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 @.github/workflows/ci.yml around lines 203 - 209, The current gh run list
call in the mapfile (mapfile -t run_ids < <(gh run list --workflow CI --branch
main --status success --limit 20 --json databaseId --jq '.[].databaseId'))
filters only fully successful workflow runs and thus skips runs that produced a
usable web-visual-review artifact but later failed (e.g., deploy-production);
remove the strict --status success filter (or replace it with --status
completed) so you still collect candidate run IDs, then continue to rely on the
subsequent gh run download --name web-visual-review check to determine whether a
usable baseline artifact actually exists.
🤖 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/treaty/TreatyContent.tsx`:
- Around line 97-99: The inline sentence "Sign the treaty here..." should be
gated on the component prop showInlineSign (in TreatyContent.tsx) so it only
appears when showInlineSign is true; update the JSX around the sentence to
conditionally render it (or alternatively change the copy to reference the
visible "court" button when showInlineSign is false), ensuring you modify the
render that uses showInlineSign and the specific text node so users aren't
instructed to "sign here" when no inline sign control exists.

In `@TODO.md`:
- Around line 896-899: Edit the TODO.md "Confirmed offenders" list to remove or
mark fixed the entry for the TreatyContent component: locate the bullet
referencing TreatyContent (the TreatyContent.tsx offender) in the confirmed
offenders section and either delete that line or append a clear "(fixed)" note
so the audit won't flag it after this PR merges; commit the update so the TODO
reflects the rewritten copy.

---

Outside diff comments:
In @.github/workflows/ci.yml:
- Around line 203-209: The current gh run list call in the mapfile (mapfile -t
run_ids < <(gh run list --workflow CI --branch main --status success --limit 20
--json databaseId --jq '.[].databaseId')) filters only fully successful workflow
runs and thus skips runs that produced a usable web-visual-review artifact but
later failed (e.g., deploy-production); remove the strict --status success
filter (or replace it with --status completed) so you still collect candidate
run IDs, then continue to rely on the subsequent gh run download --name
web-visual-review check to determine whether a usable baseline artifact actually
exists.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6c876724-1ce3-44f3-852b-5b93c65a3fe6

📥 Commits

Reviewing files that changed from the base of the PR and between 7a3029e and 8f71cc3.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • AGENTS.md
  • CLAUDE.md
  • TODO.md
  • packages/web/src/components/treaty/TreatyContent.tsx

Comment thread packages/web/src/components/treaty/TreatyContent.tsx Outdated
Comment thread TODO.md Outdated
@github-actions

github-actions Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Visual review

Start with the browser gallery for a quick before/after pass over every captured route. Use the visual diff link for changed-only review when Argos is available. The downloadable artifact is the fallback copy of packages/web/output/playwright/review/latest.html.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (1)
packages/web/src/app/tasks/[id]/page.tsx (1)

321-343: ⚡ Quick win

Run anonymous Wishonia lookup concurrently with public page fetch.

In the anonymous path, getWishoniaUserId() currently waits for getPublicTaskPageData(id) to finish. Running them together removes avoidable latency.

Proposed refactor
   const session = await getServerSession(authOptions);
   const userId = session?.user.id ?? null;
-  const publicPageData = userId
-    ? null
-    : await getPublicTaskPageData(id);
+  const [publicPageData, publicWishoniaUserId] = userId
+    ? [null, null]
+    : await Promise.all([
+        getPublicTaskPageData(id),
+        getWishoniaUserId().catch(() => null),
+      ]);
   const [data, commentFeed, activityTimeline, wishoniaUserId, ancestors, viewerIsAdmin] =
     userId
       ? await Promise.all([
@@
       : [
           publicPageData?.data ?? null,
           publicPageData?.commentFeed ?? { comments: [], total: 0 },
           publicPageData?.activityTimeline ?? [],
-          await getWishoniaUserId().catch(() => null),
+          publicWishoniaUserId,
           publicPageData?.ancestors ?? [],
           false,
         ];
🤖 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/app/tasks/`[id]/page.tsx around lines 321 - 343, The
anonymous branch currently awaits getPublicTaskPageData(id) before calling
getWishoniaUserId(), adding unnecessary latency; change the anonymous path to
run getPublicTaskPageData(id) and getWishoniaUserId() concurrently (e.g., start
both Promises and await Promise.all) and then build publicPageData, commentFeed,
activityTimeline, wishoniaUserId, ancestors, and viewerIsAdmin from the settled
results; update references to publicPageData and wishoniaUserId accordingly so
the same values are used when assembling the array.
🤖 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/db/prisma/migrations/20260509173000_rename_optimize_earth_root_task/migration.sql`:
- Around line 41-52: The migration soft-deletes the old Task root by setting
"deletedAt" on the row identified by old_id/new_id in the "Task" table, but that
does not trigger ON DELETE behavior on FK constraints so dependent tables will
still reference old_id; update all dependent FK columns (e.g., TaskClaim.taskId,
TaskComment.taskId, TaskDependency.[taskId/dependsOnId],
ReferralInvitation.taskId, ShareAttempt.taskId, and any other tables referencing
Task.id) to point to new_id or NULL as appropriate before or after moving
children (the UPDATE that sets "parentTaskId" = new_id), or explicitly
delete/clean up those dependent rows if desired, and ensure "updatedAt" is
adjusted; locate the logic around old_id/new_id and the two UPDATEs on "Task"
and add corresponding UPDATE/DELETE statements for each dependent table to
prevent dangling references.

In `@packages/web/next.config.js`:
- Around line 32-34: The serverExternalPackages array currently lists only
"@storacha/client" and "pinata" but omits "@optimitron/storage", causing
Turbopack to attempt bundling it; update the serverExternalPackages array (the
variable named serverExternalPackages) to include "@optimitron/storage" so
Turbopack externalizes it the same way webpack does, ensuring the turbopack: {
root: ... } config and the existing webpack server-side externalization logic
remain consistent with the webpack-only node: fallback handling.

In `@packages/web/scripts/render-pages-to-markdown.ts`:
- Around line 120-137: The loop over routes that calls extractPage and writes
files currently logs failures but still exits zero; introduce a failure tracker
(e.g., a boolean or counter like hadFailures) in the render-pages-to-markdown
script, set it to true whenever the catch block for the routes loop (the block
handling extractPage/routeToFilePath/writeFile) catches an error, and after the
loop (and likewise after the second similar loop around lines 143–146) throw an
Error or call process.exit(1) when hadFailures is true so the process returns a
non-zero status; update the catch blocks that build message from err to also set
the tracker when an error occurs.
- Around line 58-66: The parseRoutesFromArgs output can contain path traversal
segments (e.g., "../../") that are later used to build output file paths; to
fix, when mapping routes into output file locations (the code that joins routes
with APP_DIR in render-pages-to-markdown.ts), normalize and resolve each route
against APP_DIR (use path.normalize/path.resolve or path.join(APP_DIR, route)
then path.resolve) and verify the resolved path has APP_DIR as its prefix (e.g.,
check path.relative(APP_DIR, resolvedPath) does not start with ".."); reject or
strip routes that fail this check so no write occurs outside APP_DIR. Ensure
this validation is applied wherever parseRoutesFromArgs results are consumed
(referencing parseRoutesFromArgs, APP_DIR, and DEFAULT_ROUTES).

In `@packages/web/src/components/tasks/ProgramTaskSection.tsx`:
- Around line 41-45: Extract the duplicated date parsing/formatting helpers into
a shared module (e.g., packages/web/src/lib/tasks/task-dates.ts) and replace
local implementations: move logic for getTaskDateMs, getTaskDate (or
getTaskDateMs's Date-returning variant), formatDueDate (and any task-specific
formatters used in task-row.tsx and task-card.tsx) into exported functions like
getTaskDate, getTaskDateMs, formatTaskDueDate, formatTaskCompletedDate; then
update ProgramTaskSection.tsx, task-row.tsx, and task-card.tsx to import those
functions instead of their local duplicates so all three files call the single
canonical implementations (referencing the existing symbols getTaskDateMs,
getTaskDate, and formatDueDate when locating where to replace).
- Around line 41-45: Add unit tests for the date-parsing helpers getTaskDateMs
and getTaskDate to cover all branches: input null and undefined should return
null; valid Date input should return the Date / timestamp; valid ISO date string
should parse to the same Date / timestamp; invalid date strings and Invalid Date
objects should return null. Use your project's test runner (vitest) to create
tests that assert getTaskDate returns null/Date and getTaskDateMs returns
null/number for the cases above, including explicit checks for timestamp
equality for ISO strings and Date inputs.

---

Nitpick comments:
In `@packages/web/src/app/tasks/`[id]/page.tsx:
- Around line 321-343: The anonymous branch currently awaits
getPublicTaskPageData(id) before calling getWishoniaUserId(), adding unnecessary
latency; change the anonymous path to run getPublicTaskPageData(id) and
getWishoniaUserId() concurrently (e.g., start both Promises and await
Promise.all) and then build publicPageData, commentFeed, activityTimeline,
wishoniaUserId, ancestors, and viewerIsAdmin from the settled results; update
references to publicPageData and wishoniaUserId accordingly so the same values
are used when assembling the array.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 32134807-06dd-4cbb-af39-1bd611597789

📥 Commits

Reviewing files that changed from the base of the PR and between 8f71cc3 and 4a5b8a1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (29)
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • CLAUDE.md
  • TODO.md
  • package.json
  • packages/data/src/parameters/parameters-calculations-citations.ts
  • packages/db/package.json
  • packages/db/prisma/migrations/20260509173000_rename_optimize_earth_root_task/migration.sql
  • packages/db/src/reassign-personal-tasks.ts
  • packages/web/AGENTS.md
  • packages/web/e2e/visual-regression.spec.ts
  • packages/web/next.config.js
  • packages/web/package.json
  • packages/web/scripts/build-visual-review.mjs
  • packages/web/scripts/rename-optimize-earth-root.ts
  • packages/web/scripts/render-pages-to-markdown.ts
  • packages/web/src/app/tasks/[id]/page.tsx
  • packages/web/src/components/Navbar.tsx
  • packages/web/src/components/site/TreatyTaskDashboardClient.tsx
  • packages/web/src/components/tasks/ProgramTaskSection.tsx
  • packages/web/src/components/tasks/task-card.tsx
  • packages/web/src/components/tasks/task-row.tsx
  • packages/web/src/components/treaty/TreatyContent.tsx
  • packages/web/src/lib/__tests__/site.test.ts
  • packages/web/src/lib/routes.ts
  • packages/web/src/lib/site.ts
  • packages/web/src/lib/tasks/president-management.test.ts
  • packages/web/src/lib/tasks/president-management.ts
💤 Files with no reviewable changes (2)
  • packages/db/src/reassign-personal-tasks.ts
  • packages/web/scripts/rename-optimize-earth-root.ts
✅ Files skipped from review due to trivial changes (8)
  • packages/db/package.json
  • .gitignore
  • packages/web/src/lib/tasks/president-management.test.ts
  • packages/web/src/components/treaty/TreatyContent.tsx
  • AGENTS.md
  • packages/data/src/parameters/parameters-calculations-citations.ts
  • CLAUDE.md
  • TODO.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci.yml

Comment thread packages/web/next.config.js
Comment thread packages/web/scripts/render-pages-to-markdown.ts Outdated
Comment thread packages/web/scripts/render-pages-to-markdown.ts
Comment thread packages/web/src/components/tasks/ProgramTaskSection.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (1)
packages/web/e2e/utils/static-pages.ts (1)

16-24: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Inconsistent fallback and hardcoded host string.

The function returns "127.0.0.1:3001" when BASE_URL is unset but returns null when BASE_URL is set to an invalid URL. For consistency, both error conditions should fall back to the same default. Additionally, the hardcoded host string should be extracted to a named constant.

🔧 Proposed fix for consistent fallback and DRY
+const DEFAULT_SMOKE_TEST_HOST = "127.0.0.1:3001";
+
 function getSmokeTestHost() {
-  if (!process.env.BASE_URL) return "127.0.0.1:3001";
+  if (!process.env.BASE_URL) return DEFAULT_SMOKE_TEST_HOST;
 
   try {
     return new URL(process.env.BASE_URL).host;
   } catch {
-    return null;
+    return DEFAULT_SMOKE_TEST_HOST;
   }
 }

Based on learnings, port 3001 on 127.0.0.1 is the canonical local web server for this repository.

🤖 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/e2e/utils/static-pages.ts` around lines 16 - 24, Extract the
hardcoded host "127.0.0.1:3001" into a named constant (e.g.,
DEFAULT_SMOKE_TEST_HOST) and update getSmokeTestHost to return that constant
both when process.env.BASE_URL is unset and when new URL(process.env.BASE_URL)
throws; keep function name getSmokeTestHost and the URL parsing logic but change
the catch branch to return DEFAULT_SMOKE_TEST_HOST instead of null so both error
paths use the same fallback.
🧹 Nitpick comments (7)
packages/web/src/lib/routes.ts (3)

712-723: 💤 Low value

Explicit copyPreview: false / screenshot: false overrides on plaintiffsManageLink are correct — flag the spread-then-override pattern for future readers.

Spreading plaintiffsLink brings in copyPreview: true and screenshot: true, which are then explicitly set to false to make the manage page auth-only in the review pipeline. That's intentional and works, but it's easy to miss. A short inline comment ("manage page is auth-only; override public review flags inherited from plaintiffsLink") would save a future maintainer a few minutes.

🤖 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/lib/routes.ts` around lines 712 - 723, The
spread-then-override on plaintiffsManageLink currently resets copyPreview and
screenshot inherited from plaintiffsLink to false for auth-only behavior; add a
brief inline comment above the plaintiffsManageLink declaration (referencing
plaintiffsManageLink and plaintiffsLink and the copyPreview/screenshot fields)
stating: "manage page is auth-only; override public review flags inherited from
plaintiffsLink" so future readers understand why those booleans are explicitly
set to false.

1506-1512: 💤 Low value

href.split(/[?#]/, 1)[0] with limit 1 returns the prefix only when no separators precede content — confirm intent.

String.prototype.split(separator, limit) truncates the result array to limit items but does not change splitting behavior. For href = "/dashboard?ref=foo", this returns ["/dashboard"] (correct). For href = "/", it returns ["/"] (correct). The || ROUTES.home fallback is unreachable given the startsWith("/") guard above, since any /-prefixed href yields a non-empty first chunk. The fallback is harmless but dead — fine to leave for defensiveness.

If you want the fallback to actually mean something, drop the early-return for non-/ hrefs and let the fallback take effect; otherwise this reads cleaner without it.

🤖 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/lib/routes.ts` around lines 1506 - 1512, The function
getReviewPathFromNavItem contains an unreachable fallback "|| ROUTES.home"
because the earlier guard (if (!href.startsWith("/")) return null) guarantees
href.split(/[?#]/, 1)[0] is always a non-empty string for "/"-prefixed values;
remove the redundant fallback so the function simply returns the first split
chunk. Update getReviewPathFromNavItem to keep the existing startsWith("/")
guard and return the href.split(/[?#]/, 1)[0] result directly, referencing the
NavItem.href handling and ROUTES.home only if you later decide to change the
guard semantics.

1450-1494: 💤 Low value

getRouteReviewSpecs skips items with truthy external, but the curated list already excludes externals.

routeReviewNavItems is hand-curated and currently contains no external: true entries. The navItem.external guard at line 1478 is defensive belt-and-suspenders, which is fine, but it duplicates intent already enforced by the list itself. Consider either removing the guard (since the list is the contract) or relaxing the list to allow mixing externals (and let the guard filter them).

Not blocking — current behavior is correct either way.

🤖 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/lib/routes.ts` around lines 1450 - 1494, The
navItem.external check inside getRouteReviewSpecs duplicates the curated
contract of routeReviewNavItems; remove the redundant guard (the "||
navItem.external" condition) from the filter so getRouteReviewSpecs only checks
mode and relies on the curated list, keeping getReviewPathFromNavItem and the
existing name/path construction intact for each navItem (update any tests that
assumed externals were filtered if needed).
packages/web/scripts/build-visual-review.mjs (1)

32-61: 💤 Low value

routeOrder is a hand-maintained list — drifts the moment someone adds a screenshot flag in routes.ts without updating this file.

routeSortIndex returns routeOrder.length for unknown routes, so new routes silently sort to the end. That's a graceful fallback, but it means visual-review ordering and routes.ts review opt-ins will drift over time. Consider deriving routeOrder from getRouteReviewSpecs("screenshot") (and friends) at runtime so the two stay in sync, with the manual list reserved only for the non-nav exceptions (task-optimize-earth, task-one-percent-treaty, task-signer-canada, side-menu, side-menu-auth).

Not blocking — current behavior is correct, just drift-prone.

🤖 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/scripts/build-visual-review.mjs` around lines 32 - 61, The
manual routeOrder array drifts from routes that opt into screenshots; update the
build-visual-review logic so routeOrder is derived at runtime from
getRouteReviewSpecs("screenshot") (and other review types if used) instead of a
hard-coded list: call getRouteReviewSpecs("screenshot"), map to route names in
the same order it returns, then append the explicit-exception names
("task-optimize-earth", "task-one-percent-treaty", "task-signer-canada",
"side-menu", "side-menu-auth") to preserve their custom placement; ensure
routeSortIndex continues to fall back to routeOrder.length for unknown routes.
packages/web/e2e/visual-regression.spec.ts (2)

72-77: ⚡ Quick win

requiredText regression guard freezes exact prose in an E2E — coding guidelines push back on this.

Per the repo's testing rule:

Browser tests should assert behavior, route transitions, data contracts, analytics-critical parameters, accessibility roles, and the presence/absence of coarse UI states. Avoid exact prose, magic-number, or paragraph-level assertions unless the wording itself is the contract being tested. Put exact copy parity in focused unit/doc tests, seeded-template tests, or screenshot review instead.

The intent here (guard a president/signer task list from being silently removed) is legitimate, but the inline comment ("Do not delete without Mike's explicit approval") and the prose assertion are exactly the pattern the guideline says to avoid. Two options that keep the regression guard without freezing copy:

  1. Replace the text match with a structural/role assertion — e.g. await expect(page.getByRole("list", { name: /signer/i })).toBeVisible() or assert that page.getByTestId("signer-task-row") has at least N entries.
  2. Move the prose contract to a focused unit/snapshot test on the page module so the E2E stays behavior-only.

If the wording itself is genuinely the contract being tested, leave a one-liner explaining that and the comment is fine.

As per coding guidelines: "Browser tests should assert behavior, route transitions, data contracts, analytics-critical parameters, accessibility roles, and the presence/absence of coarse UI states. Avoid exact prose, magic-number, or paragraph-level assertions unless the wording itself is the contract being tested."

🤖 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/e2e/visual-regression.spec.ts` around lines 72 - 77, The current
regression guard uses a prose match via route.requiredText and page.getByText
which freezes copy; replace this with a structural/assertion-based check (e.g.,
assert the presence of the signer/president task list via page.getByRole("list",
{ name: /signer|president/i }) or page.getByTestId("signer-task-row") and assert
it has at least N entries) and remove the "Do not delete without Mike's explicit
approval" prose; if the exact wording truly is a contract, convert the inline
comment to a single-line justification and move the detailed copy parity check
into a focused unit/snapshot test for the page module instead.

47-53: 💤 Low value

signInDemoUser failure short-circuits via expect(...).toBe(true) — fine for first sign-in, but consider the cleanup story.

Each test gets a fresh page fixture, so cookies/storage don't leak across the cases — good. Nothing to change here. Worth noting that if the seeded demo user ever fails to mint a session (e.g., the mint-demo-session script changes), every authenticated route fails with the same error; the assertion message ("demo user should sign in before dashboard screenshot") is generic enough to cover that, but a single upfront test.beforeAll smoke check on signInDemoUser would surface the root cause in one place instead of N failing tests.

🤖 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/e2e/visual-regression.spec.ts` around lines 47 - 53, Add a
one-time smoke check that calls signInDemoUser before the suite runs so a global
authentication break fails fast: implement a test.beforeAll that creates a
page/context (or reuses an appropriate fixture), calls signInDemoUser(page), and
throws or fails with a clear message if it returns false; keep the existing
per-route expect(...) checks but remove the need to debug N identical failures
by surfacing the root signInDemoUser/session minting problem in one place.
packages/web/src/lib/site.ts (1)

472-501: 💤 Low value

Footer column wiring is consistent with the new routes.ts; double-check feedbackLink belongs in "Do Something".

feedbackLink placed alongside voteLink, plaintiffsLink, donateLink in "Do Something" reads as a low-priority sibling to vote/register/donate. Feedback is typically a lower-tier action; consider moving it to the bottom of that list (already last, good) or to a different column. Not a blocker.

🤖 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/lib/site.ts` around lines 472 - 501, The footer currently
places feedbackLink as a direct item in the "Do Something" column next to
primary actions (voteLink, plaintiffsLink, donateLink); move feedbackLink to a
less-prominent position or a different column to reflect its lower
priority—either append it as the last item in that column (ensure it remains
last) or remove it from that array and add it to another column's items (e.g.,
"Learn Something" or a new "Connect" column). Update the columns array where
bottomText and columns are defined and adjust the items arrays referencing
feedbackLink, voteLink, plaintiffsLink, donateLink, dashboardLink,
presidentManagementLink, peopleLink, tasksLink, treatyLink,
humanityVGovernmentLink, onePercentTreatyPaperLink, courtLink, endorseLink, and
organizationalSignatoryLinks accordingly so the footer order and grouping
reflect the intended priority.
🤖 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/scripts/build-visual-review.mjs`:
- Around line 496-505: The catch in comparePair currently returns {changed:
true,...} which inflates "changed" counts; change the catch to return an
explicit errored flag (e.g. {changed: false, missing: false, errored: true,
label: `diff error: ${message.slice(0,60)}`, statusClass: "error"}) and then
update summarizeGroups to count errored routes separately (increment an errored
count) and adjust routeStatusLabel / header rendering to surface an "errored"
pill with that count so errors are not rolled into the changed bucket.

In `@packages/web/src/app/court/page.md`:
- Line 34: Article V on the generated /court page still contains the forbidden
tautology ("The Treaty is the off-ramp. The Court is the road that produces the
off-ramp.") and needs to be changed; update the source for the /court content
(likely packages/web/src/app/court/page.tsx or the module that produces page.md)
to either (A) rewrite Article V to remove the off-ramp/road metaphor and state
the concrete outcomes (e.g., treaty signing, 1% military redirect, liability
caps and the 102M-deaths framing) consistent with the TreatyContent.tsx rewrite,
or (B) if you intentionally keep the legal-document register, add a short
documented exception to CLAUDE.md / AGENTS.md referencing this exact phrase so
reviewers know it is permitted; modify the corresponding source (page.tsx or the
content module generating page.md) and update CLAUDE.md/AGENTS.md if choosing
the exception path.

In `@packages/web/src/app/questions/page.md`:
- Around line 3-5: Replace the user-facing lines that contain throat-clearing
and profanity: remove the apologetic phrase "I'm very sorry to bother you, but
this is kind of the most important thing in the universe..." and the profanity
line "GO TO HELL" and replace them with concise, direct copy consistent with
Wishonia voice (e.g., a short, neutral statement or CTA and an affirmative
response option instead of "FINE"); update the page content in the questions
page markdown accordingly and do not commit these copy changes until a human
reviewer has explicitly approved the exact wording.

---

Outside diff comments:
In `@packages/web/e2e/utils/static-pages.ts`:
- Around line 16-24: Extract the hardcoded host "127.0.0.1:3001" into a named
constant (e.g., DEFAULT_SMOKE_TEST_HOST) and update getSmokeTestHost to return
that constant both when process.env.BASE_URL is unset and when new
URL(process.env.BASE_URL) throws; keep function name getSmokeTestHost and the
URL parsing logic but change the catch branch to return DEFAULT_SMOKE_TEST_HOST
instead of null so both error paths use the same fallback.

---

Nitpick comments:
In `@packages/web/e2e/visual-regression.spec.ts`:
- Around line 72-77: The current regression guard uses a prose match via
route.requiredText and page.getByText which freezes copy; replace this with a
structural/assertion-based check (e.g., assert the presence of the
signer/president task list via page.getByRole("list", { name:
/signer|president/i }) or page.getByTestId("signer-task-row") and assert it has
at least N entries) and remove the "Do not delete without Mike's explicit
approval" prose; if the exact wording truly is a contract, convert the inline
comment to a single-line justification and move the detailed copy parity check
into a focused unit/snapshot test for the page module instead.
- Around line 47-53: Add a one-time smoke check that calls signInDemoUser before
the suite runs so a global authentication break fails fast: implement a
test.beforeAll that creates a page/context (or reuses an appropriate fixture),
calls signInDemoUser(page), and throws or fails with a clear message if it
returns false; keep the existing per-route expect(...) checks but remove the
need to debug N identical failures by surfacing the root signInDemoUser/session
minting problem in one place.

In `@packages/web/scripts/build-visual-review.mjs`:
- Around line 32-61: The manual routeOrder array drifts from routes that opt
into screenshots; update the build-visual-review logic so routeOrder is derived
at runtime from getRouteReviewSpecs("screenshot") (and other review types if
used) instead of a hard-coded list: call getRouteReviewSpecs("screenshot"), map
to route names in the same order it returns, then append the explicit-exception
names ("task-optimize-earth", "task-one-percent-treaty", "task-signer-canada",
"side-menu", "side-menu-auth") to preserve their custom placement; ensure
routeSortIndex continues to fall back to routeOrder.length for unknown routes.

In `@packages/web/src/lib/routes.ts`:
- Around line 712-723: The spread-then-override on plaintiffsManageLink
currently resets copyPreview and screenshot inherited from plaintiffsLink to
false for auth-only behavior; add a brief inline comment above the
plaintiffsManageLink declaration (referencing plaintiffsManageLink and
plaintiffsLink and the copyPreview/screenshot fields) stating: "manage page is
auth-only; override public review flags inherited from plaintiffsLink" so future
readers understand why those booleans are explicitly set to false.
- Around line 1506-1512: The function getReviewPathFromNavItem contains an
unreachable fallback "|| ROUTES.home" because the earlier guard (if
(!href.startsWith("/")) return null) guarantees href.split(/[?#]/, 1)[0] is
always a non-empty string for "/"-prefixed values; remove the redundant fallback
so the function simply returns the first split chunk. Update
getReviewPathFromNavItem to keep the existing startsWith("/") guard and return
the href.split(/[?#]/, 1)[0] result directly, referencing the NavItem.href
handling and ROUTES.home only if you later decide to change the guard semantics.
- Around line 1450-1494: The navItem.external check inside getRouteReviewSpecs
duplicates the curated contract of routeReviewNavItems; remove the redundant
guard (the "|| navItem.external" condition) from the filter so
getRouteReviewSpecs only checks mode and relies on the curated list, keeping
getReviewPathFromNavItem and the existing name/path construction intact for each
navItem (update any tests that assumed externals were filtered if needed).

In `@packages/web/src/lib/site.ts`:
- Around line 472-501: The footer currently places feedbackLink as a direct item
in the "Do Something" column next to primary actions (voteLink, plaintiffsLink,
donateLink); move feedbackLink to a less-prominent position or a different
column to reflect its lower priority—either append it as the last item in that
column (ensure it remains last) or remove it from that array and add it to
another column's items (e.g., "Learn Something" or a new "Connect" column).
Update the columns array where bottomText and columns are defined and adjust the
items arrays referencing feedbackLink, voteLink, plaintiffsLink, donateLink,
dashboardLink, presidentManagementLink, peopleLink, tasksLink, treatyLink,
humanityVGovernmentLink, onePercentTreatyPaperLink, courtLink, endorseLink, and
organizationalSignatoryLinks accordingly so the footer order and grouping
reflect the intended priority.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 76756ce0-b03d-4070-bd5b-6c0bee294da7

📥 Commits

Reviewing files that changed from the base of the PR and between 4a5b8a1 and bbeb336.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (34)
  • .github/workflows/ci.yml
  • .gitignore
  • packages/web/AGENTS.md
  • packages/web/e2e/utils/static-pages.ts
  • packages/web/e2e/utils/visual-routes.ts
  • packages/web/e2e/visual-regression.spec.ts
  • packages/web/package.json
  • packages/web/scripts/build-visual-review.mjs
  • packages/web/scripts/mint-demo-session.ts
  • packages/web/scripts/render-pages-to-markdown.ts
  • packages/web/src/app/court/page.md
  • packages/web/src/app/donate/page.md
  • packages/web/src/app/employees/page.md
  • packages/web/src/app/endorse/page.md
  • packages/web/src/app/feedback/page.md
  • packages/web/src/app/humanity-v-government/page.md
  • packages/web/src/app/legal/page.md
  • packages/web/src/app/page.md
  • packages/web/src/app/people/page.md
  • packages/web/src/app/plaintiffs/page.md
  • packages/web/src/app/privacy/page.md
  • packages/web/src/app/questions/page.md
  • packages/web/src/app/signatories/page.md
  • packages/web/src/app/tasks/page.md
  • packages/web/src/app/terms/page.md
  • packages/web/src/app/treaty/page.md
  • packages/web/src/app/vote/page.md
  • packages/web/src/app/why/page.md
  • packages/web/src/lib/routes.ts
  • packages/web/src/lib/site.ts
  • packages/web/src/lib/tasks/government-task-assignee.ts
  • packages/web/src/lib/tasks/leader-accountability-network.ts
  • packages/web/src/lib/tasks/treaty-signer-network.test.ts
  • packages/web/src/lib/tasks/treaty-signer-network.ts
✅ Files skipped from review due to trivial changes (11)
  • packages/web/src/app/vote/page.md
  • packages/web/src/app/privacy/page.md
  • packages/web/src/app/legal/page.md
  • packages/web/src/app/plaintiffs/page.md
  • packages/web/src/app/feedback/page.md
  • packages/web/src/app/people/page.md
  • packages/web/src/app/page.md
  • packages/web/src/app/why/page.md
  • .gitignore
  • packages/web/src/app/tasks/page.md
  • packages/web/src/app/signatories/page.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci.yml

Comment thread packages/web/scripts/build-visual-review.mjs
Comment thread packages/web/src/app/court/page.md Outdated
Comment thread packages/web/src/app/questions/page.md Outdated
@claude

claude Bot commented May 9, 2026

Copy link
Copy Markdown

Code review

Two CLAUDE.md compliance issues found:

Issue 1 - Banned off-ramp copy still in runtime source

File: packages/data/src/referendums/court-of-humanity.ts (line 68)

The page.md snapshot committed at packages/web/src/app/court/page.md (line 34) confirms that /court still renders: "The Treaty is the off-ramp. The Court is the road that produces the off-ramp."

This is the verbatim bad example cited in the no-startup-bro rule added in this same PR. The TreatyContent.tsx fix is correct but does not reach the actual runtime source — COURT_OF_HUMANITY_TEXT in court-of-humanity.ts line 68.

See:

**Article V**: The [1% Treaty](https://manual.WarOnDisease.org/knowledge/solution/1-percent-treaty.html) is hereby established as the standing settlement offer. Governments may accept the Treaty's terms — redirecting 1% of annual military spending to pragmatic clinical trials, with bondholder and political-incentive structures attached — in exchange for prospective liability caps on Court of Humanity claims arising from acts predating Treaty ratification. The Treaty is the off-ramp. The Court is the road that produces the off-ramp.

Fix: Edit line 68 of court-of-humanity.ts — e.g. "The Treaty is the standing settlement offer. The Court enforces it."

Issue 2 - "We are building" corporate opener on /feedback

File: packages/web/src/app/feedback/page.tsx (lines 76-77)

The page.md snapshot at packages/web/src/app/feedback/page.md (line 6) shows: "We are building a decentralized to-do list for humanity: coordinate the work required to end war and disease in the least irritating way possible."

"We are building" is a corporate opener banned by the rule added in this PR. CLAUDE.md: "No blather. No 'welcome to', 'let's take a moment'..." and "No startup-bro copy. No... corporate openers (We're building, Let's take a moment)."

See:

<p className="mt-5 max-w-2xl text-base font-bold leading-7 text-muted-foreground">
We are building a decentralized to-do list for humanity: coordinate
the work required to end war and disease in the least irritating way
possible.

Fix: Replace with Wishonia-voice copy. Example: "102 million people died waiting for treatments already proven safe. Tell us what to fix."

@claude

claude Bot commented May 9, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@mikepsinn mikepsinn merged commit 706a744 into main May 9, 2026
8 checks passed
@mikepsinn mikepsinn deleted the feature/treaty-dashboard-pre-may7-layout branch May 9, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants