The stepped engine becomes a runnable taskset. protocol.py is both the render/parse boundary and the security boundary: TurnView carries the live Market, so view.market.items[i].prices is the whole held-out series and a foresight policy reading it earned +9.4% on the oracle. The renderer emits only observed ticks, the trace carries plain scalars, and a sentinel scan of every rendered turn fails if either reopens. House rule 1 had no other enforcement. Replies are a delta sheet and parsing never raises — NaN, Infinity, 1e309 and 20k-deep nesting all resolve to a hold, because the one-shot form has already shown what a real model sends when it gives up. LiveExchangeEnv.run drives the engine host-side with the harness left null. Two things learned the hard way and worth keeping: a terminated Segment mid-window holds the remaining looks instead of raising, and rewards are recorded INSIDE the interaction, before close. Recording after close writes the traces correctly and leaves every eval.log line reading reward=0.000 — the canonical verifiers reference does it after the block; do not copy it there. The reference-family gate is widened from four named rungs to the whole 8x8 (requote_band, idle_share) family: no member may out-earn the shipped reference by more than 1.02x, and any that does must still score >= 0.90. That is the check that caught the first draft's fake 0.152 gap, now shipped rather than remembered. Also guards `clean` on the reference being profitable, here and in the one-shot form. Against a reference that lost money the bar is negative, so doing nothing cleared it and inaction collected a quarter of the reward. Unreachable while viable_market admits only profitable references; one relaxed filter from reachable, and exactly the floor house rule 3 forbids. Probe values unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
24 lines
1.1 KiB
TOML
24 lines
1.1 KiB
TOML
# grand-exchange-live — see environments/grand_exchange_live for what it measures.
|
|
#
|
|
# uv run --project environments/grand_exchange_live eval @ configs/grand_exchange_live.toml \
|
|
# --model <model-id>
|
|
#
|
|
# Eight looks per episode against one basket, so a rollout here costs roughly eight times a
|
|
# one-shot `grand-exchange` rollout in requests and rather more than that in tokens: the
|
|
# whole conversation is replayed to the model on every segment. `num_tasks` is half the
|
|
# one-shot config's for that reason, not because fewer baskets measure better — realised
|
|
# P&L over sixty ticks is the noisiest number in this repository and the ladder is read
|
|
# over five blocks of twenty-four.
|
|
num_tasks = 8
|
|
num_rollouts = 2
|
|
|
|
[env.taskset]
|
|
id = "grand-exchange-live"
|
|
num_items = 5 # items in the basket, one per price tier
|
|
visible = 56 # warmup ticks, read before the first look
|
|
# The graded window is not configurable: 8 looks x 7 ticks + a 4-tick tail = 60, and every
|
|
# constant in the reward was measured against that shape (`measure_ladder.py --sweep-shape`).
|
|
|
|
[env.agent.harness]
|
|
id = "null" # pure-trace reward: a chat loop, no tools, no runtime
|