# HiLo.FM — Overnight Implementation Prompt for Claude Code You are implementing **HiLo.FM**, a high-performance forecast-modification technology demonstrator, from scratch, in one long autonomous session. Work until it is complete, tested and packaged. Do not stop to ask questions: make reasonable decisions, record them (see § Decision log), and keep going. ## 1. Authoritative specification — read it FIRST, in full Fetch and read every page before writing any code. The spec is the contract; requirement IDs (OV-xx, GL-xx, DM-xx, HE-xx, DR-xx, DF-xx, UI-xx, AP-xx, MC-xx, DE-xx) and decisions D-01…D-29 are binding. RFC-2119 language (MUST/SHOULD/MAY) applies. - https://says.hermione.online/hilo-fm-spec/index.html - https://says.hermione.online/hilo-fm-spec/01-overview.html - https://says.hermione.online/hilo-fm-spec/02-concepts.html (contains the MINI dataset — your primary test fixture) - https://says.hermione.online/hilo-fm-spec/03-data-model.html - https://says.hermione.online/hilo-fm-spec/04-hi-entries.html - https://says.hermione.online/hilo-fm-spec/05-disaggregation-rules.html - https://says.hermione.online/hilo-fm-spec/06-disaggregation-flow.html (contains worked example E6-A — your primary acceptance test) - https://says.hermione.online/hilo-fm-spec/07-ui.html - https://says.hermione.online/hilo-fm-spec/08-api.html - https://says.hermione.online/hilo-fm-spec/09-mcp.html - https://says.hermione.online/hilo-fm-spec/10-demonstrator.html - https://says.hermione.online/hilo-fm-spec/decisions.html (all 29 decisions — binding) If a page is unreachable, retry; if permanently unreachable, note it in the decision log and proceed on the remaining pages — they are heavily cross-referenced, so most content is recoverable. Key facts to internalise before coding: HI entries → four-stage pipeline (Time → Attribute→UPC → UPC→Product → Location) → integer LO rows; largest-remainder rounding with lexicographic tie-break; Σ LO(entry) = value_su always; zero *total* basis ⇒ InError with a precise message, never a guessed fallback; explicit low-level scope always wins (D-22); phase-profile fractions renormalized over the in-scope subset (D-24); product scope is exactly one `attribute=value` pair with built-ins `upc` / `product_id` (D-25); no ingestion — everything synthetic (D-23); last-write-wins concurrency (D-28); preview is summary-only (D-27). ## 2. Fixed technology decisions (owner-approved — do not revisit) - **Backend: Rust** (stable toolchain). Suggested: `axum` + `tokio` for HTTP, `rayon` for batch parallelism, `serde` for JSON, `rand` + `rand_chacha` (or similar seedable RNG) for deterministic generation. - **State: in-memory first.** The in-memory structures are the source of truth for all hot paths (disaggregation, queries). Design them columnar and cache-friendly: intern all string IDs to dense `u32` indices at generation time; store forecast and LO as flat arrays / compact structs keyed by (product_idx, location_idx, week_idx); pre-build the aggregation indexes you need (product→UPC, attribute-value→product set, UPC→products, calendar week→month/quarter). The engine must never do string comparisons or hash lookups per LO row in the hot loop. - **Persistence: SQLite**, and SQLite interactions MUST be optimized: - WAL mode, `synchronous=NORMAL`, sensible `page_size`/`cache_size`, single writer connection. - All writes batched in transactions (thousands of rows per transaction), prepared/cached statements, no per-row round trips. - Persist compactly using the interned integer IDs plus the dictionary tables. - Persistence is write-behind off the hot path: an entry create/update returns when memory is consistent (AP-07 semantics are about HI/LO consistency, which lives in memory); the SQLite write follows immediately on a background task, ordered per entity. On startup, load everything from SQLite into memory. Reset/regeneration rewrite SQLite wholesale inside one transaction. - Store: masters, calendar, forecast, split tables, phase profiles, entries, LO rows, last batch report, active profile + seeds. A restart must restore the exact visible state. - **Frontend:** React + TypeScript + Vite, single-page app. Virtualised grids (e.g. TanStack Table + Virtual) for S1/S3/S5; server-side aggregation and filtering only — never ship a full dataset to the client (UI-09/17). Dense, professional planning-tool aesthetic per Ch. 07; no decorative fluff. Built assets are served by the Rust binary. - **MCP server:** embedded in the same binary via the official Rust MCP SDK (`rmcp`), streamable-HTTP transport at `/mcp`, tool surface exactly per Ch. 09 (incl. `regenerate_forecast` and `reset_demo` with `confirm:true`). - **Auth:** two fixed accounts `user` / `admin`, passwords from environment variables (with documented defaults for local dev), `POST /auth/login` → opaque bearer token held in memory. No authorization differences (DE-06/07). - **Packaging: one Docker container — authored tonight, built by the owner in the morning.** You are expected to be running inside a dev container **without access to a Docker daemon**, so do NOT attempt `docker build` / `docker run`, and do not install or work around Docker if it is absent — that is by design, not a problem to solve. Deliver the complete, ready-to-build artifacts instead: a multi-stage `Dockerfile` (node stage builds the frontend, rust stage builds the release binary, minimal runtime image), a `.dockerignore`, and exact build/run commands in the README. Single exposed port (default 8080). SQLite file on a declared volume path (e.g. `/data/hilo.db`), configurable via env. Nightly batch schedule via a simple in-process timer (cron-style env var, default 02:00 UTC). Note the deferred image build in `DECISIONS.md`. (If, unexpectedly, a working Docker daemon IS available, you MAY build and smoke-test the image as a bonus — but never at the expense of the other deliverables.) - Everything not fixed above is your choice — choose pragmatically, optimise for performance and clarity, and record each choice. ## 3. Architecture requirements - Cargo workspace with a clear split, e.g.: `engine` (pure disaggregation + data structures, zero I/O), `generator` (seed profiles, forecast synthesis), `persistence` (SQLite), `server` (axum API + MCP + static frontend), `web/` (the Vite app). - **One code path** for disaggregation used by create/update, preview (dry-run flag), per-entry re-run and batch (DF-05). Preview runs the identical engine without committing. - Batch: parallel across entries with `rayon`; per-entry failures isolated (DF-07); collect the full DF-08 report (wall-clock, throughput, per-entry min/median/p95/max, failures with messages); serialized runs (DF-09); expose live progress. - Per-entry atomic replace of LO rows (DM-12): swap the entry's row set under a short lock or via epoch/arc-swap — readers see old or new, never a mixture. - Performance is the defining attribute (DF-10: best-effort mandate — an avoidably slow design is non-compliant). Directional sanity figures on a small VM: p95 ≤ 200 ms interactive disaggregation, ~60 s full batch on profile L (100k products, ≈5M LO rows), ≤ 2 s reporting queries. Measure everything and expose the numbers in UI, API and MCP (DF-11). Add micro-benchmarks (criterion or custom) for the engine. ## 4. Seed generation & forecast synthesis (Ch. 10, D-29) - Profiles MINI / S / M / L exactly as tabled in DE-01, **plus CUSTOM with user-specified sizing** (products, locations, customers, weeks, entries — validated against documented sane bounds). Same profile/parameters + seed ⇒ byte-identical dataset. - **MINI must reproduce the Ch. 02 dataset verbatim** — hardcode it, don't generate it randomly. - Forecast synthesis per DE-03: for each populated (product, location) series, `q(w) = max(0, base · (1 + trend·w) · season(w) · (1 + noise(w)))` — log-normal base per series, small per-series drift (± a few permille/week), gentle low-frequency seasonal oscillation (±10–30%), weekly noise (±5–15%), all from the seeded RNG. Keep the forecast sparse (a share of product×location combinations have no rows). - Generated content must satisfy DE-02: NPIs with phase-in profiles, EOLs, a mid-horizon sourcing change, a customer-specific split rule, entries of all three HE-03 archetypes, and ≥ 1 deliberately InError entry. - Generator invariants (DM-08/14): split-table and phase-profile fractions sum to exactly 1.0 per key, no overlapping ranges — assert in debug builds. - `Regenerate forecast` (DE-08): new sub-seed, forecast only, atomic swap, all entries → RequiresDisaggregation. ## 5. Mandatory self-documentation (owner requirement) 1. **Implementation decision log.** Maintain `DECISIONS.md` in the repo from the very first commit: every non-trivial choice you make during implementation (library picks, data-structure designs, SQLite schema/pragmas, trade-offs, deviations, anything ambiguous you resolved) gets a numbered, dated entry with a one-paragraph rationale. This file is also served inside the app (see next point). 2. **In-app documentation.** The application itself must contain a Documentation section (navigable from the main UI) with: - **User help:** per-screen guidance (S1–S7) — what each screen does, how to create entries, what the state chips mean, how to read error messages, how reset/regeneration work. - **Design documentation:** architecture overview (diagrams as needed), the data model, the four-stage pipeline with the rounding rules, the performance design (in-memory layout, SQLite strategy, batch parallelism), and the implementation decision log. - Concept docs may summarise the spec in your own words; keep them accurate to what you built. 3. **README.md:** quickstart — local dev run AND the exact `docker build` / `docker run` commands for the owner to execute in the morning — plus env vars, ports, default credentials, how to run tests and benchmarks. ## 6. Testing & acceptance (do not skip — this gates everything) Build the engine + tests FIRST, before API/UI/MCP: - Unit tests reproducing the spec's worked examples **exactly, number for number**: E5-A (phase profile), E5-B (split table), E6-A (end-to-end 1000 SU brand entry → the exact 13 LO rows incl. every tie-break). These run against the hardcoded MINI dataset. - Property tests: Σ LO(entry) = value_su for arbitrary generated entries/datasets (DF-04); all quantities non-negative integers; determinism — same inputs ⇒ byte-identical LO (DF-05), including on-entry vs batch paths. - Rule tests: D-22 (product-scoped entry beyond phase-out succeeds; single-location entry succeeds at split weight 0), D-24 (renormalization; zero surviving total ⇒ InError), DR-03/DR-08 orderings, HE-08 message quality (stage + rule + offending scope element). - API integration tests for the full operation catalogue (Ch. 08) incl. error model AP-04 and the 409 batch/regeneration cases. - The Ch. 10 §10.5 acceptance checklist: implement it as an automated test suite where possible; run it at the end and record results in the README. - Finish with: `cargo fmt`, `cargo clippy` clean, all tests green, and an end-to-end smoke test against the **natively running release binary** (start it, login → create the E6-A entry → verify 13 rows → run batch → fetch report) — script this as `scripts/smoke.sh` so the owner can rerun the identical smoke test against the Docker container after building it in the morning. ## 7. Working mode for the overnight run - Initialise a git repository; commit early and often with meaningful messages; keep the app runnable at every commit after the first vertical slice. - Recommended order: (1) engine + MINI fixtures + tests → (2) generator incl. CUSTOM + forecast synthesis → (3) persistence → (4) API + auth + batch → (5) MCP → (6) frontend screens S1–S7 → (7) in-app documentation → (8) Dockerfile + README build instructions + benchmarks + acceptance run + polish (no `docker build` — see §2 Packaging). - If you hit a genuine spec gap, resolve it in the spirit of the decisions (minimal, fast, honest-error) and write it into `DECISIONS.md` — do not block. - Definition of done: acceptance checklist passing against the native binary, `scripts/smoke.sh` green, Dockerfile + build/run instructions complete and plausible, documentation complete. The owner performs the image build and the containerised §10.4 demo run in the morning. Good luck — build it fast, build it exact, and let it prove its own speed.