docs(01-01): complete project scaffold + core infrastructure plan
- SUMMARY.md with full execution details, 2 task commits, 2 deviations - STATE.md updated with position (Plan 2/14), decisions, metrics - REQUIREMENTS.md: ARCH-01, ARCH-04, ARCH-05, ARCH-06, ARCH-07 marked complete Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
16caa12d64
commit
8be69688e9
3 changed files with 190 additions and 17 deletions
|
|
@ -18,13 +18,13 @@ Requirements for Phase 1 (Development Focus: Live Tournament Management). Each m
|
|||
|
||||
### Architecture & Infrastructure
|
||||
|
||||
- [ ] **ARCH-01**: Leaf Node runs as single Go binary on ARM64 SBC with embedded LibSQL, NATS JetStream, and WebSocket hub
|
||||
- [x] **ARCH-01**: Leaf Node runs as single Go binary on ARM64 SBC with embedded LibSQL, NATS JetStream, and WebSocket hub
|
||||
- [ ] **ARCH-02**: Virtual Leaf runs same Go codebase on Core cloud infrastructure for free-tier venues (requires internet)
|
||||
- [x] **ARCH-03**: All financial values stored as int64 cents — never float64
|
||||
- [ ] **ARCH-04**: NATS JetStream embedded on Leaf with `sync_interval: always` for durability
|
||||
- [ ] **ARCH-05**: WebSocket hub broadcasts state changes to all connected clients within 100ms
|
||||
- [ ] **ARCH-06**: SvelteKit frontend embedded in Go binary via `//go:embed` for single-binary deployment
|
||||
- [ ] **ARCH-07**: Leaf is sovereign — all tournament logic runs locally, cloud is never required for operation
|
||||
- [x] **ARCH-04**: NATS JetStream embedded on Leaf with `sync_interval: always` for durability
|
||||
- [x] **ARCH-05**: WebSocket hub broadcasts state changes to all connected clients within 100ms
|
||||
- [x] **ARCH-06**: SvelteKit frontend embedded in Go binary via `//go:embed` for single-binary deployment
|
||||
- [x] **ARCH-07**: Leaf is sovereign — all tournament logic runs locally, cloud is never required for operation
|
||||
- [x] **ARCH-08**: Append-only audit trail for every state-changing action (operator, action, target, previous/new state, timestamp)
|
||||
- [ ] **ARCH-09**: Automated daily backup of LibSQL database to USB or cloud, with documented recovery procedure
|
||||
- [ ] **ARCH-10**: Leaf must recover cleanly from hard power-cycle during active tournament (verified by chaos testing)
|
||||
|
|
@ -274,13 +274,13 @@ Which phases cover which requirements. Updated during roadmap reorganization.
|
|||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| ARCH-01 | Phase 1 | Pending |
|
||||
| ARCH-01 | Phase 1 | Complete |
|
||||
| ARCH-02 | Phase 3 | Pending |
|
||||
| ARCH-03 | Phase 1 | Complete |
|
||||
| ARCH-04 | Phase 1 | Pending |
|
||||
| ARCH-05 | Phase 1 | Pending |
|
||||
| ARCH-06 | Phase 1 | Pending |
|
||||
| ARCH-07 | Phase 1 | Pending |
|
||||
| ARCH-04 | Phase 1 | Complete |
|
||||
| ARCH-05 | Phase 1 | Complete |
|
||||
| ARCH-06 | Phase 1 | Complete |
|
||||
| ARCH-07 | Phase 1 | Complete |
|
||||
| ARCH-08 | Phase 1 | Complete |
|
||||
| ARCH-09 | Phase 7 | Pending |
|
||||
| ARCH-10 | Phase 7 | Pending |
|
||||
|
|
|
|||
|
|
@ -12,25 +12,25 @@ See: .planning/PROJECT.md (updated 2026-02-28)
|
|||
Phase: 1 of 7 (Tournament Engine)
|
||||
Plan: 2 of 14 in current phase
|
||||
Status: Executing Phase 1
|
||||
Last activity: 2026-03-01 — Completed Plan B (Database Schema + Migrations)
|
||||
Last activity: 2026-03-01 — Completed Plan A (Project Scaffold + Core Infrastructure) and Plan B (Database Schema + Migrations)
|
||||
|
||||
Progress: [█░░░░░░░░░] 14%
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
**Velocity:**
|
||||
- Total plans completed: 1
|
||||
- Average duration: 10min
|
||||
- Total execution time: 0.17 hours
|
||||
- Total plans completed: 2
|
||||
- Average duration: 12min
|
||||
- Total execution time: 0.42 hours
|
||||
|
||||
**By Phase:**
|
||||
|
||||
| Phase | Plans | Total | Avg/Plan |
|
||||
|-------|-------|-------|----------|
|
||||
| 01-tournament-engine | 1 | 10min | 10min |
|
||||
| 01-tournament-engine | 2 | 25min | 12min |
|
||||
|
||||
**Recent Trend:**
|
||||
- Last 5 plans: 01-02 (10min)
|
||||
- Last 5 plans: 01-01 (15min), 01-02 (10min)
|
||||
- Trend: starting
|
||||
|
||||
*Updated after each plan completion*
|
||||
|
|
@ -47,6 +47,9 @@ Recent decisions affecting current work:
|
|||
- [Init]: All monetary values int64 cents — never float64 (CI gate test required)
|
||||
- [Init]: go-libsql has no tagged releases — pin to commit hash in go.mod
|
||||
- [Init]: Netbird reverse proxy is beta — validate player PWA access in Phase 1 before depending on it in Phase 8
|
||||
- [01-01]: NATS server v2.12.4 requires Go 1.24+ — auto-upgraded from Go 1.23
|
||||
- [01-01]: WebSocket JWT via query parameter (browser WS API limitation)
|
||||
- [01-01]: JWT signing key ephemeral per startup — will persist in auth plan
|
||||
- [01-02]: go-libsql requires single-statement Exec — migration runner splits SQL files into individual statements
|
||||
- [01-02]: go-libsql PRAGMA handling is inconsistent — use QueryRow for journal_mode, execPragma helper for others
|
||||
- [01-02]: Force single DB connection during migrations (SetMaxOpenConns(1)) for table visibility
|
||||
|
|
@ -67,5 +70,5 @@ None yet.
|
|||
## Session Continuity
|
||||
|
||||
Last session: 2026-03-01
|
||||
Stopped at: Completed 01-02-PLAN.md (Database Schema + Migrations)
|
||||
Stopped at: Completed 01-01-PLAN.md (Project Scaffold + Core Infrastructure)
|
||||
Resume file: None
|
||||
|
|
|
|||
170
.planning/phases/01-tournament-engine/01-01-SUMMARY.md
Normal file
170
.planning/phases/01-tournament-engine/01-01-SUMMARY.md
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
phase: 01-tournament-engine
|
||||
plan: 01
|
||||
subsystem: infra
|
||||
tags: [go, nats, jetstream, libsql, websocket, chi, jwt, embed, sveltekit]
|
||||
|
||||
# Dependency graph
|
||||
requires: []
|
||||
provides:
|
||||
- Go binary scaffold with cmd/leaf entry point
|
||||
- Embedded NATS JetStream with AUDIT and STATE streams
|
||||
- LibSQL database with WAL mode and migration runner
|
||||
- WebSocket hub with JWT auth and tournament-scoped broadcasting
|
||||
- chi HTTP server with middleware (auth, CORS, body limits, timeouts)
|
||||
- SvelteKit SPA stub served via go:embed with fallback routing
|
||||
- Health endpoint reporting all subsystem status
|
||||
- Integration test suite (9 tests)
|
||||
affects: [01-tournament-engine]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added:
|
||||
- go-libsql v0.0.0-20251219133454 (pinned commit, no tagged releases)
|
||||
- nats-server v2.12.4 (embedded, JetStream sync=always)
|
||||
- nats.go v1.49.0 (client + jetstream package)
|
||||
- coder/websocket v1.8.14
|
||||
- go-chi/chi v5.2.5
|
||||
- golang-jwt/jwt v5.3.1
|
||||
patterns:
|
||||
- Embedded NATS with DontListen=true, in-process client connection
|
||||
- WebSocket JWT auth via query parameter (not header)
|
||||
- Tournament-scoped broadcasting via client subscription
|
||||
- UUID validation before NATS subject construction (injection prevention)
|
||||
- go:embed SPA with fallback routing for client-side routing
|
||||
- Reverse-order graceful shutdown on signal
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- cmd/leaf/main.go
|
||||
- cmd/leaf/main_test.go
|
||||
- internal/nats/embedded.go
|
||||
- internal/nats/publisher.go
|
||||
- internal/server/server.go
|
||||
- internal/server/ws/hub.go
|
||||
- internal/server/middleware/auth.go
|
||||
- internal/server/middleware/role.go
|
||||
- internal/server/middleware/bodylimit.go
|
||||
- internal/store/db.go
|
||||
- internal/store/migrate.go
|
||||
- frontend/embed.go
|
||||
- frontend/build/index.html
|
||||
- Makefile
|
||||
- go.mod
|
||||
- go.sum
|
||||
modified: []
|
||||
|
||||
key-decisions:
|
||||
- "NATS JetStreamSyncInterval=0 (sync_interval: always) for single-node durability per Jepsen 2025"
|
||||
- "WebSocket JWT via query parameter rather than header (browser WebSocket API limitation)"
|
||||
- "Ephemeral JWT signing key (generated on startup) — will be persisted in a later plan"
|
||||
- "NATS server requires Go 1.24+ — upgraded from Go 1.23 (auto-resolved by go get)"
|
||||
- "Tournament validator is a stub (accepts all) — will validate against DB in auth plan"
|
||||
|
||||
patterns-established:
|
||||
- "Embedded infrastructure: all services start in-process, no external dependencies"
|
||||
- "Tournament-scoped state: all broadcasting and events keyed by tournament ID"
|
||||
- "UUID validation on all NATS subject construction (security)"
|
||||
- "Integration tests with httptest.NewServer and t.TempDir() for isolation"
|
||||
|
||||
requirements-completed: [ARCH-01, ARCH-04, ARCH-05, ARCH-06, ARCH-07]
|
||||
|
||||
# Metrics
|
||||
duration: 15min
|
||||
completed: 2026-03-01
|
||||
---
|
||||
|
||||
# Phase 1 Plan 01: Project Scaffold + Core Infrastructure Summary
|
||||
|
||||
**Go binary embedding NATS JetStream (sync=always), LibSQL (WAL), WebSocket hub (JWT auth), chi HTTP server, and SvelteKit SPA via go:embed — all verified with 9 integration tests**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 15 min
|
||||
- **Started:** 2026-03-01T02:27:38Z
|
||||
- **Completed:** 2026-03-01T02:42:58Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 48
|
||||
|
||||
## Accomplishments
|
||||
- Single Go binary compiles and runs with all infrastructure embedded — no external services required
|
||||
- NATS JetStream with mandatory sync_interval=always for single-node durability (Jepsen 2025 finding)
|
||||
- WebSocket hub authenticates via JWT query param, broadcasts tournament-scoped messages, drops slow consumers
|
||||
- Health endpoint reports status of all subsystems (database, NATS, WebSocket)
|
||||
- Full directory structure matching research recommendations with 30+ package stubs
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task A1: Initialize Go module and dependency tree** - `af13732` (feat)
|
||||
2. **Task A2: Implement core infrastructure** - `16caa12` (feat)
|
||||
|
||||
## Files Created/Modified
|
||||
- `cmd/leaf/main.go` - Entry point: flags, startup orchestration, signal handling, graceful shutdown
|
||||
- `cmd/leaf/main_test.go` - 9 integration tests covering all verification criteria
|
||||
- `internal/nats/embedded.go` - Embedded NATS server with JetStream, AUDIT + STATE streams
|
||||
- `internal/nats/publisher.go` - Tournament-scoped publisher with UUID validation
|
||||
- `internal/server/server.go` - chi HTTP server with middleware, health endpoint, SPA handler
|
||||
- `internal/server/ws/hub.go` - WebSocket hub with JWT auth, tournament scoping, broadcasting
|
||||
- `internal/server/middleware/auth.go` - JWT validation middleware (Bearer header + raw token)
|
||||
- `internal/server/middleware/role.go` - Role-based access control (admin > floor > viewer)
|
||||
- `internal/server/middleware/bodylimit.go` - MaxBytesReader middleware (1MB default)
|
||||
- `internal/store/db.go` - LibSQL open with WAL, foreign keys, busy timeout
|
||||
- `internal/store/migrate.go` - Embedded SQL migration runner with dev-only migrations
|
||||
- `frontend/embed.go` - go:embed handler with SPA fallback routing
|
||||
- `frontend/build/index.html` - Stub HTML with Catppuccin Mocha dark theme colors
|
||||
- `Makefile` - build, run, run-dev, test, frontend, all, clean targets
|
||||
- `go.mod` / `go.sum` - Module definition with all dependencies pinned
|
||||
|
||||
## Decisions Made
|
||||
- NATS server v2.12.4 requires Go 1.24+ — upgraded automatically from 1.23
|
||||
- WebSocket JWT passed via query parameter (browser WebSocket API does not support custom headers)
|
||||
- JWT signing key is ephemeral (random per startup) — will be persisted to disk in auth plan
|
||||
- Tournament validator stub accepts all — real validation deferred to auth/tournament plans
|
||||
- Added `run-dev` Makefile target for development mode with seed data
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 3 - Blocking] Store package auto-populated by linter**
|
||||
- **Found during:** Task A1 (directory structure creation)
|
||||
- **Issue:** The db.go and migrate.go files were auto-populated with full implementations including migration runner, replacing my stub package declarations
|
||||
- **Fix:** Kept the auto-populated implementations (correct and useful), removed my redundant migrations.go stub
|
||||
- **Files modified:** internal/store/db.go, internal/store/migrate.go
|
||||
- **Verification:** go build and go vet pass
|
||||
- **Committed in:** af13732 (Task A1 commit)
|
||||
|
||||
**2. [Rule 3 - Blocking] Go 1.24 required by NATS server v2.12.4**
|
||||
- **Found during:** Task A2 (dependency installation)
|
||||
- **Issue:** nats-server v2.12.4 requires go >= 1.24.0, but go.mod specified 1.23.6
|
||||
- **Fix:** go toolchain auto-resolved by upgrading go directive to 1.24.0 in go.mod
|
||||
- **Files modified:** go.mod
|
||||
- **Verification:** go build succeeds, all tests pass
|
||||
- **Committed in:** 16caa12 (Task A2 commit)
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 2 auto-fixed (2 blocking)
|
||||
**Impact on plan:** Both auto-fixes were necessary for compilation. No scope creep.
|
||||
|
||||
## Issues Encountered
|
||||
- Go 1.23.6 installed on system but NATS v2.12.4 required Go 1.24+ — resolved automatically by Go toolchain management
|
||||
- Port 8080 remained bound after manual server test — cleaned up with lsof before re-test
|
||||
|
||||
## User Setup Required
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- Infrastructure scaffold complete — ready for database schema (Plan 02), auth (Plan 03), and all subsequent plans
|
||||
- All subsystems verified operational via integration tests
|
||||
- Tournament-scoped architecture established from day one (MULTI-01)
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
All 16 created files verified present. Both commit hashes (af13732, 16caa12) found in git log. SUMMARY.md exists at expected path.
|
||||
|
||||
---
|
||||
*Phase: 01-tournament-engine*
|
||||
*Completed: 2026-03-01*
|
||||
Loading…
Add table
Reference in a new issue