1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# ADR-006: Claudomator Integration
**Status:** IN_PROGRESS
**Date:** 2026-03-26
## Context
Claudomator (task executor, story runner) and Doot (personal dashboard) are separate services. The goal is to unify them into a single coherent product: shared visual identity, shared auth, simplified deployment, and eventually shared code.
## Decisions Made
### Auth — Gate via Doot Proxy (DONE)
All `/claudomator/*` routes require Doot session auth. Webhooks are exempted. Auth is enforced in Doot's Go proxy middleware before the request is forwarded to Claudomator. Claudomator itself remains auth-free (trusts the proxy).
- Implemented: `internal/handlers/claudomator_proxy.go` — `RequireAuth` applied to proxy routes
- Claudomator's bearer token mechanism exists but is unused; left in place for future direct API use
### WebSocket Proxy — Go, not Apache (DONE)
Claudomator's WebSocket at `/claudomator/api/ws` is proxied by Doot's Go handler (`proxyWebSocket`). Apache was updated to add an explicit `ws://` ProxyPass rule for this path so mod_proxy_wstunnel activates correctly.
- Apache vhost tracked at: `deploy/apache/doot.terst.org-le-ssl.conf`
- Go proxy handles header stripping, path rewriting, and bidirectional copy
### Visual Design — Rewrite Claudomator UI (IN PROGRESS)
Claudomator's UI (vanilla JS SPA) is being rewritten to use Doot's dark glass design system: Inter font, slate-950 bg, glass cards (backdrop-blur, slate-900/80, white/5 border), sky-400 accent. No Tailwind build step — hand-coded CSS.
- Story: `55d4a55a` on branch `story/ui-dark-glass-theme`
- app.js logic unchanged; only style.css and index.html
### Process Architecture — Two Processes, One Domain (DECIDED, NOT CHANGED)
Claudomator and Doot remain separate processes communicating over localhost. The proxy overhead is negligible. Separate processes allow independent restarts — important because Claudomator's executor manages in-flight container tasks. A future move to single-binary (mounting Claudomator's router directly into Doot's mux) is possible but not yet needed.
## Architectural Seams (Decided: Seam 1 → Seam 2)
Three integration paths were evaluated (with Gemini, 2026-03-26):
### Seam 1: HTMX Partial Provider (NEXT)
Claudomator stays a separate process but begins serving Go `html/template` HTML fragments alongside its JSON API. Doot embeds these via `hx-get="/claudomator/partials/..."`. The reverse proxy stays. SPA components are converted one at a time.
- **Pre-requisite:** Visual unification (story `55d4a55a`) — must look the same before templates are merged
- **Interface:** HTTP + shared CSS class names
- **Unlocks:** Incremental SPA → HTMX migration with no operational risk; sets up Seam 2
- **Deploy coupling:** None (still two independent deploys)
### Seam 2: Shared Library / Single Binary (FUTURE)
Claudomator's `internal/storage`, `internal/executor`, `internal/task` refactored as embeddable packages. Doot imports them directly; proxy eliminated; one process.
- **Blocker:** Executor manages in-flight container tasks — Doot restart kills them. Requires graceful shutdown in executor pool before this is safe.
- **Interface:** Go interfaces (`executor.Pool`, `storage.DB`)
- **Unlocks:** Single deploy, no proxy overhead, Doot handlers call task service as local function calls
- **Deploy coupling:** High — one binary, one restart
### Seam 3: Shared SQLite (REJECTED)
Both processes point at the same DB file (WAL mode). Rejected — schema is a fragile interface, benefit is achievable via existing REST aggregation.
### Comparison
| | Current | Seam 1 | Seam 2 | Single Binary |
|---|---|---|---|---|
| Deploy coupling | Low | Low | High | High |
| Runtime complexity | 2 procs | 2 procs | 1 proc | 1 proc |
| UI migration path | Hard | Easy (incremental) | Medium | Easy |
| In-flight task safety | Safe | Safe | Needs graceful shutdown | Needs graceful shutdown |
## Open / Remaining Questions
### Navigation (DONE)
Doot's nav already has a Claudomator tab link (`/claudomator/`) in `web/templates/index.html:86`.
### Deploy Coordination
Currently two manual deploy commands. Low priority — acceptable until Seam 2.
### Doot Atom Source (DONE)
Claudomator stories surface as atoms in Doot's task aggregation (commit `b58787c`).
### Structured Acceptance Criteria
Story model being extended with named acceptance criteria (story `bf42482d`).
## Consequences
- Claudomator is permanently behind Doot's auth — it cannot be accessed directly on port 8484 from the public internet (Apache only exposes doot.terst.org)
- The visual unification is a prerequisite for the HTMX partial migration path
- The two-process model means deploy order matters: Claudomator must be running for Doot's proxy to work; Doot startup should gracefully degrade if Claudomator is down
|