codex: low-alch-members — loss-reserve stop direction + fill-price scenario GP bounds (bounce-fix attempt 5)
Owner guidance 2026-08-29 for governor review 10361 (PR #8), finding by finding: 1. Loss-reserve stop direction — the stop read 'session net loss (total assets - initial capital) > 162,990'; a loss makes that LHS negative so it could never exceed the positive reserve (the stop could never fire). Now expressed everywhere as 'initial capital - total assets > 162,990' (stop_conditions, worked-example step 6, recovery block, version pin): a loss makes the difference positive, the strict-greater comparison fires on losses and never on profits, and exactly-at-boundary does not fire. tools/validate.py gains alch_accounting_regression(): comparator boundary fixtures (below 162,989 / at 162,990 / above 162,991 / profit side +50,000 / breakeven) plus entry-text pins rejecting the reversed form anywhere in the file. 2. Fill-price scenarios for realized GP bounds — previously gp_per_hour_low /high derived only from the live-low -3.00/cast margin while the buy policy permits live low + 5% (candidate 423.15 + nature 147 = 570.15 vs 540 lowalch = -30.15/cast). The economy block now declares FILL-PRICE SCENARIOS A (live-low 543 -> -3.00/cast) and B (max allowed +5% 570.15 -> -30.15/cast) as the single ledger behind capital, batch economics AND the GP bounds: gp_per_hour_low -29,463 (scenario B x session-fast 977.2), gp_per_hour_high -1,758 (scenario A x session-slow 585.9), midpoints -22,365 / -2,225 pinned; validator enforces the exact bound values and the -30.15/570.15/423.15 scenario pins. Preserved: complete GE acquisition/restock flow, one-cast iteration, monotonic break/restock counters, total-assets accounting (floor 575,150), fail-closed staff path, and the earlier fixed pacing/equip findings. version 5 -> 6, updated 2026-08-29. Gate: python3 tools/validate.py -> 2 entries, 0 errors, 1 pre-existing F2P WARN (low-alch-f2p researched, untouched); git diff --check clean; regression negative-tested (old gp pins, reversed form, missing scenario pins all rejected).
This commit is contained in:
parent
a197b34aa8
commit
052c6984ac
@ -3,8 +3,8 @@ title: Low-Level Alchemy (Members)
|
||||
domain: economy
|
||||
tags: [alching, magic-training, members, loss-training]
|
||||
status: verified
|
||||
version: 5 # 5: bounce-fix 4 2026-08-28 (owner guidance 10325) — complete GE acquisition path (open -> place -> fill -> collect) for initial buy AND every restock (bank-stock fast path only when the bank holds stock); fail-closed staff equip (bounded retries, no fire-rune fallback); capital model (cash vs supplies, staff cost, max-fill worst case, 6-batch loss reserve, float); monotonic break/restock counters (breaks 550/1,100/1,650 independent of restocks 901/1,802) + validator regression; startup-vs-steady-state rates over a 2 h session horizon
|
||||
updated: "2026-08-28" # ISO dates must stay quoted — YAML 1.1 parses bare dates to datetime.date
|
||||
version: 6 # 6: bounce-fix 5 2026-08-29 (owner guidance for governor 10361) — loss-reserve stop fixed to 'initial capital - total assets > 162,990' everywhere + validator boundary fixtures (below/at/above/profit) + realized GP/hr bounds derived from declared fill-price scenarios (A live-low -3.00/cast, B max allowed +5% -30.15/cast): gp low -29,463 / high -1,758. # 5: bounce-fix 4 2026-08-28 (owner guidance 10325) — complete GE acquisition path (open -> place -> fill -> collect) for initial buy AND every restock (bank-stock fast path only when the bank holds stock); fail-closed staff equip (bounded retries, no fire-rune fallback); capital model (cash vs supplies, staff cost, max-fill worst case, 6-batch loss reserve, float); monotonic break/restock counters (breaks 550/1,100/1,650 independent of restocks 901/1,802) + validator regression; startup-vs-steady-state rates over a 2 h session horizon
|
||||
updated: "2026-08-29" # ISO dates must stay quoted — YAML 1.1 parses bare dates to datetime.date
|
||||
|
||||
summary: >
|
||||
Magic training from level 21 by low-alching members items with the lowest
|
||||
@ -13,7 +13,10 @@ summary: >
|
||||
(mapping lowalch != null, members=true, live GE prices 2026-08-27). At
|
||||
current prices the method burns a small amount of GP per cast for 31 XP —
|
||||
run it for XP, not GP. Least-loss liquid anchor at last check: rune
|
||||
javelin tips (-3/cast). Model pins (owner guidance 2026-08-28): one
|
||||
javelin tips (live-low net -3/cast; realized loss band -1,758 to -29,463
|
||||
gp/hr across the declared live-low and max-allowed +5% fill scenarios —
|
||||
XP is fill-independent at 23,000/hr session-realized midpoint). Model
|
||||
pins (owner guidance 2026-08-28): one
|
||||
iteration = one cast; breaks every 400-700 COMPLETED CASTS (cast-count
|
||||
based, independent of bank visits — midpoint example: 550, 1,100, 1,650,
|
||||
...); restock when candidate or nature drops below the numeric
|
||||
@ -68,8 +71,8 @@ economy:
|
||||
cost_per_cycle: 543 # javelin tips buy 403 + nature rune 140 (staff of fire, live low 2026-08-27)
|
||||
income_per_cycle: 540 # lowalch of rune javelin tips (40% of value 1350)
|
||||
net_per_cycle: -3
|
||||
gp_per_hour_low: -2930 # session-realized fast bound: 977.2 casts/hr x -3 = -2,932 (3.4 s cycle, 300 s startup, 2 h horizon)
|
||||
gp_per_hour_high: -1760 # session-realized slow bound: 585.9 casts/hr x -3 = -1,758 (5.2 s cycle, 600 s startup, 2 h horizon)
|
||||
gp_per_hour_low: -29463 # WORST-CASE realized: max-allowed fill scenario B (-30.15/cast) x session-fast 977.2 casts/hr = -29,462.6 (3.4 s cycle, 300 s startup, 2 h horizon) — see FILL-PRICE SCENARIOS below
|
||||
gp_per_hour_high: -1758 # BEST-CASE realized: live-low fill scenario A (-3.00/cast) x session-slow 585.9 casts/hr = -1,757.7 (5.2 s cycle, 600 s startup, 2 h horizon) — see FILL-PRICE SCENARIOS below
|
||||
xp_per_hour: 23000 # session-realized midpoint: 741.8 casts/hr x 31 = 22,995 (pin 23,000)
|
||||
# ---- rate model (pinned; owner guidance 2026-08-28) ----
|
||||
# LOOP (idealised, zero overhead — ceiling reference ONLY, never the
|
||||
@ -87,14 +90,30 @@ economy:
|
||||
# SESSION-REALIZED (2 h horizon = 7,200 s; one-time startup 300-600 s,
|
||||
# mid 450 s -> 450/7200 = 6.25 %): realized = steady-state x (1 -
|
||||
# startup/session): fast 977.2, mid 741.8, slow 585.9 casts/hr.
|
||||
# xp mid = 741.8 x 31 = 22,995 -> pin 23,000; gp = casts/hr x -3:
|
||||
# low -2,932 (fast), high -1,758 (slow), mid -2,225.
|
||||
# xp mid = 741.8 x 31 = 22,995 -> pin 23,000. REALIZED GP/hr derives from
|
||||
# the FILL-PRICE SCENARIOS below (the SAME ledger as the batch economics):
|
||||
# worst = -29,463 = scenario B x session-fast 977.2 (-30.15 x 977.2 = -29,462.6)
|
||||
# best = -1,758 = scenario A x session-slow 585.9 (-3.00 x 585.9 = -1,757.7)
|
||||
# midpoints: scenario A x 741.8 = -2,225; scenario B x 741.8 = -22,365.
|
||||
# BATCH ECONOMICS (901 casts; deposits 901 x 540 = 486,540 gp per batch):
|
||||
# input cost at live low: 901 x 543 = 489,243 -> net -2,703/batch
|
||||
# input cost at MAX fill (live low + 5 %): 901 x 570.15 = 513,705 -> net
|
||||
# -27,165/batch (worst case). Reserve = 6 worst-case batches (Magic
|
||||
# 21 -> 55 = ~5,300 casts = ~6 batches) = 162,990 gp; the capital stop
|
||||
# checks TOTAL ASSETS, not raw cash (see accounts + stop_conditions).
|
||||
# FILL-PRICE SCENARIOS (one ledger for capital, batch economics, AND the
|
||||
# realized GP bounds — every number below comes from the same scenario):
|
||||
# A live-low fill: candidate 403 + nature 140 = 543/cast vs
|
||||
# 540 lowalch -> net -3.00/cast (the anchor)
|
||||
# B max allowed fill (+5%): candidate 403x1.05 = 423.15 + nature
|
||||
# 140x1.05 = 147 -> 570.15/cast vs 540 lowalch
|
||||
# -> net -30.15/cast (the executable buy policy
|
||||
# permits live low + 5%; this scenario, not the
|
||||
# -3 live-low margin, bounds the downside)
|
||||
# gp_per_hour_low = -29,463 | gp_per_hour_high = -1,758 derive from these
|
||||
# scenarios at the session rates above; the batch ledger uses the same
|
||||
# 543 / 570.15 per-cast costs (901-cast batch: -2,703 live-low, -27,165
|
||||
# max fill), so capital accounting and GP bounds can never diverge.
|
||||
supplies:
|
||||
- item: rune javelin tips
|
||||
qty_per_cycle: 1
|
||||
@ -363,7 +382,7 @@ run_control:
|
||||
- "magic level >= target (55 -> hand off to HLA)"
|
||||
- "session elapsed >= 2 h (session horizon — startup is amortised over this window in the rate model)"
|
||||
- "total assets (cash + supplies at current buy cost) < 575,150 — cannot fund the next batch at max fill (570,150) plus staff replacement (5,000); assets, NOT raw cash: cash that became supplies is not a loss"
|
||||
- "session net loss (total assets - initial capital) > 162,990 — the 6-batch worst-case loss reserve is exhausted"
|
||||
- "session net loss: initial capital - total assets > 162,990 — a loss makes 'initial capital - total assets' POSITIVE, so this strict-greater comparison fires on losses and never on profits; 162,990 = the 6-batch worst-case reserve (exactly AT the boundary it does NOT fire — strict >)"
|
||||
- "3 consecutive failed casts (client issue — do not loop)"
|
||||
- "3 consecutive no-fill GE rounds (initial acquisition or restock) with no fallback candidate available"
|
||||
- "staff of fire equip failed after bounded retries — FAIL CLOSED (log ERROR, alert, stop)"
|
||||
@ -406,8 +425,9 @@ run_control:
|
||||
# 1,802 (901-cadence, 1,802 = 901 x 2). The sequences 550/1,100/1,650/2,200
|
||||
# and 901/1,802/2,703 interleave independently.
|
||||
# Step 6 — continue until a stop_condition fires: Magic >= 55 (HLA handoff),
|
||||
# the 2 h session horizon, the capital stops (assets floor 575,150 or net
|
||||
# loss > 162,990), 3 failed casts, or 3 consecutive no-fill GE rounds.
|
||||
# the 2 h session horizon, the capital stops (assets floor 575,150, or
|
||||
# loss = initial capital - total assets > 162,990), 3 failed casts, or 3
|
||||
# consecutive no-fill GE rounds.
|
||||
# ============================================================================================
|
||||
|
||||
risk:
|
||||
@ -436,7 +456,11 @@ risk:
|
||||
# (a8); 3 consecutive failed casts -> failed (stop, log ERROR sentinel, alert).
|
||||
# - Capital: the stop checks TOTAL ASSETS (cash + supplies at current buy cost), and
|
||||
# both capital stops are assets-based (see stop_conditions) — cash converted into
|
||||
# supplies is not a loss and never fires a stop by itself.
|
||||
# supplies is not a loss and never fires a stop by itself. Loss direction is pinned
|
||||
# everywhere as 'initial capital - total assets > 162,990': a loss makes that
|
||||
# difference positive, so the stop fires on losses and never on profits (the
|
||||
# reversed sign form can never exceed the threshold on a loss and is rejected by
|
||||
# the validator regression; boundary fixtures: below/at/above + profit side).
|
||||
# - Explicit completion/stop: stop_conditions above (Magic 55 HLA handoff, 2 h session
|
||||
# horizon, assets floor 575,150, loss reserve 162,990, repeated failures, fail-closed
|
||||
# staff equip).
|
||||
|
||||
@ -72,6 +72,77 @@ def alch_worked_example_regression(rel, data, raw_text):
|
||||
return errs
|
||||
|
||||
|
||||
def _loss_reserve_stop(initial_capital, total_assets, reserve):
|
||||
"""Loss-reserve stop comparator in the pinned direction (owner guidance
|
||||
2026-08-29, governor review 10361, PR #8): stop fires only when the
|
||||
loss EXCEEDS the reserve, i.e. when (initial capital - total assets)
|
||||
> reserve. A loss makes the LHS positive; a profit (total assets >
|
||||
initial capital) makes it negative and can never fire this stop. The
|
||||
reversed 'total assets - initial capital' form is invalid because it
|
||||
is negative exactly when a loss exists."""
|
||||
return (initial_capital - total_assets) > reserve
|
||||
|
||||
|
||||
def alch_accounting_regression(rel, data, raw_text):
|
||||
"""Loss-reserve + fill-price accounting regression (owner guidance
|
||||
2026-08-29 for governor review 10361, PR #8): the low-alch-members
|
||||
entry must express the loss-reserve stop in the correct direction
|
||||
EVERYWHERE ('initial capital - total assets > 162,990'), the reversed
|
||||
sign form must never reappear, and the realized GP/hour bounds must be
|
||||
derived from the declared fill-price scenarios (A live-low -3.00/cast
|
||||
vs B max allowed +5% fill -30.15/cast), exposing the +5% fill loss
|
||||
instead of recycling the live-low margin. Includes below/at/above
|
||||
boundary fixtures and a profit-side negative regression for the
|
||||
comparator itself. Scoped to the members low-alchemy entry only."""
|
||||
if data.get("id") != "low-alch-members":
|
||||
return []
|
||||
errs = []
|
||||
|
||||
# 1. comparator boundary fixtures (pure function, entry's own constants)
|
||||
INIT, RESERVE = 1_308_290, 162_990 # entry capital / 6-batch reserve
|
||||
fixtures = [
|
||||
("below (loss 162,989)", INIT - 162_989, False),
|
||||
("at boundary (loss 162,990, strict >)", INIT - 162_990, False),
|
||||
("above (loss 162,991)", INIT - 162_991, True),
|
||||
("profit side (assets 50,000 above initial)", INIT + 50_000, False),
|
||||
("breakeven (assets == initial)", INIT, False),
|
||||
]
|
||||
for label, total_assets, expect in fixtures:
|
||||
got = _loss_reserve_stop(INIT, total_assets, RESERVE)
|
||||
if got != expect:
|
||||
errs.append(f"{rel}: loss-reserve comparator fixture '{label}' "
|
||||
f"returned {got}, expected {expect}")
|
||||
|
||||
# 2. entry direction: correct form present, reversed form absent
|
||||
if "initial capital - total assets > 162,990" not in raw_text:
|
||||
errs.append(f"{rel}: loss-reserve stop must be expressed as "
|
||||
f"'initial capital - total assets > 162,990' everywhere")
|
||||
if "total assets - initial capital" in raw_text:
|
||||
errs.append(f"{rel}: loss-reserve stop uses the reversed sign form — "
|
||||
f"on a loss it is negative and can never exceed the "
|
||||
f"reserve; use 'initial capital - total assets > 162,990'")
|
||||
|
||||
# 3. realized GP bounds must come from the fill-price scenarios
|
||||
eco = data.get("economy", {})
|
||||
if eco.get("gp_per_hour_low") != -29463:
|
||||
errs.append(f"{rel}: gp_per_hour_low must be -29,463 (max-fill "
|
||||
f"scenario B -30.15/cast x session-fast 977.2 casts/hr "
|
||||
f"= -29,462.6), got {eco.get('gp_per_hour_low')}")
|
||||
if eco.get("gp_per_hour_high") != -1758:
|
||||
errs.append(f"{rel}: gp_per_hour_high must be -1,758 (live-low "
|
||||
f"scenario A -3.00/cast x session-slow 585.9 casts/hr "
|
||||
f"= -1,757.7), got {eco.get('gp_per_hour_high')}")
|
||||
for pin, label in (("-30.15", "max-fill per-cast loss -30.15"),
|
||||
("570.15", "max-fill per-cast cost 570.15"),
|
||||
("423.15", "max-fill candidate price 423.15")):
|
||||
if pin not in raw_text:
|
||||
errs.append(f"{rel}: economy FILL-PRICE SCENARIOS missing {label} "
|
||||
f"({pin}) — the +5% accepted-fill scenario must be "
|
||||
f"declared so the realized GP bounds cannot silently "
|
||||
f"revert to the live-low-only margin")
|
||||
return errs
|
||||
|
||||
|
||||
def main():
|
||||
global STALE_DAYS
|
||||
if "--stale-days" in sys.argv:
|
||||
@ -134,6 +205,10 @@ def main():
|
||||
# monotonic break/restock counters, scoped to the one-cast model
|
||||
errors += alch_worked_example_regression(rel, data, path.read_text())
|
||||
|
||||
# loss-reserve direction + fill-price GP bound regression (owner
|
||||
# guidance 2026-08-29 for governor 10361), scoped to low-alch-members
|
||||
errors += alch_accounting_regression(rel, data, path.read_text())
|
||||
|
||||
# action id/step uniqueness
|
||||
a_ids = [a["id"] for a in data["actions"]]
|
||||
a_steps = [a["step"] for a in data["actions"]]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user