Skip to content

Commit 4da33cd

Browse files
docs: streamline 013 spec to focus on remaining work
Remove completed items (smart-mcp-proxy#192 Unified Health Status): - HealthStatus struct, calculator, and frontend integration - Health field on Server - Action buttons in UI Remaining scope: - OAuthState and ConnectionState structured types - Doctor() aggregation from Health - Dashboard UI consolidation (remove duplicate diagnostics)
1 parent f38cd15 commit 4da33cd

7 files changed

Lines changed: 205 additions & 479 deletions

File tree

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Specification Quality Checklist: Structured Server State
22

3-
**Purpose**: Validate specification completeness and quality before proceeding to planning
4-
**Created**: 2025-12-13
3+
**Purpose**: Validate specification completeness and quality
4+
**Updated**: 2025-12-16
55
**Feature**: [spec.md](../spec.md)
66

77
## Content Quality
@@ -16,26 +16,22 @@
1616
- [x] No [NEEDS CLARIFICATION] markers remain
1717
- [x] Requirements are testable and unambiguous
1818
- [x] Success criteria are measurable
19-
- [x] Success criteria are technology-agnostic (no implementation details)
19+
- [x] Success criteria are technology-agnostic
2020
- [x] All acceptance scenarios are defined
2121
- [x] Edge cases are identified
2222
- [x] Scope is clearly bounded
23-
- [x] Dependencies and assumptions identified
2423

2524
## Feature Readiness
2625

2726
- [x] All functional requirements have clear acceptance criteria
2827
- [x] User scenarios cover primary flows
2928
- [x] Feature meets measurable outcomes defined in Success Criteria
30-
- [x] No implementation details leak into specification
3129

3230
## Notes
3331

34-
- All items pass validation
35-
- Spec is ready for `/speckit.clarify` or `/speckit.plan`
36-
- Key design decisions captured from prior conversation:
37-
- Structured state objects (OAuthState, ConnectionState) added to Server
32+
- Spec updated 2025-12-16 to reflect #192 (Unified Health Status) completion
33+
- Remaining scope: structured state objects, Doctor() refactor, UI consolidation
34+
- Key design decisions:
35+
- OAuthState and ConnectionState added to Server
3836
- Flat fields kept for backwards compatibility
39-
- Health calculated server-side from structured state
4037
- Doctor() aggregates from Health (single source of truth)
41-
- DockerStatus remains the only system-level check

specs/013-structured-server-state/contracts/api-changes.md

Lines changed: 18 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,18 @@
11
# API Contract Changes: Structured Server State
22

33
**Feature**: 013-structured-server-state
4-
**Date**: 2025-12-13
5-
**Updated**: 2025-12-16
6-
7-
## Implementation Status
8-
9-
| Change | Status | Notes |
10-
|--------|--------|-------|
11-
| `health` field on Server | ✅ DONE | Merged in #192 |
12-
| `oauth_state` field on Server | ❌ TODO | Proposed in this doc |
13-
| `connection_state` field on Server | ❌ TODO | Proposed in this doc |
14-
| Diagnostics aggregation from Health | ❌ TODO | Doctor() still uses raw fields |
4+
**Date**: 2025-12-16
155

166
## Overview
177

18-
This document describes the API changes for the structured server state feature. All changes are **additive** - existing fields remain unchanged for backwards compatibility.
8+
This document describes API changes for adding structured state objects. All changes are **additive** - existing fields remain unchanged for backwards compatibility.
199

2010
## Affected Endpoints
2111

2212
| Endpoint | Change Type | Description |
2313
|----------|-------------|-------------|
2414
| `GET /api/v1/servers` | Additive | Add `oauth_state`, `connection_state` to each server |
25-
| `GET /api/v1/diagnostics` | Modified | Aggregate from `server.Health` instead of separate logic |
26-
| `GET /events` (SSE) | No change | Existing `servers.changed` events include updated data |
15+
| `GET /api/v1/diagnostics` | Modified | Aggregate from `server.Health` instead of raw fields |
2716

2817
## Schema Changes
2918

@@ -129,100 +118,56 @@ ConnectionState:
129118
"data": {
130119
"servers": [
131120
{
132-
"id": "abc123",
133121
"name": "github-server",
134122
"enabled": true,
135-
"quarantined": false,
136123

137124
"oauth_state": {
138125
"status": "authenticated",
139126
"token_expires_at": "2025-12-14T12:00:00Z",
140127
"last_attempt": "2025-12-13T10:00:00Z",
141128
"retry_count": 0,
142129
"user_logged_out": false,
143-
"has_refresh_token": true,
144-
"error": null
130+
"has_refresh_token": true
145131
},
146132

147133
"connection_state": {
148134
"status": "ready",
149135
"connected_at": "2025-12-13T10:01:00Z",
150-
"last_error": null,
151136
"retry_count": 0,
152-
"last_retry_at": null,
153137
"should_retry": false
154138
},
155139

156140
"health": {
157141
"level": "healthy",
158142
"admin_state": "enabled",
159-
"summary": "Connected (5 tools)",
160-
"detail": null,
161-
"action": ""
143+
"summary": "Connected (5 tools)"
162144
},
163145

164146
"authenticated": true,
165-
"oauth_status": "authenticated",
166147
"connected": true,
167-
"last_error": "",
168148
"tool_count": 5
169149
}
170-
],
171-
"stats": { ... }
172-
}
173-
}
174-
```
175-
176-
### GET /api/v1/diagnostics
177-
178-
**Response structure unchanged** - Diagnostics is populated by aggregating `server.Health`:
179-
180-
```json
181-
{
182-
"success": true,
183-
"data": {
184-
"total_issues": 2,
185-
"upstream_errors": [
186-
{
187-
"server_name": "failing-server",
188-
"error_message": "Connection refused",
189-
"timestamp": "2025-12-13T11:00:00Z"
190-
}
191-
],
192-
"oauth_required": [
193-
{
194-
"server_name": "oauth-server",
195-
"state": "expired",
196-
"message": "Run: mcpproxy auth login --server=oauth-server"
197-
}
198-
],
199-
"oauth_issues": [],
200-
"missing_secrets": [],
201-
"runtime_warnings": [],
202-
"docker_status": {
203-
"available": true,
204-
"version": "24.0.5"
205-
},
206-
"timestamp": "2025-12-13T11:30:00Z"
150+
]
207151
}
208152
}
209153
```
210154

211155
## Backwards Compatibility
212156

213-
| Existing Field | Status | Notes |
214-
|----------------|--------|-------|
215-
| `authenticated` | ✅ KEPT | Returns same value as `oauth_state.status == "authenticated"` |
216-
| `oauth_status` | ✅ KEPT | Returns same value as `oauth_state.status` |
217-
| `connected` | ✅ KEPT | Returns same value as `connection_state.status == "ready"` |
218-
| `connecting` | ✅ KEPT | Returns same value as `connection_state.status == "connecting"` |
219-
| `last_error` | ✅ KEPT | Returns same value as `connection_state.last_error` |
220-
| `reconnect_count` | ✅ KEPT | Returns same value as `connection_state.retry_count` |
221-
| `should_retry` | ✅ KEPT | Returns same value as `connection_state.should_retry` |
222-
| `health` | ✅ IMPLEMENTED | Added in #192, fully functional |
157+
All existing flat fields remain unchanged:
158+
159+
| Field | Consistent With |
160+
|-------|-----------------|
161+
| `authenticated` | `oauth_state.status == "authenticated"` |
162+
| `oauth_status` | `oauth_state.status` |
163+
| `connected` | `connection_state.status == "ready"` |
164+
| `connecting` | `connection_state.status == "connecting"` |
165+
| `last_error` | `connection_state.last_error` |
166+
| `reconnect_count` | `connection_state.retry_count` |
167+
| `should_retry` | `connection_state.should_retry` |
223168

224169
## Migration Path
225170

226-
1. **Phase 1**: Add new fields alongside existing (this feature)
171+
1. **Phase 1** (this feature): Add new fields alongside existing
227172
2. **Phase 2** (future): Deprecation warnings in API docs
228173
3. **Phase 3** (future): Remove flat fields in major version bump

specs/013-structured-server-state/data-model.md

Lines changed: 13 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,27 @@
11
# Data Model: Structured Server State
22

33
**Feature**: 013-structured-server-state
4-
**Date**: 2025-12-13
5-
**Updated**: 2025-12-16
6-
7-
## Implementation Status
8-
9-
| Entity | Status | Location |
10-
|--------|--------|----------|
11-
| `HealthStatus` | ✅ DONE | `internal/contracts/types.go:568-583` |
12-
| `OAuthState` | ❌ TODO | Proposed in this doc |
13-
| `ConnectionState` | ❌ TODO | Proposed in this doc |
4+
**Date**: 2025-12-16
145

156
## Entity Overview
167

178
```
189
┌─────────────────────────────────────────────────────────────────┐
1910
│ Server │
2011
├─────────────────────────────────────────────────────────────────┤
21-
│ id: string │
22-
│ name: string │
23-
│ enabled: bool │
24-
│ quarantined: bool │
25-
│ │
2612
│ // NEW: Structured state objects │
27-
│ oauth_state: OAuthState? ←───────────────────┐
28-
│ connection_state: ConnectionState ←───────────────┐ │
29-
30-
│ // KEEP: Flat fields (backwards compat) │ │
31-
│ authenticated: bool
32-
│ oauth_status: string
33-
│ connected: bool
34-
│ last_error: string
35-
│ ...
36-
37-
│ // Calculated │ │
38-
│ health: HealthStatus ←────────────────────────────┴───┘
13+
│ oauth_state: OAuthState? ←── Only if OAuth configured
14+
│ connection_state: ConnectionState ←── Always present
15+
16+
│ // EXISTING: Flat fields (kept for backwards compat) │
17+
│ authenticated: bool
18+
│ oauth_status: string
19+
│ connected: bool
20+
│ last_error: string
21+
│ ...
22+
23+
│ // EXISTING: Calculated health (implemented in #192)
24+
│ health: HealthStatus
3925
└─────────────────────────────────────────────────────────────────┘
4026
4127
┌─────────────────────────────────────────────────────────────────┐
@@ -60,16 +46,6 @@
6046
│ last_retry_at: time? // Last retry timestamp │
6147
│ should_retry: bool // Whether retry is pending │
6248
└─────────────────────────────────────────────────────────────────┘
63-
64-
┌─────────────────────────────────────────────────────────────────┐
65-
│ HealthStatus ✅ IMPLEMENTED │
66-
├─────────────────────────────────────────────────────────────────┤
67-
│ level: string // healthy|degraded|unhealthy │
68-
│ admin_state: string // enabled|disabled|quarantined │
69-
│ summary: string // Human-readable status │
70-
│ detail: string? // Extended explanation │
71-
│ action: string? // login|restart|enable|approve|view_logs│
72-
└─────────────────────────────────────────────────────────────────┘
7349
```
7450

7551
## New Types (Go)
@@ -169,11 +145,6 @@ type Server struct {
169145
// NEW: Structured state objects
170146
OAuthState *OAuthState `json:"oauth_state,omitempty"`
171147
ConnectionState *ConnectionState `json:"connection_state,omitempty"`
172-
173-
// KEEP: Existing flat fields for backwards compatibility
174-
Authenticated bool `json:"authenticated"`
175-
OAuthStatus string `json:"oauth_status,omitempty"`
176-
// ... etc
177148
}
178149
```
179150

@@ -186,11 +157,6 @@ export interface Server {
186157
// NEW: Structured state objects
187158
oauth_state?: OAuthState;
188159
connection_state?: ConnectionState;
189-
190-
// KEEP: Existing flat fields
191-
authenticated: boolean;
192-
oauth_status?: string;
193-
// ... etc
194160
}
195161
```
196162

@@ -225,13 +191,8 @@ disconnected ──→ connecting ──→ ready
225191
| OAuthState.RetryCount | Must be >= 0 |
226192
| ConnectionState.Status | Must be one of: disconnected, connecting, ready, error |
227193
| ConnectionState.RetryCount | Must be >= 0 |
228-
| Health.Level | Must be one of: healthy, degraded, unhealthy |
229-
| Health.AdminState | Must be one of: enabled, disabled, quarantined |
230-
| Health.Action | Must be one of: "", login, restart, enable, approve, view_logs |
231194

232195
## Relationships
233196

234197
- **Server → OAuthState**: Optional (1:0..1) - only present if OAuth configured
235198
- **Server → ConnectionState**: Required (1:1) - always present
236-
- **Server → HealthStatus**: Required (1:1) - always calculated
237-
- **OAuthState + ConnectionState → HealthStatus**: Input for calculation

0 commit comments

Comments
 (0)