From cdacf3a23456051fa85f9ca1e14e89b5b95ef7dd Mon Sep 17 00:00:00 2001 From: Hanchun Wang Date: Thu, 2 Jul 2026 01:25:29 +0100 Subject: [PATCH 1/3] Add Verified track preview page and design doc Introduce a gated, DB-free preview of the proposed Verified publication track (author-agnostic, claim-verified): - app/(site)/verified/page.tsx: static preview landing page. Hidden in production behind NEXT_PUBLIC_VERIFIED_PREVIEW (notFound() otherwise) and not linked from navigation, so merging cannot expose it to users. - docs/verified-track.md: design + production-deployment notes. - .env.example: document the preview flag. - .claude/launch.json: local dev-server config for previewing. No schema, API, or navigation changes; nothing runs untrusted code or touches the database. Co-Authored-By: Claude Opus 4.8 --- .claude/launch.json | 11 + .env.example | 5 + app/(site)/verified/page.tsx | 397 +++++++++++++++++++++++++++++++++++ docs/verified-track.md | 136 ++++++++++++ 4 files changed, 549 insertions(+) create mode 100644 .claude/launch.json create mode 100644 app/(site)/verified/page.tsx create mode 100644 docs/verified-track.md diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 00000000..04ffa28b --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "dev", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "dev"], + "port": 3000 + } + ] +} diff --git a/.env.example b/.env.example index dd37f023..257fb8af 100644 --- a/.env.example +++ b/.env.example @@ -53,6 +53,11 @@ YJS_COMPACTION_PENDING_THRESHOLD=500 YJS_COMPACTION_IDLE_MS=300000 YJS_COMPACTION_MAX_DOCS=20 +# Feature previews +# Show the in-progress Verified track page in production. Defaults to on in local dev, +# off in production. Set to "true" on a Vercel preview deploy to view /verified there. +NEXT_PUBLIC_VERIFIED_PREVIEW=false + # Security defaults SECURITY_RATE_LIMIT=true SECURITY_SUSPICIOUS_DETECTION=true diff --git a/app/(site)/verified/page.tsx b/app/(site)/verified/page.tsx new file mode 100644 index 00000000..80d9923a --- /dev/null +++ b/app/(site)/verified/page.tsx @@ -0,0 +1,397 @@ +import type { Metadata } from "next"; +import { notFound } from "next/navigation"; +import { + ArrowRight, + BadgeCheck, + CheckCircle2, + Coins, + Cpu, + FileText, + FlaskConical, + Lock, + Scale, + ShieldCheck, + Sparkles, + XCircle, +} from "lucide-react"; + +import Footer from "@/components/site/Footer"; +import SiteHeaderLight from "@/components/site/SiteHeaderLight"; +import { Badge } from "@/components/ui/badge"; +import { buttonVariants } from "@/components/ui/button"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { cn } from "@/lib/utils"; + +export const metadata: Metadata = { + title: "Verified", + description: + "A publication track for research whose contributions are checked by machine. Author-agnostic, claim-verified: write it however you like — including with AI — and if your claims pass verification, we publish them.", + openGraph: { + title: "Verified – interactives", + description: + "Author-agnostic, claim-verified publishing. Declare your claims, submit tests, we run and verify them, then publish.", + type: "website", + }, + twitter: { + card: "summary_large_image", + title: "Verified – interactives", + description: "Author-agnostic, claim-verified publishing.", + }, + // Preview page — keep it out of search indexes while it is internal-only. + robots: { index: false, follow: false }, +}; + +// Preview gate: visible in local dev automatically; hidden in production unless +// NEXT_PUBLIC_VERIFIED_PREVIEW="true" is set. Mirrors the repo's notFound() hide pattern. +function previewEnabled() { + if (process.env.NEXT_PUBLIC_VERIFIED_PREVIEW === "true") return true; + return process.env.NODE_ENV !== "production"; +} + +const STEPS = [ + { + icon: FileText, + title: "1 · Declare your claims", + body: "State each contribution as an explicit, testable claim — not a paragraph of prose. “This sorts in O(n log n)”, “this beats baseline B by ≥3% on dataset D”, “this pipeline reproduces Figure 4 byte-for-byte.”", + }, + { + icon: FlaskConical, + title: "2 · Submit tests", + body: "Attach the tests that prove each claim, plus a pinned environment (image, entrypoint, resource budget). Tests are the evidence; the prose is just the story around them.", + }, + { + icon: BadgeCheck, + title: "3 · We verify, then publish", + body: "We run your tests in an isolated sandbox and check they actually substantiate your claims. Pass both gates and the paper is published with a verification record attached.", + }, +]; + +const GATES = [ + { + icon: Cpu, + label: "Gate 1 — Execution", + title: "The tests run and pass, deterministically.", + body: "Your tests execute in a pinned, network-isolated sandbox with fixed seeds and a hard CPU / memory / time budget. A re-run must reproduce. This is the cheap, objective gate.", + }, + { + icon: ShieldCheck, + label: "Gate 2 — Faithfulness", + title: "The tests actually back the claim.", + body: "Passing isn’t enough — we check the tests aren’t tautological, cherry-picked, or narrower than the prose claim. This gate is what the badge is worth; without it, “tests pass” means nothing.", + }, +]; + +const VERIFIABLE = [ + "Algorithmic correctness against a reference oracle", + "Benchmark / performance numbers on pinned data", + "“This code produces exactly this output”", + "Machine-checkable math and proofs", + "Reproducible data pipelines (figures, tables)", +]; + +const NOT_YET = [ + "Human-subjects or empirical field claims", + "Novelty claims (“first to …”)", + "Qualitative or design contributions", + "Theory not reducible to a check", + "Anything needing GPUs or non-determinism (v1)", +]; + +const cardCls = "bg-card rounded-xl border shadow-sm"; + +export default function VerifiedPage() { + if (!previewEnabled()) notFound(); + + return ( +
+ + +
+ {/* Preview banner — makes clear this is an internal, non-live concept page */} +
+
+ + Preview + + — internal concept page for the Verified track. Not live, nothing here writes to the + database. + +
+
+ +
+ {/* Hero */} +
+ + New track + +

+ Verified +

+

+ Author-agnostic, claim-verified. +

+

+ A publication track for research whose contributions are checked by machine, not + vouched for by reputation. Write it however you like — including with AI. If your + claims pass verification, we publish them. You pay for the compute, not for the + publication. +

+ +
+ + {/* Three steps */} +
+ {STEPS.map((s) => { + const Icon = s.icon; + return ( + + +
+ +
+ {s.title} +
+ +

{s.body}

+
+
+ ); + })} +
+ + {/* How it works — two gates */} +
+

+ Two gates, not one +

+

+ The whole idea hinges on one thing: tests passing is not the same as a claim being + true. So verification is two gates — and the second is the hard one. +

+ +
+ {GATES.map((g) => { + const Icon = g.icon; + return ( +
+
+ + {g.label} +
+

{g.title}

+

{g.body}

+
+ ); + })} +
+ + {/* Pipeline strip */} +
+ {["Claim", "Tests", "Sandbox run", "Faithfulness check", "Published"].map( + (step, i, arr) => ( + + + {step} + + {i < arr.length - 1 && } + + ) + )} +
+
+ + {/* Sample submission mock (static, illustrative) */} +
+

+ What a submission looks like +

+

+ An illustrative example — one claim, its test, and the verification record that + would be attached on publication. +

+ +
+ {/* Claim + test */} +
+
+
+ Claim 1 +
+

+ sortpartial{" "} + returns a fully sorted array and uses at most{" "} + + 3·n·log₂n + {" "} + comparisons, matching a reference oracle on 10,000 random inputs. +

+
+ +
+
+ claim_1_test.py + + sandboxed · no network + +
+
+                    {`def test_matches_oracle():
+    for seed in range(10_000):
+        xs = random_ints(seed, n=1_000)
+        assert sortpartial(xs) == sorted(xs)
+
+def test_comparison_budget():
+    ops = count_comparisons(sortpartial, n=100_000)
+    assert ops <= 3 * 100_000 * log2(100_000)`}
+                  
+
+
+ + {/* Verification record */} +
+
+
+ + Verification record + + Published +
+ +
+
+
+ Execution +
+
+ Passed +
+
+
+
+ Faithfulness +
+
+ Passed +
+
+
+
+ Compute billed +
+
0.8 CPU·min · $0.04
+
+
+ +
+ A failed run shows the same record with a{" "} + + Failed + {" "} + gate and the logs — you still pay for the compute, but it isn't + published. +
+
+
+
+
+ + {/* Pricing model */} +
+
+
+
+ +
+
+

+ Pay for compute, not for publication +

+

+ You pay the metered cost of running your tests — the same whether you pass + or fail. We never sell the publication itself; the only thing that gets you + published is passing verification. That is the line between this and a + pay-to-publish mill. +

+
+
+
+
+ + {/* Scope */} +
+

+ What we can — and can't — verify +

+

+ Honesty up front: this track only accepts claims a machine can actually check. The + first version is deliberately narrow. +

+ +
+
+
+ Verifiable +
+
    + {VERIFIABLE.map((v) => ( +
  • + + {v} +
  • + ))} +
+
+
+
+ Not yet +
+
    + {NOT_YET.map((v) => ( +
  • + + {v} +
  • + ))} +
+
+
+
+ + {/* Closing */} +
+
+

+ A verifiable record, not a reputation contest +

+

+ This is an internal preview of the Verified track. The flow above is illustrative; + submission, the sandbox runner, and billing are still being designed. +

+
+
+
+
+ +
+
+ ); +} diff --git a/docs/verified-track.md b/docs/verified-track.md new file mode 100644 index 00000000..5cddc991 --- /dev/null +++ b/docs/verified-track.md @@ -0,0 +1,136 @@ +# Verified Track — Design & Deployment Notes + +> Status: **Draft** · Branch: `feat/verified-track` · Target deploy: production (Vercel + Supabase) + +A new publication track where acceptance is gated on **machine-verifiable claims** rather +than (or in addition to) human peer review. Authors declare their contributions as explicit +**claims**, submit **tests**, and the platform runs those tests in an isolated environment and +checks that they actually substantiate the declared claims. Verified → published. Compute is +metered and billed. + +## 1. Framing (this is load-bearing) + +**Author-agnostic, claim-verified.** We are not selling *publication*; we are selling +*verification*. Who/what wrote the paper (human or AI) is irrelevant — the gate checks whether +each claim is reproducibly true. "Published on the verified track" signals **"this contribution +was machine-checked"**, nothing more, nothing less. + +This framing is what separates the idea from a pay-to-publish paper mill. Keep it central in all +copy and UX. + +## 2. The core risk: "tests pass" ≠ "claim is true" + +A test only proves *the assertion the author wrote*, on *the data/seed the author chose*. Failure +modes to defend against: + +- cherry-picked data / random seed +- tautological tests (implementation checked against itself) +- hardcoded / overfit answers +- prose claim broader than what the test covers + +Therefore verification is **two gates**, not one: + +1. **Cheap gate** — tests execute and pass in a pinned, sandboxed, deterministic environment. +2. **Faithfulness gate** — the tests are *adequate and faithful* to the declared claim. This is + the hard part and the source of the badge's value. Mechanism is an **open decision** (§7): + LLM judge, enforced test spec (held-out data, fixed seed, baseline comparison, no network), + human spot-check, or a combination. + +If gate 2 is weak, the track gets gamed within weeks and the badge is worthless. + +## 3. Scope of verifiable claims (v1 should be narrow) + +Works well: algorithmic correctness, benchmark/perf numbers, "this code produces this output", +machine-checkable math, data-pipeline reproducibility. + +Works poorly: human-subjects/empirical claims, novelty ("first to…"), qualitative contributions, +non-mechanizable theory. + +The track must **state explicitly** what it can and cannot verify. v1 recommendation: accept only +**deterministic, CPU-only, single-process, assertion-based** claims; defer GPU/ML/statistical +claims. + +## 4. Architecture — two tiers, deployed differently + +``` +┌─────────────────────────── Vercel (existing app) ───────────────────────────┐ +│ Next.js: track UI, claim/test submission, billing records, │ +│ thin enqueue + status API (NO untrusted code runs here) │ +└───────────────┬──────────────────────────────────────────────────────────────┘ + │ enqueue job / poll status (Upstash Redis as queue + metering) +┌───────────────▼─────────────── Runner tier (OFF Vercel) ─────────────────────┐ +│ Isolated execution: container / microVM (Firecracker/gVisor) OR managed │ +│ sandbox (E2B / Modal). Pinned image, no network, CPU/mem/time caps. │ +│ Runs gate 1; emits logs + result. Faithfulness gate (§2.2) runs here or in │ +│ a separate judge step. │ +└───────────────────────────────────────────────────────────────────────────────┘ +``` + +**Why the split:** Vercel serverless is short-lived and cannot safely isolate untrusted code. +The only async infra today is **Upstash Redis** (rate-limit + AI quota) — reusable as the job +queue and the metering store, but it is *not* an execution environment. There is no queue/worker/ +sandbox in the repo today; the runner tier must be provisioned separately. + +## 5. Data model additions (PROPOSED — not final) + +Additive only. Mirrors the existing Prisma + manual-SQL pattern (see §6). + +- `PaperType` += `VERIFIED` (new enum value). +- `PaperStatus` += `VERIFICATION_PENDING`, `VERIFICATION_RUNNING`, `VERIFICATION_PASSED`, + `VERIFICATION_FAILED` (new enum values). +- **`Claim`** — `paperId` → 1:N declared contributions (text + structured assertion descriptor). +- **`TestArtifact`** — submitted tests + environment spec (pinned image, entrypoint, resource + budget), linked to a paper and to the claims it targets. +- **`VerificationRun`** — one execution attempt: status, logs ref, compute cost, exit result, + per-claim pass/fail, faithfulness verdict. +- Billing: reuse the existing Redis daily-quota pattern (`quota:{id}:{date}`) for metering; + consider a Postgres usage-record table for auditable billing. + +## 6. Production deployment playbook (CRITICAL — read before any schema change) + +This repo does **not** use Prisma Migrate. `prisma/` has only `schema.prisma` + `seed.ts`; there +is **no `prisma/migrations/`**. The build runs only `next build` (+ `prisma generate` via +`postinstall`) and **never touches the database**. Schema changes are applied **by hand**. + +To add a model/enum and ship it to production: + +1. Edit `prisma/schema.prisma` (additive only) → run `npx prisma generate` locally. +2. Hand-write an **idempotent** SQL file in `supabase/migrations/YYYYMMDD_verified_track.sql`: + - tables: `CREATE TABLE IF NOT EXISTS "PascalCaseName" (...)` — names **must match Prisma** + exactly (models here have no `@@map`, so Prisma expects quoted PascalCase, e.g. + `"VerificationRun"`). Follow the `20251229_yjs_doc_events.sql` precedent. + - enums: `CREATE TYPE "EnumName" AS ENUM (...)`, or `ALTER TYPE ... ADD VALUE IF NOT EXISTS` + for adding values to an existing enum. + - RLS: if the table is reachable from the browser via the anon/authenticated key, hand-write + `ENABLE ROW LEVEL SECURITY` + policies (Prisma cannot express these). +3. **Run the SQL on Supabase FIRST** (before merging code). Order matters: build the additive + tables, *then* merge code. Old code ignores the new tables, so this is safe. +4. Local self-check (CI does **not** build): `npm run lint && npm run typecheck && npm run test:ci + && npm run build`. +5. Push branch → Vercel preview + GitHub "Quality" CI (`quality.yml`: lint/typecheck/test only — + no build, no deploy). ⚠️ Preview deploys reuse prod env incl. `DATABASE_URL` — preview writes + hit the production DB unless a separate Supabase project is configured for preview. +6. Open PR → `master`. Merge → Vercel auto-deploys to production via its Git integration (there is + no deploy GitHub Action). +7. Post-deploy: add any new env vars to **both** `.env.example` and the Vercel project settings; + keep the feature behind a flag until ready. + +Safety rules for prod: additive-only migrations, `IF NOT EXISTS` everywhere, never `DROP`/`ALTER` +existing columns, confirm Supabase PITR/backups before the first migration, ship behind a flag. + +## 7. Open decisions (lock these before writing real schema) + +1. **Faithfulness gate (§2.2):** LLM judge / enforced test spec / human spot-check / combination? + This determines whether the badge is worth anything. +2. **Runner compute (§4):** self-host an isolated tier (Firecracker/gVisor on a provisioned host) + vs managed sandbox (E2B / Modal)? Determines the runner architecture. +3. **v1 claim scope (§3):** start with deterministic CPU-only assertion tests, or support ML/ + benchmarks from the start? Determines MVP size. + +## 8. Branch slicing + +- **Branch 1 (`feat/verified-track`, Vercel-safe):** schema + migration SQL, track UI, claim/test + submission form, thin enqueue/status API (execution stubbed), billing/usage data structures. + Deploys cleanly through the existing Vercel + Supabase flow, end-to-end with a stubbed runner. +- **Branch 2 (separate infra):** the real isolated execution tier + the faithfulness gate. Lives + off Vercel; its deployment is a separate track from the web app. From c2c1dd87706198e73ea07b92b9a48c7e5491896d Mon Sep 17 00:00:00 2001 From: Hanchun Wang Date: Fri, 3 Jul 2026 15:44:35 +0100 Subject: [PATCH 2/3] Retrigger Vercel preview build No code changes; empty commit to re-run the preview deployment. Co-Authored-By: Claude Fable 5 From 6db58ff2cfc3f235dbe9be2b7561fe727841d21c Mon Sep 17 00:00:00 2001 From: Yitong Sun Date: Sat, 4 Jul 2026 13:57:20 +0100 Subject: [PATCH 3/3] Polish Verified track launch --- app/(site)/home-client.tsx | 115 +--- app/(site)/verified/page.tsx | 896 ++++++++++++++++++---------- components/site/SiteHeaderLight.tsx | 14 +- components/site/SiteMenu.tsx | 1 + 4 files changed, 616 insertions(+), 410 deletions(-) diff --git a/app/(site)/home-client.tsx b/app/(site)/home-client.tsx index 13b9fc2e..6e368d08 100644 --- a/app/(site)/home-client.tsx +++ b/app/(site)/home-client.tsx @@ -4,7 +4,6 @@ import { gsap } from "gsap"; import { Observer } from "gsap/Observer"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import { TextPlugin } from "gsap/TextPlugin"; -import { ChevronDown } from "lucide-react"; import Link from "next/link"; import { useEffect, useRef, useState } from "react"; @@ -21,10 +20,7 @@ if (typeof window !== "undefined") { export default function HomePage() { const containerRef = useRef(null); - const heroRef = useRef(null); - const pinContainerRef = useRef(null); const paragraphRef = useRef(null); - const scrollIndicatorRef = useRef(null); const textScrollRef = useRef(null); const videoRef = useRef(null); const [videoLoaded, setVideoLoaded] = useState(false); @@ -45,7 +41,7 @@ export default function HomePage() { const lines = text.split(//i); // Words that should have gradient effect - const gradientWords = ["interactives", "CHI", "2026."]; + const gradientWords = ["Verified", "evidence."]; element.innerHTML = lines .map((line, lineIndex) => { @@ -93,9 +89,6 @@ export default function HomePage() { return progress; }); - // Add 0.2 snap breakpoint for first screen - snapPoints.push(0.18); - // Add end point if last section doesn't reach bottom if (snapPoints[snapPoints.length - 1] < 0.99) { snapPoints.push(1); @@ -197,7 +190,7 @@ export default function HomePage() { // Ensure initial position is set for all words gsap.set(words, { - x: window.innerWidth - 25, + x: 0, }); // Make paragraph visible after wrapping and initial position is set @@ -208,56 +201,6 @@ export default function HomePage() { }); } - // Scroll indicator bounce animation - if (scrollIndicatorRef.current) { - // Create bouncing animation - gsap.to(".scroll-arrow-container", { - y: 15, - duration: 1, - ease: "power1.inOut", - repeat: -1, - yoyo: true, - }); - - // Fade out on scroll - gsap.to(scrollIndicatorRef.current, { - opacity: 0, - scrollTrigger: { - trigger: pinContainerRef.current, - start: "top top", - end: "+=50", - scrub: true, - }, - }); - } - - // Main text animation with snap point at the end - gsap.to(words, { - x: 0, - stagger: 0.02, - ease: "power4.inOut", - scrollTrigger: { - trigger: pinContainerRef.current, - start: "top top", - end: "bottom bottom", - scrub: true, - pin: heroRef.current, - }, - }); - - // Add snap point for the hero section - ScrollTrigger.create({ - trigger: pinContainerRef.current, - start: "top top", - end: "bottom bottom", - snap: { - snapTo: [0, 0.95, 1], // Snap at start, near end, and end - duration: { min: 0.2, max: 0.5 }, - delay: 0.1, - ease: "power1.inOut", - }, - }); - // Scroll-triggered animations gsap.utils.toArray(".scroll-section").forEach((section: any) => { gsap.from(section, { @@ -691,28 +634,12 @@ export default function HomePage() { - {/* Text Scrolling Hero Section */} -
+ {/* Hero Section */} +
- {/* Scroll Indicator */} -
-
- Scroll - -
-
- {/* Content Container */}
{/* Header */} @@ -747,13 +674,13 @@ export default function HomePage() { className="paragraph" style={{ fontFamily: "var(--font-roboto-flex), sans-serif", - fontSize: "5vw", - lineHeight: 1.0, - letterSpacing: "-0.05em", + fontSize: "clamp(42px, 5vw, 74px)", + lineHeight: 0.95, + letterSpacing: "0", fontWeight: 500, }} dangerouslySetInnerHTML={{ - __html: `The research behind
interactives was published at
CHI 2026.`, + __html: `New track!
Verified papers
with executable evidence.`, }} />
+

+ New Track announcement +

- Read the paper to learn about the technology and story behind the platform. + A new interactives publication track for papers whose core claims can be checked + by running code and tests.

- +
diff --git a/app/(site)/verified/page.tsx b/app/(site)/verified/page.tsx index 80d9923a..5e21e6f0 100644 --- a/app/(site)/verified/page.tsx +++ b/app/(site)/verified/page.tsx @@ -1,260 +1,575 @@ +import { ArrowRight } from "lucide-react"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; -import { - ArrowRight, - BadgeCheck, - CheckCircle2, - Coins, - Cpu, - FileText, - FlaskConical, - Lock, - Scale, - ShieldCheck, - Sparkles, - XCircle, -} from "lucide-react"; +import type { CSSProperties, ReactNode } from "react"; import Footer from "@/components/site/Footer"; import SiteHeaderLight from "@/components/site/SiteHeaderLight"; -import { Badge } from "@/components/ui/badge"; import { buttonVariants } from "@/components/ui/button"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { cn } from "@/lib/utils"; export const metadata: Metadata = { title: "Verified", description: - "A publication track for research whose contributions are checked by machine. Author-agnostic, claim-verified: write it however you like — including with AI — and if your claims pass verification, we publish them.", + "Verified is a new interactives publication track for papers whose core research claims can be checked by running code and tests.", openGraph: { - title: "Verified – interactives", + title: "Verified - interactives", description: - "Author-agnostic, claim-verified publishing. Declare your claims, submit tests, we run and verify them, then publish.", + "A publication track for testable research claims: declare the claim, run the evidence, publish the verification record.", type: "website", }, twitter: { card: "summary_large_image", - title: "Verified – interactives", - description: "Author-agnostic, claim-verified publishing.", + title: "Verified - interactives", + description: "Executable evidence for scoped research claims.", }, - // Preview page — keep it out of search indexes while it is internal-only. robots: { index: false, follow: false }, }; -// Preview gate: visible in local dev automatically; hidden in production unless -// NEXT_PUBLIC_VERIFIED_PREVIEW="true" is set. Mirrors the repo's notFound() hide pattern. function previewEnabled() { if (process.env.NEXT_PUBLIC_VERIFIED_PREVIEW === "true") return true; return process.env.NODE_ENV !== "production"; } -const STEPS = [ +const CONTRACT_ITEMS = [ { - icon: FileText, - title: "1 · Declare your claims", - body: "State each contribution as an explicit, testable claim — not a paragraph of prose. “This sorts in O(n log n)”, “this beats baseline B by ≥3% on dataset D”, “this pipeline reproduces Figure 4 byte-for-byte.”", + label: "01", + title: "Author-agnostic", + body: "The source of the manuscript is not the publication gate. The claim is.", }, { - icon: FlaskConical, - title: "2 · Submit tests", - body: "Attach the tests that prove each claim, plus a pinned environment (image, entrypoint, resource budget). Tests are the evidence; the prose is just the story around them.", + label: "02", + title: "Claim-scoped", + body: "A badge never means the whole paper is true. It means these declared claims were checked under stated conditions.", }, { - icon: BadgeCheck, - title: "3 · We verify, then publish", - body: "We run your tests in an isolated sandbox and check they actually substantiate your claims. Pass both gates and the paper is published with a verification record attached.", + label: "03", + title: "Evidence-first", + body: "The prose tells the story. The executable package carries the evidence.", }, ]; +const PROCESS_STEPS = [ + ["Declare", "Turn contributions into explicit, testable claims."], + ["Package", "Attach tests, fixtures, seeds, references, and a pinned environment."], + ["Run", "Execute in a network-isolated sandbox with fixed CPU, memory, and time budgets."], + ["Assess", "Check whether the tests faithfully support the claim, not merely whether they pass."], + ["Publish", "Attach a transparent verification record to claims that pass both gates."], +] as const; + const GATES = [ { - icon: Cpu, - label: "Gate 1 — Execution", - title: "The tests run and pass, deterministically.", - body: "Your tests execute in a pinned, network-isolated sandbox with fixed seeds and a hard CPU / memory / time budget. A re-run must reproduce. This is the cheap, objective gate.", + label: "Gate 1", + name: "Execution", + question: "Did it run?", + body: "The submitted package executes in a pinned, deterministic, network-isolated environment. This gate is objective, repeatable, and produces the raw run record.", + outputs: ["exit code", "logs", "resource usage", "re-run result"], }, { - icon: ShieldCheck, - label: "Gate 2 — Faithfulness", - title: "The tests actually back the claim.", - body: "Passing isn’t enough — we check the tests aren’t tautological, cherry-picked, or narrower than the prose claim. This gate is what the badge is worth; without it, “tests pass” means nothing.", + label: "Gate 2", + name: "Faithfulness", + question: "Did the evidence match the claim?", + body: "Passing tests are not enough. The second gate checks for tautological tests, cherry-picked fixtures, overfit answers, and prose that claims more than the evidence supports.", + outputs: ["claim coverage", "adequacy notes", "scope limits", "verdict"], }, ]; -const VERIFIABLE = [ - "Algorithmic correctness against a reference oracle", - "Benchmark / performance numbers on pinned data", - "“This code produces exactly this output”", - "Machine-checkable math and proofs", - "Reproducible data pipelines (figures, tables)", +const RECEIPT_ROWS = [ + ["Paper", "Sorting with partial comparisons"], + ["Claim", "C1"], + ["Execution", "Passed"], + ["Faithfulness", "Passed"], + ["Environment", "python:3.12-slim"], + ["Network", "Disabled"], + ["Budget", "2 vCPU / 512 MB / 90 s"], + ["Compute", "0.8 CPU·min / $0.04"], + ["Record", "Published with claim"], +] as const; + +const SCOPE_GOOD = [ + "Deterministic algorithmic correctness", + "CPU-only benchmarks on pinned data", + "Exact output reproduction", + "Machine-checkable proofs or assertions", + "Reproducible data pipelines for figures/tables", ]; -const NOT_YET = [ - "Human-subjects or empirical field claims", - "Novelty claims (“first to …”)", +const SCOPE_NOT_YET = [ + "Human-subjects or field claims", + 'Novelty claims, e.g. "first to..."', "Qualitative or design contributions", - "Theory not reducible to a check", - "Anything needing GPUs or non-determinism (v1)", + "Non-mechanizable theory", + "GPU-heavy or nondeterministic ML claims", ]; -const cardCls = "bg-card rounded-xl border shadow-sm"; +const POLICY_ITEMS = [ + ["Billed", "Sandbox execution and verification work."], + ["Not sold", "Acceptance, badge, or publication outcome."], + ["Public record", "What ran, what passed, and what was out of scope."], +] as const; -export default function VerifiedPage() { - if (!previewEnabled()) notFound(); +type WindowTone = "plain" | "blue" | "strong"; + +function SentenceLines({ text }: { text: string }) { + const sentences = text.split(". "); + + return sentences.map((sentence, index) => ( + + {index < sentences.length - 1 ? `${sentence}.` : sentence} + + )); +} + +function ScreenSection({ + children, + className, + id, + style, +}: { + children: ReactNode; + className?: string; + id?: string; + style?: CSSProperties; +}) { + return ( +
+
+ {children} +
+
+ ); +} + +function SectionIntro({ + eyebrow, + title, + body, + className, +}: { + eyebrow: string; + title: string; + body?: string; + className?: string; +}) { + return ( +
+

{eyebrow}

+

+ +

+ {body ? ( +

{body}

+ ) : null} +
+ ); +} + +function StatusPill({ children, tone = "plain" }: { children: ReactNode; tone?: WindowTone }) { + const toneClass = { + plain: "border-gray-400 bg-[#F7F7F4] text-gray-800", + blue: "border-brand-600 bg-brand-50 text-brand-700", + strong: "border-gray-950 bg-gray-950 text-[#F1F1F1]", + }[tone]; + + return ( + + {children} + + ); +} + +function WindowFrame({ + title, + children, + className, + tone = "plain", + eyebrow, +}: { + title: string; + children: ReactNode; + className?: string; + tone?: WindowTone; + eyebrow?: string; +}) { + const shadowClass = { + plain: "shadow-[10px_10px_0_0_rgba(17,24,39,0.11)]", + blue: "shadow-[12px_12px_0_0_rgba(37,99,235,0.18)]", + strong: "shadow-[12px_12px_0_0_rgba(17,24,39,0.16)]", + }[tone]; + + return ( +
+
+ {title} + {eyebrow ? ( + {eyebrow} + ) : null} +
+ {children} +
+ ); +} + +function ManifestPanel() { + const rows = [ + ["claim", '"sortpartial returns a sorted array under the stated comparison budget"'], + ["evidence", "tests/claim_01.py"], + ["env", "python:3.12-slim"], + ["network", "disabled"], + ["budget", "2 vCPU / 512 MB / 90 s"], + ["gate.execution", "passed"], + ["gate.faithfulness", "passed"], + ["record", "ready_to_publish"], + ] as const; + + return ( + +
+
+ {rows.map(([label, value]) => ( +
+
{label}:
+
{value}
+
+ ))} +
+
+ Execution passed + Faithfulness passed + Compute 0.8 CPU·min +
+
+
+ ); +} + +function PaperClaim() { + return ( +
+
+ Claim C1 + paper excerpt +
+

+ + sortpartial + {" "} + returns a sorted array and stays under the stated comparison budget on the pinned workload. +

+
+ ); +} + +function ContractPanel() { + return ( + +
+ {CONTRACT_ITEMS.map(item => ( +
+

{item.label}

+

+ {item.title} +

+

{item.body}

+
+ ))} +
+
+ ); +} + +function ProcessPanel() { + return ( + +
    + {PROCESS_STEPS.map(([label, body], index) => ( +
  1. +
    + + {String(index + 1).padStart(2, "0")} + + {index < PROCESS_STEPS.length - 1 ? ( + -> + ) : null} +
    +

    + {label} +

    +

    {body}

    +
  2. + ))} +
+
+ ); +} + +function GatePanel({ + gate, + highlighted = false, +}: { + gate: (typeof GATES)[number]; + highlighted?: boolean; +}) { + return ( + +
+
+ {gate.label} + {gate.name} +
+

+ {gate.question} +

+

{gate.body}

+
+

Outputs

+
    + {gate.outputs.map(output => ( +
  • + {output} +
  • + ))} +
+
+
+
+ ); +} + +function ReceiptPanel() { + return ( + +
+ {RECEIPT_ROWS.map(([label, value]) => ( +
+
{label}
+
+ {value} +
+
+ ))} +
+
+ ); +} +function ScopeMatrix() { return ( -
- - -
- {/* Preview banner — makes clear this is an internal, non-live concept page */} -
-
- - Preview - - — internal concept page for the Verified track. Not live, nothing here writes to the - database. - + +
+
+
+ Good v1 candidates +
+
    + {SCOPE_GOOD.map(item => ( +
  • + {item} +
  • + ))} +
+
+
+
+ Not v1
+
    + {SCOPE_NOT_YET.map(item => ( +
  • + {item} +
  • + ))} +
+
+
+ ); +} + +function PolicyLedger() { + return ( + +
+ {POLICY_ITEMS.map(([label, body]) => ( +
+

{label}

+

{body}

+
+ ))} +
+
+ ); +} + +export default function VerifiedPage() { + if (!previewEnabled()) notFound(); + + return ( +
+ -
- {/* Hero */} -
- - New track - -

- Verified -

-

- Author-agnostic, claim-verified. -

-

- A publication track for research whose contributions are checked by machine, not - vouched for by reputation. Write it however you like — including with AI. If your - claims pass verification, we publish them. You pay for the compute, not for the - publication. -

-
- - How verification works - - - + +
+
+

+ Verified publication track +

+

- What we can verify - + +

+

+ Verified is an interactives track for papers whose core contribution is testable. + Authors declare claims, attach executable evidence, and receive a public + verification record when both gates pass. +

+

+ Who wrote the paper is not the gate. The record shows what was checked, how it ran, + what passed, and what remains outside the claim. +

+
-
- - {/* Three steps */} -
- {STEPS.map((s) => { - const Icon = s.icon; - return ( - - -
- -
- {s.title} -
- -

{s.body}

-
-
- ); - })} -
- - {/* How it works — two gates */} -
-

- Two gates, not one -

-

- The whole idea hinges on one thing: tests passing is not the same as a claim being - true. So verification is two gates — and the second is the hard one. -

- -
- {GATES.map((g) => { - const Icon = g.icon; - return ( -
-
- - {g.label} -
-

{g.title}

-

{g.body}

-
- ); - })} + +
+
+
+ - {/* Pipeline strip */} -
- {["Claim", "Tests", "Sandbox run", "Faithfulness check", "Published"].map( - (step, i, arr) => ( - - - {step} - - {i < arr.length - 1 && } - - ) - )} + +
+ + +
+
+ + +
+ + +
+
+ + +
+ +
+ +
-
- - {/* Sample submission mock (static, illustrative) */} -
-

- What a submission looks like -

-

- An illustrative example — one claim, its test, and the verification record that - would be attached on publication. -

- -
- {/* Claim + test */} -
-
-
- Claim 1 -
-

- sortpartial{" "} - returns a fully sorted array and uses at most{" "} - - 3·n·log₂n - {" "} - comparisons, matching a reference oracle on 10,000 random inputs. -

-
+
+ -
-
- claim_1_test.py - - sandboxed · no network - -
-
-                    {`def test_matches_oracle():
+        
+          
+
+ + +
+
+ +
+                  {`def test_matches_oracle():
     for seed in range(10_000):
         xs = random_ints(seed, n=1_000)
         assert sortpartial(xs) == sorted(xs)
@@ -262,133 +577,76 @@ export default function VerifiedPage() {
 def test_comparison_budget():
     ops = count_comparisons(sortpartial, n=100_000)
     assert ops <= 3 * 100_000 * log2(100_000)`}
-                  
-
-
+
+ + +
+
+ - {/* Verification record */} -
-
-
- - Verification record - - Published -
- -
-
-
- Execution -
-
- Passed -
-
-
-
- Faithfulness -
-
- Passed -
-
-
-
- Compute billed -
-
0.8 CPU·min · $0.04
-
-
- -
- A failed run shows the same record with a{" "} - - Failed - {" "} - gate and the logs — you still pay for the compute, but it isn't - published. -
-
+ +
+
+ +
+
-
- - {/* Pricing model */} -
-
-
-
- -
-
-

- Pay for compute, not for publication -

-

- You pay the metered cost of running your tests — the same whether you pass - or fail. We never sell the publication itself; the only thing that gets you - published is passing verification. That is the line between this and a - pay-to-publish mill. -

-
-
+ +
+ + + +
+
+

Executable publishing

+

+ +

-
- - {/* Scope */} -
-

- What we can — and can't — verify -

-

- Honesty up front: this track only accepts claims a machine can actually check. The - first version is deliberately narrow. -

- -
-
-
- Verifiable + +
+

+ The badge is scoped to the claim and the environment. It says what was checked, + how it ran, and which parts remain outside the record. +

+
+ Claim scoped + Evidence executed + Record attached
-
    - {VERIFIABLE.map((v) => ( -
  • - - {v} -
  • - ))} -
-
-
-
- Not yet + -
    - {NOT_YET.map((v) => ( -
  • - - {v} -
  • - ))} -
-
-
- - {/* Closing */} -
-
-

- A verifiable record, not a reputation contest -

-

- This is an internal preview of the Verified track. The flow above is illustrative; - submission, the sandbox runner, and billing are still being designed. -

-
-
-
+ +
+