Skip to content

Commit 9efb8d6

Browse files
chore: merge main into fix/caldav-412-report-error (resolve conflicts)
- manifest.json: keep caldav==2.1.0 (main) + version 3.1.0-rc13 (ours) - caldav_sync.py: keep _build_event_url from our branch; no change elsewhere - strings.json / translations/en.json / test_strings_icu_escape.py: accept main's ICU-escape curly-placeholder fix (Phase 35) - Remove .planning/HANDOFF.json (deleted on main) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2 parents 4cab084 + 9a02035 commit 9efb8d6

101 files changed

Lines changed: 9614 additions & 3451 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
.planning/
2+
.claude/
3+
CLAUDE.md
24

35
# Spatial index files (too large for git, built via build script / downloaded on first HA setup)
46
src/gps2asp/data/index/*.idx

.planning/HANDOFF.json

Lines changed: 0 additions & 52 deletions
This file was deleted.

.planning/RETROSPECTIVE.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,53 @@
22

33
*A living document updated after each milestone. Lessons feed forward into future planning.*
44

5+
## Milestone: v3.2 — UX Improvements and Monthly Updates
6+
7+
**Shipped:** 2026-05-19
8+
**Phases:** 4 (31–34) | **Plans:** 14 | **Timeline:** 7 days (2026-05-10 → 2026-05-17) | **Commits:** 96
9+
10+
### What Was Built
11+
12+
- `vendor-guard.yml` + `scripts/sync_vendored.py` — automated CI drift detection for vendored gps2asp mirror; 27-test TDD suite; strings.json byte-sync
13+
- Three-tier date-aware sensor format ("⚠ Today, H:MM AM" / "Tomorrow, H:MM AM" / "Weekday (M/D), H:MM AM"); HA-local timezone Today gate; `now_ha_local()` helper
14+
- `index_io.py` + three new HA entities — download-from-GitHub-releases, atomic dir swap, zip-slip refusal, `asyncio.Lock` concurrency guard, `SpatialIndex.reset()`
15+
- `caldav_sync.py` — pure async CalDAV glue (SHA-256 UID, VEVENT build, validate/list/write/delete); coordinator suspension choke-point; Store-persisted UID; `async_remove_entry` cleanup; credentials redacted from diagnostics
16+
17+
### What Worked
18+
19+
- **CI guard shipped first (Phase 31)** — all subsequent phases inherited vendored-mirror protection automatically; zero drift incidents in Phases 32-34
20+
- **now_ha_local() extracted early** — Phase 32 introduced the helper; Phase 34 reused it without duplication; forward-planned dependencies paid off
21+
- **Suspension choke-point refactor (Phase 34)** — consolidating 6 scattered suspension-mutation sites into one method (`_async_apply_suspension_state`) eliminated Pitfall 8 entirely; clean and testable
22+
- **SHA-256 deterministic UID** — decided before any code was written; persists correctly across restarts without storing state in options (which would trigger reload)
23+
24+
### What Was Inefficient
25+
26+
- **ROADMAP.md and STATE.md not updated after Phase 34 execution** — milestone was marked "shipped" in STATE.md but internal position and CALDAV requirements were left stale; forensic audit at milestone close caught it
27+
- **Phase 33 live-HA UAT deferred again** — same pattern as Phase 25 (Phase 22 before that); human UAT requiring a live HA instance continues to be deferred rather than integrated
28+
- **HANDOFF.json from Phase 17 was never cleaned up** — orphaned for 7+ weeks across two milestone closings; forensic audit finally surfaced it
29+
30+
### Patterns Established
31+
32+
- CI guard ships first in a milestone — protects all subsequent phases automatically
33+
- Suspension choke-point pattern — single method owns all suspension-state mutation; never scatter suspension writes
34+
- `Store` for cross-restart UID persistence — `entry.options` triggers reload; `hass.data` is lost on restart; `Store` is the right tool
35+
- `caldav_sync.py` as HA-specific glue NOT mirrored — CalDAV is integration-only; keep the CI guard clean by not adding exception lists
36+
37+
### Key Lessons
38+
39+
1. **Update tracking files at execution time, not at milestone close** — Phase 34's ROADMAP.md progress row and CALDAV-* requirements checkboxes were left stale for days; update the row in ROADMAP.md when you write the SUMMARY
40+
2. **Clean up HANDOFF.json at the end of every session** — if work was paused and then resumed from a different entry point, delete the old handoff immediately
41+
3. **Schedule live-HA UAT as a concrete calendar item** — three milestones running, live-HA scenarios keep being deferred; it won't happen unless it's explicitly scheduled
42+
4. **forensic --forensic catches what yolo mode skips** — the forensic progress check found 4 issues that would have been invisible in a standard progress check
43+
44+
### Cost Observations
45+
46+
- Model mix: claude-sonnet-4-6 throughout (switched from opus to reduce cost)
47+
- Sessions: ~8 distinct execution sessions over 7 days
48+
- Notable: 96 commits in 7 days — highest commit velocity of any milestone; indicates tight TDD discipline (RED/GREEN/commit rhythm)
49+
50+
---
51+
552
## Milestone: v3.0 — Suspension Handling
653

754
**Shipped:** 2026-04-30

0 commit comments

Comments
 (0)