From dc6bd6a3f6435e14162731728289c7ef70e7cc8b Mon Sep 17 00:00:00 2001 From: Max Winterstein <5927148+MaxWinterstein@users.noreply.github.com> Date: Tue, 22 Sep 2026 09:32:17 +0000 Subject: [PATCH] Give the README a banner and badges, and correct what it claims Presentation: an SVG banner and four badges. The banner is committed rather than hotlinked and is opaque rather than adaptive, because GitHub renders README images through its proxy where `prefers-color-scheme` follows the reader's operating system and not the theme GitHub is showing -- an adaptive banner is wrong for anyone with those two set differently. Its fact strip is one text element, not three positioned ones: no font is guaranteed, and the first measurement-based layout I tried overlapped the artwork in a monospace fallback. Each badge was fetched and read before being used. CI renders "passing", the Pages deployment "success", the licence "MIT", and the dependency count is a hand-maintained static badge that is true and is the point of the project. An npm version badge is deliberately absent: fitfix is not published, so it renders "package not found". Corrections, all of which had drifted: - "Three real sessions" headed a table with six rows, two of them in an 18 m pool rather than the 50 m the sentence promised. - "tuned on four files" and "four sessions from one swimmer" against seven fixtures. - The freestyle/breaststroke split was described as hard-coded at 40 strokes per length with a note that it "should be derived from the session". It has defaulted to 'auto' and scaled from the pool length since swim-05, so the paragraph described a wish that had already been granted. AGENTS.md said "It is private today" and listed two things parked until it was not, both long done. Replaced with the consequence that actually still applies: everything pushed is published immediately, including the parts that do not look like data -- a filename, a commit message, a fixture name. The H1 gives way to the banner, whose alt text carries the same words. Co-Authored-By: Claude Opus 5 (1M context) --- .github/banner.svg | 68 ++++++++++++++++++++++++++++++++++++++++++++++ AGENTS.md | 16 ++++++----- README.md | 21 +++++++++----- 3 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 .github/banner.svg diff --git a/.github/banner.svg b/.github/banner.svg new file mode 100644 index 0000000..5e70ed3 --- /dev/null +++ b/.github/banner.svg @@ -0,0 +1,68 @@ + + + phantomturn + Fixes phantom turns in Garmin pool-swim FIT files. Runs in your browser; nothing is uploaded. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + phantomturn + Your watch counted turns that never happened. + Garmin pool-swim FIT repair · runs in your browser · nothing uploaded + + + + diff --git a/AGENTS.md b/AGENTS.md index 55eec2d..be31a0e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -225,15 +225,17 @@ is strong but not confirmation. Both files are deliberately absent from the `TRUTH` table in `auto-lengths.test.mjs`, and the disagreement reaches the user as an `uncertain-lengths` finding carrying both readings. -## Before this repository goes public +## This repository is public -It is private today, and a few things are deliberately parked until it is not: +It has been since the Pages deploy was turned on, and both items that used to +be parked here are done: the `workflow_run` trigger in +`.github/workflows/pages.yml` is live, and `tools/needles.local.json` is +untracked. What is left is the standing consequence. -1. **Turn on the Pages deploy.** Uncomment the `workflow_run` trigger in - `.github/workflows/pages.yml` and set Settings → Pages → Source to - "GitHub Actions". Pages needs a public repo on free plans. -2. **Check `tools/needles.local.json` is still untracked.** It holds a name, a - watch serial and sensor ids. +**Everything you add is published the moment it is pushed**, including the +parts that do not look like data. A filename is data — see the fourth +guardrail above. So is a commit message, a test fixture name and an error +string. There is no staging period in which to notice. `web/legal.html` carries a name and an email and no postal address — a deliberate call for a private, non-commercial page that collects nothing. If diff --git a/README.md b/README.md index 3db6ae7..6dd05bc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# 🌊 phantomturn +![phantomturn — fixes phantom turns in Garmin pool-swim FIT files, in your browser](.github/banner.svg) + +[![CI](https://github.com/MaxWinterstein/phantomturn/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/MaxWinterstein/phantomturn/actions/workflows/ci.yml) +[![site](https://img.shields.io/github/deployments/MaxWinterstein/phantomturn/github-pages?label=site)](https://maxwinterstein.github.io/phantomturn/) +[![runtime dependencies: 0](https://img.shields.io/badge/runtime%20dependencies-0-047857)](#why-it-patches-bytes-instead-of-decoding) +[![licence: MIT](https://img.shields.io/github/license/MaxWinterstein/phantomturn?label=licence)](LICENSE) ### → [maxwinterstein.github.io/phantomturn](https://maxwinterstein.github.io/phantomturn/) @@ -31,7 +36,7 @@ length. The length gets split in two, and you are credited with distance you never swam. The same laps usually come back with the wrong stroke, because the watch switches stroke at the turn it imagined. Two symptoms, one cause. -Three real sessions, all Forerunner 265 in a 50 m pool: +Six real sessions, all Forerunner 265, in a 50 m pool unless noted: | Watch said | Actually swum | What went wrong | | ----------------- | --------------- | ------------------------------------- | @@ -153,18 +158,20 @@ scrubbing step that is not optional. - **Lengths per lap is inferred from the file**, per lap, by measuring each lap against how long one length takes you in that swim. That handles a session you lapped inconsistently, which no single number can. It is still a - heuristic tuned on four files — check the before/after numbers, and put a + heuristic tuned on seven files — check the before/after numbers, and put a number in if you disagree. - **It only ever merges, never splits.** If the watch *missed* a turn and recorded two lengths as one, nothing here will recover it. -- The freestyle/breaststroke split is **40 strokes per length**, calibrated in a - 50 m pool. A 25 m pool would need roughly half that. It should be derived from - the session instead of hard-coded. +- The freestyle/breaststroke split defaults to `auto`, which scales it from the + pool length — 40 strokes per length at 50 m, proportionally fewer in a short + pool. The constant behind it was still fitted on one swimmer, so a fixed + `--stroke-split` is there if your stroke count runs differently. - Freestyle and breaststroke only. No backstroke, butterfly, IM or drill — a watch that labels a length backstroke gets it silently reclassified as one of the two the classifier does know. - Multisport files are rejected. The guard is implemented but untested. -- Tested against a Forerunner 265, 50 m pool, four sessions from one swimmer. +- Tested against a Forerunner 265 only: seven sessions from one swimmer, in a + 50 m and an 18 m pool. ## Licence