docs: add CONTRIBUTING.md with local dev + build recipes #231

Merged
james merged 3 commits from contributing-md into main 2026-06-21 19:15:24 +00:00
Owner

Summary

Adds CONTRIBUTING.md at the repo root for the day-to-day developer surface, plus a one-line pointer from README.md.

The README is structured for self-hosters / operators — deployment, env vars, OIDC setup. Anyone wanting to develop on Carol had to piece together the dev story from CLAUDE.md + ADR-0027 + scattered PR descriptions; this collects it.

What's in CONTRIBUTING.md

  • Quick reference — minimal command set for daily work.
  • Prerequisites — required (mise + the tools pinned in .tool-versions) and per-build-target (JDK 21 + Android SDK for Android, Rust + webkit2gtk + flatpak-builder for Flatpak).
  • Initial setup — clone, install, lefthook wiring + escape hatches.
  • Repo layout — workspace tree.
  • Daily workflows — API dev server; the universal client on web, Android (Expo Go / emulator / signed APK), and Linux Flatpak; the full container.
  • Tests — SQLite-only vs full matrix; one-shot Postgres container recipe.
  • Lint / typecheck / format.
  • API contract workflow — zod → openapi-routes → openapi:generate → typed-client regen.
  • Database migrations — forward-only, dual-engine, one logical change per file.
  • Conventions — load-bearing rules distilled from CLAUDE.md.
  • Git workflow — branch naming, Conventional Commits, PR template, lefthook.
  • CI — what runs on PRs vs tag pipeline.
  • Where things live — table mapping common questions to docs.
  • Troubleshooting — the gotchas that have actually surfaced this cycle (No QueryClient duplication, expo prebuild rewriting package.json, Postgres FK drop order in tests, lefthook escape hatches).

The doc links to existing sources (README for env vars, ADRs for decisions, docs/api-conventions.md for contract shape) rather than restating them.

Out of scope

  • Restructuring or rewriting the README's content — it stays operator-focused.
  • Code of conduct / governance docs — separate.

Test plan

  • pnpm install clean (no functional changes outside docs).
  • Markdown links to existing files resolve (idea.md, CLAUDE.md, docs/api-conventions.md, every ADR referenced).
  • Sample commands match the actual package.json scripts (export:web, build:android, build:flatpak, openapi:generate, openapi:check, openapi:coverage, etc.).
  • lefthook + Conventional Commits pass on the single commit.
## Summary Adds `CONTRIBUTING.md` at the repo root for the day-to-day developer surface, plus a one-line pointer from `README.md`. The README is structured for self-hosters / operators — deployment, env vars, OIDC setup. Anyone wanting to develop on Carol had to piece together the dev story from `CLAUDE.md` + `ADR-0027` + scattered PR descriptions; this collects it. ## What's in CONTRIBUTING.md - **Quick reference** — minimal command set for daily work. - **Prerequisites** — required (mise + the tools pinned in `.tool-versions`) and per-build-target (JDK 21 + Android SDK for Android, Rust + webkit2gtk + flatpak-builder for Flatpak). - **Initial setup** — clone, install, lefthook wiring + escape hatches. - **Repo layout** — workspace tree. - **Daily workflows** — API dev server; the universal client on web, Android (Expo Go / emulator / signed APK), and Linux Flatpak; the full container. - **Tests** — SQLite-only vs full matrix; one-shot Postgres container recipe. - **Lint / typecheck / format**. - **API contract workflow** — zod → openapi-routes → openapi:generate → typed-client regen. - **Database migrations** — forward-only, dual-engine, one logical change per file. - **Conventions** — load-bearing rules distilled from `CLAUDE.md`. - **Git workflow** — branch naming, Conventional Commits, PR template, lefthook. - **CI** — what runs on PRs vs tag pipeline. - **Where things live** — table mapping common questions to docs. - **Troubleshooting** — the gotchas that have actually surfaced this cycle (No QueryClient duplication, expo prebuild rewriting package.json, Postgres FK drop order in tests, lefthook escape hatches). The doc links to existing sources (README for env vars, ADRs for decisions, `docs/api-conventions.md` for contract shape) rather than restating them. ## Out of scope - Restructuring or rewriting the README's content — it stays operator-focused. - Code of conduct / governance docs — separate. ## Test plan - [x] `pnpm install` clean (no functional changes outside docs). - [x] Markdown links to existing files resolve (`idea.md`, `CLAUDE.md`, `docs/api-conventions.md`, every ADR referenced). - [x] Sample commands match the actual `package.json` scripts (`export:web`, `build:android`, `build:flatpak`, `openapi:generate`, `openapi:check`, `openapi:coverage`, etc.). - [x] lefthook + Conventional Commits pass on the single commit.
docs: add CONTRIBUTING.md with local dev + build recipes
Some checks failed
Commits / Conventional Commits (pull_request) Successful in 8s
PR / OSV-Scanner (pull_request) Successful in 2m11s
PR / OpenAPI (pull_request) Successful in 2m32s
PR / Static analysis (pull_request) Successful in 2m32s
PR / Lint (pull_request) Successful in 2m52s
PR / pnpm audit (pull_request) Successful in 3m26s
PR / Client (web export smoke) (pull_request) Successful in 3m53s
PR / Package age policy (soft) (pull_request) Successful in 1m46s
PR / Typecheck (pull_request) Successful in 4m20s
PR / Test (postgres) (pull_request) Successful in 4m20s
PR / Test (sqlite) (pull_request) Successful in 4m23s
PR / Build (pull_request) Successful in 4m29s
Secrets / gitleaks (pull_request) Successful in 1m38s
PR / Trivy (image) (pull_request) Failing after 2m21s
PR / Coverage (soft) (pull_request) Successful in 2m23s
f73958c945
The README is the self-hoster/operator surface (deployment, env vars,
auth setup). Contributors had to piece together the dev story from
CLAUDE.md + ADR-0027 + scattered PR descriptions.

CONTRIBUTING.md collects:

- Prerequisites (mise + .tool-versions baseline; per-target deps for
  Android and Flatpak).
- Daily workflows — API dev server, web client, Android (Expo Go +
  emulator + signed APK), Linux Flatpak, full container.
- Tests including the SQLite + Postgres matrix recipe.
- API contract workflow (zod → openapi-routes → drift gate).
- Git workflow (branching, Conventional Commits, lefthook, PRs).
- CI overview and where-things-live table.
- Troubleshooting for the gotchas that have actually surfaced (No
  QueryClient, expo prebuild rewriting package.json, Postgres FK drop
  order in tests, lefthook escape hatches).

README gets a one-line pointer.

Trivy (container image)

Threshold: high  ·  Total findings: 121  ·  At/above threshold: 1

critical high medium low
0 1 50 70
severity id package installed / range fix
high CVE-2026-12151 undici 6.25.0 6.27.0, 7.28.0, 8.5.0
<!-- scanner-comment: trivy --> ### Trivy (container image) **Threshold:** `high` &nbsp;·&nbsp; **Total findings:** 121 &nbsp;·&nbsp; **At/above threshold:** 1 | critical | high | medium | low | |---:|---:|---:|---:| | 0 | 1 | 50 | 70 | | severity | id | package | installed / range | fix | |---|---|---|---|---| | high | [CVE-2026-12151](https://avd.aquasec.com/nvd/cve-2026-12151) | undici | 6.25.0 | `6.27.0, 7.28.0, 8.5.0` |

📊 Test coverage

Patch coverage: no testable lines changed.

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 82.9% ≥ 50%
Branches 76.0% ≥ 75%
Functions 91.3% informational

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** no testable lines changed. **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 82.9% ✅ | ≥ 50% | | Branches | 76.0% ✅ | ≥ 75% | | Functions | 91.3% | informational | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
docs: fix the Expo Go recipe — don't pass --android
Some checks failed
Commits / Conventional Commits (pull_request) Successful in 8s
PR / OSV-Scanner (pull_request) Successful in 2m47s
PR / pnpm audit (pull_request) Successful in 3m9s
PR / Client (web export smoke) (pull_request) Successful in 3m17s
PR / Static analysis (pull_request) Successful in 3m20s
PR / OpenAPI (pull_request) Successful in 3m34s
PR / Package age policy (soft) (pull_request) Successful in 34s
PR / Typecheck (pull_request) Successful in 4m2s
PR / Build (pull_request) Successful in 4m9s
PR / Lint (pull_request) Successful in 4m23s
PR / Test (sqlite) (pull_request) Successful in 4m23s
Secrets / gitleaks (pull_request) Successful in 1m13s
PR / Test (postgres) (pull_request) Successful in 4m38s
PR / Coverage (soft) (pull_request) Successful in 1m55s
PR / Trivy (image) (pull_request) Failing after 2m11s
85ed67dd59
fix(deps): pin react + react-dom to 19.2.3 via pnpm.overrides
Some checks failed
Commits / Conventional Commits (pull_request) Successful in 8s
PR / OSV-Scanner (pull_request) Successful in 2m21s
PR / pnpm audit (pull_request) Successful in 2m41s
PR / OpenAPI (pull_request) Successful in 2m47s
PR / Static analysis (pull_request) Successful in 2m47s
PR / Typecheck (pull_request) Successful in 3m2s
PR / Lint (pull_request) Successful in 3m37s
PR / Client (web export smoke) (pull_request) Successful in 4m0s
Secrets / gitleaks (pull_request) Successful in 1m10s
PR / Package age policy (soft) (pull_request) Successful in 1m12s
PR / Test (sqlite) (pull_request) Successful in 4m17s
PR / Test (postgres) (pull_request) Successful in 4m17s
PR / Build (pull_request) Successful in 4m24s
PR / Coverage (soft) (pull_request) Successful in 2m4s
PR / Trivy (image) (pull_request) Failing after 3m8s
ab2ed6287a
Expo SDK 56 ships its native renderer built against React 19.2.3
exactly. Carol's workspace previously resolved React to 19.2.7
(latest matching ^19.2.3 / ^19.0.0 across api / client / api-client),
which Expo Go reports as "incompatible versions of react and
react-native-renderer" when loading the dev bundle.

The earlier fix to loosen apps/client's pin from "19.2.3" to "^19.2.3"
solved the "No QueryClient" duplicate-React-in-bundle issue. Keep
that — it's still load-bearing for dedupe — but add a root-level
pnpm.overrides forcing react + react-dom to 19.2.3 so the deduped
copy matches what Expo Go's renderer was built against.

When Expo SDK 57 lands and its renderer is rebuilt against a newer
React patch, bump the overrides in the same PR.
james merged commit 0ee4841301 into main 2026-06-21 19:15:24 +00:00
james deleted branch contributing-md 2026-06-21 19:15:24 +00:00
Sign in to join this conversation.
No description provided.