Repository navigation
Upgrade: career-aligned rigour + BYOK AI (Cachex-AI) - #12
Merged
Merged
Conversation
Wilson and Newcombe intervals, seeded percentile bootstrap (plain, stratified, paired and vector-valued), Wilcoxon signed-rank (exact and tie-corrected normal approximation) with rank-biserial effect size, Bradley-Terry by MM with an Elo conversion, type-7 quantiles and high-precision normal functions. Unit tests pin reference values from scipy 1.17, statsmodels and R. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- /tournament: seeded round robin of the original agent against variants that change one knob (fixed depth 2/3, greedy one-ply) and the random baseline, colour-swapped pairs, run in a pool of Web Workers. Wilson CIs, Bradley-Terry Elo with stratified bootstrap CIs, first-move effect, move times, illegal moves, CSV export. - Precomputed 1,200-game reference tournament (TypeScript port) and a cross-check that replays the feasible pairings from the unchanged Python (scripts/crosscheck_tournament.py); the 144/160 benchmark is restated with its Wilson interval. - Alpha-beta efficiency study: nodes with vs without pruning on 120 positions, plus a clearly labelled textbook variant. Finding: the original's inverted beta update leaves 92-100% of the tree searched. The agent itself is unchanged. - /astar: paired Manhattan vs Euclidean study with paired bootstrap CI, Wilcoxon signed-rank test, effect sizes and a BFS optimality check, live in a worker and as a 980-board reference. - Agent port gains opt-in fixedDepth and prune options; defaults keep parity with the original (all parity tests unchanged and passing). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- AI settings dialog: Anthropic (default, Claude Haiku 4.5 or Sonnet 5.5) or OpenAI (editable model id). The visitor's key is kept in sessionStorage by default, localStorage only on opt-in, with a forget button. Calls go straight from the browser to the provider; the key never reaches this site, the audit log or the repository. - Provider adapters in lib/ai (official Anthropic SDK with browser access, OpenAI Chat Completions with strict JSON schema), zod validation and friendly errors (invalid key, rate limit, overload, network/CORS, refusal, truncation). - Move commentator grounded in the agent's own evaluation breakdown, with an automatic grounding check and accept / edit / reject review. - LLM Arena: the model plays the minimax agent with JSON moves checked against the legal moves (retry, then forfeit), compared on identical seeds with random and greedy baselines; Wilson CIs, illegal-answer rate, latency and tokens, CSV export. - Every call is audit-logged in IndexedDB and viewable at /ai-log with JSON and CSV export. All output is labelled AI-generated. - Tests mock fetch for both providers and assert the key never appears in log entries or exports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ment - /methods: data provenance, method, evaluation design, assumptions, limitations and what I'd change, plus the AI use statement. - DR-001 (evaluation features and weights), DR-002 (dynamic depth allocation) and DR-003 (TypeScript port, Web Workers, parity tests), each stating the decision first and reporting weak numbers honestly; rendered under /methods/decisions. - Agent card (docs/model-card.md) with intended use, provenance, evaluation with intervals and known weaknesses, at /methods/agent-card. - docs/ is synced into web/content/docs for the Vercel build; a test fails if the copies drift and checks the decision-record format. - Navigation gains Tournament, LLM Arena and Methods; the landing page shows the benchmark's Wilson interval and links the evaluation pages. - README covers the new features, bring-your-own-key, the audit log, methods and decision records, and how every artefact is regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address review findings on the bring-your-own-key layer: - Anthropic adapter calls messages.create with a JSON schema built from the zod schema (enums kept, unsupported numeric bounds dropped) and checks stop_reason before parsing, so a reply cut off at max_tokens is "truncated" and a refusal is "refusal", not a format error. - OpenAI adapter sends max_completion_tokens, so both providers answer under the same output budget. - AiError carries the raw reply and token usage; failed calls now log both in the audit entry, and the CSV export gains an output_text column. - LLM arena: truncated, refused and malformed replies are counted as "no usable move", separately from illegal moves, and no longer abort the run. The headline rate is per turn (first answer only), with the forfeit rate over games. Baselines are replayed on exactly the games the model finished, the caption says when colours are unbalanced, and a scripted first-legal-cell baseline is added. - Board prompt draws two-character cells shifted half a cell per row. - Grounding check now catches numbers that end a sentence. - Spectate pauses autoplay and pins the move when commentary is requested; commentary state survives remounts, and /ai-log can review entries left pending. - "Forget key" clears every provider's key; the dialog returns focus to whatever opened it; checked checkboxes are visible in dark mode; scrollable tables are focusable, named regions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Exact McNemar test (two-sided binomial on discordant units), checked
against scipy binomtest, statsmodels mcnemar(exact=True) and R
binom.test.
- A* study: shortest-path rates on the same boards are now compared by a
paired bootstrap difference (-11.3 pp, 95% CI -13.3 to -9.1) and exact
McNemar (1 vs 106 discordant boards); copy says "fewer nodes" instead
of a negative count.
- Tournament: Elo differences between every pair of agents, with
intervals from the same bootstrap refits as the leaderboard (original
minus greedy +15 [-24, +56]; depth 3 minus original +151 [106, 195]).
Shown in a new table, the summary CSV and the findings, which no
longer argue from overlapping intervals. Per-agent intervals are
unchanged.
- Leaderboard header reflects the anchor ("vs field mean" when random is
not in the run); the head-to-head caption says when a stopped run left
colours unbalanced or pairings without games.
- DR-004 records the decision.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Agent card: real table headers; "no first-move advantage" no longer implies a STEAL effect that was never tested; Elo comparisons and the Python cross-check's resolution are stated; new failure mode "does not block one-move wins" (a scripted Blue filling row 0 wins 50/50 on 4x4, 43/50 on 5x5, 34/50 on 6x6; pinned by tests). - README: "no detectable difference" wording with the resolution of each check, paired A* results, DR-004, and the new arena metrics. - AI use statement: same scoring rule for both providers, raw replies of failed calls are logged, pending commentary can be reviewed on /ai-log. - Home page benchmark table shows Wilson intervals per row. - Markdown tables and code blocks are focusable, named scroll regions; two-column tables wrap instead of scrolling; long inline code wraps. - Methods page describes the paired analyses and per-turn LLM scoring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The "run your own" leaderboard needs about 820px, but beside the 340px setup panel it got 802px at 1280-1440px, so the ms/move interval column was cut off. The setup panel now sits beside the results only from xl (300px wide), and spans the width in two columns below that. Also say "boards 4 x 4 to 7 x 7" on the home page instead of "n = 4-7", which read as a sample size next to "144 of 160 games". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commentator capped replies at 1,500 output tokens. On reasoning models that cap also has to cover thinking: Claude Sonnet 5.5 runs adaptive thinking by default, and OpenAI counts reasoning tokens in max_completion_tokens (the default gpt-5-mini is a reasoning model), so a commentary could be cut off before its JSON finished. The LLM player already uses 4,096 for this reason. - Add COMMENTATOR_MAX_TOKENS (4,096, the same as LLM_PLAYER_MAX_TOKENS) and commentaryRequest(facts), so the panel and the tests share one request. - Test what each provider receives: the budget, effort "low" on Sonnet, and no thinking or sampling parameters (both are 400s on Sonnet 5.5). The cap is a ceiling, not a charge; providers bill the tokens generated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The grounding check verified feature directions, numbers and moves, but not
who moved. A smoke test with a mocked provider returned "Red played (4, 0)"
for a move Blue made, and the check still passed.
Add a fourth check: when the text says a colour made a move ("Red played",
"Blue has taken"), that colour must be the mover in the facts. The pattern
is narrow on purpose, so naming the other colour ("blocks Blue", "Blue's
tiles") is not treated as a claim about who moved. Tests cover the wrong
mover, the right mover, plain mentions and no mention. The AI use statement
and README now list this check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The check results sat in a collapsed <details>, so a reviewer saw only "Grounding check found problems" and had to expand it to learn what was wrong before accepting, editing or rejecting. Open it by default when a check fails; a passing result stays collapsed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… its intervals Web Workers return games in the order they finish, and the seeded stratified bootstrap indexes into the record arrays in that order, so the same seed gave the same games but different Bradley-Terry intervals and a differently ordered games CSV from run to run. summariseTournament and gamesCsv now sort records into buildSchedule's order (size, pairing, round, colour leg) first. The reference run was played in that order, so its numbers do not change; tests shuffle records and check the summary and CSV are identical, and that the reference order is left as is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k in the audit log
Commentator
- The facts now say what the score means at the depth searched
(score_scope) and whether the search found a forced win (forced_win).
The feature breakdown describes the position one ply after the move;
at depth 2+ the score is a backed-up minimax value, so the prompt no
longer asks the model to explain the score through the features.
Regression: 4x4, seed 76, depth 3, +infinity with features summing to -12.
- New check "Forced wins reported as the search found them": the summary
must report a forced win the search found, for the right player, and
never claim one it did not (denials are fine).
- The shared empty-hex feature may be called neutral.
Audit trail
- callStructured takes a `check` hook; the grounding result is stored in
the same audit entry as the output, exported as grounding_passed and
grounding_failures (CSV) and in full (JSON).
- /ai-log shows the stored check above the review buttons (open when it
failed), flags failed entries and counts them. Older entries are
re-checked from the logged prompt, labelled as recomputed, and the
recomputed check is stored with the reviewer's decision.
AI settings
- The dialog keeps provider, models, key and "remember" as a draft until
Save; closing it changes nothing. The remember box follows the selected
provider's saved key and a key only moves between session and local
storage when the visitor changed the box (a tab-only key was silently
persisted after a provider switch).
LLM arena statistics
- Rejected first answers: Wilson interval on the effective number of
turns after a design effect from the between-game spread (floored at 1),
instead of treating turns as independent. clusteredWilson is checked
against statsmodels' cluster-robust variance.
- Each baseline is compared with the model game by game: discordant
games and an exact McNemar test.
Also: p-values are shown as statements ("p = 0.012", "p < 0.001").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…x headings and source links - /tournament: the alpha-beta copy now gives the per-search picture next to the averages (in the agent's own order 222 of 240 searches visit every node; the 18 that prune visit 12.5% to 86.2% of the tree) and the mechanism (beta stays at +infinity, so a cut-off needs a forced win for Red). - /methods: the AI use statement's subsections render as h3 under its h2 (Markdown `nested`); evaluation-design bullets describe the paired LLM comparison and the clustered rejected-answer interval. - Scroll regions fade their right edge while more columns are hidden (iOS hides scrollbars), dropping the fade while keyboard-focused so the focus ring stays whole. - Header nav links draw their focus ring inside, so the scrolling nav no longer clips it. - "Source" links point at the deployed commit when the build knows it (NEXT_PUBLIC_GIT_REF or VERCEL_GIT_COMMIT_SHA), else main: files that exist only on an unmerged branch no longer 404 from production. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tored grounding checks - DR-005 (report uncertainty at the unit that was sampled) supersedes DR-002's pruning-ratio sentence and DR-004's per-turn arena interval: 444 of 480 searches visit the whole tree and the 36 that prune visit 0.6% to 92%; the "92% to 100%" range is of averages. It also records the design-effect interval for rejected answers (and why a game-level bootstrap was rejected), the paired McNemar arena comparison and the schedule-order fix for reproducible tournament intervals. - DR-006 records grounding commentary in the search's scope (forced wins, depth 2+ scores) and storing the check with the human decision. - Past records are untouched; a decision-record page now notes, from the newer record's "Supersedes" line, when part of it has been superseded. - Agent card, README and AI use statement updated to match; docs/README lists DR-004 to DR-006. Synced into web/content/docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The JSON and CSV export names used toISOString(), the UTC date, while the log shows local timestamps. In Adelaide an export made before 10:30 am was named for the previous day. Use the local calendar date, computed when the button is pressed, with a unit test that pins the Adelaide case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`pnpm showcase` runs web/e2e/showcase.spec.ts on the system Chrome (channel "chrome", no browser download; the ffmpeg on PATH records the video). Three journeys (play the agent, the A* Lab, the tournament and LLM evaluation) run at a human pace with an on-screen caption banner and cursor highlight, and assert what they show: the steal, both captures, the recorded A* output, the seeded tournament, the mocked LLM run and the audit log. No real key is used: provider requests are intercepted and answered by a mock that is labelled on screen. The same run captures the screenshots. scripts/showcase-media.mjs turns the raw output into optimised PNGs, H.264 MP4s with WebVTT captions and posters, and README GIFs that cut waits and scrolls to stay under 8 MB at 960 px. /tour shows the walkthroughs (lazy-loaded videos, captions, step transcripts, the mocked-AI notice) and the screenshots in a lightbox. It is linked from the header, the footer and the landing page. The header now matches whole path segments so /tournament does not light up /tour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recorded with `pnpm showcase` against a production build of this commit's parent: 13 screenshots (landing light and dark at 1440 x 900, eight key features, three phone shots at 390 x 844), three captioned MP4s with WebVTT tracks and posters for /tour, and three README GIFs (960 px, 10 fps, waits and scrolls cut). The tournament walkthrough's AI steps use a placeholder key and a mocked reply, labelled as such on screen and in the README. The README gains a Showcase section: the hero GIF, a two-column screenshot grid with captions, and the numbered steps of each walkthrough. A test keeps the media, captions and README steps in sync with src/lib/showcase.ts and checks the size limits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Career-aligned upgrade of the Cachex revival: statistical rigour around the original 2022 results, and optional bring-your-own-key AI features with transparency and an audit trail. The original coursework and its results are unchanged; the upgrade adds analysis around them.
Live: https://cachex-ai.vercel.app
What's new
Statistics and evaluation
web/src/lib/stats/: Wilson and Newcombe intervals, seeded percentile and paired bootstraps, the Wilcoxon signed-rank test, Bradley-Terry fits on the Elo scale, and an exact McNemar test. Unit tests check them against scipy, statsmodels and R./tournament: a seeded, colour-swapped round robin. You can rerun it in the browser in Web Workers, with CSV export. It also has the 1,200-game reference run, a cross-check against the original Python, the original 144/160 benchmark (90.0%, 95% CI 84.4% to 93.8%) and an alpha-beta efficiency study./astar: a paired study of Manhattan versus Euclidean (980 boards). It reports a bootstrap CI and Wilcoxon test for node counts, and a BFS optimality check that adds a paired difference and McNemar test./methods: data provenance, methods, evaluation design, assumptions, limitations and "what I'd change". It renders the agent card and decision records DR-001 to DR-006.Bring-your-own-key AI (optional; the site works fully without a key)
/playand/spectateis grounded in the agent's own numbers, including what the score means at the depth searched. An automatic grounding check runs on every reply and is stored with the call; you can accept, edit or reject it./llm-arena: an evaluation harness in which a language model plays the minimax agent. It is compared with random, greedy and a scripted first-legal-cell baseline on the same seeds./ai-log: every call is recorded in IndexedDB with its input, output (including the raw reply when validation failed), latency, tokens, grounding check and human decision, with JSON and CSV export. The key is never recorded.Second review round
Governance and grounding
score_scope,forced_win). The feature breakdown describes the position one ply after the move, so it no longer gets presented as the reason for a deeper search's score or a forced win. A fifth check fails a reply that misses, misattributes or invents a forced win. Regression test: 4×4, seed 76, a depth-3 forced win whose features sum to −12. The shared empty-hex feature may be called neutral.grounding_passed,grounding_failures)./ai-logshows it above the review buttons, flags and counts failures, and re-checks older entries from the logged prompt.Statistics
Site
First review round
stop_reasonbefore parsing, so truncated replies and refusals are no longer reported as format errors. It sends a schema that keepsenum(the SDK helper had been turning enums into descriptions)./ai-log.Checks
pnpm lint && pnpm typecheck && pnpm test && pnpm buildall pass on the final commit, with 979 tests (up from 957).pnpm format:checkis clean./ai-log, and exported in JSON and CSV. An entry logged before this change is re-checked and the check is stored with the decision.The AI use statement is informed by the Australian DTA responsible-AI policy, EU AI Act transparency principles and the NIST AI RMF. It is not a claim of compliance.
🤖 Generated with Claude Code