\section{LLM agent design} \label{sec:llm_design} The laboratory follows one discipline, borrowed from the zero-intelligence tradition of \citet{gode1993allocative}: the market and the accounting are deterministic code, and a language model is one of several interchangeable \emph{policies} that may propose actions. Nothing a model writes changes a ledger until it has been parsed, validated and clipped. \paragraph{Roles and mandates.} Eight roles are defined (household, investor, firm manager, lender, market maker, AI portfolio manager, procurement agent, regulator). The experiments in this paper exercise the investor/AI portfolio manager role, with the lender and market-maker roles implemented as deterministic rules; the remaining prompts are in Appendix~\ref{app:prompts} and are part of the replication package. The investor mandate states the principal's objective (next-period expected wealth with moderate risk), the borrowing limit and the exact JSON format. \paragraph{Observations and actions.} Observations are JSON objects containing only $t$-dated information plus the agent's own signal about $t+1$ (price, dividend, rate, expected dividend, cash, holdings, loan, equity, margin, loan capacity, the last five prices and the agent's own valuation). Actions must satisfy a JSON schema (\texttt{side}, \texttt{quantity}, \texttt{order\_type}, \texttt{limit\_price}, \texttt{borrow}, \texttt{rationale}); a reply that is not a valid object is sent back once with a repair instruction, and a second failure is recorded as an \emph{invalid action} and treated as ``hold''. Valid actions are clipped by the ledger (borrowing to capacity, purchases to cash, sales to holdings). Invalid and clipped actions are counted and reported. \paragraph{Inference, audit and cache.} Inference runs on local open-weight models served through an OpenAI-compatible endpoint (\texttt{mlx\_lm.server} on Apple-silicon nodes of the author's cluster): Qwen2.5-7B-Instruct, Mistral-7B-Instruct-v0.3 and Llama-3.2-3B-Instruct, all 4-bit. Optional hosted providers are supported through environment variables only; no credential is embedded and none was used for the results reported here. Every call records provider, model, system fingerprint, prompt and context hashes, full messages, temperature, seed, response, validity, latency, token usage and (zero, here) cost, in an append-only JSONL audit log. Responses are cached content-addressed on (provider, model, messages, temperature, seed, schema); network errors are never cached. A run can therefore be replayed bit-for-bit without inference. \paragraph{Controls.} The pre-registered controls are the Bayesian mean-variance agent; a rule-based \emph{surrogate} that implements the Bayesian rule behind the LLM interface (interface effects only); a single shared model for all agents; three heterogeneous models assigned round-robin; one model with five prompt variants; temperature 0 and 0.7; memory of the last three actions; and seed stability. Simulated LLM behaviour is reported as such and is never interpreted as evidence about human preferences. \paragraph{What is and is not live.} Figures labelled ``LLM'' use live inference on the models above, at the dates in the audit logs. The surrogate is not an LLM and is labelled as such everywhere. No trained policy surrogate (a model fitted to LLM actions) is used in this version; the design supports it, and validation on held-out actions would be required before any such surrogate is reported.