safesight/docs/superpowers/specs/2026-04-19-config-management-minimal-loop-design.md

155 lines
5.4 KiB
Markdown

# Config Management Minimal Loop Design
## Purpose
Improve configuration management without returning to hand-maintained full JSON configs. The first implementation loop makes rendered configs traceable and lets the RK3588 agent report which config file is present and, when metadata is available, which config identity it represents.
This is intentionally smaller than the full backend management system. It creates the device-side facts that the backend can rely on later.
## Current Context
The maintained media-server config source is the template/profile/overlay workflow:
- Template: `configs/templates/workshop_face_shoe_alarm.json`
- Device/site profile: `configs/profiles/local_3588_test.json`
- Scenario overlays: `configs/overlays/*.json`
- Generated runtime configs: `configs/generated/*.json`
The agent already exposes build metadata through UDP discovery, `GET /v1/info`, and `GET /v1/versions`. It also has older `config/ui/*` endpoints that generate configs from Go-embedded templates. Those endpoints remain supported, but this work should not expand the embedded-template model.
## First-Loop Scope
1. Add optional trace metadata to rendered configs.
2. Add an agent read API that reports config path, hash, timestamps, metadata, and media-server process config path when available.
3. Keep current `GET /v1/config` and `PUT /v1/config` behavior intact.
4. Keep generated config files disposable and out of git.
Out of scope for this loop:
- Full backend UI implementation.
- Full profile/overlay package upload and server-side rendering in Go.
- Hot reload guarantees for hardware-dependent media-server behavior.
- Replacing existing `config/ui/*` endpoints.
## Config Metadata Model
Rendered configs may include a top-level `metadata` object:
```json
{
"metadata": {
"config_id": "local_3588_face_debug",
"config_version": "20260419.001",
"template": "workshop_face_shoe_alarm",
"template_path": "configs/templates/workshop_face_shoe_alarm.json",
"profile": "local_3588_test",
"profile_path": "configs/profiles/local_3588_test.json",
"overlays": [
"face_debug"
],
"overlay_paths": [
"configs/overlays/face_debug.json"
],
"rendered_by": "tools/render_config.py",
"rendered_at": "2026-04-19T00:00:00Z"
}
}
```
`metadata` is operational trace data. Media-server should ignore it if it only consumes `global`, `queue`, `templates`, `instances`, or `graphs`.
`config_hash` should not be embedded into the JSON in this loop because hashing a file that contains its own hash creates awkward circular semantics. The agent computes and reports the file hash instead.
## Render Tool Behavior
`tools/render_config.py` gains optional flags:
- `--config-id`
- `--config-version`
- `--rendered-at`
- `--metadata-json`
When any metadata flag is provided, the script writes top-level `metadata`. Without those flags, existing output remains compatible except for stable implementation details needed by tests.
`--metadata-json` accepts a JSON object and is merged first. CLI fields override same-named metadata keys so automation can supply defaults and still stamp a specific config ID/version.
## Agent API
Add:
`GET /v1/config/status`
Response shape:
```json
{
"ok": true,
"config_path": "/etc/rk3588sys/config.json",
"exists": true,
"size": 12345,
"mtime_ms": 1776528000000,
"sha256": "hex",
"metadata": {
"config_id": "local_3588_face_debug",
"config_version": "20260419.001"
},
"last_good_path": "/etc/rk3588sys/config.json.last_good.json",
"last_good": {
"exists": true,
"size": 12340,
"mtime_ms": 1776520000000,
"sha256": "hex",
"metadata": {}
},
"media_server": {
"supported": true,
"running": true,
"pid": 1234,
"config_path": "/etc/rk3588sys/config.json",
"started_at_ms": 1776528005000
}
}
```
If the config file is missing, the endpoint returns `200` with `exists:false` and no hash instead of `404`. This makes the backend device-detail page simpler: missing config is status, not transport failure.
## Backend-Visible Field Boundaries
User-facing configurable fields should be profile/overlay parameters such as:
- RTSP/video source
- device/site/channel identity
- backend token/API URLs
- MinIO endpoint, bucket, and credentials
- face gallery path when deployment layout requires it
- selected overlays for debug, sensitivity, or production quiet mode
- carefully selected alarm thresholds and cooldowns
Internal fields stay hidden unless an engineering mode later exposes them:
- DAG edges and internal node IDs
- shared state keys
- gallery embedding dimension
- model input/output tensor assumptions
- CPU affinity and low-level queue tuning
- tracker and plugin glue parameters that can break cross-node contracts
## Validation
Local code-level validation:
- Python unit tests or focused script checks for metadata rendering.
- Go tests for `GET /v1/config/status` response behavior.
- `git diff --check`.
- `go test ./...` in `agent` if changes touch agent code.
RK3588 device-side validation:
- Pull latest code on device.
- Render a config with metadata.
- Start or restart media-server with that generated config.
- Query `GET /v1/config/status`, `GET /v1/info`, and `GET /v1/versions`.
- Confirm `/tmp/media-server.log` shows the expected runtime config path and no startup regression.
Device-side validation is required before claiming hardware/runtime behavior is verified.