Bump python from 3.11-slim to 3.14-slim - #19
Open
dependabot[bot] wants to merge 33 commits into
Open
Conversation
added 30 commits
August 7, 2026 13:33
Adds an explicit statement that Row Tracker is fully self-hosted with no backend of ours in the loop, and calls out the AI coaching feature as the one exception (opt-in, uses the user's own Anthropic key, sends only minimal workout context). Also removes the Support/sponsorship section for now.
Establishes 0.x.y SemVer going forward (major-zero: breaking changes still possible in minor bumps). The version lives in a single VERSION file, read once at app startup and exposed as an app_version Jinja global — shown in a new site-wide footer and on the FAQ page subtitle, replacing the hardcoded "June 2026" date that was already stale. CHANGELOG.md backfills 0.1.0 through 0.9.0 from commit history, grouped by what actually shipped in each burst of work, since nothing was tagged contemporaneously.
… cache Moved the version display from a centered footer line to a small, low-opacity vX.Y.Z badge fixed to the bottom-right corner on every page. While verifying it live, found that the service worker's static-asset cache name was a hardcoded constant that never changed across deploys — cache-first meant any CSS/JS update was invisible to a browser that had already loaded the app once. sw.js is now rendered from a Jinja template with CACHE_NAME tied to app_version, so every version bump invalidates the old cache automatically instead of silently serving stale assets.
Fixes a real issue found while auditing the repo for public release: no .dockerignore existed, so the real .env (with live credentials) and the full .git history were being baked directly into every built Docker image. The app never reads that in-image copy — all config comes from os.environ via docker-compose's env_file — so excluding it is a pure fix with no behavior change. Also fixes the README's placeholder clone URL, a copyright-name casing mismatch between LICENSE.md and the README, removes the unused python-dotenv dependency, and a couple of small doc-sync items. Does not cover the remaining open items from the same audit pass (a leaked credential still present in git history, and a couple of untracked-file cleanup questions) — those need a decision first.
Both were flagged in the public-readiness audit: designidea.webp is an unreferenced design-reference image, and the two docs/superpowers/ files are AI-agent implementation plans/specs, not user-facing documentation. Untracked (git rm --cached) rather than deleted, and added to .gitignore alongside the existing row-tracker-spec.md / docs/redesign-spec.md convention — local copies are kept, just not part of the public repo.
The README said AI coaching was "the only feature that talks to a third party," which stopped being true the moment the feedback form existed — it emails the developer directly (hardcoded recipient, not configurable via .env), using whatever Gmail credentials the deployer configured. Added a dedicated Feedback section spelling out exactly what it does and doesn't send, and cross-referenced it from the top privacy blurb.
…s audit Removes _persist_refresh_token() from c2_api.py — unreachable (Concept2 issues a non-expiring bearer token, so nothing ever rotates it), and wouldn't have worked reliably even if called (writes to .env inside the container, which isn't a mounted file and no longer exists there at all post the .dockerignore fix). Also fixes the module docstring, which still described an OAuth token-exchange flow the code never implements. This closes out the two-pass pre-public-release audit: git history is clean (leaked credential scrubbed + revoked), the Docker image no longer bakes in secrets, docs are accurate and cross-linked, stray files are untracked, CONTRIBUTING.md and GitHub topics are in place, and the full test suite (187 tests) passes against the final state.
Clicking Sync on a dashboard left open >1h returned 400 'request failed' with a 'CSRF token has expired' log line. The token stays session-bound regardless, so the 1-hour expiry was UX friction with no security benefit for a single-user self-hosted app.
… AI coach's read A new nav section that reads the full workout history and surfaces patterns in plain language (best day, rest-day effect, pace/volume trends, fastest steady stroke rate, session-length clusters, consistency, PB clustering). Each insight clears a minimum-sample and significance check before it appears and is tagged Strong pattern or Early signal; the strongest carry a recommendation. Built as a rule-based engine (insights_engine.py) with facts separated from phrasing, so an optional AI 'coach's read' (insights_ai.py, USE_AI_INSIGHTS, off by default) can rephrase the computed facts without ever inventing a number. Includes tests (11), README/FAQ/QUICKSTART + in-app twins, and .env.example.
…-proof Tuned insight surfacing against real data. Day-of-week, rest-gap, and seasonal pace effects were left gated — the signal is genuinely flat at the median, so loosening would manufacture noise — while adding rules the data actually supports: - Milestones section (years rowing, biggest day, hours on the erg, longest streak), rendered as a big-number 'stat' card with no confidence tag since they're facts. - Year-over-year volume: meters Jan 1 -> today vs the same span last year. - Pace-trend now measures steady pieces (20 min+) only, so a shift in workout mix can't masquerade as a pace change. Adds 7 tests (18 total in the module); README/FAQ + in-app twins updated.
The rower emblem replaces the placeholder emoji in the desktop and mobile nav, and the full ROW TRACKER lockup anchors the top of the Dashboard, switching between the dark- and light-mode artwork with the theme. Source logos were processed to transparent backgrounds (stray export badge and edge line removed) and normalised to a shared frame so theme changes cause no size shift.
…ry instances Default true (prod unchanged). Set RUN_SCHEDULER=false so a dev instance doesn't run the nightly C2 sync/PB recalc/badge eval/backup and fire duplicate notification emails alongside the instance that owns the live data.
Year-over-year and weekly-volume cards showed distances as '1,996k m' / '56.0k m/week', an ambiguous kilo-metres hybrid that read like a typo. Now rendered as consistent kilometres in detail text, pills, and sparkline labels.
… read Covers the availability gate, the happy path (right model, briefing grounded in the engine's real facts, system prompt forbids inventing numbers), and every failure mode falling back to None. Runs with no API key — no real calls made.
All prior screenshots predated the logo (Aug 7, logo shipped Aug 10) and still showed the old placeholder emoji nav. Retaken against the live app: new branded nav + dashboard hero visible throughout, plus a new Insights screenshot for the page that didn't exist when the originals were taken.
Swapped # 🚣 Row Tracker for a theme-switched logo banner using the same <picture>/prefers-color-scheme trick GitHub renders correctly in READMEs — dark artwork on a dark-mode viewer, light artwork on a light-mode one.
Image vulnerability scan (Docker Scout) found known CVEs in the base image's bundled pip/setuptools/wheel/jaraco-context — never upgraded past whatever shipped with python:3.11-slim. Now upgraded explicitly before installing app dependencies, plus apt-get upgrade for OS packages so future rebuilds pick up Debian security patches automatically. Verified on disk post-rebuild: real fixes (setuptools 79.0.1->84.0.0, pip 24.0->26.2.1, etc.), no regressions — two apparent new findings from the scanner (a stale setuptools version, a pip-internal vendored msgpack copy) were confirmed to be scanner artifacts, not real state of the image, by direct filesystem inspection.
Closes the last blind spot from the security review — the vendored copy had no version pinned anywhere and nothing would catch it going stale. Pinned to Chart.js 4.4.1 via jsDelivr with a sha384 integrity hash verified against the actual served bytes, so a tampered/compromised CDN response fails to execute rather than running silently. Falls back to the local file (now byte-identical to the CDN version, not a different unverified build) if the CDN is unreachable, keeping 'no external dependencies required' true for offline/air-gapped use — the service worker already pre-caches that file for offline PWA support regardless. All 5 templates now share one partial (_chart_cdn.html) instead of duplicating the script tag, with the version-bump recipe documented inline. Verified in-browser: CDN loads (200), SRI passes with zero console errors, Chart.version reports 4.4.1, fallback correctly stays dormant, charts render on both Dashboard and the Charts pages.
…ocal time Container had no TZ set, so the '3:00 AM' cron jobs (sync, PB recalc, badge eval, backup) actually ran at 3:00 AM UTC — hours off from the FAQ/Quick Start's documented 'Toronto time'. Added TZ to .env.example, defaulting to America/Toronto to match the docs.
…g + last-synced indicator - scheduler.py: CronTrigger doesn't inherit BackgroundScheduler's timezone kwarg unless given its own — every job's trigger now gets it explicitly (sourced from TZ, defaulting to America/Toronto). v0.9.12's TZ env var only worked by coincidence; this is the actual fix. - c2_api.py: a bad/expired token (401) or network failure was indistinguishable from 'nothing new to sync' — now surfaced as a real error via C2ApiClient.last_error instead of silently swallowed. - New SyncStatus model + sync_status.py: tracks last attempt/success/error, shared by the nightly scheduler and the manual /sync route. - Dashboard: 'last synced' indicator next to the Sync button. - notify.py: notify_job_failure() emails NOTIFY_EMAIL when the nightly sync, PB recalc, badge eval, or backup job fails — previously log-only. - Manual sync button's frontend now treats the /sync route's 'partial' status as a failure (it was falling through to the success branch). - 227 tests passing, 12 new.
Added to the desktop nav when Insights shipped in 0.9.5, never added to the mobile hamburger drawer, so it's been invisible on phones/tablets since then. Added the link, plus a regression test that diffs desktop vs. mobile nav hrefs so a future nav addition can't repeat this.
The 228-test pytest suite has existed for a while but nothing ran it automatically. Adds .github/workflows/tests.yml: Python 3.11 (matching the Docker base image), pip caching, runs on every push to main and every PR. Status badge + license badge added to README; CONTRIBUTING.md updated to mention the automated check.
actions/checkout@v4 and actions/setup-python@v5 were both being forced onto a deprecated Node target on the first CI run. Bumped to @v7/@v7.
Weekly automated PRs across all three ecosystems this repo actually uses. Every Dependabot PR gets checked by the CI workflow added in 0.10.2, so a breaking bump fails the check instead of merging silently.
Bumps python from 3.11-slim to 3.14-slim. --- updated-dependencies: - dependency-name: python dependency-version: 3.14-slim dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Author
LabelsThe following labels could not be found: Please fix the above issues or remove invalid values from |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps python from 3.11-slim to 3.14-slim.
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)