Add simulator replica, persistence, planet scan, README; split empire state out of the repo

- tools/simulate.py + puga/simulate.py: replica of PRUNplanner's simulator (flows and
  efficiency verified against screenshots), reports real new capex (planned minus built)
- tools/scan.py: staffing variants, freight, HQ/experts, --planet mode, demolish-later,
  --min-n as a pure market-size filter, --json output
- tools/history.py, tools/persistence.py: margin history and short-horizon payback checks
- tools/plan_push.py: guarded delete; tools/state.py: syncs to empire/
- README with features and setup; CLAUDE.md made generic
- Own-empire material (profile, state, plans, notes) moved to gitignored empire/;
  generic examples in plans/examples and state/company.example.yaml

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-19 00:11:02 +02:00
co-authored by Claude Sonnet 5
parent 7a538cb300
commit 3bbf524ebb
26 changed files with 778 additions and 259 deletions
+31 -25
View File
@@ -1,44 +1,50 @@
# PuGa: Prosperous Universe advisory toolkit
Agent-first toolkit for advising Dominik (username dodox, company GBI, faction Antares, home CX AI1). He asks questions; you answer by running tools in `tools/` against live data. Read this file first, then `docs/mechanics.md` and `state/company.yaml`.
Agent-first toolkit for advising a Prosperous Universe player. The player asks questions; you answer by running the tools in `tools/` against live data, not by guessing.
## How to work with Dominik
- Expert user. Numbers, tables, ROI per day. Short answers, no fluff, no moralising. Semicolons over dashes; no em dashes.
- He plays on browser APEX (free licence) and sends screenshots; read them carefully, they override assumptions.
- Never guess APEX commands or numbers. Pull data (tools, FIO, PRUNplanner) or search. Command list: `docs/apex.md` (when written) and `docs/handoff-2026-09-18.md` §4.
## Read first
1. `empire/PROFILE.md` if it exists: who the player is, how they want answers, their company and current plans. `empire/` is gitignored and holds everything specific to this player's empire (see Layout). If it does not exist, ask the player the basics and create it.
2. `docs/mechanics.md` for game mechanics (source of truth order below).
3. `empire/state/company.yaml` for the current position; refresh it with `tools/state.py sync` before answering anything about it.
## Working rules
- Numbers, tables, ROI per day. Short answers, no fluff. Match the style in the player's profile.
- The player plays on browser APEX and may send screenshots; read them carefully, they override assumptions.
- Never guess APEX commands or numbers. Pull data (tools, FIO, PRUNplanner) or search.
- Label every number: live (tool output), state (company.yaml), or estimate; say which in-game command would confirm an estimate.
- Prices move; re-run tools before quoting. Snapshot prices in the handoff doc are stale.
- Prices move; re-run tools before quoting. Anything older than a day is stale.
- Do not commit or push unless asked. Writes to the player's PRUNplanner account follow the guardrails in `docs/decisions.md`.
## Source-of-truth rules
1. **PRUNplanner code wins** over our own docs for game mechanics (`ref/frontend/src/features/planning/calculations/`, `ref/backend/`). If `docs/handoff-2026-09-18.md` conflicts with it, the handoff is wrong; fix `docs/mechanics.md`.
2. In-game numbers Dominik reports beat both, especially for planet resource factors.
1. **PRUNplanner code wins** over our own docs for game mechanics (`ref/frontend/src/features/planning/calculations/`, `ref/backend/`). If any older handoff or note conflicts with it, the note is wrong; fix `docs/mechanics.md`.
2. In-game numbers the player reports beat both, especially for planet resource factors.
3. `ref/` is a gitignored copy of the PRUNplanner repos; refresh with `tools/refresh_refs.sh`.
## Setup
- Python venv at `.venv` (`.venv/bin/python`, `.venv/bin/pip`). Deps in `requirements.txt`.
- Secrets in `.env` (gitignored; template `.env.example`): FIO REST key, FIO API key, PRUNplanner key. Never print or commit them; do not ask Dominik to paste keys into chat.
- Scope: whole universe supported; default region Antares (exchange AI1, `--cx` to change).
- Secrets in `.env` (gitignored; template `.env.example`): FIO REST key, FIO API key, PRUNplanner key, FIO username, company code. Never print or commit them; do not ask the player to paste keys into chat.
- Scope: whole universe supported; default exchange from `DEFAULT_CX` (AI1 = Antares), `--cx` to change.
## Layout
- `CLAUDE.md` this file; `docs/` mechanics, refs, roadmap, decisions, archived handoff.
- `state/company.yaml` company state (bases, buildings, ships); update when Dominik reports changes.
- `puga/` shared library (data layer, market, econ, world); `tools/` CLIs; `data/cache/` fetched data; `tests/`.
- `ref/` PRUNplanner source (read-only reference).
- `CLAUDE.md` this file; `README.md` for humans.
- `docs/` GAME and toolkit knowledge, safe to publish: `mechanics.md` (verified rules), `saturation-design.md` (market model), `decisions.md` (toolkit decisions and guardrails), `roadmap.md`.
- `empire/` (**gitignored**) OUR game state, nothing here goes public: `PROFILE.md`, `state/company.yaml` (synced from FIO), `plans/` (own plan specs), `docs/` (handoffs, build plans, personal notes).
- `puga/` library; `tools/` CLIs; `plans/examples/` generic plan specs (also test fixtures); `state/company.example.yaml` example state; `tests/`; `data/` (gitignored fetched data cache); `ref/` (gitignored PRUNplanner source).
- Rule: game facts and generic methods go in `docs/`; anything about the player's own bases, cash, decisions or preferences goes in `empire/`.
## Tools (current)
- `tools/state.py sync|show` refreshes `state/company.yaml` from live FIO (cash, permits, buildings, real production efficiency, storage, ships). Run it before answering anything about his current position.
- `tools/plan_push.py` builds/validates PRUNplanner plans from `plans/*.yaml` (dry run by default; `--apply` only after Dominik says yes; only `[PuGa]`-named plans are created/updated; `list` shows his plans). Specs live in `plans/`.
## Tools
- `tools/state.py sync|show` refreshes `empire/state/company.yaml` from live FIO (cash, permits, buildings, real production efficiency, storage, ships).
- `tools/plan_push.py` builds/validates PRUNplanner plans from YAML specs (`plans/examples/`, `empire/plans/`). Dry run by default; `--apply` only after the player says yes; only `[PuGa]`-named plans are created/updated/deleted (`delete <uuid>`, only when asked); `list` shows the account's plans.
- `tools/simulate.py <spec.yaml | --uuid U> [--off EXT,SME] [--basis real|uni30|vwap30|ask|...]` replica of PRUNplanner's simulator (efficiency, workforce, material I/O, profit). Flows and efficiency verified exact vs screenshots; profit within ~2%. The NEW CAPEX line = planned minus already built (from state), the honest payback; ignore the plan-level ROI (PRUNplanner always adds a core module). `--uuid` reads the SAVED plan from the account (UI edits must be saved first).
- `tools/scan.py` DEPTH-AWARE recipe scan (use this): buildings the market could absorb, ROI for our own size, patient prices, ask-walked inputs. Fully staffed AND understaffed variants by default (`--staffing`), freight netted out (`--trip-cost`, `--cargo`), HQ/COGC/experts/faction, `--planet ID` adds that planet's extraction, fertility and COGC (a planet not in state is a new base: no HQ, permits+1), `--deprec 60` prices demolish-later. `--min-n` is ONLY a noise filter on market capacity (use 3, ideally 10); ROI is always for our own size (`--own`, default 1 building), never at the filtered scale. Below 1 lets sub-building junk in. `--json rows.json` feeds `persistence.py`. Library: `puga/saturation.py`.
- `tools/history.py TICKER` monthly margin history of the recipe producing TICKER; `tools/persistence.py rows.json` re-prices scan rows over history (mean ROI 7/14/30/90/180d, payback, net gain over 7 and 14 days, % days profitable). ALWAYS check persistence before recommending: current margins are often a spike.
- `tools/chain.py TICKER` make-vs-buy cost tree plus sourcing depth of inputs.
- `tools/book.py` order-book ladder (price levels, cumulative units) for one material at one CX.
- `tools/price.py` prices across CX with VWAP, daily volume, and order-book fill price for a quantity (`--qty`). Library: `puga/market.py`, `puga/fio.py`, `puga/prunplanner.py`.
- `tools/scan.py` DEPTH-AWARE recipe scan (use this): N* buildings the market absorbs, ROI at N=1 and N*, patient prices, ask-walked inputs. Flags: --cx --tier --cogc --skip <tier> --hq --budget --min-n --sort roi|total|roi1 --show-thin. Library: `puga/saturation.py`.
- `tools/prun_scan.py` legacy single-step scan at top-of-book prices; overstates thin markets. Baseline only.
- `tools/prun_cxarb.py` inter-exchange arbitrage per material. Legacy; overstated profit 7 to 11x on thin routes; `tools/arb.py` replacement is on the roadmap.
- `puga/econ.py` pure formulas ported from PRUNplanner: efficiency stack, workforce satisfaction/consumption, extraction, production I/O, hab optimizer. `tests/test_econ.py` holds the reference values.
- `tools/price.py` prices across exchanges with VWAP, volume, fill price for a quantity; `tools/book.py` order-book ladder.
- `tools/prun_scan.py`, `tools/prun_cxarb.py` legacy top-of-book scans; overstate thin markets. Baseline only. `tools/arb.py` replacement is on the roadmap.
- `puga/econ.py` pure formulas ported from PRUNplanner (efficiency stack, workforce, extraction, production I/O, hab optimizer); `tests/test_econ.py` holds the reference values.
## Model policy
Sonnet builds; spawn a bigger model (Agent `model: opus|fable`) for the review points in `docs/decisions.md`. Roadmap: `docs/roadmap.md`.
## Key analytic rule: depth matters
PRUNplanner's ROI Overview ranks recipes as if the market absorbs unlimited output (e.g. 0.25 day ROI on a recipe whose whole market fits in 2 buildings). Every opportunity we report must include **saturation**: max buildings the market can absorb on both the output side (demand, traded volume, order-book walk) and the input side (supply). Report ROI at realistic fill prices, not top-of-book, and total absorbable profit/day.
PRUNplanner's ROI Overview ranks recipes as if the market absorbs unlimited output (e.g. 0.25 day ROI on a recipe whose whole market fits in 2 buildings). Every opportunity we report must include **saturation** (buildings the market can absorb) and, for anything we would act on, **persistence** (is the margin a spike?). Report ROI at realistic fill prices, not top-of-book.