Spaces:
Paused
Paused
Commit History
-
Evolve the AI: a genome, mutation, crossover, and a selection loop
Claude +1: Claude Opus 5Unverified signaturePhase 1 of docs/ai-evolution-design.md. Nothing under engine/ changes -- the whole point is that a candidate AI was already JSON, so the genotype lives in tools/ and the shipped simulation never learns any of this exists. tools/genome.js is the schema and the operators. GENOME_SCHEMA is one source of truth for what a legal gene is -- 28 genes over two chromosomes and six linkage groups -- and the operators are per gene KIND rather than one operator for everything, which is the decision that matters most here: ratios mutate multiplicatively (an additive step means something different at 0.2 than at 1.5, and 0 would be absorbing), headcounts additively so 0 stays reachable because 0 is a real allele, flags rarely because they are epistatic switches that decide whether other genes mean anything at all, and unitMix through sequence operators because it is a cyclic production cycle where order and multiplicity both carry meaning. Crossover cuts at MODULE boundaries, not per gene: the linka…9f53528
-
Phase 2 (part 2): roster + persistent ladder wired into Quick Duel, archetype threaded end-to-end
Claude +1: Claude Sonnet 5Unverified signatureTurns Phase 1's one-off Quick Duel into the persistent competition mode docs/competitions-and-elo.md Phase 2 describes: Quick Duel / Roster / Standings, one coherent mode behind a small tab row, all three reading and writing the SAME competitionLedger.js ledger. THE KEY UX CHANGE: ad-hoc, free-typed entrants are retired. Each Quick Duel entrant is now either picked "From Roster" (a <select> of competitionLedger's current roster) or drafted "New Entrant" (name + strategy + archetype + faction) -- a new draft joins the roster, via addRosterEntry, the instant startDuel() actually commits to running (after buildJob's own validation passes, before the Worker spins up), never on a keystroke, so an abandoned draft never pollutes the roster. A finished duel's rows are folded into the ledger for the pinned difficulty bracket via recordCompetition alone -- no second, hand-rolled elo.js applySeries call in competition.js. The results view's old "Elo isn't saved" line is gone, replaced by "Elo up…628afc1 -
Phase 1 foundations: elo.js, tools/duelCore.js, and an Elo column in ailab's CLI
Claude +1: Claude Sonnet 5Unverified signaturedocs/competitions-and-elo.md's Phase 1 turns the tuning bench into the first slice of an in-game competition: a rating system (D7), one shared between the CLI and (in a later stage of this same phase) the game (D1), plus the fairness-critical duel primitive split out where a browser Worker can reach it next. UI and the Worker itself are out of scope for this stage on purpose -- foundations only. - elo.js (new, root, `// @ts-check`, JSDoc-annotated): INITIAL_RATING, expectedScore, kFactor, applyResult, applySeries -- plain Elo (D7): K=40 while provisional (<10 games, wins over the rating-based rule even at a seeded-high rating), then 20, then 10 above 2400. applyResult creates missing entrants at INITIAL_RATING/0 games rather than throwing, and derives both sides' deltas from ONE shared actual-minus-expected value so they're exact negatives of each other whenever both sides share a K-bucket (verified: two independently-rounded expectedScore(a,b)/expectedScore(b,a) calls are…9af0ddd