Domain-specific market query API (Closes #158) #167

Open
Winnie wants to merge 4 commits from 158-market into 157-control
Owner

Declarative queries as special forms so :where exprs compile as field templates: (loans :where (> term 5) :order-by amount :take 3), (bonds :cheapest 3), (deposits :average-rate), (bank :equity). Keywords are self-evaluating. Brains adopted them (super's sort-shelf, vault/adapt shelf reads). Byte-identical spectate vs pre-#158. Base is 157-control, which is still awaiting merge (#166).

Declarative queries as special forms so :where exprs compile as field templates: (loans :where (> term 5) :order-by amount :take 3), (bonds :cheapest 3), (deposits :average-rate), (bank :equity). Keywords are self-evaluating. Brains adopted them (super's sort-shelf, vault/adapt shelf reads). Byte-identical spectate vs pre-#158. Base is 157-control, which is still awaiting merge (#166).
Domain-specific market query API (Closes #158)
All checks were successful
build / build (push) Successful in 27s
9611342a54
The declarative queries land as special forms, so the :where
expressions arrive unevaluated and compile as field templates:

- (loans :where (> term 5) :order-by amount :take 3) — field names
  (id, amount, term, default) are in scope inside :where; :order-by
  takes a field name or a key function; :take truncates
- (bonds :cheapest 3) — price-ordered head of the bond market
- (deposits :average-rate | :sum | :count)
- (bank :equity | :cash | :deposits | :deposit-rate | :id)
- keywords (:name) are now self-evaluating, so the kw args need no
  quoting

The engine installs a marketQuery bridge per game, so the queries
see the phase-start snapshots exactly like the raw accessors.

Brains: super's sort-shelf is now (loans :order-by loan-hazard-est),
vault and adapt read the shelf through the (loans) query. The
predicates loan?/bond?/offer? already shipped in #156.

Behavior-preserving: byte-identical seeded spectate against the
pre-#158 build.
State and config as first-class concepts (Closes #159)
All checks were successful
build / build (push) Successful in 28s
b0e17fdd21
- define-state: (define-state counter 0 :doc "times we've bid") —
  per-seat state (each brain loads into its own env chain), with a
  doc string and reset semantics
- reset-state: re-evaluates every define-state initial in the seat
- state-docs: lists (name doc) for the seat's defined state
- config schema: every (config 'key) now carries a type, sane range,
  default, and doc. Brains can ask:
  - (config-doc 'loan-rate-cap)
  - (config-range 'loan-rate-cap)
  - (config-schema) — the full 14-entry schema as records
  No more guessing units and bounds.

Full suite green, vet clean.
Strategy combinators + state/config (Closes #160)
All checks were successful
build / build (push) Successful in 27s
46b2d090e9
- A strategy prelude (ai/prelude.lisp) loads before every brain:
  risk primitives (hazard, cum-default, ev, cushion, vickrey-bid),
  decision helpers (when-regime, priority, fallback, guard,
  weighted-choice), and an opponent model (ema, softmax-share,
  predict-next, laplace)
- (define-state name initial :doc "...") with reset-state and
  state-docs; per-seat by construction
- config schema introspection: (config-doc 'key), (config-range 'key),
  (config-schema) — every config key carries type, range, default,
  and a doc string
- nil? builtin joins the stdlib (empty list counts as nil)

Brains: mill now takes its cumulative-default risk from the prelude
instead of its local copy. Behavior-preserving: byte-identical
seeded spectate.
- Hook errors now carry the brain file and hook name (broken.lisp:
  deposit-rate: ...), on top of the existing stderr + game-log
  surfacing and the panic/recovery, recursion-limit, arity-guard,
  and non-finite rejection sandbox (#121/#91)
- -trace flag: logs every hook decision as it happens
  (bankwars -trace) so an author can see what the brain did and why
- (import 'path) loads a module into the seat's env; disk files take
  precedence, the embedded copy is the fallback
- AI-AUTHORING.md: the full hook contract, the record/query API, the
  stdlib and prelude reference, state/config, and a cookbook (pricing
  a loan, detecting a storm, a Vickrey bid, backtesting a regime)

Headless simulation with seeds, replay, and tournaments already
existed (--replay, --save, the bench); the decision tracing and the
error context complete the issue's remaining asks. Byte-identical
seeded spectate.
All checks were successful
build / build (push) Successful in 28s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin 158-market:158-market
git switch 158-market

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch 157-control
git merge --no-ff 158-market
git switch 158-market
git rebase 157-control
git switch 157-control
git merge --ff-only 158-market
git switch 158-market
git rebase 157-control
git switch 157-control
git merge --no-ff 158-market
git switch 157-control
git merge --squash 158-market
git switch 157-control
git merge --ff-only 158-market
git switch 157-control
git merge 158-market
git push origin 157-control
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Winnie/bankwars!167
No description provided.