diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..f33b45d --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,150 @@ +# Continuous integration. +# +# Two jobs, split by language, because they prove different things and the +# Python one is the slow half. +# +# What this actually gates, in order of how likely each is to catch something: +# +# 1. The two implementations of the game agree. `engine.py` and `engine.ts` +# score every ordered pair of words in the answer list — 4,603^2 = 21.2M +# feedback patterns — and their SHA-256 digests must match each other and +# the committed value. The page claims it VERIFIES a recorded run in your +# browser; that claim is only worth something if the browser's scorer and +# the environment's scorer cannot drift. +# 2. The reward measures something. `probe.py` plays seven deliberately +# crafted policies and asserts the reward orders them the way a person +# would, PER WEIGHTED COMPONENT — a component that is flat across every +# policy is measuring nothing and still moves the total. It also asserts +# neither good policy dominates the other, because the reward editor on +# the site is a claim about a real trade-off. +# 3. Every committed fixture replays through the engine and reproduces its +# own recorded rewards. A fixture that cannot be regenerated is a claim +# with no receipt behind it. +# 4. The word lists rebuild byte-identically from their committed sources. +# If they do not, the conformance digest is describing a different game. +# 5. The demo contract holds — see scripts/check-demos.mjs. +# 6. Four things that fail SILENTLY in production and nowhere else: +# prerendered routes carrying their own
, sitemap.xml existing, +# no blob-backed worker, and the bundle budget. +# +# NO MODEL IS EVER CALLED. Rollouts are captured by hand and committed; a gate +# that cost a paid inference call would be switched off within a month. +# +# This runner is aarch64 and configured with `container.network: host`. Nothing +# here needs a service container, so the traps that cost PIG three failed runs +# do not apply — but do not add `services:` here without reading that repo's +# workflow first. + +name: ci + +on: + push: + branches: [main] + pull_request: + +jobs: + web: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + # Corepack ships with Node and installs the exact pnpm pinned by + # `packageManager`, so CI and a laptop run the same version. The download + # prompt is disabled because a non-interactive runner cannot answer it and + # would otherwise hang until the job times out. + - name: Enable pnpm + env: + COREPACK_ENABLE_DOWNLOAD_PROMPT: '0' + run: | + corepack enable + corepack prepare --activate + test "$(pnpm -v)" = "11.21.0" || { echo "pnpm $(pnpm -v) != 11.21.0"; exit 1; } + + - name: Install + env: + CI: 'true' + run: pnpm install --frozen-lockfile + + # `pnpm build` ends in the prerender pass, which drives a real browser. + # Without this the build fails on its very last action, after everything + # else has gone green — the most expensive place to find a missing + # dependency. + - name: Install chromium + run: pnpm exec playwright install --with-deps chromium + + - run: pnpm typecheck + - run: pnpm check + - run: pnpm test + - run: pnpm build + - run: node scripts/bundle-budget.mjs + + # Crawlers do not run JavaScript. Without a real per-route HTML file every + # shared link previews as the homepage, and the failure is invisible from + # inside the app. + - name: The prerendered head is real + run: | + test -f dist/demos/wordle/index.html || { echo "no prerendered demo route"; exit 1; } + grep -q 'og:title' dist/demos/wordle/index.html || { echo "og tags missing"; exit 1; } + grep -q 'These demos are interactive and need JavaScript. The substance behind them does not.
Every demo on this site ships a real verifiers environment and a set of recorded rollouts, both in the repository. You can run the environment yourself:
-git clone https://github.com/karti-ai/PIG-Demo
+ git clone https://git.karti.ai/PIG/PIG-Demo
cd PIG-Demo && uv sync --all-packages
uv run vf-eval wordle-five -n 8
-
+
diff --git a/src/components/demo/DemoErrorBoundary.tsx b/src/components/demo/DemoErrorBoundary.tsx
index 0dc22da..62c479c 100644
--- a/src/components/demo/DemoErrorBoundary.tsx
+++ b/src/components/demo/DemoErrorBoundary.tsx
@@ -3,7 +3,7 @@ import type { ErrorInfo, ReactNode } from 'react';
import { AlertTriangle, ExternalLink, RotateCcw } from 'lucide-react';
import { Button } from '@/components/ui/button';
-const REPO_URL = 'https://github.com/karti-ai/PIG-Demo';
+const REPO_URL = 'https://git.karti.ai/PIG/PIG-Demo';
export interface DemoErrorBoundaryProps {
children: ReactNode;
diff --git a/src/components/demo/DemoShell.tsx b/src/components/demo/DemoShell.tsx
index befd147..32f5f84 100644
--- a/src/components/demo/DemoShell.tsx
+++ b/src/components/demo/DemoShell.tsx
@@ -35,7 +35,7 @@ import { RecordedBadge, TracePlayer } from './TracePlayer';
import { VerifyBadge } from './VerifyBadge';
import { formatOrDash, useIsDesktop } from './format';
-const REPO_BLOB = 'https://github.com/karti-ai/PIG-Demo/blob/main/';
+const REPO_BLOB = 'https://git.karti.ai/PIG/PIG-Demo/src/branch/main/';
/** The tab the step-detail strip opens on. Kept out of the URL when it is this. */
const DEFAULT_DETAIL_TAB = 'reasoning';
diff --git a/src/components/site/SiteFooter.tsx b/src/components/site/SiteFooter.tsx
index 9d21b54..22afce3 100644
--- a/src/components/site/SiteFooter.tsx
+++ b/src/components/site/SiteFooter.tsx
@@ -1,5 +1,5 @@
import { Link } from 'react-router-dom';
-import { Github } from 'lucide-react';
+import { GitBranch } from 'lucide-react';
import { Separator } from '@/components/ui/separator';
import { PIG_URL, REPO_URL } from '@/components/site/links';
@@ -24,8 +24,8 @@ export function SiteFooter() {
target="_blank"
rel="noreferrer noopener"
>
-
- Source on GitHub
+
+ Source on Gitea
- Source on GitHub
-
+ Source on Gitea
+
@@ -534,9 +534,9 @@ export function SiteHeader() {
href={REPO_URL}
target="_blank"
rel="noreferrer noopener"
- aria-label="Source on GitHub"
+ aria-label="Source on Gitea"
>
-
+
diff --git a/src/components/site/links.tsx b/src/components/site/links.tsx
index 7bf21c8..a447f8a 100644
--- a/src/components/site/links.tsx
+++ b/src/components/site/links.tsx
@@ -2,7 +2,7 @@
* The three off-site destinations the chrome links to, in one place so the
* header and the footer can never disagree about them.
*/
-export const REPO_URL = 'https://github.com/karti-ai/PIG-Demo';
+export const REPO_URL = 'https://git.karti.ai/PIG/PIG-Demo';
export const PIG_URL = 'https://primeintellectgrowth.com';
export const VERIFIERS_WORDLE_URL =
'https://github.com/PrimeIntellect-ai/verifiers/tree/main/environments/wordle';
diff --git a/src/content/evidence.ts b/src/content/evidence.ts
index 5dbd6b0..d2bca6f 100644
--- a/src/content/evidence.ts
+++ b/src/content/evidence.ts
@@ -125,7 +125,7 @@ export const optimalPlay = {
/** Commands anyone can run against a clone of this repository. */
export const reproduce = {
- clone: 'git clone https://github.com/karti-ai/PIG-Demo',
+ clone: 'git clone https://git.karti.ai/PIG/PIG-Demo',
install: 'cd PIG-Demo && uv sync --all-packages',
evaluate: 'uv run vf-eval wordle-five -n 8',
conformance: 'pnpm conformance',
diff --git a/src/demos/wordle/demo.tsx b/src/demos/wordle/demo.tsx
index 9a48c5e..1efd921 100644
--- a/src/demos/wordle/demo.tsx
+++ b/src/demos/wordle/demo.tsx
@@ -43,7 +43,7 @@ export default defineDemo({
},
{
label: 'Our word lists and how they were built',
- href: 'https://github.com/karti-ai/PIG-Demo/blob/main/envs/wordle_five/words/PROVENANCE.md',
+ href: 'https://git.karti.ai/PIG/PIG-Demo/src/branch/main/envs/wordle_five/words/PROVENANCE.md',
},
],
},
diff --git a/src/pages/NotFound.tsx b/src/pages/NotFound.tsx
index 5ac284b..6622134 100644
--- a/src/pages/NotFound.tsx
+++ b/src/pages/NotFound.tsx
@@ -102,7 +102,7 @@ export default function NotFound() {
Honesty
- The source on GitHub
+ The source
diff --git a/src/router.tsx b/src/router.tsx
index 6ab7d56..a4e5c1b 100644
--- a/src/router.tsx
+++ b/src/router.tsx
@@ -111,7 +111,7 @@ function describeError(error: unknown): { heading: string; body: string; detail?
if (error instanceof Error) {
return {
heading: 'This page failed to load',
- body: 'The rest of the site still works. If this keeps happening, the source is on GitHub and the issue is reproducible from it.',
+ body: 'The rest of the site still works. If this keeps happening, the source is public and the issue is reproducible from it.',
detail: error.message,
};
}