Skip to content

Commit b18e28e

Browse files
committed
docs: update retrospective for v1.0
1 parent ba40af0 commit b18e28e

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

.planning/RETROSPECTIVE.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Project Retrospective
2+
3+
*A living document updated after each milestone. Lessons feed forward into future planning.*
4+
5+
## Milestone: v1.0 — StravaMCP Go Rewrite
6+
7+
**Shipped:** 2026-04-01
8+
**Phases:** 3 | **Plans:** 8
9+
10+
### What Was Built
11+
- Complete Go rewrite of Strava MCP server with 11 tools across 5 categories
12+
- OAuth browser flow with singleflight token refresh and file-based token store
13+
- goreleaser v2 cross-platform release pipeline with Homebrew cask distribution
14+
- Portfolio-quality README with 8 badges, Mermaid architecture diagrams, 11-tool reference
15+
- GitHub Actions release workflow triggered on v* tags
16+
17+
### What Worked
18+
- Strict 3-phase dependency chain (infra → tools → polish) prevented rework
19+
- Raw JSON pass-through for Strava data avoided schema coupling and maintenance burden
20+
- Handler closure pattern (HandleXxx(client) returns ToolHandlerFunc) made tool registration clean and testable
21+
- Map-based PUT body for update_activity avoided Go zero-value overwrite trap
22+
- singleflight.Group for token refresh coalescing was elegant and correct
23+
24+
### What Was Inefficient
25+
- Phase 3 plan 03-01 (module path migration) required touching all 22 Go files for import path changes — could have been the module path from the start in Phase 1
26+
- VHS terminal recording requires live OAuth which blocks automated execution — deferred to manual step
27+
28+
### Patterns Established
29+
- stderr-only logging via slog (stdout reserved for MCP JSON-RPC)
30+
- Closure-over-client handler pattern for all MCP tools
31+
- FormatResponse/HandleToolError shared helpers for consistent tool output
32+
- Atomic write-then-rename for file-based token persistence
33+
- Tag-triggered releases via goreleaser + GitHub Actions
34+
35+
### Key Lessons
36+
1. Set the correct Go module path from day one — migrating later touches every file
37+
2. goreleaser v2 homebrew_casks requires a separate PAT for cross-repo tap push — GITHUB_TOKEN is scoped to current repo only
38+
3. Raw JSON pass-through is the right default for API wrapper tools — Go structs add maintenance without value when the LLM consumes the JSON directly
39+
40+
### Cost Observations
41+
- Model mix: primarily opus for execution, sonnet for verification
42+
- 3 phases completed across multiple sessions
43+
- Notable: parallel wave execution (plans 03-02 + 03-03) saved time in the final phase
44+
45+
---
46+
47+
## Cross-Milestone Trends
48+
49+
### Process Evolution
50+
51+
| Milestone | Phases | Plans | Key Change |
52+
|-----------|--------|-------|------------|
53+
| v1.0 | 3 | 8 | Initial milestone — established GSD workflow with strict phase dependencies |
54+
55+
### Cumulative Quality
56+
57+
| Milestone | Tests | Packages | Zero-Dep Additions |
58+
|-----------|-------|----------|-------------------|
59+
| v1.0 | 80+ | 5 | 3 (mcp-go, browser, sync) |
60+
61+
### Top Lessons (Verified Across Milestones)
62+
63+
1. Set canonical identifiers (module paths, package names) in the first phase
64+
2. Raw JSON pass-through beats typed structs for API wrapper tools consumed by LLMs

0 commit comments

Comments
 (0)