From 0e32c0bbab1a5a2b62c5bba828badf0e94d8fa2b Mon Sep 17 00:00:00 2001 From: Chris Amow Date: Mon, 10 Aug 2026 17:10:24 -0500 Subject: [PATCH] Rename to /ESsence and write down the house rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The header spent a whole line on a "CME FUTURES" eyebrow that told you nothing the chart didn't — it only ever shows /ES. Dropping it takes the header from 64px to 44px and hands the space to the chart. The title becomes /ESsence. AGENTS.md records the rules worth keeping, chief among them that a bug should prompt the question of whether a unit test could reasonably have caught it — written when the answer is yes, skipped when it is a rendering or data-source quirk, and named after the failure rather than the function. It is AGENTS.md rather than CLAUDE.md deliberately: opencode's instruction loader walks up looking for AGENTS.md only and never reads CLAUDE.md, and the ask-opencode skill asks the calling agent to distil house rules by hand rather than forwarding a file. CLAUDE.md is a symlink to it so both tools resolve to one source of truth. Co-Authored-By: Claude Opus 5 --- AGENTS.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + static/index.html | 4 +-- static/style.css | 4 +-- 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 AGENTS.md create mode 120000 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..aab8eef --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,70 @@ +# Working on this repo + +## Tests earn their place by catching a real bug + +When a bug is found, ask whether a unit test could reasonably have caught it. If +yes, write that test with the fix. If no — a rendering artefact, a browser +quirk, a data-source oddity — say so and don't add one. + +The bar is "would this have failed before the fix, and would it fail again if +someone reintroduced it". Tests that restate the implementation, assert +constructor defaults, or exercise paths nothing depends on are noise; they make +the suite slow to run and expensive to change, which is how a suite stops being +trusted. + +What has actually paid off here: bar aggregation and bucket boundaries, the +store's replace-vs-append rules, level and alert arithmetic, parsing real +market-data payloads (fixtures are trimmed real responses, not invented), and +the invariants that would otherwise be silent — a comment must never become a +level, a tick must never overwrite a settled bar, volume must be counted once. + +Name the test after the failure, not the function: `test_a_tick_cannot_overwrite +_a_settled_bar` beats `test_put`. + +## Verify UI in a real browser + +Chart bugs are invisible from the outside — the API, the socket and the +frontend source can each be correct while the screen is wrong. Drive the +Playwright container against the dev stack: + +``` +docker exec -i chart-playwright-1 node - <<'EOF' +const { chromium } = require('/usr/lib/node_modules/playwright'); +// launch with args:['--lang=en-US'] — see below +EOF +``` + +**Always launch Chromium with `args: ['--lang=en-US']`.** The container has no +usable locale, so Chromium reports `en-US@posix`, `Intl` throws, and the chart +renders as a blank canvas that looks exactly like a broken app. + +`window.__chart` is a deliberate debug handle. Querying it separates "the data +is missing" from "the data is off-screen" — which is how a viewport bug that +three passing API checks had missed was finally found. + +## Running tests + +``` +docker exec chart-api-1 sh -c "cd /app && python -m pytest -q" +``` + +pytest + pytest-asyncio, declared in `requirements-dev.txt`. Tests live in +`tests/`, import from `app.*`, and use `tmp_path` for anything that persists. +Async paths are driven with `asyncio.run(...)` directly rather than async test +markers. + +## Things that will cost you an hour + +- **Never write scratch `.py` files into the repo root.** It is bind-mounted, so + `--reload` restarts the app, and startup takes ~82 seconds. Pipe throwaway + scripts over stdin instead: `docker exec -i chart-api-1 python - <<'EOF'`. + Screenshots into `artifacts/` are safe; only `.py` triggers the reloader. +- **Dev and production keep separate drawing stores.** Dev writes + `data/manual_lines.json`; production has its own Coolify volume. A fix that + "didn't land" is often the other store. +- **Rebuild the image after touching `requirements.txt`.** The bind mount makes + source edits look live while an added dependency is simply absent. +- **A deploy resets alert cooldowns**, so production may re-alert on whatever + price is sitting on. There is no durable state yet. +- Times are epoch seconds, UTC, everywhere. Only the display is localised — + never shift the stored values. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..47dc3e3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file diff --git a/static/index.html b/static/index.html index eda8d94..e727d96 100644 --- a/static/index.html +++ b/static/index.html @@ -3,7 +3,7 @@ - /ES Confluence + /ESsence