Appearance
Centralized Configuration
RIGOR has one editable runtime configuration source at config/sdlx.yaml and one local secret store at config/secrets.yaml. Both files are ignored by Git. The configuration file contains secret_ref objects; the secret store contains the corresponding values. Runtime services never receive a redacted or blanked key.
Normal workflow
Open RIGOR Control at http://127.0.0.1:8079, choose Centralized Configuration, edit the YAML, validate it, and apply it. The API never returns secret values. Applying a draft validates every reference and port, archives the current configuration and secrets under config/revisions/, writes the new source atomically, and regenerates runtime projections. The page reports the units that must be restarted.
The same operations are available locally:
bash
python3 scripts/sdlx-config.py validate
python3 scripts/sdlx-config.py show
python3 scripts/sdlx-config.py plan /path/to/draft.yaml
python3 scripts/sdlx-config.py apply /path/to/draft.yaml --actor operator-name
python3 scripts/sdlx-config.py rollback <revision-id> --actor operator-name
python3 scripts/sdlx-config.py verify-projectionsshow is always redacted. Edit config/secrets.yaml locally when a key must be changed, then run validate and render; do not replace a working key with an empty placeholder. The MinIO rotation helper updates all linked service credentials, saves a rollback revision, regenerates projections, and does not print credential values.
Browser-facing links are centralized too. Configure infrastructure.docs.public_url for Docs. infrastructure.supervisor.public_url is optional; leave it empty in the normal two-host deployment where Controller remains private. Non-empty browser URLs are projected into ASCEND so navigation never guesses from a loopback service address.
Runtime projections
Services consume generated, read-only inputs rather than environment variables:
| Consumer | Generated input |
|---|---|
| ASCEND, Composer, PACE, LabFlow, LabBridge, PRISM | <module>/config/generated.yaml |
| Supervisor | supervisor/config/generated.json |
| Docs | docs-site/config/generated.json |
| Local MinIO | labbridge/deployments/minio/generated.compose.yaml |
| Local EMQX | labbridge/deployments/emqx/generated.compose.yaml |
These files contain resolved secrets where required, use mode 0600, and remain ignored. Do not edit them: ./run.sh start validates and regenerates them from the two central files before starting any service.
Migration and recovery
python3 scripts/sdlx-config.py migrate is a one-time importer for installations that still have module-local YAML, legacy MinIO/EMQX files, or PACE/Docs values in running process environments. It preserves the existing values and keys, then renders the new projections. It refuses to overwrite an existing central configuration. Existing installations created before EMQX joined the bundle can run python3 scripts/sdlx-config.py migrate-emqx once.
Every apply or credential rotation archives both central files before changing them. Rollback restores the configuration and the matching secret values as one revision, then regenerates every projection. Legacy local files may remain on disk as migration evidence, but no production loader or run script reads them.
Rules
- Business settings and credentials do not use process-environment overrides.
- Non-empty fields whose names indicate a key, token, password, secret, or credential must use
secret_refinconfig/sdlx.yaml. - Module-specific validation remains owned by each module after projection.
config/sdlx.example.yamlandconfig/secrets.example.yamldocument shape only and never contain deployment values.- MinIO and EMQX start through
scripts/minio.shandscripts/emqx.sh; backup and credential rotation read the same central bundle.