SPEC v0.8: UX-session decisions (D-047 to D-054), category contract v2, M12 plans

Records the owner's UX-sprint decisions UX-1 to UX-8 of docs/ux/proposed-decisions.md:
D-047 direction Kalas muted, D-048 three tabs, D-049 category suggestion (§9.11,
suggestCategory, contracts/category-keywords.csv, suggest_category.json), D-050 S-1
display-name field, D-051 colour token values from Kalas (slate, amber TODO(U2)),
D-052 smaller UX rules, D-053 finer Splitwise mapping, D-054 fourteen default
categories with server schema 2 (migration 0002, §14.1.1). Adds milestone group M12
(PLAN-M12a/b/c, prompts), the CLAUDE.md UX-sprint note, and rewrites HANDOFF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-18 08:06:45 +02:00
parent aa765bbb48
commit d39eb2c79b
15 changed files with 553 additions and 68 deletions
+18 -15
View File
@@ -3,27 +3,30 @@
Living document, rewritten in place (never a second copy). A new orchestrator session reads CLAUDE.md, then this.
## 1. Where things stand
- `main` at `ab298ab` (M9) plus the SPEC v0.7 docs commit from `agent-spec7` 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.
- Landed: M0 spec, M1 contracts and vectors (`c6df2ab`), M2a server skeleton and `kvitt-domain` (`fdf2093`), M2b Android skeleton and `:domain` (`fad6fc9`), M2c-dev infra for development (`c885aba`), M3 server core API (`503cee5`), M4 server sync, audit, push, scheduler (`bd6f10a`), M5 Android data layer (`c28c52b`), M9 Splitwise importer (`ab298ab`), SPEC v0.6 (`23a2f1e`). With `agent-spec7`: SPEC v0.7 with M9's D-044 to D-046 and D-044's nine Swedish names in `server/crates/kvitt-import/data/splitwise_categories.csv`.
- `main` at `6b60ef7` (M12a) plus the SPEC v0.8 docs commit from `agent-spec8` 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.
- Landed: M0 spec, M1 contracts and vectors (`c6df2ab`), M2a server skeleton and `kvitt-domain` (`fdf2093`), M2b Android skeleton and `:domain` (`fad6fc9`), M2c-dev infra for development (`c885aba`), M3 server core API (`503cee5`), M4 server sync, audit, push, scheduler (`bd6f10a`), M5 Android data layer (`c28c52b`), M9 Splitwise importer (`ab298ab`), SPEC v0.7 (`e8ee518`), M12a category contract v2 contracts and `:domain` `suggestCategory` (`6b60ef7`; OpenAPI `DefaultCategoryKey` and the new category examples held back for M12b). With `agent-spec8`: SPEC v0.8, the owner's UX-session decisions UX-1 to UX-8 as D-047 to D-054 (Kalas muted, three tabs, category suggestion §9.11, S-1 name field, colour tokens, smaller UX rules, finer import mapping, fourteen default categories with server schema 2), and the milestone group M12 with PLAN-M12a/b/c and prompts, reconciled with what M12a landed (§14.1.1 copied from the contract file, `:domain` types with `UnicodeText`, vector keys).
- **Known red test:** from the landing of SPEC v0.8 until M12b lands, `main`'s server gate has exactly one failing test, the importer's `category_table_matches_the_spec`, which parses the §10.8 table that v0.8 changed (D-053). M12b fixes it; land M12b next.
- 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/`).
- Worktrees in flight under `.claude/worktrees/`: `agent-spec7` (this docs change: SPEC v0.7).
- The owner runs the UX sprint in a separate Claude session in `~/orca/workspaces/kvitt/UX-sprint` on branch `UX-sprint`; it commits only under `docs/ux/` and rebases on `main` before landing. U1 is committed on `UX-sprint` at `210ab5c` (`docs/ux/`: directions, ia, screens, flows, components, tokens, `strings.csv`); the owner has not yet picked a direction.
- Importer rehearsal (M11 preparation), 2026-10-18: the real run reconciled on both real files in a throwaway database (Vardag 1746 rows, Hemma 37 rows); 21 rows were unmapped before D-044, 0 are expected after it (confirm with the next dry run). The CSV files stay in `export/` (git-ignored).
- Development stack (M2c-dev): running on the Mac with the M4 image, reachable at `http://192.168.1.210:8080`; the owner confirmed `/health` from the phone on the home Wi-Fi on 2026-10-17. 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).
- Worktrees in flight under `.claude/worktrees/`: `agent-spec8` (this docs change: SPEC v0.8).
- The owner runs the UX sprint in a separate Claude session in `~/orca/workspaces/kvitt/UX-sprint` on branch `UX-sprint`; it commits only under `docs/ux/` and rebases on `main` before landing; its results reach the main line through `docs/ux/proposed-decisions.md` and a docs agent (CLAUDE.md › Orchestration). Direction 3 "Kalas" with the muted palette is picked and approved (D-047); U2 (design spec, renamed `strings.csv`, per-screen PNGs, the §9.7 hex values including `slate` and `amber`) is in progress there.
- Importer rehearsal (M11 preparation), 2026-10-18: the real run reconciled on both real files in a throwaway database (Vardag 1746 rows, Hemma 37 rows); 21 rows were unmapped before D-044, 0 are expected after it. After M12b the mapping is finer (D-053); the next dry run confirms it. The CSV files stay in `export/` (git-ignored).
- Development stack (M2c-dev): running on the Mac with the M4 image, reachable at `http://192.168.1.210:8080`; the owner confirmed `/health` from the phone on the home Wi-Fi on 2026-10-17. Its database is at schema 1; an image with M12b upgrades it to 2 on start (back it up first). 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` built from `main` at `c28c52b`, as of 2026-10-18.
## 2. Open work (one line each, with who owns it: agent or owner)
- Land `agent-spec7` (orchestrator): SPEC v0.7, decisions D-044 to D-046, the category data file, `server/README.md`, prompts/README status.
- Land `agent-spec8` (orchestrator): SPEC v0.8, decisions D-047 to D-054, PLAN-M12a/b/c, prompts M12a/b/c, CLAUDE.md UX-sprint note, plan touch-ups (M6, M7c, M7f, U2).
- Next: M12b (server; also the OpenAPI enum and the held-back examples) and M12c (Android) in parallel.
- Image build for the Pi (M2c-pi or M10): since M4 the arm64 server image needs a C toolchain in the build stage (aws-lc-rs) and CA roots in the distroless image (§10.3); confirm both and one FCM send from the shipped image.
- D-027 re-stamp (orchestrator assigns: M8 as a contract request on `:data`, or a small `:data` agent): on the first sync attempt after a `clock_skew` rejection the phone re-stamps `updated_at` of each such pending row to its current clock before pushing. Not in `:data` at `c28c52b`.
- D-027 re-stamp (orchestrator assigns: M8 as a contract request on `:data`, a small `:data` agent, or fold into M12c): on the first sync attempt after a `clock_skew` rejection the phone re-stamps `updated_at` of each such pending row to its current clock before pushing. Not in `:data` at `c28c52b`.
- Picture size (M6, if needed): `:data` always fetches E-11 at 512; a size parameter for the 128 variant is a contract request on `:core:model` and `:data`.
- Plans (SPEC §11.2 v0.7), in dependency order; prompt `prompts/<id>.md`:
- After U2 reports: a docs agent records the §9.7 hex values (muted Kalas, `slate` and `amber`), U2's other spec proposals, and the four new default names in `docs/ux/strings.csv` (D-051, D-054).
- Plans (SPEC §11.2 v0.8), in dependency order; prompt `prompts/<id>.md`:
- M1, M2a, M2b, M2c-dev, M3, M4, M5, M9: landed.
- U1 UX directions: committed on `UX-sprint` (`210ab5c`); waiting for the owner's pick.
- Next waves: U2 UX design spec (owner's session, after the pick; owner approves; then the §9.7 colour change goes into the spec by a docs agent), then M6 Design system, M7a to M7f Features after M6 in parallel, M8 App integration after M7, M2c-pi Infra on the Pi after M8 (owner: answer OQ-3, grant the Pi, Home Assistant Pi, Gitea and Drive allowances at the start, D-023), M10 First release after M2c-pi (owner: keystore per §10.6, D-024), M11 Import history after M9 and M10 (procedure §10.8 "Production run", D-025; each run must reconcile, D-045).
- M12a Category contract v2, contracts: landed (`6b60ef7`).
- Next waves: M12b (server) and M12c (Android) in parallel now; U2 (owner's session; owner approves); then M6 Design system after U2, the §9.7 values and M12c; M7a to M7f after M6 in parallel (M7c also after M12c); M8 App integration after M7; M2c-pi Infra on the Pi after M8 (owner: answer OQ-3, grant the Pi, Home Assistant Pi, Gitea and Drive allowances at the start, D-023); M10 First release after M2c-pi (owner: keystore per §10.6, D-024); 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)
- UX direction pick from U1's directions in `docs/ux/` on `UX-sprint`, with comments (owner's UX-sprint session).
- U2 approval: the owner approves U2's design spec in the UX-sprint session.
## 4. Owner questions (asked, unanswered)
- OQ-3 LAN addresses and SSH users of the Kvitt Pi and the Home Assistant Pi; SSH port of the HA Pi; certificate directory there; which SSH add-on (SPEC §12). Needed by M2c-pi only. The only open question (OQ-1, OQ-2, OQ-4 answered: D-001, D-003, §10.9).
@@ -32,9 +35,9 @@ Living document, rewritten in place (never a second copy). A new orchestrator se
- Nothing.
## 6. Numbering
- Decisions: D-001 to D-046 used (D-008 and D-009 unused). Next free: **D-047**.
- Spec version: v0.7 written; next **v0.8**.
- Server schema version **1**; next **2**. Room schema version **1** (`android/data/schemas/se.hagstedt.kvitt.data.db.KvittDatabase/1.json`); next **2**.
- Decisions: D-001 to D-054 used (D-008 and D-009 unused). Next free: **D-055**.
- Spec version: v0.8 written; next **v0.9**.
- Server schema version **2** (migration 0002, implemented by M12b); next **3**. Room schema version **1** (`android/data/schemas/se.hagstedt.kvitt.data.db.KvittDatabase/1.json`, unchanged by M12); next **2**.
- Sync protocol **1**, push payload **1**.
## 7. How the work is run