v0.5.0: clean up the AI API — namespaces, scopes, file-vs-game defines; migrate all AIs #79
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
v0.5.0 work stream 2 of 3 (Robert's checklist, #26).
Completely clean up the AI API. Today an AI is a series of define blocks with no clear separation of: what is defined in the file vs defined by the game engine, what is a global read-only constant vs a write that defines behavior, and what namespace anything belongs to. The API must make namespaces very identifiable, and the file/game and read/write distinctions explicit, in a way that reads naturally as Lisp.
Then migrate ALL brains to the new API: the four mains (adapt, empire, mill, vault) AND the specialist ones.
Constraint: the v0.5.0 super AI will be written in this API next, so push a compiling, runnable commit early and keep the branch green (build + tests + spectate smoke with zero [ai errors) at every commit.
Robert's settled rulings that must survive: Lisp-style hyphenated names, no dot notation; (config 'key) must be quoted; no hard-coded values in brains.
Dispatch comment — Winnie Ismo taking issue #79.
Plan for the AI Lisp API redesign, per Robert's settled rulings (hyphenated Lisp names, no dot notation, quoted
(config 'key), no hard-coded values, four mains keep structurally distinct world models):bank-*(this bank's own state),market-*(game state),game-*(clock/die),(config 'key)(game configuration, quoted), plus clearly-named action forms for behavior (set-deposit-rate,bid-loan,offer-bond,take-bonds,revoke-offers,bid-acquisition). File-defined vs game-defined becomes structurally visible.docs/ai-api.mdwith examples.[aierrors and zero ACCT/CF DIVERGENCE; quick bench (30 games x 13 presets) green.Branch:
79-api-cleanofforigin/master. PRs only. Progress comments after every step. Early green commit first, then iterate.Step 1 — design settled, engine work starting.
The redesign, worked out against the current lisp.go/ai.go and all 14 brains:
Namespaces (every game-defined name is in one of these, all READ-ONLY):
bank-*— this bank's own state (bank-id, bank-cash, bank-deposits, bank-deposit-rate, bank-equity, bank-loans, bank-bond-assets, bank-bond-debts, bank-offers)market-*— public game state (market-avg-rate, market-deposit-rates, market-loans, market-bonds, market-banks-alive, market-acquisition-net)game-*— the clock (game-turn, game-die)(config 'key)— game configuration, quoted as always; gainsdeposit-rate-cap/loan-rate-capas keys (the two bare cap symbols become config keys — no more top-level loose ends)Behavior writes (the ONLY forms that change the game, all imperative verbs):
set-deposit-rate,bid-loans,bid-loan,offer-bond,take-bonds,revoke-offers,bid-acquisition.File-vs-game explicit: new definition forms —
(defun name (params) body…)for functions,(defvar name init)for file-global state, and(define-hook name (params) body…)for the engine entry points (validated at LOAD time against the six known hooks, so a typo'd hook dies loudly instead of silently no-op'ing). The interpreter will REJECT anydefine/defun/defvar/define-hook/set!on a name the game owns (bank-/market-/game- prefixes,config, language builtins, installed engine builtins) — the file literally cannot blur the boundary.Reads naturally as Lisp:
condgains a properelseclause (retiring the((> 1 0) …)/(1 …)default-clause hacks in every brain), unquoted or unknown(config …)keys now produce a clear error instead of silently returning 0.World models untouched: migration is purely mechanical — each of the four mains keeps its structurally distinct model (empire's funding-horizon term structure, mill's per-loan actuary, vault's cushion + book-quality, adapt's regime inference), no logic changes.
Commit order (green at every commit): (1) engine + protections, backward-compatible; (2) four mains migrated; (3) ten specialists migrated; (4) docs/ai-api.md + README + tests; (5) remove deprecated bare caps, lockdown + full gate (build/test/vet/smoke/quick bench/gauntlet smoke). Writing code now.
Step 2 — first green commit pushed:
8d32292on79-api-clean.Engine-side API landed, backward-compatible:
defun/defvar/define-hookforms,condelseclause, load-time hook-name validation, and hard rejections of any filedefine/set!that touches a game-owned name (bank-*,market-*,game-*,config, core builtins).(config 'deposit-rate-cap)/(config 'loan-rate-cap)added as keys; unknown/unquoted config keys now error instead of silently returning 0.Gate:
go build+go test .(ok) +go vet ./...(clean) + spectate smoke with seed 33: 0[aierrors, 0 ACCT/CF DIVERGENCE.Three file helpers caught and renamed because they claimed the
market-namespace (mill'smarket-max-term, vault'smarket-avg-term/market-best-price, plus vault'smarket-bleeds-usstate var) — the exact file-vs-game blur this issue kills.Next: migrate the four mains to the new forms (defun/defvar/define-hook/else/config caps), logic untouched.
Step 3 — four mains migrated, pushed:
a460a8b.All four mains now read in the new API:
defunfor every helper,defvarfor file-global state (spread, bid-state, last-loan-id, did-bid, seen-banks, bleeds-us…),define-hookfor the six engine entry points,(config 'deposit-rate-cap)/(config 'loan-rate-cap)instead of bare cap symbols, and real(else …)cond clauses replacing the((> 1 0) …)/(1 …)hacks. World models untouched — empire's funding-horizon term structure, mill's per-loan actuary, vault's cushion/book-quality, adapt's regime inference all intact.The smoke gate caught a real interpreter bug this commit:
(else)written as a one-element list didn't match my matcher (brains write((else) …)), so cond fell through to eval and died with "unbound symbol: else" — 222[aierrors in the spectate. Fixed the matcher to accept both forms; re-ran the gate: 0[ai, 0 DIVERGENCE, tests + vet clean.Next: the ten specialists (deposit/loan/bond/auction-spec + all six two-mech hybrids).
Step 4 — specialists migrated and pushed:
5432cc6, quick bench green.All ten specialists now read in the new API (helpers
defun, entry pointsdefine-hook, quoted config caps,elsedefaults), each still playing exactly its own mechanism(s). Gates at commit: build/test/vet clean, spectate smokes of the mains roster AND every specialist (two games) with 0[aierrors, 0 DIVERGENCE.Quick regression bench (30 games × 13 presets, gauntlet 2 games per specialist across all 13 presets) completed with zero FATALs — every brain loads and plays under the new interpreter. Main-brain shape is intact: adapt leads hot-caps/thin-margins/base, mill leads duel, empire leads mega-loans/cash-glut/deposit-drought, vault present but behind, same as the pre-migration baseline. Specialists still get beat by the mains as designed (e.g. deposit-auction-spec 0/52).
Next:
docs/ai-api.md+ README section + new API tests, then the lockdown commit that removes the deprecated bare cap symbols.Step 5 — docs + tests pushed:
93a61f1, lockdown in progress.docs/ai-api.mdis in: the full contract — four game-owned read-only namespaces, the seven behavior actions, the file's own namespace (defun/defvar/define-hook/set!), the six hooks with expected returns, list shapes, language reference, what the interpreter enforces, a minimal-brain example, and the old-to-new migration table. README's AI section rewritten and linked to it.Tests:
TestReadAIFilesnow covers all 14 brain files; newapi79_test.gopins the contract — namespace reads, read-only protection (define/set! of game-owned names rejected with and without an engine env), define-hook load-time validation, defun/defvar/set! semantics,condelsein both forms, andTestAllBrainsLoadAndHooksRunwhich loads every brain file and calls all six hooks on every bank. Release copies indist/ai/synced. All tests green, vet clean, smoke 0/0.Lockdown: the two deprecated bare cap symbols are now removed from the engine —
(config 'deposit-rate-cap)/(config 'loan-rate-cap)are the only forms. Final bench (30×13 + gauntlet smoke) running now, then the PR.Done — PR #81 open: #81
Five commits on
79-api-clean, each green at its own gate:8d32292— engine:defun/defvar/define-hookforms,condelse, load-time hook validation, hard rejections of filedefine/set!on game-owned names,(config 'deposit-rate-cap)/(config 'loan-rate-cap)keys, unknown/unquoted config keys now error.a460a8b— four mains migrated (logic untouched; the smoke gate caught and fixed an(else)-form matcher bug).5432cc6— ten specialists migrated.93a61f1—docs/ai-api.md, README section,api79_test.go(namespace reads, read-only protection, hook validation, defun/defvar/set!, cond else, all-brains-load-and-run),TestReadAIFileson all 14 files,dist/ai/synced.3206240— lockdown: bare cap symbols removed; the config keys are the only forms.Final verification:
go build+ fullgo test .pass,go vet ./...clean, spectate smoke seed 33 (0[aierrors, 0 ACCT/CF DIVERGENCE), specialist-roster smokes 0/0, quick bench 30 games × 13 presets + gauntlet smoke with zero FATALs and the pre-migration win shape (mill 118 / empire 105 / adapt 85 / vault 33).The four mains keep their structurally distinct world models; the specialists still play exactly their own mechanisms. Review requested from robertismo.
Merged via PR #81 (
5fd73ddon master). Issue closed — ship note:The AI Lisp API redesign is on master:
bank-*/market-*/game-*/(config 'key)with the caps as config keys, enforced by the interpreter.defun/defvar, entry points viadefine-hook(load-time validated).condelse, strict(config 'key)errors.Next on the board: #15 (central bank) and #26 (v0.5.0 ideas incl. the full AI overhaul), plus #75's PR #76 still awaiting review.
Independent verification of merged master
5fd73dd(PR #81) — passed.I re-ran the full gate against a fresh worktree of the merge, not the feature branch:
go build+go test -count=1 .(all 20 tests incl. the new api79_test.go suite) +go vet ./...— clean.[aierrors, 0 ACCT/CF DIVERGENCE in every run.define/top-levelset!/bare cap symbols all gone), all 14 register hooks viadefine-hook, ai.go has 0 bare cap builtins, namespace protections in lisp.go, docs/ai-api.md present, dist/ai synced.API summary: game-owned reads live in four read-only namespaces (
bank-*,market-*,game-*,(config 'key)— quoted, now including the two caps); the only forms that change the game are the seven action verbs; file code usesdefun/defvar/define-hook(load-time validated) and the interpreter hard-rejects any file define/set! of a game-owned name. Full contract: docs/ai-api.md. Issue #79 done — PR #81 merged; the v0.5.0 super AI (#80) now has a clean API to be written in.Independent verification on merged master (
9417412, after #82 landed).Re-checked the AI API layer on the current master, since the GAAP audit (#82) merged right after #81 and changed accounting recognition:
Win mix on current master: empire 114 / mill 106 / vault 63 / adapt 88. The shift vs the #79 pre-merge baseline (105/118/33/85) is expected — #78 changed what bank-equity reports, and vault is the equity-cushion brain — not an API regression: every brain loads, every hook fires, zero [ai errors.
On the #79 merge itself (
5fd73dd) the bench was behavior-preserving: identical win shape to the pre-migration tree, which is the API-redesign guarantee. #79 work is verified end to end.