An exported GITEA_TOKEN only exists in the shell that exported it, so
tooling invoked from elsewhere could not find it. Resolve in order:
$GITEA_TOKEN, ~/.config/gitea/token, then the macOS Keychain — so the
token can live somewhere durable and non-world-readable instead of a
plaintext dotfile.
Also factors the API call and repo coordinates into scripts/lib/gitea.sh
so pr.sh and review.sh stop duplicating them, and adds
`review.sh --list` for enumerating open PRs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Prepares the repo for parallel agent work. No application code.
- CLAUDE.md: conventions, branch naming, and the six non-negotiable
invariants from the design (immutable raw bytes, no stored odometers,
SI integers, dual-layer user isolation, secret containment, single
ingestion path). Also records a model-allocation policy: the
orchestrator runs Opus 5, workers default to Sonnet, and Opus is
reserved for review plus the areas where a mistake is silent and
expensive (ingest, wear SQL, auth/RLS, the Bryton protocol client).
And the Gitea Actions gotchas, so nobody rediscovers them:
GITEA_TOKEN cannot push to the container registry, jobs.*.environment
is ignored, and cron needs a workflow_dispatch pair.
- CONTRIBUTING.md: day-to-day flow, worktrees for parallel branches,
review expectations.
- .gitea/workflows/ci.yml: repo hygiene (branch naming, secret scan,
no ride data in git), plus API/web/migration jobs that guard on whether
the code exists yet, so CI is meaningful now and grows into the real
thing rather than being rewritten.
- .gitea/PULL_REQUEST_TEMPLATE.md: forces an honest "how this was
verified" and an invariant checklist.
- scripts/pr.sh, scripts/review.sh: open and inspect PRs via the Gitea API.
- Directory scaffold with placeholder READMEs.
Agents open PRs; humans merge them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Planning output only; no application code yet.
Key findings driving the design:
- The Bryton Rider 650 has on-device Wi-Fi (Main Menu -> Data Sync) and
uploads to Bryton's cloud with no phone and no Bryton Active app. Paired
with the reverse-engineered Bryton cloud API — which returns the original
unmodified FIT bytes — this makes ride sync fully hands-off, and higher
fidelity than the current Strava route (Strava's API cannot return the
original file, only smoothed streams).
- Build fresh rather than forking Endurain or FitTrackee; borrow Endurain's
gear/component structure and strava-gear's retroactive time-ranged wear
computation.
- PWA rather than a native iOS app: iOS 16.4+ gives home-screen PWAs real
push notifications, which was the only thing that used to force native.
Docs:
docs/PLAN.md stack, schema, ingestion, auth, notifications, roadmap,
CI/CD, risks, verification
docs/RESEARCH.md Bryton cloud protocol, FIT library comparison,
maintenance intervals, geo services, Gitea gotchas
docs/DECISIONS.md decisions taken, alternatives rejected, rationale
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>