codex: complete GE-flip lifecycle per owner addendum — partial fills, ge_cancel recovery, ledger, break/resume, realized rates (bounce-fix 4)

Owner lifecycle addendum (2026-08-28) + governor bounce 4 (lifecycle contract):
- state machine now covers the ENTIRE buy -> sell -> collect flow with no
  stranded state: partial fills tracked per slot (filled_qty ledger), 4h-lapse
  buys go to a new cancel_requote state (ge_cancel: units return to inventory,
  cash refunds, slot freed) instead of collect, cancelled units still sell at
  the high edge, lapse sells re-quote or lower rather than strand
- action grammar + schema extended ONCE with the cancellation mutation
  ge_cancel (was missing; ge_clear/ge_offers_done are predicates only) and
  used explicitly in the new a8 cancel-requote action
- concrete runtime state: minimum per-slot capital table (buy x 4h limit),
  members 8-slot vs F2P 3-slot paths, per-slot offer phase + quantities,
  buy-limit window, inventory/collection reconciliation in a9
- breaks connected to an explicit safe/resume path: resting offers persist
  server-side + per-slot ledger survive the pause; resume = re-open GE,
  re-check offers, continue current phase; never break mid-collect/mid-place
- rates qualified against the full lifecycle: 149,500 gp/h is named the 4h
  buy-limit CEILING; realized range = ceiling x fill_factor (~0.5-0.9) x
  duty_cycle (~0.90-0.95) ~ 96,300 gp/h midpoint; gp_per_hour_low 74,750
- pinned worked example: capital 22.5M -> 8 slot quotes -> arrowtips partial
  fill (4,000/10,000 tracked) -> iron bar full fill sell (90,000 net) ->
  cosmic no-fill ge_cancel + requote -> arrowtips partial matures at lapse
  (cancel, sell 4,000, 68,000 net) -> first break after 6-10 rotations ->
  resume -> stop conditions
- version 2 -> 3; evidence: validate 2 entries 0 errors 1 pre-existing WARN,
  selftest 4 PASS (fractional-tax fail, ge non-margin pass, floored pass,
  above-cap pass), synthetic merge main 79cab78 + head clean + gate green,
  git diff --check clean
This commit is contained in:
Claude 2026-08-28 03:19:13 -05:00
parent 00bfc358cb
commit 3572255a11
3 changed files with 182 additions and 50 deletions

View File

@ -3,17 +3,22 @@ title: GE Flipping (margin trading)
domain: economy
tags: [flipping, merchanting, ge, money-making, hybrid]
status: verified
version: 2
updated: "2026-08-27" # ISO dates must stay quoted — YAML 1.1 parses bare dates to datetime.date
version: 3 # 3: bounce-fix 4 2026-08-28 (owner lifecycle addendum) — complete runnable flow: partial fills, ge_cancel + requote recovery, per-slot ledger, break/resume path, lifecycle-qualified rates, worked example pinned; ge_cancel added to the action grammar + schema
updated: "2026-08-28" # ISO dates must stay quoted — YAML 1.1 parses bare dates to datetime.date
summary: >
Buy-and-sell Grand Exchange margin flipping: place resting buy offers at
the low edge of an item's price band and resting sell offers at the high
edge, harvesting the spread on high-volume items. There are no skill or
quest requirements — capital breadth and slot discipline are the whole
game. Members accounts run 8 GE slots over the full candidate set;
F2P accounts get 3 slots and F2P-tradeable rows only (separate F2P path
in profit_drivers).
game. Members accounts run 8 GE slots over the full candidate set; F2P
accounts get 3 slots and F2P-tradeable rows only (separate F2P path in
profit_drivers). Lifecycle (owner addendum 2026-08-28): the entry models
the complete runnable flow — capital allocation, per-slot quotes with a
quoted/filled/sold/collected ledger, partial fills, ge_cancel +
requote recovery on window lapse or stale prices, collection and
reconciliation, breaks on resting offers, and explicit stop conditions —
with a pinned worked example and realized (not idealised) rates.
accounts:
membership: hybrid # members: 8 slots/full set; F2P: 3 slots/F2P rows (see economy)
@ -22,6 +27,7 @@ accounts:
requires_other:
- "Post-Tutorial Island account with Grand Exchange access (no skill or quest requirement)"
- "Members account: 8 GE slots, full candidate set (the modeled path below). F2P account: 3 GE slots and F2P-tradeable rows only — run the F2P path in profit_drivers."
- "Minimum starting capital: per slot = buy edge x 4h limit (arrowtips 2.23M, iron bar 1.45M, cosmic 2.196M, silver ore 0.949M, swordfish 3.09M, lobster 1.59M, magic logs 9.264M, mud 1.728M at the 2026-08-27 snapshot) — full 8-slot members coverage ~22.5M; the 3-slot F2P path needs ~5.5M (iron 1.45M + cosmic 2.196M + silver 0.949M). Capital below one slot's requirement takes that slot off the table."
best_practice:
equipment:
@ -58,15 +64,22 @@ best_practice:
members set — a hybrid account must swap to the 3-slot F2P path (Iron bar /
Cosmic rune / Silver ore) instead of chasing members-only rows it cannot buy."
source: "OSRS wiki — Grand Exchange (Members get eight Grand Exchange slots ... free players are limited to three. Additionally, free players may only purchase free-to-play items, and not members' items)"
- name: keep a per-slot offer ledger; cancel-and-requote on lapse, never strand units
why: "Every slot tracks quoted qty -> filled qty -> sold qty -> collected proceeds.
A partially-filled offer keeps resting with its acquired units attached; on the 4h
window lapse or a stale price the slot is ge_cancel'ed — acquired units return to
inventory, unspent cash refunds — then re-quoted at the fresh edge (buy) or exited
at the current high edge (sell). No items, coins, or GE slots are ever stranded."
source: "OSRS wiki — Grand Exchange (offer mechanics; 4h window); docs/action-grammar.md (ge_cancel, added 2026-08-28)"
economy:
# Model (documented, reproducible from the snapshot):
# Members path (8 GE slots — the modeled economics below):
# per slot: buy `limit` units at the low edge, sell at the high edge.
# tax_pu = floor(0.02 * sell) # 2% convenience fee, rounded DOWN to
# # whole coins per item; the 5M/item cap
# # and the sub-50gp rounding exemption
# # are not hit at these prices
# tax_pu = min(floor(0.02 * sell), 5_000_000) # 2% convenience fee,
# # rounded DOWN to whole coins per item,
# # capped 5M/item (owner decision
# # 2026-08-28; cap never hit here)
# net_pu = sell - tax_pu - buy # integer per-item net (floored tax)
# 4h/slot = net_pu * limit # buy-limit window caps per-4h volume
# F2P path (3 GE slots, F2P-tradeable rows only): same arithmetic, top-3
@ -74,13 +87,25 @@ economy:
# Snapshots 2026-08-27: prices.runescape.wiki mapping + latest; limits and
# members flags cross-checked against the wiki item pages (all agree). Top 8
# by 4h/slot below in profit_drivers.
#
# Lifecycle qualification (owner addendum 2026-08-28): the 4h figures are
# an economic CEILING — ideal full fills of every slot with zero overhead.
# The realized operating range is:
# realized gp/h = ceiling x fill_factor x duty_cycle, where
# fill_factor ~0.5-0.9 (partial fills, cancels, requotes reduce the
# filled volume) and duty_cycle ~0.90-0.95 (scan + place + collect
# ~3 min per ~40-min rotation; breaks every 6-10 rotations).
# Example midpoint: 149,500 x 0.70 x 0.92 ≈ 96,300 gp/h.
# gp_per_hour_low (74,750) = 50% of the ceiling — a conservative realized
# lower bound; gp_per_hour_high (149,500) = the named ceiling, never
# presented as the achieved runtime rate.
item: Rune arrowtips # anchor: top candidate by modeled 4h/slot (members)
item_id: 44
cost_per_cycle: 223 # buy @ low edge per unit (snapshot 2026-08-27)
income_per_cycle: 244 # sell @ high edge per unit, gross (snapshot 2026-08-27)
net_per_cycle: 17 # 244 - floor(244*0.02) - 223 = 244 - 4 - 223 (floored tax)
gp_per_hour_low: 74750 # 50% of the top-8 modeled upper bound — partial fills/drift
gp_per_hour_high: 149500 # top-8 modeled upper bound: sum(4h/slot) / 4 (8 slots, full fills)
net_per_cycle: 17 # 244 - min(floor(244*0.02), 5M) - 223 = 244 - 4 - 223 (floored, capped tax)
gp_per_hour_low: 74750 # realized lower bound = 50% of the ceiling: partial fills, cancels/requotes, collection trips, breaks
gp_per_hour_high: 149500 # 4h buy-limit CEILING: sum(4h/slot) / 4 (8 members slots, ideal full fills, zero overhead) — qualified above
xp_per_hour: 0 # flipping awards no XP
supplies:
- item: Rune arrowtips # canonical wiki names per action-grammar conventions
@ -98,70 +123,95 @@ economy:
profit_drivers:
- "Spread per unit x trade volume; volume is the safety factor (high-volume items fill faster and drift less)"
- "Slot breadth: cover as many net-positive candidates as capital allows (members 8 slots / F2P 3 slots)"
- "Members path — snapshot 2026-08-27 top 8 by modeled 4h/slot (floored 2% tax): Rune arrowtips 170,000 (M, buy 223 / sell 244 / limit 10000); Iron bar 90,000 (F2P, 145/157/10000); Cosmic rune 72,000 (F2P, 122/128/18000); Magic logs 72,000 (M, 772/793/12000); Silver ore 65,000 (F2P, 73/79/13000); Mud rune 54,000 (M, 96/101/18000); Raw swordfish 45,000 (F2P, 206/213/15000); Raw lobster 30,000 (F2P, 106/110/15000) — total 598,000 per 4h = 149,500 gp/h on 8 slots"
- "F2P path — 3 slots, F2P-tradeable rows only: Iron bar 90,000 + Cosmic rune 72,000 + Silver ore 65,000 = 227,000 per 4h = 56,750 gp/h (alternates: Raw swordfish 45,000, Raw lobster 30,000)"
- "Members path — snapshot 2026-08-27 top 8 by modeled 4h/slot (floored+capped 2% tax): Rune arrowtips 170,000 (M, buy 223 / sell 244 / limit 10000); Iron bar 90,000 (F2P, 145/157/10000); Cosmic rune 72,000 (F2P, 122/128/18000); Magic logs 72,000 (M, 772/793/12000); Silver ore 65,000 (F2P, 73/79/13000); Mud rune 54,000 (M, 96/101/18000); Raw swordfish 45,000 (F2P, 206/213/15000); Raw lobster 30,000 (F2P, 106/110/15000) — total 598,000 per 4h = 149,500 gp/h CEILING on 8 slots"
- "F2P path — 3 slots, F2P-tradeable rows only: Iron bar 90,000 + Cosmic rune 72,000 + Silver ore 65,000 = 227,000 per 4h = 56,750 gp/h ceiling (alternates: Raw swordfish 45,000, Raw lobster 30,000)"
- "Post-2%-fee reality: 11 of 21 classic staples are net-positive at band edges for members; sub-2%-spread items (law/chaos/blood runes, dragon bones, adamantite/mithril bars) need sub-low buys or above-high sells"
- "Realized vs ceiling (work the full lifecycle): realized gp/h = ceiling x fill_factor (~0.5-0.9, partials/cancels/requotes) x duty_cycle (~0.90-0.95, scan/place/collect + breaks) — e.g. 149,500 x 0.70 x 0.92 ~ 96,300 gp/h midpoint; do not quote the ceiling as an achieved rate"
state_machine:
initial: idle
terminal: [complete, failed]
states:
idle:
goal: be logged in at a bank with a GE booth, capital >= floor
next: [scan, complete, failed]
goal: "be logged in at a bank with a GE booth, capital >= floor, per-slot offer ledger empty (quoted = filled = sold = collected = 0 for every slot)"
next: [scan, complete]
scan:
goal: read the current high/low band for every candidate
goal: "read the current high/low band for every candidate; compute net-positive edges with floored+capped tax"
next: [buy, idle]
buy:
goal: place one resting buy offer per slot at or below the low edge
next: [wait_buy_fill, collect, idle]
goal: "place one resting buy offer per free slot at or below the low edge; record quoted qty and remaining 4h limit per slot in the ledger"
next: [wait_buy_fill, idle]
wait_buy_fill:
goal: hold BUY offers; re-quote any approaching the 4h window lapse
next: [sell, buy, collect]
goal: "hold BUY offers; track filled_qty per slot (partial fills included, units stay attached to the resting offer); on the 4h window lapse or a stale price, cancel the unfilled balance"
next: [sell, cancel_requote]
sell:
goal: place one sell offer per filled slot at or above the high edge
next: [wait_sell_fill, collect]
goal: "place one sell offer per slot holding units (its filled_qty) at or above the high edge"
next: [wait_sell_fill, cancel_requote]
wait_sell_fill:
goal: hold SELL offers; re-quote any approaching the 4h window lapse
next: [collect, sell, idle]
goal: "hold SELL offers; track sold qty per slot; on lapse or a stale price, cancel and re-quote — units are never left stranded"
next: [collect, cancel_requote]
cancel_requote:
goal: "ge_cancel the timed-out/stale offers of the current phase: acquired units return to inventory, unspent cash refunds, slot freed; re-quote at a fresh edge (buy when margin is still positive; sell to exit at the current high edge) or free the slot"
next: [wait_buy_fill, sell, wait_sell_fill]
collect:
goal: collect proceeds, deposit coins, log the cycle
goal: "collect proceeds, deposit coins, reconcile (inventory empty of flip items, all GE slots free, each slot's ledger closed with a logged RESULT)"
next: [scan, complete, idle]
complete:
goal: session GP target reached
goal: "session GP target reached"
failed:
goal: hard failure — stop, log ERROR sentinel, alert
goal: "hard failure — stop, log ERROR sentinel, alert"
transitions:
- from: idle
when: "capital below floor OR session target reached"
when: "GE access available AND capital >= floor AND session target not reached"
to: scan
- from: idle
when: "capital below floor OR session target already reached"
to: complete
- from: scan
when: "no candidate net-positive at band edges on 3 consecutive scans"
when: "at least one net-positive candidate at the scanned band edges (floored+capped tax)"
to: buy
- from: scan
when: "no net-positive candidate on 3 consecutive scans (prices stale — stand down)"
to: idle
- from: buy
when: "all slots quoted"
when: "all free slots quoted (quoted qty recorded per slot)"
to: wait_buy_fill
- from: buy
when: "capital exhausted before quoting (insufficient funds)"
to: idle
- from: wait_buy_fill
when: "all pending buys filled"
when: "a slot's buy offer is FULLY filled (filled_qty == quoted qty) — that slot's units move to sell"
to: sell
- from: wait_buy_fill
when: "4h window lapse with unfilled BUY offers"
to: collect
when: "a slot's buy offer hits the 4h window lapse or a stale price with filled_qty < quoted qty — ge_cancel: acquired units return to inventory, unspent cash refunds, slot freed"
to: cancel_requote
- from: cancel_requote
when: "re-quoted buy offers placed at the fresh low edge (window renewed, margin still positive)"
to: wait_buy_fill
- from: cancel_requote
when: "buy-side margin is gone — free the slot on the buy side; any acquired units from the cancelled offer still sell at the current high edge (exit at cost or a small loss rather than strand inventory)"
to: sell
- from: cancel_requote
when: "re-quoted sell offers placed at the fresh high edge (or lowered to the current band) for units in hand"
to: wait_sell_fill
- from: sell
when: "sells placed"
when: "sell offers placed for all units in hand (filled_qty per slot)"
to: wait_sell_fill
- from: wait_sell_fill
when: "all pending sells filled"
when: "all pending sells filled — per-slot proceeds ready to collect"
to: collect
- from: wait_sell_fill
when: "4h window lapse with unfilled SELL offers"
to: sell
when: "a sell offer hits the 4h window lapse or a stale price — ge_cancel and re-quote at the fresh high edge or lower to the current band; units are never stranded"
to: cancel_requote
- from: collect
when: "session GP target reached"
to: complete
- from: collect
when: "rotation done and window open"
when: "rotation done and window open — start the next rotation"
to: scan
- from: collect
when: "capital fell below floor after reconciliation"
to: idle
actions:
- id: a1
@ -192,6 +242,7 @@ actions:
params:
items: "top-N candidates from the entry table"
band: "high and low edge per item"
margin: "net-positive = sell - min(floor(0.02 x sell), 5,000,000) - buy > 0"
on_fail: skip
anti_ban:
delay: [1200, 2800]
@ -202,9 +253,10 @@ actions:
target: grand-exchange
params:
item: "per candidate slot"
qty: "min(remaining 4h limit, slot capacity)"
qty: "min(remaining 4h limit, slot capacity, capital available)"
price: "low edge (rounded down)"
max_price: "low edge — never instant"
ledger: "record quoted qty and remaining 4h limit per slot"
on_fail: skip
anti_ban:
delay: [900, 2700]
@ -214,39 +266,71 @@ actions:
verb: sleep
params:
delay: [6000, 12000]
until: "ge_offers_done changes or 4h window lapse"
until: "ge_offers_done changes or a fill event or 4h window lapse"
on_fail: retry
anti_ban:
delay: [300, 900]
- id: a6
step: check-fills
verb: ge_offers_done
target: "all quoted slots"
params:
phase: "buy (no pending sells) | sell (no pending buys)"
per_slot: "filled_qty vs quoted_qty for every slot (partial fills included)"
verdict: "full | partial | none | 4h-lapse"
on_fail: retry
- id: a7
step: place-sells
verb: ge_sell
target: grand-exchange
params:
item: "per filled slot"
qty: "filled quantity"
item: "per slot holding units (filled_qty)"
qty: "filled_qty of that slot"
price: "high edge (rounded up)"
ledger: "record sold qty per slot"
on_fail: skip
anti_ban:
delay: [900, 2700]
- id: a7
- id: a8
step: cancel-requote
verb: ge_cancel
target: "timed-out or stale slot offers (current phase)"
params:
offers: "the slots that hit the 4h window lapse or a stale price"
cancelled: "acquired units return to inventory; unspent cash refunds; slot freed"
requote: "buy: re-place at the fresh low edge when the margin is still positive; sell: re-place at the fresh high edge or lower to the current band; margin gone on the buy side: free the slot and sell any acquired units to exit"
on_fail: retry
- id: a9
step: collect-and-log
verb: ge_collect
target: grand-exchange
params:
deposit: "coins to bank"
log: "RESULT item, qty, net gp per slot"
reconcile: "inventory empty of flip items, all GE slots free, per-slot ledger closed"
log: "RESULT item, qty, net gp per slot (floored+capped tax)"
on_fail: alert
anti_ban:
delay: [600, 1400]
- id: a10
step: take-break
verb: take_break
target: "current location"
params:
duration: "[60, 240] seconds of idle AFK per break (matches run_control.break.for)"
safe: "resting offers persist server-side at their quoted edges — the full state lives in the GE interface plus the per-slot ledger, so a break at any resting-offer point is safe"
resume: "re-open GE (a2), re-check offer state (a6), continue from the current phase (a4/a7/a8/a9) — never break mid-collect (coins in hand) or mid-place (offer half-configured)"
on_fail: skip
run_control:
iteration: "one full buy -> buy-fill -> sell -> sell-fill -> collect rotation across all slots"
iteration: "one full rotation: quote buys -> fills/cancels/requotes -> sell filled units -> sells fill/cancel/requote -> collect + reconcile, across all slots"
max_iterations: null
break:
every: [6, 10] # rotations
every: [6, 10] # rotations (resting offers persist; state = GE + per-slot ledger)
for: [60, 240] # seconds of idle AFK
stop_conditions:
- "session GP target reached"
@ -254,12 +338,58 @@ run_control:
- "no net-positive candidates on 3 consecutive scans"
- "3 consecutive aborted offers (client issue — do not loop)"
# ================= WORKED EXAMPLE (pinned, deterministic — owner addendum 2026-08-28) =================
# Members account, 8 GE slots, capital 22,500,000 gp. Snapshot prices 2026-08-27
# (buy/sell = low/high edge; tax = min(floor(0.02 x sell), 5,000,000)).
#
# Step 0 — preparation and capital allocation: capital at the bank, GE-adjacent.
# Scan bands (a3): only net-positive slots are quoted. Per-slot capital needs:
# arrowtips 223x10,000 = 2.23M; iron bar 145x10,000 = 1.45M; cosmic 122x18,000 =
# 2.196M; silver ore 73x13,000 = 0.949M; swordfish 206x15,000 = 3.09M; lobster
# 106x15,000 = 1.59M; magic logs 772x12,000 = 9.264M; mud 96x18,000 = 1.728M
# (total 22.497M <= 22.5M). Ledger: quoted=filled=sold=collected=0 per slot.
# Step 1 — place buys (a4): quote all 8 slots at the low edges (qty = 4h limit).
# wait_buy_fill (a5/a6).
# Step 2 — PARTIAL FILL: arrowtips fills 4,000 of 10,000 after ~18 min -> check-fills
# (a6) verdict PARTIAL: ledger arrowtips.filled = 4,000. The offer KEEPS resting
# (acquired units stay attached to the resting offer; nothing is stranded).
# Step 3 — FULL FILL: iron bar fills all 10,000 -> transition to sell (a7): place
# sell 10,000 @ 157 (high edge). wait_sell_fill -> fills -> collect (a9):
# proceeds 1,570,000; tax floor(157 x 0.02) = 3/item -> net = (157-3-145) x 10,000
# = 90,000. Reconcile: inventory empty, slot free, ledger closed.
# Step 4 — NO-FILL / STALE recovery on the buy side: cosmic 18,000 @ 122 is unfilled
# approaching the 4h lapse -> cancel_requote (a8, ge_cancel): 0 units return,
# 2,196,000 cash refunds, slot freed; re-scan (a3): cosmic still net-positive ->
# requote 18,000 @ 122 on the fresh window. (If the buy margin had vanished the
# slot is freed on the buy side; any units acquired from a cancelled offer still
# sell at the current high edge.)
# Step 5 — PARTIAL matures at lapse: arrowtips still 4,000/10,000 -> ge_cancel:
# 4,000 units return to inventory, 6,000 x 223 = 1,338,000 refunded -> sell (a7):
# 4,000 @ 244 -> tax floor(244 x 0.02) = 4/item -> net = (244-4-223) x 4,000 =
# 68,000. Collect (a9) + reconcile.
# Step 6 — FIRST SCHEDULED BREAK after 6-10 rotations (midpoint 8): execution is at
# a safe point — every slot is either collected or resting at its quoted edge; the
# state (offers + per-slot ledger) persists server-side. take-break 60-240 s
# (a10); RESUME at a2 (re-open GE) -> a6 (check-fills) -> continue the current
# phase (a4 buys / a7 sells / a8 cancel-requote / a9 collect). Breaks never strand
# an offer and never interrupt a collect/place in progress.
# Step 7 — STOP: session target (e.g. 900,000 net) -> collect -> complete; capital
# fell below floor -> idle -> complete; 3 consecutive aborted offers -> failed.
# Rate qualification: the 149,500 gp/h figure is the 4h buy-limit CEILING (8 slots,
# full fills, zero overhead). Realized midpoint ~ 149,500 x 0.70 (fill factor) x
# 0.92 (duty cycle incl. scan/place/collect + breaks) ~ 96,300 gp/h — the entry's
# low bound 74,750 (50% ceiling) sits under that; the ceiling is never presented
# as an achieved runtime rate.
# =====================================================================================================
risk:
ban_level: low
notes:
- "Flipping is standard gameplay; the detectable signal is quote churn — keep per-offer pacing humanised, never instant-buy/sell loops."
- "The 2% fee (since 2025-05-29) and 5M/item cap make sub-2%-spread staples unprofitable at band edges; re-scan before every rotation."
- "Thin/volatile items: a resting offer can sit for hours — cap quote lifetime to the 4h window and re-quote rather than chase."
- "Thin/volatile items: a resting offer can sit for hours — cap quote lifetime to the 4h window and re-quote (ge_cancel + fresh edge) rather than chase."
- "Partial fills are normal; never cancel-and-replace a partially-filled offer mid-window just to churn — the ledger keeps the filled qty attached to the resting offer until full/lapse."
- "Breaks are safe only at resting-offer or post-collect points (see a10); state = GE offers + the per-slot ledger, which survive the pause."
sources:
- "OSRS wiki — Grand Exchange (2% convenience fee since 2025-05-29, capped 5M/item, sub-50gp effectively untaxed, tax-exempt low-value items; buying rate restricted per 4h; connected limits; verified 2026-08-27)"
@ -267,7 +397,8 @@ sources:
- "OSRS wiki — Merchanting (flipping = spread exploitation; high trade volume = safety; bulk flipping needs ~20M+ cash; avoid static-price items; offer matching at or better than your price)"
- "prices.runescape.wiki/api/v1/osrs/mapping (item ids, members flags, limits — limits cross-checked against Module:Exchange/<Item>, all agree)"
- "prices.runescape.wiki/api/v1/osrs/latest (high/low price band snapshot 2026-08-27)"
verified: "2026-08-27" # keep quoted (YAML 1.1 date parsing)
- "docs/action-grammar.md (ge_cancel verb added 2026-08-28: cancel a pending offer — bought units return to inventory, unspent cash refunds) + schemas/entry.schema.json verb enum; owner lifecycle addendum 2026-08-28 (complete runnable flow, worked example, realized rates)"
verified: "2026-08-27" # keep quoted (YAML 1.1 date parsing); prices last re-fetched live 2026-08-27
related:
- low-alch-f2p

View File

@ -68,6 +68,7 @@ Legend for the mapping table:
| `ge_open` | open GE at a bank | — | — | — |
| `ge_buy` | buy `qty` of `item` at offer price, paced | — | — | — |
| `ge_sell` | sell `qty` of `item`, confirm | — | — | — |
| `ge_cancel` | cancel a pending offer: bought units return to inventory, unspent cash refunds | — | — | — |
| `ge_offers_done` | predicate: no pending buy/sell offers | — | — | — |
| `ge_collect` | collect finished GE transactions | — | — | — |
| `ge_check_price` | read current buy/sell price of an item | — | — | — |

View File

@ -155,7 +155,7 @@
"click_button", "menu_option",
"bank_inventory", "deposit_all", "withdraw", "has_item",
"count_item", "move_to_inv", "sort_inventory",
"ge_open", "ge_buy", "ge_sell", "ge_offers_done", "ge_collect",
"ge_open", "ge_buy", "ge_sell", "ge_cancel", "ge_offers_done", "ge_collect",
"ge_check_price",
"attack", "prayer", "buff", "eat", "retreat", "is_dead", "respawn",
"is_at", "item_count", "level_is", "xp_is", "hp_is",