# Worklog ## Current Task Goal Move Claudomator UI auth into Doot: replace Apache proxy rules with a Doot-side reverse proxy, gating `/claudomator/*` behind Doot's session auth. ## Status: PLAN — awaiting user confirmation --- ## Plan: Claudomator UI behind Doot auth ### Architecture ``` Browser → Apache (SSL) → Doot :38080 → [session auth] → Claudomator :8484 ``` Apache currently proxies `/claudomator/*` directly to :8484 with no auth. Goal: move the proxy into Doot so session middleware gates it. Two processes, two systemd units — unchanged. Claudomator base-path already hardcoded to `/claudomator` in web/index.html. ### Step 1 — Doot: add `ClaudomatorURL` config - `internal/config/config.go` — add `ClaudomatorURL string` (env: `CLAUDOMATOR_URL`, default: `http://127.0.0.1:8484`) - Tests: default + override ### Step 2 — Doot: HTTP + WebSocket reverse proxy handler - New file: `internal/handlers/claudomator_proxy.go` - `httputil.ReverseProxy` for normal requests; WS connection hijacker for upgrades - Director strips `/claudomator` prefix from both `URL.Path` AND `URL.RawPath` (handles encoded chars in task names/IDs) - Do NOT set `ReadDeadline`/`WriteDeadline` on hijacked WS connections (kills long-lived task monitoring) - Preserve `Service-Worker-Allowed` response header so SW scopes correctly under `/claudomator` - Tests: HTTP forward, prefix strip, WS tunnel ### Step 3 — Doot: restructure CSRF middleware, mount proxy - `cmd/dashboard/main.go`: move CSRF out of global middleware into a route group - `/claudomator` → redirect 301 to `/claudomator/` (trailing slash; prevents asset fetch breakage) - `/claudomator/api/webhooks/github` → exempt from `RequireAuth` (GitHub POSTs have no session; endpoint does its own HMAC validation) - `/claudomator/*` route: `RequireAuth` only (no CSRF — SPA doesn't send Doot's CSRF token) - All other routes: wrapped in CSRF group (behavior unchanged) ### Step 4 — Apache: remove Claudomator proxy rules - Remove 4 lines from `/etc/apache2/sites-enabled/doot.terst.org-le-ssl.conf` - `apache2ctl configtest && apache2ctl graceful` ### Step 5 — Smoke tests - Unauthenticated `/claudomator/` → 302 to `/login` - `/claudomator` (no slash) → 301 to `/claudomator/` - Authenticated: UI loads, task CRUD works, WS live updates, log streaming - GitHub webhook POST to `/claudomator/api/webhooks/github` → not redirected to login ### Risks - CSRF restructure: verify all existing Doot routes still pass their tests after moving CSRF to a group - SecurityHeaders CSP already allows `wss: ws:` — no change needed - Claudomator :8484 remains accessible on localhost without auth (acceptable for now) - Future: `/claudomator/api/*` technically CSRF-vulnerable from other origins; mitigate later by injecting `XSRF-TOKEN` cookie --- ## Previous Task: ADR-007 — Epic→Story→Task hierarchy (IN_PROGRESS) ### Completed Items | Step | Description | Test / Verification | |------|-------------|---------------------| | Phase 1 | Doot dead code removal: Bug struct, BugToAtom, bug store methods, bug handlers, bug routes, bugs.html template, TypeNote, AddMealToPlanner stub | `go test ./...` in /workspace/doot — all pass | | Phase 2 | Claudomator project registry: `task.Project` type, storage CRUD + UpsertProject, seed.go, API endpoints, legacy fields removed | `TestCreateProject`, `TestListProjects`, `TestUpdateProject`, `TestProjects_CRUD` | | Phase 3 | Stories data model: Story struct + ValidStoryTransition, stories table, CRUD, story API endpoints | committed 5081b0c | | Phase 4 | Story execution and deploy: checkStoryCompletion → SHIPPABLE, story branch checkout, POST /api/stories/{id}/branch | committed 15a46b0 | | Phase 5 | Story elaboration: POST /api/stories/elaborate + approve, SeedProjects at startup, GetProject on executor Store interface | committed bc62c35 | ### Pending (Claudomator tasks queued) | Task ID | Phase | Status | |---------|-------|--------| | f39af70f-72c5-4ac1-9522-83c2e11b37c9 | Phase 6: Doot — Claudomator integration | QUEUED | ### Key Files Changed (Phases 1–5) #### Claudomator - `internal/task/project.go` — Project struct - `internal/task/story.go` — Story struct + ValidStoryTransition - `internal/task/task.go` — removed Agent.ProjectDir/RepositoryURL/SkipPlanning - `internal/storage/db.go` — projects + stories tables, CRUD - `internal/storage/seed.go` — SeedProjects - `internal/api/projects.go`, `stories.go`, `elaborate.go` — handlers - `internal/executor/executor.go` — GetProject on Store interface, RepositoryURL resolution - `internal/cli/serve.go` — SeedProjects at startup #### Doot - Bug feature removed entirely (models, handlers, store, routes, template, migration) - `internal/models/atom.go` — SourceBug, TypeBug, TypeNote, BugToAtom removed