Docs: register today's fixes, prune completed roadmap items

CLAUDE.md/docs/library.md updated to match the sell.py/parkcash.py/
scan.py changes in the preceding commits. docs/decisions.md gets the
full reasoning trail: the Black-Scholes closed form marked superseded,
the actual backtest entry (BHP/AL touch-probability table) that both
sell.py and library.md already cited but was never written, the
discretization-bias caveat on that backtest, the price-impact-cap and
demolition-value decisions. docs/roadmap.md pruned back to open items
only - finished work is discoverable from CLAUDE.md/library.md/
decisions.md instead of staying listed as a done backlog entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-10 23:07:02 +02:00
co-authored by Claude Sonnet 5
parent 3ee26e5a85
commit 12d26c5d68
4 changed files with 210 additions and 34 deletions
+40 -28
View File
@@ -1,34 +1,46 @@
# Roadmap
Legend: [ ] todo, [x] done. Build order matters; each step is usable on its own.
Open work only - what's already built/fixed is discoverable from `CLAUDE.md`'s Tools list,
`docs/library.md`, `docs/decisions.md`, and module docstrings, not repeated here.
1. [x] Repo skeleton, git (master), venv, CLAUDE.md, mechanics from PRUNplanner.
2. [x] `puga/fio.py`: cached FIO client (TTL per endpoint, keys from `.env`), plus `puga/prunplanner.py` for `api.prunplanner.org/data/*`. Inspect what `exchanges/` adds (VWAP?) vs FIO `/exchange/all`.
3. [x] (price + book tools done; cxpc trend history not needed, PRUNplanner has vwap7/30) `puga/market.py` + `tools/price.py`, `tools/book.py`: prices across all CX, trends from cxpc, order-book walk for real fill price at quantity N.
4. [x] `puga/econ.py` (22 tests pass, expected values from PRUNplanner's suite): efficiency stack, workforce consumption, hab LP, extraction (port the formulas from `docs/mechanics.md`, with tests against PRUNplanner values).
5. [x] (v1 done; see saturation-design.md for refinements) `tools/scan.py` (replaces prun_scan.py): depth-aware ROI. Per recipe report: buildings the market can absorb (output demand + traded volume, input supply), ROI at fill price for N buildings, absorbable profit/day. Filter `--min-buildings`. Both CX-local and universe.
5b. [ ] `tools/arb.py` (replaces prun_cxarb.py): inter-CX arbitrage on `market.walk` at real fill size; capital required, fuel/shipping cost from state, profit per trip within cash. Reason: old script uses top-of-book spread x min(supply,demand); on 2 of 4 top hits it overstated profit 7 to 11x (WAI, SCN).
6. [x] `tools/chain.py`: full bill of materials, make-vs-buy per node.
7. [x] `tools/whatif.py`: marginal ROI of adding a building to a base you already run (whole-plan diff via `simulate()`, built dict from `state/company.yaml`; flags newly-caused workforce overloads).
8. [x] `tools/planet.py`: rank planets for a resource (FIO bulk `Resources`/`BuildRequirements` data), founding cost from real environment-extras materials, jump distance via `tools/route.py`. `tools/found.py` (full founding workflow/writeback) still todo.
13b. [x] `puga/network.py` + `tools/network.py`: multi-base chain modelling (per-base simulate, net transfers against real freight, `cm_free` for kits). Worked example: `plans/chains/nike_deimos_lst.yaml` (Nike LST -> Deimos PP2/BSE). Known gap: reports whole-plan profit per base, not the marginal addition; caller must diff manually.
9. [x] `tools/route.py`: jump graph (FIO `/systemstars`, Dijkstra by straight-line ly, jump count alongside). `tools/haul.py` (fuel cost, profit per trip) still todo.
9c. [x] `puga/shipping.py` + `tools/shipcost.py` (explicit params) + `tools/shiptrip.py` (just ship/from/to) + `puga.shipping.round_trip_cost()` wired into `tools/network.py`'s freight cost: real ship flight fuel/cost model (STL cruise + FTL jump/charge, linear in the fuel-usage/reactor-usage sliders, additive/no cross-term; gateway hops free-fuel + manual LOCK fee read off the live game, not lookupable via any FIO/PRUNplanner endpoint - checked; landing fuel a measured per-planet lookup). Calibrated 2026-10-09 on this account's one hull/reactor (blueprint BP-STRT-0000, shared by both ships AVI-07JFB/AVI-07JFC, confirmed identical specs via FIO) via a controlled 4x4-slider-grid sweep across 5 real destinations, read from the live APEX Ship Flight Control DOM. Raw data: `empire/data/shipping_calibration/`. Open gaps (see `puga/shipping.py` docstring): departure-side gravity dependence untested (every calibration DEP left the same origin), landing fuel vs gravity/distance confounded (n=3), no second hull/reactor to cross-check generalization. `tools/scan.py --trip-cost` still uses the flat 9250 AIC placeholder (not yet wired to the real model - needs a per-recipe destination planet, not just a CX code).
9d. [x] `puga/contracts.py` + `tools/lmscan.py`: live Local Market hauling-ad scan (FIO `/localmarket/shipping/{source,destination}`, public/no-auth - real player-posted freight jobs, not the CONTD player-contract system) ranked by margin after real fuel cost (`puga.shipping.leg_cost`, one-way, with a small measured gateway-fee table `KNOWN_GATEWAY_ROUTES` for ANT<->HRT/BEN). Ship cargo hold confirmed 500t/500m3 via FIO for both ships.
9b. [x] (dry-run default, --apply after user yes) `tools/plan_push.py`: create/update `[PuGa]` plans in PRUNplanner from YAML (Api-Key auth; see decisions.md for guardrails).
10. [x] `tools/state.py sync` (sites, production efficiency, storage, ships, cash, permits): inventory, production, ships into `state/`.
11. [ ] Docs to fill: `docs/apex.md`, `docs/fio.md`, `docs/playbook.md` (question type -> tool), `docs/decisions.md`.
## Todo
- [ ] `tools/arb.py`: inter-CX arbitrage at real fill size (replaces `prun_cxarb.py`, which
overstated profit 7-11x on 2/4 top hits).
- [ ] `tools/haul.py`: fuel cost / profit per trip (route.py has the jump graph).
- [ ] `tools/portfolio.py`: profit-maximizing set of 1-building opportunities under shared
housing/capex/permits. Ties into backlog #2 (profit/permit ranking, needs this tool to mean
anything - permits bind at the whole-base level, not per-recipe).
- [ ] Docs to fill: `docs/apex.md`, `docs/fio.md`, `docs/playbook.md`.
13. [x] `tools/buy.py`: cash-aware shopping list (construction gap vs empire state's built count, plus N days of net operating stock via simulate(), priced at real fill cost, checked against cash/reserve).
14. [x] `tools/sell.py`: ask-post-price + expected-clear-time advisor from 30d traded-volume percentiles, vs hitting the bids now.
15. [x] `tools/runway.py`: days-of-runway per material from simulate()'s net consumption, base storage plus auto-detected inbound ship cargo (tools/state.py now tags each ship with its live flight origin/destination, and each STORE with its planet, needed once a 2nd base existed).
12. [ ] `tools/portfolio.py`: choose the set of 1-building opportunities for one base that maximises total profit given shared whole-building housing (HB1/HB2/...), capex, permits and (for demolish-later) 60-day value decay. Persistence check exists (`tools/persistence.py`); wire it into the ranking.
14. [x] `tools/undervalued.py`: trading (not building) strategy - manufactured goods priced below implied production cost, candidates for a buy-and-hold-for-reversion bet. Backtested 2026-10-09 (326 output tickers, 287 deduplicated dip-onset episodes, 112 distinct tickers): +3mo forward return mean +21.3%/median +8.9%/73.2% hit rate at >=10 units/day volume - roughly 0.10-0.24%/day, far below the 14-29%/day marginal ROI on production builds found this session. Only worth excess idle capital, not a primary strategy.
## Backlog: review findings, still open (spot-checked against code)
1. [ ] `scan.py` payback ignores working capital (input stock/output inventory/consumables) - can
rival building capex for smelting-type recipes. `buy.py` already computes this number.
2. [ ] No profit/permit ranking (permits bind at the base level, not per-recipe) - needs
`tools/portfolio.py`'s cross-recipe/whole-base view.
3. [ ] `scan.py` doesn't charge degradation (capex/180/day) like `simulate.py` does - small but real
inconsistency between tools ranking the same thing.
4. [ ] No input-side flow cap (buying a big share of an input's flow should price-impact like
selling output does) - documented as absent, not modelled.
5. [ ] `persistence.py --lag 3` default is too low given `docs/mechanics.md`'s weekly workforce
distribution - real lag is 3-10 days.
6. [ ] Possible forward-fill bias if any tool reindexes `daily_prices()` onto a full calendar grid
(it only emits trade days) - would understate volatility for sparse tickers. Not yet confirmed
whether `persistence.py`/`undervalued.py` actually do this.
7. [ ] `undervalued.py`'s backtest (+21.3%/3mo) has no control group - meaningless without the
universe's unconditional return over the same window.
8. [ ] `persistence.py` measures past margin variance of a market we were NOT in - can't see the
dominant real risk (our own entry + the next player's compressing margin).
9. [ ] `undervalued.py::manufacturing_candidates()` keeps the first recipe seen per output, not
the cheapest (`seen.setdefault`).
10. [ ] `scan.py` hab cost ignores combined habs (HBB/HBC/HBM/HBL), which can be cheaper per head.
11. [ ] `scan.py --trip-cost` still defaults to the flat 9250 placeholder despite the real
`puga/shipping.py` model existing and already used by `whatif.py`.
12. [ ] `sell.py`'s `s0` is the day's VWAP, not its high - `--tiers` touch probability is slightly
pessimistic (same discretization conservatism as `empirical_touch()`, see `docs/decisions.md`).
13. [ ] `empirical_touch()`'s optional `horizon` (fixed-window right-censoring) exists but isn't
wired into any tool's default call yet.
## Open questions
- PRUNplanner auth is known (`Authorization: Api-Key <key>`). FIO REST and FIO API are separate services with separate keys (separate services with separate keys; an earlier "one API" reading was wrong). Keys are in `.env`. Verified 2026-09-18: FIO_REST_KEY works on rest.fnar.net as `Authorization: <key>` (own /sites, /storage etc. readable); FIO_API_KEY gives 401 there, host unknown. PRUNplanner key works (plans 0, empires 1, cx prefs 1 on his account). Still unknown: the OpenAPI spec at https://doc.fnar.net/api.json has no securitySchemes. Probe with read-only calls.
- (resolved) PRUNplanner `exchanges/` has vwap_daily/7d/30d and traded volume; merged into `puga/market.py`. Trend history via cxpc still todo.
- Extraction: concentration to daily rate formula.
- (resolved 2026-09-25) Real price-band filtering (`NarrowPriceBandLow/High`, `WidePriceBandLow/High`) implemented in `puga/saturation.py` (`in_band`, `effective_demand`, `effective_supply` band param) and wired into `tools/scan.py` stage 2. Was flagged as an unimplemented refinement in saturation-design.md since day one; the player noticed a stale out-of-band bid in a live screenshot and asked the right question.
- FIO REST and FIO API are separate services/keys (`.env`). FIO_REST_KEY works on rest.fnar.net;
FIO_API_KEY's host is unknown; PRUNplanner's Api-Key works. `doc.fnar.net/api.json` has no
securitySchemes.