Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,28 @@ Do not let lower items crowd out higher ones.
lives in campaign-facing pages, shared snippets, and the badge artifact,
not the onboarding form.

## P1 - Person/Org Conversion Surfaces (post-PR #81)

Roadmap from Mike's 2026-05-15 brainstorm. /people/[id] redesign lands in PR #81; the rest follow once that merges. Ship in this order for maximum reuse.

- **PR-A: Foundation-action seed tasks.** Seed `optimize-earth` task tree with concrete user actions: donate $1, print poster, hang flyer, social-share. New task category `campaign-action`. Hours-prevented impact metric per task. One file: `packages/db/src/managed-data/managed-seed-data.ts`. Smallest, lowest risk; unlocks PR-B and PR-C.

- **PR-B: `/orgs/[slug]` task display.** Mirror `/people/[id]` conversion-surface pattern onto org pages. Reuse `SufferingPreventedMetric` (extracted in #81). Wire `getOrganizationTasks` MCP to a page consumer. Primary CTA: ENDORSE (visitor not in org) vs SHARE (visitor's org already endorsed). Below-fold: org-completed tasks + member leaderboard.

- **PR-C: Add-org + assign-task UX.** Backend primitives exist (`createOrganization` + `createTask` MCP). New surfaces: `/orgs/[slug]/admin/tasks` for org admin self-assignment; `/admin/assign-task` (superuser, Mike-only) for cross-org. Gate behind superuser role until proper moderation. Audience: org admin who endorsed via `/endorse`, wants to coordinate their members.

- **PR-D: Hand-curated public-figure catalog.** Seed Person rows for top 50-100 public figures (scientists, politicians, celebrities). Each row: displayName, handle (`mlk`, `einstein`, `gates`), 50-word deadpan-Wishonia bio, 1-3 attributed campaign-relevant actions with documented public-statement sources, impact-estimate (DALYs averted, methodology-cited from `parameters-calculations-citations.ts`), `isPublicFigure: true` flag (new bool on Person). `/people/<famous-slug>` renders with "Public-figure record" eyebrow. Visitors can co-sign the figure's position.

- **PR-E: AI-cataloged public-figure activity (deferred).** Scale PR-D with NER on Wikipedia/news/govt records → impact-attribution model → manual-review pipeline. Scaffolding only after PR-D's manual seed proves the UX works. Not on the campaign critical path.

**Out-of-scope for this roadmap:** peer-task-assignment on `/people/[id]` (Mike deferred 2026-05-15; needs whitelist/opt-in moderation design — separate plan).

**Shared component reuse:** all five PRs share `SufferingPreventedMetric` (extracted in #81). No new design primitive.

**Risks:** public-figure attribution disputes (use only documented public statements; label "historical position, not active endorsement"); spam on `/admin/assign-task` (superuser-gated); org-task display competing with conversion CTA (keep task list below the fold).

Drafted plan: `.claude/plans/campaign-impact-attribution-roadmap.md` (not yet reviewed; Mike declined full `/autoplan` review for speed).

## P1 - Plaintiffs and Court Framing

### `/humanity-v-government` plaintiff-first rework
Expand Down
639 changes: 595 additions & 44 deletions packages/data/src/parameters/parameters-calculations-citations.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/web/e2e/email-screenshots.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ test.describe("email visual coverage", () => {
"post-vote-share",
"email-post-vote-share",
[
"Forward this message",
"Forward this message to everyone you don't want to suffer and die of horrible diseases.",
"122 stored apocalypses",
"COPY THIS MESSAGE",
"1% Treaty",
Expand Down
1 change: 1 addition & 0 deletions packages/web/e2e/utils/visual-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const SEEDED_DYNAMIC_ROUTES: VisualRoute[] = [
path: "/organizations/institute-for-accelerated-medicine",
required: false,
},
{ name: "people-mike", path: "/people/mike", required: false },
{ name: "task-optimize-earth", path: "/tasks/optimize-earth", required: false },
{ name: "task-one-percent-treaty", path: "/tasks/1-pct-treaty", required: false },
{ name: "task-signer-canada", path: "/tasks/1-pct-treaty-signer-ca", required: false },
Expand Down
1 change: 1 addition & 0 deletions packages/web/scripts/build-visual-review.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const routeOrder = [
"tasks-index-auth",
"people",
"people-auth",
"people-mike",
"questions",
"feedback",
"settings",
Expand Down
32 changes: 22 additions & 10 deletions packages/web/src/app/donate/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { WaysToGiveCard } from "@/components/donate/WaysToGiveCard";
import { TreatyTradeThesis } from "@/components/referendum/TreatyTradeThesis";
import { ParameterTemplate } from "@/components/shared/ParameterTemplate";
import { ParameterValue } from "@/components/shared/ParameterValue";
import { defaultButtonClassName } from "@/components/ui/default-button";
import { getSiteMetadata } from "@/lib/metadata";
import { donateLink, onePercentTreatyPaperLink, ROUTES } from "@/lib/routes";
import { getSiteFromHeaders } from "@/lib/site";
Expand All @@ -37,7 +38,16 @@ export async function generateMetadata() {

export default function DonatePage() {
return (
<div className="min-h-screen bg-background text-foreground">
<div className="min-h-screen bg-background pb-24 text-foreground sm:pb-0">
<div className="fixed inset-x-0 bottom-0 z-50 border-t border-foreground bg-background px-4 py-3 sm:hidden">
<a
aria-label="Jump to donation calculator"
className={`${defaultButtonClassName} w-full bg-foreground text-background hover:bg-background hover:text-foreground`}
href="#donate-calculator"
>
Donate
</a>
</div>
<div className="mx-auto max-w-5xl px-4 py-8 sm:px-6 sm:py-12">
<section className="mb-4 border-2 border-foreground p-5 sm:p-6">
<p className="text-xs font-black uppercase tracking-[0.18em] text-muted-foreground">
Expand Down Expand Up @@ -130,15 +140,17 @@ export default function DonatePage() {
</div>
</section>

<Suspense
fallback={
<div className="border border-foreground p-6 text-sm">
Loading calculator…
</div>
}
>
<DonationImpactCalculator />
</Suspense>
<div id="donate-calculator" className="scroll-mt-6">
<Suspense
fallback={
<div className="border border-foreground p-6 text-sm">
Loading calculator…
</div>
}
>
<DonationImpactCalculator />
</Suspense>
</div>

<div className="mt-10">
<WaysToGiveCard />
Expand Down
19 changes: 5 additions & 14 deletions packages/web/src/app/endorse/page.logged-out.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,21 @@
- Add your organization. Publicly support the [1% Treaty](/treaty) once. Then use the member link, email starter, website button, or iframe to help your audience answer the Global Survey to End War and Disease.
- Join first. Your tools page gives you the member link, email starter, website button, iframe, one-hour action checklist, and outreach grant request draft for funding from the International Campaign.
### APPLY FOR A CAMPAIGN GRANT
- Estimate the outreach grant your organization could request from the International Campaign to End War and Disease to run the Global Survey to End War and Disease through your audience. Campaign links and embeds keep attribution and impact measurement in one system.
- OUTREACH CAPACITY
- EMAIL LIST
- MONTHLY SITE VISITORS
- SOCIAL REACH
- MONTHS EMBEDDED
- ASSUMPTIONS
- MESSAGE REACH %
- SURVEY RESPONSE RATE %
- MEMBER SHARING LIFT
- GRANT $ PER RESPONSE
- Use this after you join: one email, one social post, and a website embed can turn your existing audience into verified responses to the Global Survey to End War and Disease. The estimate starts with the grant request and lives saved. Change the assumptions below if you need to.
- GRANT REQUEST
- $3,960
- ESTIMATED OUTREACH COST PER RESPONSE: $2
- SURVEY RESPONSES
- 1,980
- FROM 66,000 PEOPLE REACHED
- MODELED LIVES SAVED
- 5,346
- $0.74 PER MODELED LIFE SAVED
- SURVEY RESPONSES
- 1,980
- FROM 66,000 PEOPLE REACHED
- SUFFERING PREVENTED
- 109,058
- YEARS OF SUFFERING PREVENTED
- 1,980 verified survey responses × [2.7](https://manual.WarOnDisease.org/knowledge/economics/1-pct-treaty-impact.html) lives and [55](https://manual.WarOnDisease.org/knowledge/appendix/dfda-impact-paper.html) years prevented per response. At an estimated outreach cost of $2 per response, the outreach request is $3,960.
#### SHOW ASSUMPTIONS
#### GRANT REQUEST DRAFT
- COPY REQUEST DRAFT
- LEGAL NOTES FOR ORGANIZATIONS
Expand Down
2 changes: 0 additions & 2 deletions packages/web/src/app/people/[id]/page.logged-out.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
## 404
- PAGE NOT FOUND
- Fascinating. You've managed to navigate to a page that doesn't exist. On my planet, our routing infrastructure hasn't lost a page in 4,237 years. You lot can't even keep track of a URL.
- To be fair, your species also loses approximately $2.1 trillion annually to administrative inefficiency, so misplacing a web page is relatively on-brand.
- The page you're looking for has either been moved, deleted, or — and I cannot stress how likely this is — never existed in the first place. Much like your evidence-based policymaking.
- WISHONIA DIAGNOSTIC REPORT
- Problem: Page not found
- Severity: Mildly embarrassing
Expand Down
Loading
Loading