jsgui3-server 0.0.149 → 0.0.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/agents/Mobile Developer.agent.md +89 -0
- package/.github/instructions/copilot.instructions.md +1 -0
- package/AGENTS.md +6 -0
- package/README.md +185 -0
- package/admin-ui/client.js +73 -43
- package/admin-ui/v1/admin_auth_service.js +197 -0
- package/admin-ui/v1/admin_user_store.js +71 -0
- package/admin-ui/v1/client.js +17 -0
- package/admin-ui/v1/controls/admin_shell.js +1399 -0
- package/admin-ui/v1/controls/group_box.js +84 -0
- package/admin-ui/v1/controls/stat_card.js +125 -0
- package/admin-ui/v1/server.js +658 -0
- package/admin-ui/v1/utils/formatters.js +68 -0
- package/docs/admin-extension-guide.md +345 -0
- package/docs/api-reference.md +383 -303
- package/docs/books/adaptive-control-improvements/01-control-candidate-matrix.md +122 -0
- package/docs/books/adaptive-control-improvements/02-tier-1-layout-playbooks.md +207 -0
- package/docs/books/adaptive-control-improvements/03-tier-2-navigation-form-overlay.md +140 -0
- package/docs/books/adaptive-control-improvements/04-cross-cutting-platform-functionality.md +141 -0
- package/docs/books/adaptive-control-improvements/05-styling-theming-density-upgrades.md +114 -0
- package/docs/books/adaptive-control-improvements/06-testing-quality-gates.md +97 -0
- package/docs/books/adaptive-control-improvements/07-delivery-roadmap-and-ownership.md +137 -0
- package/docs/books/adaptive-control-improvements/08-appendix-tier1-acceptance-and-pr-templates.md +261 -0
- package/docs/books/adaptive-control-improvements/README.md +66 -0
- package/docs/books/admin-ui-authentication/01-threat-model-and-goals.md +124 -0
- package/docs/books/admin-ui-authentication/02-session-model-and-token-model.md +75 -0
- package/docs/books/admin-ui-authentication/03-auth-middleware-patterns.md +77 -0
- package/docs/books/admin-ui-authentication/README.md +25 -0
- package/docs/books/creating-a-new-admin-ui/01-introduction-and-vision.md +130 -0
- package/docs/books/creating-a-new-admin-ui/02-architecture-and-data-flow.md +298 -0
- package/docs/books/creating-a-new-admin-ui/03-server-introspection.md +381 -0
- package/docs/books/creating-a-new-admin-ui/04-admin-module-adapter-layer.md +592 -0
- package/docs/books/creating-a-new-admin-ui/05-domain-controls-stat-cards-and-gauges.md +513 -0
- package/docs/books/creating-a-new-admin-ui/06-domain-controls-process-manager.md +544 -0
- package/docs/books/creating-a-new-admin-ui/07-domain-controls-resource-pool-inspector.md +493 -0
- package/docs/books/creating-a-new-admin-ui/08-domain-controls-route-table-and-api-explorer.md +586 -0
- package/docs/books/creating-a-new-admin-ui/09-domain-controls-log-viewer-and-activity-feed.md +490 -0
- package/docs/books/creating-a-new-admin-ui/10-domain-controls-build-status-and-bundle-inspector.md +526 -0
- package/docs/books/creating-a-new-admin-ui/11-domain-controls-configuration-panel.md +808 -0
- package/docs/books/creating-a-new-admin-ui/12-admin-shell-layout-sidebar-navigation.md +210 -0
- package/docs/books/creating-a-new-admin-ui/13-telemetry-integration.md +556 -0
- package/docs/books/creating-a-new-admin-ui/14-realtime-sse-observable-integration.md +485 -0
- package/docs/books/creating-a-new-admin-ui/15-styling-theming-aero-design-system.md +521 -0
- package/docs/books/creating-a-new-admin-ui/16-testing-and-quality-assurance.md +147 -0
- package/docs/books/creating-a-new-admin-ui/17-next-steps-process-resource-roadmap.md +356 -0
- package/docs/books/creating-a-new-admin-ui/README.md +68 -0
- package/docs/books/device-adaptive-composition/01-platform-feature-audit.md +177 -0
- package/docs/books/device-adaptive-composition/02-responsive-composition-model.md +187 -0
- package/docs/books/device-adaptive-composition/03-data-model-vs-view-model.md +231 -0
- package/docs/books/device-adaptive-composition/04-styling-theme-breakpoints.md +234 -0
- package/docs/books/device-adaptive-composition/05-showcase-app-multi-device-assessment.md +193 -0
- package/docs/books/device-adaptive-composition/06-implementation-patterns-and-apis.md +346 -0
- package/docs/books/device-adaptive-composition/07-testing-harness-and-quality-gates.md +265 -0
- package/docs/books/device-adaptive-composition/08-roadmap-and-adoption-plan.md +250 -0
- package/docs/books/device-adaptive-composition/README.md +47 -0
- package/docs/comparison-report-express-plex-cpanel.md +549 -0
- package/docs/comprehensive-documentation.md +220 -220
- package/docs/configuration-reference.md +227 -204
- package/docs/designs/server-admin-interface-aero.svg +611 -0
- package/docs/middleware-guide.md +236 -0
- package/docs/system-architecture.md +24 -18
- package/docs/troubleshooting.md +84 -53
- package/middleware/compression.js +217 -0
- package/middleware/index.js +15 -0
- package/module.js +19 -11
- package/package.json +1 -1
- package/serve-factory.js +29 -0
- package/server.js +280 -20
- package/tests/README.md +5 -0
- package/tests/admin-ui-jsgui-controls.test.js +581 -0
- package/tests/test-runner.js +1 -0
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-071799b982906680f5fd699d.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-07352945ad5c92654fcb8b65.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-138a601fadb6191ea314c6fd.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-171f6c381c2cadf2e9fa7087.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-1d973388156b84a04373fac9.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-20e117bc8a10d2cd16234bbe.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-2b028a82b0e5efddba42425f.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-4518556cd5c7e059e82b22b8.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5bac1aa0f213902f718ed74f.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-5f9996ac7822caf777d92f56.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-60a92c702e65fd9cf748e3ec.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6164c1f8f738995c541895d2.js +0 -44
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-6718a85eb9e5aa782dd47a05.js +0 -45
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-69e280f14e37aee76a1d4675.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7570d1b030d44b111ed59c4c.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7798c9bbd55e510d5039f936.js +0 -42
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-78cd511ea1ef18ecb03d1be5.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-7d482e0b95bcb5e3c543118b.js +0 -43
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-80e9476d1127c55b40fdb36f.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-810ced55d5320a3088a05b13.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-8423565f1a40e329afc8c6cf.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-900bef783b8cee36506ec282.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-a1a37aff6416fdad74040ddf.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-ad48d5e8eda40f175b4df090.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-aec5a2d963015528c9099462.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-af9d34e0f1722fab9e28c269.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-b818e4015e2f1fe86280b5ab.js +0 -41
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bcb2541adc70b7aba61768c5.js +0 -44
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-bfe89d2c78ed44f95ed7dd73.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c06f04806a1e688e1187110c.js +0 -40
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-c3f3adf904f585afc544b96a.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-d45acb873e1d8e32d5e60f2e.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-db06f132533706f4a0163b8c.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f660f40d78b135fc8560a862.js +0 -39
- package/.jsgui3-server-cache/jsgui3-html-shims/jsgui3-html-controls-shim-f9dee4ec18a96e09bee06bae.js +0 -39
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# Chapter 17 — Next Steps Roadmap (Process/Resource-Centric Admin)
|
|
2
|
+
|
|
3
|
+
## Purpose of This Chapter
|
|
4
|
+
|
|
5
|
+
This chapter is a **handoff-grade implementation roadmap** for the next phase of the Admin UI. It captures the current baseline, architectural direction, concrete work packages, and acceptance criteria so another agent (or engineer) can continue confidently.
|
|
6
|
+
|
|
7
|
+
This roadmap is intentionally **domain-agnostic**: it does not assume crawler-specific behavior or any workload-specific semantics.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Current Baseline (Already Implemented)
|
|
12
|
+
|
|
13
|
+
### Admin UI v1 shell and read-only sections
|
|
14
|
+
|
|
15
|
+
- Admin shell with sidebar, toolbar, content, and status bar.
|
|
16
|
+
- Dashboard stat cards.
|
|
17
|
+
- Read-only sections for Resources, Routes, Settings with loading/error/retry states.
|
|
18
|
+
- Control-first rendering for section content (tables, key-value rows, actions) using jsgui controls, not direct DOM string patching.
|
|
19
|
+
- Interactive shell wiring implemented for:
|
|
20
|
+
- sidebar item activation
|
|
21
|
+
- phone tab synchronization
|
|
22
|
+
- hamburger/overlay sidebar toggling
|
|
23
|
+
- custom section insertion and refresh replacement
|
|
24
|
+
- logout/retry actions in dynamic panels
|
|
25
|
+
|
|
26
|
+
### Telemetry adapter and APIs
|
|
27
|
+
|
|
28
|
+
- `/api/admin/v1/status`
|
|
29
|
+
- `/api/admin/v1/resources`
|
|
30
|
+
- `/api/admin/v1/routes`
|
|
31
|
+
- `/api/admin/v1/events` (SSE)
|
|
32
|
+
|
|
33
|
+
### Authentication and authorization groundwork
|
|
34
|
+
|
|
35
|
+
- Login/logout/session endpoints:
|
|
36
|
+
- `POST /api/admin/v1/auth/login`
|
|
37
|
+
- `POST /api/admin/v1/auth/logout`
|
|
38
|
+
- `GET /api/admin/v1/auth/session`
|
|
39
|
+
- Protected UI + API surface (`/admin/v1` and `/api/admin/v1/*`).
|
|
40
|
+
- In-memory sessions and role groundwork:
|
|
41
|
+
- `admin_read`
|
|
42
|
+
- `admin_write` (reserved for future mutation endpoints)
|
|
43
|
+
|
|
44
|
+
### Documentation baseline
|
|
45
|
+
|
|
46
|
+
- Auth book started:
|
|
47
|
+
- Threat model
|
|
48
|
+
- Session/token model
|
|
49
|
+
- middleware/authorization patterns
|
|
50
|
+
- Troubleshooting updated with generated shim cache guidance.
|
|
51
|
+
- Admin shell and testing chapters updated to match current implementation (`Chapter 12`, `Chapter 16`).
|
|
52
|
+
|
|
53
|
+
### Test baseline (currently implemented)
|
|
54
|
+
|
|
55
|
+
- `tests/admin-ui-render.test.js` (rendering baseline)
|
|
56
|
+
- `tests/admin-ui-jsgui-controls.test.js` (interactive behavior + SSE lifecycle + DOM-pattern guard)
|
|
57
|
+
- Included in `tests/test-runner.js` as `admin-ui-jsgui-controls.test.js`.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Architectural Direction: Process as Resource
|
|
62
|
+
|
|
63
|
+
## Decision
|
|
64
|
+
|
|
65
|
+
Adopt **Process as a Resource type** and keep a **ProcessManager as a Resource** for orchestration.
|
|
66
|
+
|
|
67
|
+
### Why this is the right direction
|
|
68
|
+
|
|
69
|
+
1. Uniform control plane: everything is a resource with lifecycle and telemetry.
|
|
70
|
+
2. Better admin UX: one table model for states/health/actions.
|
|
71
|
+
3. Extensible orchestration: manager policies can evolve independently.
|
|
72
|
+
4. Natural language remains intact: teams still talk about “processes,” while implementation is resource-based.
|
|
73
|
+
|
|
74
|
+
### Conceptual model
|
|
75
|
+
|
|
76
|
+
- `Process_Resource` extends `Resource`.
|
|
77
|
+
- `Process_Manager_Resource` extends `Resource` and manages a set of `Process_Resource` instances.
|
|
78
|
+
- Resource pool remains the system registry and event bus anchor.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Target Capabilities (Next Phase)
|
|
83
|
+
|
|
84
|
+
The next phase should improve the admin interface as a **task/process coordinator** while keeping risk low.
|
|
85
|
+
|
|
86
|
+
### Read-side capabilities (implement first)
|
|
87
|
+
|
|
88
|
+
1. Process inventory and state overview.
|
|
89
|
+
2. Process detail panel (identity, runtime, state timeline).
|
|
90
|
+
3. Process manager summary (counts, policy settings, queue pressure if available).
|
|
91
|
+
4. Event stream correlation for process state transitions.
|
|
92
|
+
|
|
93
|
+
### Write-side capabilities (planned later)
|
|
94
|
+
|
|
95
|
+
1. Start/stop/restart process operations.
|
|
96
|
+
2. Desired-state reconciliation through manager policy.
|
|
97
|
+
3. Controlled write actions guarded by `admin_write` + CSRF + audit logs.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Data Contract Proposal (Generic)
|
|
102
|
+
|
|
103
|
+
These contracts should be introduced incrementally and versioned under `/api/admin/v1/...`.
|
|
104
|
+
|
|
105
|
+
### `GET /api/admin/v1/processes`
|
|
106
|
+
|
|
107
|
+
Returns process-like resources in normalized shape. V1 returns all items (no pagination). If pagination is needed later, add `?limit=N&offset=M` query parameters — but defer until there's evidence of large inventories.
|
|
108
|
+
|
|
109
|
+
**Process state enum** (strict at adapter level):
|
|
110
|
+
`starting` | `running` | `degraded` | `crashed` | `stopped` | `unknown`
|
|
111
|
+
|
|
112
|
+
Resources whose state doesn't map cleanly to one of these values should be normalized to `unknown`.
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"ok": true,
|
|
117
|
+
"items": [
|
|
118
|
+
{
|
|
119
|
+
"name": "worker-a",
|
|
120
|
+
"type": "Process_Resource",
|
|
121
|
+
"manager": "default_process_manager",
|
|
122
|
+
"desired_state": "running",
|
|
123
|
+
"observed_state": "running",
|
|
124
|
+
"health": "healthy",
|
|
125
|
+
"pid": 12345,
|
|
126
|
+
"uptime_seconds": 842,
|
|
127
|
+
"restart_count": 0,
|
|
128
|
+
"last_error": null,
|
|
129
|
+
"updated_at": 1739590000000
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### `GET /api/admin/v1/processes/:name`
|
|
136
|
+
|
|
137
|
+
Returns detailed process metadata and recent events.
|
|
138
|
+
|
|
139
|
+
### `GET /api/admin/v1/process-managers`
|
|
140
|
+
|
|
141
|
+
Returns manager-level summaries:
|
|
142
|
+
|
|
143
|
+
- total managed processes
|
|
144
|
+
- running/degraded/crashed counts
|
|
145
|
+
- policy configuration snapshot
|
|
146
|
+
|
|
147
|
+
### SSE event names (existing + proposed)
|
|
148
|
+
|
|
149
|
+
- existing: `resource_state_change`, `crashed`, `recovered`, `heartbeat`
|
|
150
|
+
- proposed normalized process events:
|
|
151
|
+
- `process_state_changed`
|
|
152
|
+
- `process_unhealthy`
|
|
153
|
+
- `process_exited`
|
|
154
|
+
- `process_restarted`
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## UI Roadmap (Admin v1.x)
|
|
159
|
+
|
|
160
|
+
### UI-1: Processes section (read-only)
|
|
161
|
+
|
|
162
|
+
Add a dedicated sidebar item and panel:
|
|
163
|
+
|
|
164
|
+
- columns: Name, Manager, Desired, Observed, Health, Uptime, Restarts
|
|
165
|
+
- sorting by state and uptime
|
|
166
|
+
- status color badges
|
|
167
|
+
- empty/error/loading states
|
|
168
|
+
|
|
169
|
+
**Adaptive composition** (ref: Device-Adaptive Composition book, Chapter 2 — four-layer model)
|
|
170
|
+
|
|
171
|
+
- **Desktop**: dense table layout with all columns visible.
|
|
172
|
+
- **Tablet**: table with horizontal scroll or column prioritization (hide Restarts, Manager).
|
|
173
|
+
- **Phone**: card list — one card per process showing Name, Observed State badge, and Health. Tap to navigate to detail.
|
|
174
|
+
- Use `[data-layout-mode]` attribute selectors, not raw `@media` queries (Chapter 4).
|
|
175
|
+
- Touch targets for state badges and row actions must meet 44×44 px minimum.
|
|
176
|
+
|
|
177
|
+
**Acceptance criteria**
|
|
178
|
+
|
|
179
|
+
- panel loads with auth-protected API
|
|
180
|
+
- handles empty inventories gracefully
|
|
181
|
+
- updates key state badges from SSE without full reload
|
|
182
|
+
- SSE auto-reconnects on stream drop with exponential backoff (1s → 2s → 4s → max 30s)
|
|
183
|
+
- renders correctly across the viewport test matrix: phone portrait (390×844), tablet landscape (1024×768), desktop wide (1920×1080)
|
|
184
|
+
|
|
185
|
+
### UI-2: Process detail drawer/panel (read-only)
|
|
186
|
+
|
|
187
|
+
Selecting a process shows:
|
|
188
|
+
|
|
189
|
+
- identity + manager
|
|
190
|
+
- desired vs observed state
|
|
191
|
+
- runtime metadata
|
|
192
|
+
- recent event timeline
|
|
193
|
+
|
|
194
|
+
**Adaptive composition** (ref: Device-Adaptive Composition book, Chapter 2)
|
|
195
|
+
|
|
196
|
+
- **Desktop**: side drawer (right panel, ~400px) overlays or splits alongside the process list.
|
|
197
|
+
- **Tablet**: drawer pushes list content or opens as a slide-over.
|
|
198
|
+
- **Phone**: full-screen panel with back-navigation to the process list.
|
|
199
|
+
- Use JS composition (`compose_adaptive()`) for the discrete phone → drawer switch (Chapter 6).
|
|
200
|
+
|
|
201
|
+
**Acceptance criteria**
|
|
202
|
+
|
|
203
|
+
- all values match API payload
|
|
204
|
+
- timeline updates while panel is open via SSE (auto-reconnect on drop)
|
|
205
|
+
- no write actions exposed yet
|
|
206
|
+
- drawer/panel transition works across all three layout modes
|
|
207
|
+
|
|
208
|
+
### UI-3: Process manager summary panel (read-only)
|
|
209
|
+
|
|
210
|
+
Displays manager-level health and policy snapshot.
|
|
211
|
+
|
|
212
|
+
**Adaptive composition** (ref: Device-Adaptive Composition book, Chapter 2)
|
|
213
|
+
|
|
214
|
+
- **Desktop/Tablet**: stat cards in a responsive grid (like Dashboard).
|
|
215
|
+
- **Phone**: single-column stacked cards.
|
|
216
|
+
- Use CSS-only continuous adaptation (flexbox wrap) — no JS composition switch needed.
|
|
217
|
+
|
|
218
|
+
**Acceptance criteria**
|
|
219
|
+
|
|
220
|
+
- supports multiple managers
|
|
221
|
+
- summarizes counts correctly
|
|
222
|
+
- includes "last updated" timestamp and stale-data indicator
|
|
223
|
+
- cards reflow correctly at phone viewport width
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Backend Roadmap (Process/Resource layer)
|
|
228
|
+
|
|
229
|
+
### BE-1: Normalize process resource shape
|
|
230
|
+
|
|
231
|
+
Add utility mapping in admin adapter to produce a stable process DTO from heterogeneous resources.
|
|
232
|
+
|
|
233
|
+
**Acceptance criteria**
|
|
234
|
+
|
|
235
|
+
- missing fields fall back to explicit defaults:
|
|
236
|
+
- `health` → `'unknown'`
|
|
237
|
+
- `desired_state` → `null`
|
|
238
|
+
- `observed_state` → `'unknown'`
|
|
239
|
+
- `restart_count` → `0`
|
|
240
|
+
- `uptime_seconds` → `null`
|
|
241
|
+
- `last_error` → `null`
|
|
242
|
+
- `pid` → `null`
|
|
243
|
+
- `manager` → `null`
|
|
244
|
+
- `updated_at` → `Date.now()` (timestamp of normalization)
|
|
245
|
+
- no access to hazardous getters that can throw side effects
|
|
246
|
+
|
|
247
|
+
### BE-2: Add process inventory endpoints
|
|
248
|
+
|
|
249
|
+
Implement read-only endpoints listed above under `admin_read` guard.
|
|
250
|
+
|
|
251
|
+
**Acceptance criteria**
|
|
252
|
+
|
|
253
|
+
- unauthenticated => 401
|
|
254
|
+
- authenticated without role => 403
|
|
255
|
+
- authenticated with `admin_read` => 200
|
|
256
|
+
|
|
257
|
+
### BE-3: Event normalization bridge
|
|
258
|
+
|
|
259
|
+
Map generic pool events to process-centric event names when resource type indicates process semantics.
|
|
260
|
+
|
|
261
|
+
**Event mapping table**
|
|
262
|
+
|
|
263
|
+
| Pool event | Condition | Normalized event |
|
|
264
|
+
|---|---|---|
|
|
265
|
+
| `resource_state_change` | `resource.type === 'Process_Resource'` | `process_state_changed` |
|
|
266
|
+
| `crashed` | resource is process type | `process_exited` (with `exit_reason: 'crash'`) |
|
|
267
|
+
| `recovered` | resource is process type | `process_restarted` |
|
|
268
|
+
| `resource_state_change` where `new_state` is degraded | resource is process type | `process_unhealthy` |
|
|
269
|
+
|
|
270
|
+
Normalized event payloads should include: `{ name, manager, previous_state, current_state, timestamp }`.
|
|
271
|
+
|
|
272
|
+
**Acceptance criteria**
|
|
273
|
+
|
|
274
|
+
- existing events remain available (normalized events are additive, not replacements)
|
|
275
|
+
- normalized events are documented in this chapter's data contract section
|
|
276
|
+
- unmapped resource types pass through without transformation
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Security and Authorization Next Steps
|
|
281
|
+
|
|
282
|
+
### S-1: Role policy enforcement consistency
|
|
283
|
+
|
|
284
|
+
Ensure every new process endpoint is explicitly guarded (`admin_read` for read endpoints now).
|
|
285
|
+
|
|
286
|
+
### S-2: Write action gate (future)
|
|
287
|
+
|
|
288
|
+
Before adding any mutation endpoint:
|
|
289
|
+
|
|
290
|
+
1. require `admin_write`
|
|
291
|
+
2. require CSRF protection for browser-initiated writes
|
|
292
|
+
3. emit audit events (actor, action, target, result)
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Testing Roadmap
|
|
297
|
+
|
|
298
|
+
### T-1: API auth contract tests
|
|
299
|
+
|
|
300
|
+
- unauthorized requests return 401
|
|
301
|
+
- role violations return 403
|
|
302
|
+
- valid read role returns 200
|
|
303
|
+
|
|
304
|
+
### T-2: UI smoke tests for process panels
|
|
305
|
+
|
|
306
|
+
- login flow
|
|
307
|
+
- process panel renders
|
|
308
|
+
- SSE updates state badge in place
|
|
309
|
+
|
|
310
|
+
### T-3: Regression checks
|
|
311
|
+
|
|
312
|
+
- existing status/resources/routes views still pass
|
|
313
|
+
- no route collisions with static assets
|
|
314
|
+
- startup still succeeds without process resources present
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Implementation Order (Recommended)
|
|
319
|
+
|
|
320
|
+
1. **BE-1** process DTO normalization helper
|
|
321
|
+
2. **BE-2** `/processes` and `/process-managers` read endpoints
|
|
322
|
+
3. **UI-1** process list panel
|
|
323
|
+
4. **UI-2** process detail panel
|
|
324
|
+
5. **BE-3 + UI-3** normalized events + manager summary
|
|
325
|
+
6. tests for auth and rendering regression
|
|
326
|
+
|
|
327
|
+
This order keeps risk low by landing read-side observability first.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Open Questions for Reviewer Agent
|
|
332
|
+
|
|
333
|
+
1. ~~Should process endpoints be nested under `/api/admin/v1/resources/processes` or top-level `/api/admin/v1/processes`?~~ **Resolved: top-level.** The process endpoint is a first-class concept, not a filtered view of a generic resource browser that doesn't exist yet.
|
|
334
|
+
2. Should timeline events be pulled (`GET`) only, or include in-band SSE replay snapshots?
|
|
335
|
+
3. What minimum manager policy fields should be exposed in v1 read-only summary?
|
|
336
|
+
4. ~~Should process state enums be strict at adapter level now?~~ **Resolved: yes.** Strict enum (`starting | running | degraded | crashed | stopped | unknown`) at the adapter layer. Costs nothing, prevents downstream string-comparison drift. `unknown` covers unmapped resources.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Definition of Done for Next Milestone
|
|
341
|
+
|
|
342
|
+
The next milestone is complete when:
|
|
343
|
+
|
|
344
|
+
1. Admin UI has a working **Processes** read-only section.
|
|
345
|
+
2. Process inventory and manager summary endpoints exist and are documented.
|
|
346
|
+
3. Role-guarded access is verified (`401/403/200` behavior).
|
|
347
|
+
4. SSE-driven process state updates appear in UI.
|
|
348
|
+
5. No workload-specific logic is introduced into this repo.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Notes for Contributors
|
|
353
|
+
|
|
354
|
+
- Keep naming conventions aligned with project rules (`snake_case` for functions/variables, PascalCase classes).
|
|
355
|
+
- Keep process/resource abstractions generic.
|
|
356
|
+
- Avoid introducing write actions until CSRF + audit plan is implemented.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Creating a New Admin UI
|
|
2
|
+
|
|
3
|
+
**A comprehensive guide to building the jsgui3-server Administration Interface**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## About This Book
|
|
8
|
+
|
|
9
|
+
This book documents the design, architecture, and implementation of a rich administration interface for jsgui3-server. The admin UI is built entirely with jsgui3 controls — dogfooding the framework to create a production-quality dashboard that provides real-time visibility into server internals, process health, resource pools, routing tables, build outputs, and configuration.
|
|
10
|
+
|
|
11
|
+
The admin UI lives at `admin-ui/v1/` and is served automatically at the `/admin/v1` route of any running jsgui3-server instance.
|
|
12
|
+
|
|
13
|
+
## Design Reference
|
|
14
|
+
|
|
15
|
+
The visual design is inspired by a Windows Aero-era aesthetic — glass-effect title bars, warm parchment content areas, subtle gradients, and grouped panels with classic separators. The SVG design reference (`server-admin-interface-aero.svg`) provides the canonical visual target.
|
|
16
|
+
|
|
17
|
+
## Chapters
|
|
18
|
+
|
|
19
|
+
| # | Chapter | Description |
|
|
20
|
+
|---|---------|-------------|
|
|
21
|
+
| 01 | [Introduction & Vision](01-introduction-and-vision.md) | Goals, audience, design philosophy, and what the admin UI aims to achieve |
|
|
22
|
+
| 02 | [Architecture & Data Flow](02-architecture-and-data-flow.md) | Client-server architecture, data paths, isomorphic rendering, and component hierarchy |
|
|
23
|
+
| 03 | [Server Introspection — What Data Is Available](03-server-introspection.md) | Audit of every data source in jsgui3-server that the admin UI can surface |
|
|
24
|
+
| 04 | [The Admin Module Adapter Layer](04-admin-module-adapter-layer.md) | API endpoints, telemetry collection, and the bridge between server internals and the UI |
|
|
25
|
+
| 05 | [Domain Controls — Stat Cards & Gauges](05-domain-controls-stat-cards-and-gauges.md) | Status indicator cards, numeric displays, progress gauges, and sparkline charts |
|
|
26
|
+
| 06 | [Domain Controls — Process Manager Panel](06-domain-controls-process-manager.md) | Process tree, fork visualization, PID/memory display, start/stop/restart actions |
|
|
27
|
+
| 07 | [Domain Controls — Resource Pool Inspector](07-domain-controls-resource-pool-inspector.md) | Resource table, type badges, health indicators, memory breakdown |
|
|
28
|
+
| 08 | [Domain Controls — Route Table & API Explorer](08-domain-controls-route-table-and-api-explorer.md) | HTTP method badges, route listing, handler types, interactive API testing |
|
|
29
|
+
| 09 | [Domain Controls — Log Viewer & Activity Feed](09-domain-controls-log-viewer-and-activity-feed.md) | Timestamped log stream, severity filtering, auto-scroll, search |
|
|
30
|
+
| 10 | [Domain Controls — Build Status & Bundle Inspector](10-domain-controls-build-status-and-bundle-inspector.md) | Bundle size cards, module count, build timing, source map status |
|
|
31
|
+
| 11 | [Domain Controls — Configuration Panel](11-domain-controls-configuration-panel.md) | Read-only and editable config fields, port/debug/entry-point display |
|
|
32
|
+
| 12 | [The Admin Shell — Layout, Sidebar, & Navigation](12-admin-shell-layout-sidebar-navigation.md) | Window chrome, sidebar navigation, toolbar, status bar, content area routing |
|
|
33
|
+
| 13 | [Integrating with the Server — Telemetry Endpoints](13-telemetry-integration.md) | Modifying `server.js` and `Admin_Module` to expose new telemetry APIs |
|
|
34
|
+
| 14 | [Real-Time Updates — SSE & Observable Integration](14-realtime-sse-observable-integration.md) | Connecting the UI to `HTTP_SSE_Publisher` and `HTTP_Observable_Publisher` for live data |
|
|
35
|
+
| 15 | [Styling & Theming — The Aero-Inspired Design System](15-styling-theming-aero-design-system.md) | Token definitions, gradient recipes, glass effects, typography, and density |
|
|
36
|
+
| 16 | [Testing & Quality Assurance](16-testing-and-quality-assurance.md) | Unit tests, integration tests, viewport matrix testing, and acceptance criteria |
|
|
37
|
+
| 17 | [Next Steps — Process/Resource Roadmap](17-next-steps-process-resource-roadmap.md) | Handoff-grade implementation plan for process-centric admin capabilities, auth boundaries, and test gates |
|
|
38
|
+
|
|
39
|
+
## Key Principles
|
|
40
|
+
|
|
41
|
+
1. **Dogfooding** — The admin UI is built entirely with jsgui3 controls. Every pattern used here validates the framework.
|
|
42
|
+
2. **Zero Configuration** — The admin UI is available at `/admin/v1` on every jsgui3-server instance with no extra setup.
|
|
43
|
+
3. **Read Before Write** — The admin UI primarily reads and displays server state. Write operations (restart, config change) are guarded and opt-in.
|
|
44
|
+
4. **Incremental Delivery** — Each domain control is independently functional. The shell composes them, but each can be developed and tested in isolation.
|
|
45
|
+
5. **Real Data Only** — No mock data in production. Every number shown comes from actual server telemetry.
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- Familiarity with jsgui3-html control lifecycle (`compose` → `activate`)
|
|
50
|
+
- Understanding of jsgui3-server's publisher and resource systems
|
|
51
|
+
- Node.js and basic HTTP/SSE concepts
|
|
52
|
+
|
|
53
|
+
## Directory Structure
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
admin-ui/
|
|
57
|
+
├── v1/
|
|
58
|
+
│ ├── client.js # Client-side entry point (registers Admin_Shell)
|
|
59
|
+
│ ├── server.js # Admin module (adapter layer + auth + telemetry)
|
|
60
|
+
│ ├── admin_auth_service.js # Session auth service
|
|
61
|
+
│ ├── admin_user_store.js # In-memory user store
|
|
62
|
+
│ ├── controls/
|
|
63
|
+
│ │ ├── admin_shell.js # Main shell with sidebar + content
|
|
64
|
+
│ │ ├── stat_card.js # Stat card control
|
|
65
|
+
│ │ └── group_box.js # Reusable grouped panel container
|
|
66
|
+
│ └── utils/
|
|
67
|
+
│ └── formatters.js # Shared formatting helpers
|
|
68
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Chapter 1 — Platform Feature Audit
|
|
2
|
+
|
|
3
|
+
Before proposing new infrastructure, we need to understand what jsgui3 already provides and where the real gaps are. This chapter walks through the existing capabilities, illustrates them with actual platform code, and identifies what's missing.
|
|
4
|
+
|
|
5
|
+
## Existing Strengths
|
|
6
|
+
|
|
7
|
+
### 1) Isomorphic Composition Model
|
|
8
|
+
|
|
9
|
+
Controls in jsgui3 are composed on the server and activated on the client. The constructor builds the DOM tree; the `activate()` method wires up event listeners. This gives us a crucial advantage for adaptive UI: we can make **structural composition decisions** at construction time, not just CSS overrides.
|
|
10
|
+
|
|
11
|
+
For responsive design, this means a control can choose entirely different internal compositions based on environment state — a sidebar can be composed as a `Drawer` on mobile and as a static panel on desktop, using the same business logic, without CSS gymnastics.
|
|
12
|
+
|
|
13
|
+
### 2) Layout Primitives with Practical APIs
|
|
14
|
+
|
|
15
|
+
The layout primitives in `controls/organised/1-standard/6-layout/` provide building blocks for most responsive patterns:
|
|
16
|
+
|
|
17
|
+
**Stack** — flexbox container with direction, gap, alignment, wrapping:
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
const nav = new Stack({
|
|
21
|
+
context,
|
|
22
|
+
direction: 'row', // or 'column'
|
|
23
|
+
gap: 8,
|
|
24
|
+
align: 'center',
|
|
25
|
+
justify: 'between',
|
|
26
|
+
wrap: true // allows items to flow to next line
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Stack supports runtime property changes (`set_direction()`, `set_gap()`, etc.), which means a control can switch from horizontal to vertical layout without rebuilding its DOM tree.
|
|
31
|
+
|
|
32
|
+
**Cluster** — wrapped inline groups for tags, chips, buttons:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
const chips = new Cluster({ context, gap: 6, align: 'center' });
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Center** — centering with max-width constraint:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
const content = new Center({ context, max: 960 });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Grid_Gap** — CSS Grid with column/row templates and gap.
|
|
45
|
+
|
|
46
|
+
**Split_Pane** — resizable dual-panel layout:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
const editor = new Split_Pane({
|
|
50
|
+
context,
|
|
51
|
+
orientation: 'horizontal',
|
|
52
|
+
initial_ratio: 0.3
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Drawer** — the most responsive-aware primitive today. It already has a `breakpoint` property and an `overlay_mode` that switches between overlay and docked behavior:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
const nav_drawer = new Drawer({
|
|
60
|
+
context,
|
|
61
|
+
position: 'left',
|
|
62
|
+
breakpoint: 960, // below this width: overlay mode
|
|
63
|
+
overlay_mode: true,
|
|
64
|
+
content: nav_panel
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
In `activate()`, the Drawer listens for `window.resize` and calls `update_responsive_state()`:
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
update_responsive_state() {
|
|
72
|
+
if (typeof window === 'undefined') return;
|
|
73
|
+
const is_overlay = this.overlay_mode && window.innerWidth < this.breakpoint;
|
|
74
|
+
if (is_overlay) {
|
|
75
|
+
this.remove_class('drawer-docked');
|
|
76
|
+
this.add_class('drawer-overlay-mode');
|
|
77
|
+
} else {
|
|
78
|
+
this.add_class('drawer-docked');
|
|
79
|
+
this.remove_class('drawer-overlay-mode');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This is the closest thing to adaptive composition behavior in the current platform. It proves the pattern works; the question is how to generalize it.
|
|
85
|
+
|
|
86
|
+
### 3) Design Token Infrastructure
|
|
87
|
+
|
|
88
|
+
The token system in `css/jsgui-tokens.css` provides a comprehensive set of CSS custom properties with the `--j-` prefix:
|
|
89
|
+
|
|
90
|
+
- **Spacing scale** (8px base): `--j-space-1` through `--j-space-8`
|
|
91
|
+
- **Typography scale**: `--j-text-xs` through `--j-text-xl`
|
|
92
|
+
- **Radius, shadow, motion**: `--j-radius-sm` through `--j-radius-full`, `--j-shadow-sm` through `--j-shadow-xl`
|
|
93
|
+
- **Color system**: semantic foreground/background tokens with full dark-mode overrides
|
|
94
|
+
- **Motion tokens**: `--j-duration-fast`, `--j-duration-normal`, `--j-duration-slow` with automatic zeroing under `prefers-reduced-motion`
|
|
95
|
+
|
|
96
|
+
The admin theme bridge (`--admin-*` tokens) provides an additional layer used by data-oriented controls like tables, forms, and editors.
|
|
97
|
+
|
|
98
|
+
Dark mode is handled via `[data-theme="dark"]` or `.jsgui-dark-mode` selectors, and the `Admin_Theme` presets map named themes to token overrides. This gives a solid foundation for device-adaptive theming — the same token-override pattern can drive density and layout-mode styling.
|
|
99
|
+
|
|
100
|
+
### 4) MVVM Foundations
|
|
101
|
+
|
|
102
|
+
`Data_Model_View_Model_Control` and `control_model_factory.js` provide explicit separation between:
|
|
103
|
+
|
|
104
|
+
- **`data.model`** — domain state (business data)
|
|
105
|
+
- **`view.data.model`** — presentation state (what the view needs to render)
|
|
106
|
+
- **`view.model`** — view-instance state (UI interaction state)
|
|
107
|
+
- **`view.ui`** — UI structure metadata
|
|
108
|
+
|
|
109
|
+
The factory function `ensure_control_models()` sets up this stack automatically:
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
ensure_control_models(this, spec);
|
|
113
|
+
// After this call:
|
|
114
|
+
// this.data.model → Data_Object (domain state)
|
|
115
|
+
// this.view.data.model → Data_Object (presentation state)
|
|
116
|
+
// this.view.ui → Control_View_UI (structure)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This separation is essential for adaptive UI. Device-specific state (layout mode, sidebar visibility, density) belongs in the view model, not the data model. The infrastructure already exists; we just need conventions for using it with environment state.
|
|
120
|
+
|
|
121
|
+
### 5) Interaction and Accessibility Utilities
|
|
122
|
+
|
|
123
|
+
`control_mixins/keyboard_navigation.js` provides orientation-aware keyboard handling — arrow keys navigate differently in vertical vs horizontal contexts, which is directly relevant when layouts change orientation across breakpoints.
|
|
124
|
+
|
|
125
|
+
The guidance in `docs/accessibility_and_semantics.md` establishes patterns for ARIA roles, focus management, and screen reader support. The existing `prefers-reduced-motion` reset in the token system ensures motion tokens go to `0ms` when the user requests reduced motion.
|
|
126
|
+
|
|
127
|
+
## Current Gaps
|
|
128
|
+
|
|
129
|
+
### 1) No Unified Responsive Policy Layer
|
|
130
|
+
|
|
131
|
+
Responsive behavior is currently ad-hoc. The Drawer has its own `breakpoint` property and resize listener. Other controls rely on whatever `@media` queries the app developer writes. There is no shared service that answers the question "what layout mode are we in?" and notifies controls when it changes.
|
|
132
|
+
|
|
133
|
+
This means every control that needs responsive behavior reinvents its own detection logic, and controls can't coordinate — a sidebar might think it's in "desktop" mode while a toolbar uses a different breakpoint to decide it's in "tablet" mode.
|
|
134
|
+
|
|
135
|
+
### 2) No Declarative Viewport/Container Model
|
|
136
|
+
|
|
137
|
+
The platform doesn't currently expose semantic mode labels. A developer can read `window.innerWidth`, but there's no first-class concept of:
|
|
138
|
+
|
|
139
|
+
- **Layout mode**: phone / tablet / desktop
|
|
140
|
+
- **Density mode**: compact / cozy / comfortable
|
|
141
|
+
- **Interaction mode**: touch / pointer / hybrid
|
|
142
|
+
- **Motion mode**: normal / reduced
|
|
143
|
+
|
|
144
|
+
These concepts exist implicitly — Drawer's breakpoint check is really a layout-mode check — but they aren't formalized into a shared vocabulary.
|
|
145
|
+
|
|
146
|
+
### 3) Display-Mode System: Architecturally Rich but Not Productionized
|
|
147
|
+
|
|
148
|
+
`control_mixins/display.js` contains a sophisticated class hierarchy (`Ctrl_Display`, `Ctrl_Display_Modes`, `Ctrl_Display_Mode_Category`, `Ctrl_Display_Modes_Categories`) designed to let controls express multiple display modes with categories like size, layout, colors, and interactivity. The architecture envisions controls that can render as icons, thumbnails, cards, or full panels depending on context.
|
|
149
|
+
|
|
150
|
+
However, this system is still in design-exploration phase. The classes exist and work, but no production controls use them as their display-mode API. The code contains extensive design notes like:
|
|
151
|
+
|
|
152
|
+
> "Want it to be easy to call on and use display mode functionality."
|
|
153
|
+
> "May want nice CSS transitions between display modes."
|
|
154
|
+
|
|
155
|
+
This is valuable forward thinking that aligns well with adaptive composition. The question is whether to productionize this existing architecture or build the adaptive system alongside it and unify later.
|
|
156
|
+
|
|
157
|
+
### 4) Responsive Testing Is Not Standardized
|
|
158
|
+
|
|
159
|
+
The Playwright test suite validates rich interactivity across 14+ test suites, but all tests run at a single viewport size. There is no systematic viewport-matrix testing (run the same assertions at phone, tablet, and desktop sizes) and no structural assertions like "no horizontal overflow at 390px width."
|
|
160
|
+
|
|
161
|
+
## Summary
|
|
162
|
+
|
|
163
|
+
| Area | Status | Key Asset |
|
|
164
|
+
|------|--------|-----------|
|
|
165
|
+
| Isomorphic composition | Strong | Constructor + activate() split |
|
|
166
|
+
| Layout primitives | Strong | Stack, Drawer, Split_Pane, Grid_Gap |
|
|
167
|
+
| Token/theme system | Strong | `--j-*` and `--admin-*` tokens, dark mode |
|
|
168
|
+
| MVVM model separation | Strong | data.model, view.data.model, view.ui |
|
|
169
|
+
| Accessibility | Adequate | keyboard_navigation, reduced-motion |
|
|
170
|
+
| Responsive policy | Gap | No shared environment service |
|
|
171
|
+
| Declarative adaptive modes | Gap | No layout_mode / density_mode vocabulary |
|
|
172
|
+
| Display-mode API | In design | Classes exist, not productionized |
|
|
173
|
+
| Viewport-matrix testing | Gap | No multi-viewport Playwright runner |
|
|
174
|
+
|
|
175
|
+
The platform is well-positioned. The composition model, token system, and model separation give us the right foundations. What's needed is a thin coordination layer — an environment service and adaptive composition helpers — that turns ad-hoc responsive code into a consistent, testable pattern.
|
|
176
|
+
|
|
177
|
+
**Next:** [Chapter 2](02-responsive-composition-model.md) introduces the four-layer composition model that organizes adaptive decisions.
|