Files
kvitt/docs/HANDOFF.md
T

55 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handoff: state of the work
Living document, rewritten in place (never a second copy). A new orchestrator session reads CLAUDE.md, then this.
## 1. Where things stand
- `main` at `3c68594` (M8d) plus the SPEC v0.16 docs commit from `agent-docs-v016` once it lands. History: `5e1be38` plans and prompts, `c885aba` M2c-dev, `76ee957` SPEC v0.3, `fad6fc9` M2b, `fdf2093` M2a, `040bf41` SPEC v0.4, `503cee5` M3, `c28c52b` M5, `982451d` SPEC v0.5, `bd6f10a` M4, `23a2f1e` SPEC v0.6, `ab298ab` M9, `e8ee518` SPEC v0.7, `6b60ef7` M12a, `7fb9f6f` SPEC v0.8, `e499107` M12c, `2e2ebe7` M12b, `d452fa6` UX Kalas categories and tokens, `16c4d01` UX sprint U2, `45eecd1` SPEC v0.9, `bdba9d3` M12d, `3080804` M6, `7bd0aa1` SPEC v0.10, `72f21b2` app debug fakes bindings (temporary, deleted by M8), `e6ad858` app release wiring of `:data` (pre-M8), `b9b061a` M7a, `6ac711d` M7e, `082b8dc` M7d, `31760f9` M7b, `1e42f76` M7c, `a54eb7c` M7f, `3a1bd14` M6b, `d504004` SPEC v0.11, `34a2590` M7g, `369e516` and `00a14a3` M8, `cf8ef45` SPEC v0.12, `1470a2f` M12e contract pass, `90505a8` M12e launcher icon, `03b7184` SPEC v0.13, `2b4e21c` Vico catalog entries removed (D-063), `c694f78` server FCM target in `fid` (D-096), `1e404cc` Pi image arm64 check (`docs/spikes/pi-image-arm64.md`), `fd60170` SPEC v0.14, `f0575d3` M8b UI fixes from the first phone test, `09f474f` `FcmMessageBody.fid` in `:data` (D-096 follow-up), `e7d963a` SPEC v0.15, `b481fab` M8c goldens at 1x in three variants (D-098), `64f5706` M8c S-22 licences row removed (D-099), `7c453d8` every PNG through oxipng, `57f984f` R8 release build, `3c68594` M8d editor rows (D-102).
- Landed: M0 spec, M1 contracts and vectors (`c6df2ab`), M2a (`fdf2093`), M2b (`fad6fc9`), M2c-dev (`c885aba`), M3 (`503cee5`), M4 (`bd6f10a`), M5 (`c28c52b`), M9 (`ab298ab`), M12a (`6b60ef7`), M12b (`2e2ebe7`), M12c (`e499107`), U1 and U2 (`16c4d01`, owner approved), M12d (`bdba9d3`), M6 (`3080804`), M7a to M7f, M6b (`3a1bd14`), SPEC v0.11 (`d504004`, D-069 to D-080), M7g feature cleanups (`34a2590`), M8 app integration (`369e516` + `00a14a3`, landed 2026-10-18, gate green: BUILD SUCCESSFUL, 710 actionable tasks), SPEC v0.12 (`cf8ef45`, D-081 to D-085), M12e contract pass (`1470a2f` + `90505a8`, landed 2026-10-18; gates green: Android BUILD SUCCESSFUL, 710 actionable tasks, 906 tests; cargo 253 tests, OpenAPI equality, vectors and migration byte-identity green), SPEC v0.13 (`03b7184`, D-086 to D-095), Vico removal (`2b4e21c`), FCM `fid` target (`c694f78`, D-096), Pi image arm64 check (`1e404cc`: C stage, CA roots and an OAuth plus FCM call from the arm64 image confirmed on the Mac; running on the Pi stays M2c-pi's), SPEC v0.14 (`fd60170`, D-096), M8 on-phone test (2026-10-18, passed), M8b (`f0575d3`, D-097), `FcmMessageBody.fid` (`09f474f`), SPEC v0.15 (`e7d963a`, D-097, D-100, D-101); landed today after v0.15: M8c (`b481fab`, `64f5706`, `7c453d8`; D-098, D-099), the R8 release build (`57f984f`), M8d (`3c68594`, D-102).
- M8 outcome (recorded in SPEC v0.12 as D-081 to D-085): both variants bind `:data` through `di/AppDataModule.kt`, debug fakes module gone (D-081, revises D-041); debug network security config allows cleartext everywhere, the AC-2.8 limit is enforced in `SessionRepositoryImpl.normaliseServerUrl`, pinned-root config behind `kvitt.tls.pinnedRoot` (D-082); FCM registration by Firebase Installation ID, firebase-messaging 26.0.0, no server change (D-083); invite links ignored while paired (D-084); generic-notification, deletion and `sync_batch` taps open Home, push in an expedited WorkManager job (D-085).
- M8 end-to-end test (2026-10-18, dev server, owner's S26): pairing with the bootstrap code OK; a scripted partner joined through a second admin device paired with `kvitt-server pair-device` (the CLI has no partner-invite subcommand: small ops request for a later server plan); Home showed the account; the offline expense showed the pending marker and synced after reconnect (pending 0, the server has the row); the owner's device registered `fcm_token` and `app_version_name`; a push by `fid` was delivered and the notification tap worked. Still unverified on the phone: the status-bar fix (next install) and the design-spec §2.7 typeface check (the owner looked, no complaint).
- M8b outcome (SPEC v0.15): invite-code field holds the raw code, hyphens as a `VisualTransformation` (cursor bug fixed, unit test); quick-row selected badge drawn above the ripple clip; `KvittTopAppBar` pads for the status-bar inset (`windowInsets` parameter), `KvittScaffold` follows; chart bars top 4, bottom 2 dp (D-097); 221 goldens re-recorded. `FcmMessageBody.fid` in `:data` followed (`09f474f`).
- M8c, R8 and M8d outcome (SPEC v0.16): goldens `<name>_sv_light`, `_sv_dark`, `_en_light` plus `_sv_light_200`, at 1x (`w411dp-h<height>dp-mdpi`), oxipng-compressed: 1143 PNGs / 131 MB to 865 / 26 MB, mock-ups 36.8 to 26.0 MB (D-098, revises D-066); S-22 has no licences row, `settings_about_licences` gone (D-099, OQ-5 closed); release APK R8-shrunk, about 11 MB (was 43 MB), `mapping.txt` to be kept beside the APK by the publish script (SPEC §10.6); release signing verified (alias `kvitt`, RSA 4096, v2); S-7 options as four fixed rows `EditorOptionRows`, connected buttons 8 dp side padding (D-102).
- Owner answers 2026-10-18: "boende" keeps suggesting `travel` (no change); the 128 px picture size is not needed; OQ-5 "no, hide the button" (implemented by M8c); the account page split bar stays as designed; M2c-pi becomes an owner-run bundle (D-100); the keystore lives at the repository root (D-101); the Gitea push waits for fewer goldens and a history rewrite, no LFS.
- M12e outcome (recorded in SPEC v0.13 as D-086 to D-095): E-3 `invite_kind` and `Pairing`, S-2 only after a `partner` pairing (D-086); admin name in E-12 links via `?from=`, passed on by E-4, S-1 help line names the admin (D-087); `SyncSummary.lastAttemptFailed` (D-088); `Rejection.actor` (D-089); `X-Kvitt-App-Version-Name`, migration 0003, server schema 3, S-20 "Kvitt 1.1" (D-090); `NewRecurringTemplate` (D-091); `UpdateCheck` (D-092, revises D-073); `SettleState.untouched` (D-093, revises D-074); D-027 re-stamp in `:data` (D-094); `PushEvent` in `:core:model`, six screen-hosted snackbar hosts, snackbar resource ids, adaptive vector launcher icon (D-095, revises D-071). 128 px picture size: the owner confirmed it is not needed (single 512 size, SPEC §14.2.4).
- Compatibility: the M12e APK cannot pair or list devices against a pre-M12e server (DTOs without defaults, by design), so the server is rebuilt and redeployed before the new APK is installed (SPEC §14.8). Old phones on the new server work.
- In flight: M2c-pi bundle `infra/pi/` (D-103 to D-106), M8e (S-19 editor rows, D-107), `agent-docs-v016` (this docs change: SPEC v0.16, D-098, D-099, D-102). Then a one-off history rewrite (drop the superseded PNG blobs; no clone exists) and the first push to `origin` (owner authorised, no confirmation needed), which also runs the Gitea Actions workflow.
- Remote: `origin` on Gitea exists and the SSH key works; the golden reduction (M8c) has landed; the history rewrite and the first push follow this docs pass (owner authorised 2026-10-18, no further confirmation). The owner created the Gitea secret `kvitt_cicd` and the Drive token (`infra/secrets/rclone-drive-token.json`, turned into `rclone.conf`; both git-ignored).
- Both gates exist: Android `tools/gradle-serial.sh check` (from `android/`), server `cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test` (from `server/`). Both green on `main` as far as reported.
- The UX sprint branch `UX-sprint` and its worktree `~/orca/workspaces/kvitt/UX-sprint` were removed on 2026-10-18 (fully merged).
- Importer: the dry run of 2026-10-18 with M12b's mapping reconciled on both real files (Vardag 1746 rows, 0 unmapped; Hemma 37 rows, 0 unmapped). The CSV files stay in `export/` (git-ignored).
- Development stack (M2c-dev): running on the Mac, reachable at `http://192.168.1.210:8080`; rebuilt on 2026-10-18 with the M12e server and the `fid` target (a push by `fid` arrived in the M8 test), database at schema 3, data kept. Backups `infra/dev/backups/kvitt-20261018T093143Z.sqlite.gz` (before schema 2) and `infra/dev/backups/kvitt-20261018T130443Z.sqlite.gz` (before schema 3) exist (git-ignored). On this Podman setup `infra/dev/up.sh` alone does not swap in a rebuilt image: run `infra/dev/up.sh --down`, then `infra/dev/up.sh`. The owner's phone paired with the bootstrap code on 2026-10-18; a scripted partner exists, joined through a second admin device paired with `kvitt-server pair-device` (tokens held by the orchestrator outside the repo). Firebase project `kvitt-1337` with apps `se.hagstedt.kvitt` and `se.hagstedt.kvitt.debug`; service account `kvitt-fcm`; `infra/secrets/fcm-service-account.json` and `infra/secrets/google-services.json` in the main checkout (git-ignored).
- Installed on the owner's phone (SM-S942B): the debug app `se.hagstedt.kvitt.debug`, paired against the dev server for the M8 test on 2026-10-18; the next install carries M8b, M8c and M8d.
## 2. Open work (one line each, with who owns it: agent or owner)
- Land `agent-docs-v016` (orchestrator): SPEC v0.16, D-098, D-099, D-102, HANDOFF, `prompts/README.md`, design-spec §3.7, §3.10 and S-22.
- Land the M2c-pi bundle (D-103 to D-106) and M8e (D-107) when they report (orchestrator), then a docs agent for v0.17.
- History rewrite (drop superseded PNG blobs; no clone exists), then the first push to Gitea `origin` (orchestrator; owner authorised, no confirmation needed); the push runs the Gitea Actions workflow (§3 item 3).
- Install the next debug build and have the owner look (§3 item 1); build a signed release for the smoke taps (§3 item 2).
- Cleanup (agents of the owning modules, no plan yet): 20 unused strings R8 found (`editor_next`, `home_notification_rationale`, `settle_empty_settled`, `home_sync_status_tag_*`, …) could be deleted by their modules; optional `localeFilters` en+sv.
- Ops request (no plan yet): a `kvitt-server` subcommand for a partner invite, so a scripted partner needs no second admin device.
- Plans (SPEC §11.2 v0.16), in dependency order; prompt `prompts/<id>.md`:
- M1, M2a, M2b, M2c-dev, M3, M4, M5, M6, M6b, M7a to M7g, M8 (phone test passed), M8b, M8c, M8d, M9, M12a, M12b, M12c, M12d, M12e, U1, U2, R8 release build: landed.
- Now: M2c-pi bundle, M8e.
- Next: the owner runs the M2c-pi bundle on the Kvitt Pi, after the app is proven (D-100); M10 First release after M2c-pi (keystore per §10.6, D-101); M11 Import history after M9 and M10 (procedure §10.8 "Production run", D-025; each run must reconcile, D-045).
## 3. HUMAN steps pending (relay in chat)
1. Next install on the phone (yes/no each): the title bar sits below the status bar; the quick-row selected badge is whole; the invite-code field cursor stays after the last character; the expense editor shows Konto, Datum, Betalt av, Delning as four rows that do not move when a value changes; "Household" fits its half of the Analytics filter bar.
2. Release build smoke taps: the app opens; S-1 or Home renders; Settings opens and shows the version; add one expense and see it sync.
3. After the first push: tell me whether the Gitea Actions run succeeded.
4. Later, Pi (D-100), after the app is proven: copy the `infra/pi/` bundle to the Kvitt Pi, fill the placeholders in its `.env`, run the README checklist.
## 4. Owner questions (asked, unanswered)
- None. OQ-3 is answered by placeholders (D-100); OQ-5 answered and implemented (D-099).
## 5. Paused (waiting on something outside the repo)
- Nothing.
## 6. Numbering
- Decisions: D-001 to D-102 used except D-008 and D-009 (D-103 to D-106 reserved by M2c-pi, D-107 by M8e). Next free: **D-108**.
- Spec version: v0.16 written; next **v0.17** (taken by the M2c-pi and M8e outcomes).
- Server schema version **3** (migration 0003, landed with M12e); next **4**. Room schema version **1** (`android/data/schemas/se.hagstedt.kvitt.data.db.KvittDatabase/1.json`); next **2**. Both unchanged by v0.16.
- Sync protocol **1**, push payload **1**.
## 7. How the work is run
See CLAUDE.md › Orchestration. HUMAN steps in reports are relayed in chat by the orchestrator; the owner does not read them in files.