chore: rename project Roundtable → Steward

Renames the Python package directory, CLI command, env var prefix,
docker-compose service/container/image, Postgres role/db, and all
visible branding. Marketing form is "Fabled Steward".

Clean break from the previous rebrand: drops the fabledscryer→roundtable
import shim in __init__.py and the FABLEDSCRYER_* env var fallback in
config.py and migrations/env.py. Env vars are now STEWARD_* only.

Heads-up for existing deployments:
- Postgres user/db renamed fabledscryer → steward in docker-compose.yml.
  Existing volumes need the role/db renamed inside Postgres, or override
  POSTGRES_USER/POSTGRES_DB to keep the old names.
- Host-agent systemd unit is now steward-agent.service. Existing agents
  keep running under the old name; reinstall to switch.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 16:20:14 -04:00
parent e118543b2e
commit 88ab5b917e
148 changed files with 570 additions and 619 deletions
+2 -2
View File
@@ -14,7 +14,7 @@ When any monitor or plugin calls `record_metric()`:
4. If a state transition occurs, an `AlertEvent` row is written
5. Notification I/O is deferred outside the transaction via `asyncio.create_task()`
**Key function:** `roundtable/core/alerts.py``record_metric(session, source_module, resource_name, metric_name, value)`
**Key function:** `steward/core/alerts.py``record_metric(session, source_module, resource_name, metric_name, value)`
`record_metric()` must always be called inside an active transaction:
@@ -130,7 +130,7 @@ Webhook is skipped if `webhook.url` is empty.
## Data Models
Defined in `roundtable/models/alerts.py`:
Defined in `steward/models/alerts.py`:
- **`alert_rules`** — one row per configured rule
- **`alert_states`** — one row per rule, tracks current state and consecutive failure count
+6 -6
View File
@@ -1,6 +1,6 @@
# Ansible Integration
Roundtable can browse, trigger, and stream output from Ansible playbooks directly from the web UI. Runs execute as asyncio tasks inside the same process — no Celery, no external workers.
Steward can browse, trigger, and stream output from Ansible playbooks directly from the web UI. Runs execute as asyncio tasks inside the same process — no Celery, no external workers.
---
@@ -115,7 +115,7 @@ Output stored in the DB is capped at 1 MB. If truncated, `[output truncated]` is
## Data Model
`ansible_runs` table (defined in `roundtable/models/ansible.py`):
`ansible_runs` table (defined in `steward/models/ansible.py`):
| Column | Type | Description |
|---|---|---|
@@ -137,7 +137,7 @@ Runs older than `data.retention_days` (default 90) are pruned by the `data_clean
| File | Purpose |
|---|---|
| `roundtable/ansible/sources.py` | Source discovery, git pull logic |
| `roundtable/ansible/executor.py` | Subprocess execution and output streaming |
| `roundtable/ansible/routes.py` | HTTP routes (browse, trigger, stream, history) |
| `roundtable/models/ansible.py` | `AnsibleRun` model |
| `steward/ansible/sources.py` | Source discovery, git pull logic |
| `steward/ansible/executor.py` | Subprocess execution and output streaming |
| `steward/ansible/routes.py` | HTTP routes (browse, trigger, stream, history) |
| `steward/models/ansible.py` | `AnsibleRun` model |
+10 -12
View File
@@ -1,6 +1,6 @@
# Configuration
Roundtable uses a two-layer configuration system. Only the bare minimum needed to boot lives in files or environment variables. Everything else is stored in the database and managed through the Settings UI.
Steward uses a two-layer configuration system. Only the bare minimum needed to boot lives in files or environment variables. Everything else is stored in the database and managed through the Settings UI.
---
@@ -10,31 +10,29 @@ These three values are read at startup from `config.yaml` and/or environment var
| Key | Env var | Default | Description |
|---|---|---|---|
| `database.url` | `ROUNDTABLE_DATABASE_URL` | — | PostgreSQL async URL. **Required.** |
| `secret_key` | `ROUNDTABLE_SECRET_KEY` | auto-generated | Flask/Quart session signing key. Auto-generated and saved to `/data/secret.key` if not set. |
| `plugin_dir` | `ROUNDTABLE_PLUGIN_DIR` | `plugins` | Path to the plugins directory. |
| `database.url` | `STEWARD_DATABASE_URL` | — | PostgreSQL async URL. **Required.** |
| `secret_key` | `STEWARD_SECRET_KEY` | auto-generated | Flask/Quart session signing key. Auto-generated and saved to `/data/secret.key` if not set. |
| `plugin_dir` | `STEWARD_PLUGIN_DIR` | `plugins` | Path to the plugins directory. |
**Resolution order for `database_url`:** env var `ROUNDTABLE_DATABASE_URL` → env var `ROUNDTABLE_DATABASE__URL` (legacy double-underscore) → `database.url` in `config.yaml`.
**Resolution order for `database_url`:** env var `STEWARD_DATABASE_URL` → env var `STEWARD_DATABASE__URL` (legacy double-underscore) → `database.url` in `config.yaml`.
**Resolution order for `secret_key`:** env var `ROUNDTABLE_SECRET_KEY``secret_key` in `config.yaml``/data/secret.key` file → auto-generate and write to `/data/secret.key`.
**Resolution order for `secret_key`:** env var `STEWARD_SECRET_KEY``secret_key` in `config.yaml``/data/secret.key` file → auto-generate and write to `/data/secret.key`.
### Minimal config.yaml
```yaml
database:
url: "postgresql+asyncpg://user:password@localhost/roundtable"
url: "postgresql+asyncpg://user:password@localhost/steward"
```
### Minimal env-only setup (Docker)
```bash
ROUNDTABLE_DATABASE_URL=postgresql+asyncpg://user:password@db/roundtable
STEWARD_DATABASE_URL=postgresql+asyncpg://user:password@db/steward
```
A `.env` file is loaded automatically if present.
> **Legacy env vars:** `FABLEDSCRYER_*` env vars are still accepted as a fallback for existing deployments. They will be removed in a future release — migrate to `ROUNDTABLE_*` when convenient.
---
## App Settings (Database-backed)
@@ -68,7 +66,7 @@ Default webhook template:
### Reading and Writing Settings in Code
```python
from roundtable.core.settings import get_setting, set_setting
from steward.core.settings import get_setting, set_setting
# Read
async with current_app.db_sessionmaker() as session:
@@ -84,7 +82,7 @@ async with current_app.db_sessionmaker() as session:
### The DEFAULTS Dict
`roundtable/core/settings.py` contains the `DEFAULTS` dict — the canonical list of all recognised settings and their default values. Add new settings here to make them recognised by `get_all_settings()` and the settings UI.
`steward/core/settings.py` contains the `DEFAULTS` dict — the canonical list of all recognised settings and their default values. Add new settings here to make them recognised by `get_all_settings()` and the settings UI.
---
+7 -7
View File
@@ -1,13 +1,13 @@
# Core Monitors
Roundtable ships two built-in monitors: Ping and DNS. Both run as asyncio scheduled tasks on the same event loop as the web server, with no separate processes.
Steward ships two built-in monitors: Ping and DNS. Both run as asyncio scheduled tasks on the same event loop as the web server, with no separate processes.
---
## Ping Monitor
**Source:** `roundtable/monitors/ping.py`
**Scheduler task:** `ping_monitor` in `roundtable/app.py`
**Source:** `steward/monitors/ping.py`
**Scheduler task:** `ping_monitor` in `steward/app.py`
**Interval:** `monitors.poll_interval_seconds` (default 60s), runs on startup
### How It Works
@@ -29,7 +29,7 @@ Each probe writes a `PingResult` row and calls `record_metric()`:
### Data Model
`ping_results` table (defined in `roundtable/models/monitors.py`):
`ping_results` table (defined in `steward/models/monitors.py`):
| Column | Type | Description |
|---|---|---|
@@ -51,8 +51,8 @@ Old rows are pruned by the `data_cleanup` task (default: 90 days).
## DNS Monitor
**Source:** `roundtable/monitors/dns.py`
**Scheduler task:** `dns_monitor` in `roundtable/app.py`
**Source:** `steward/monitors/dns.py`
**Scheduler task:** `dns_monitor` in `steward/app.py`
**Interval:** `monitors.poll_interval_seconds` (default 60s), runs on startup
### How It Works
@@ -70,7 +70,7 @@ Each check writes a `DnsResult` row and calls `record_metric()`:
### Data Model
`dns_results` table (defined in `roundtable/models/monitors.py`):
`dns_results` table (defined in `steward/models/monitors.py`):
| Column | Type | Description |
|---|---|---|