Contributing to the Documentation¶
Architecture¶
Mnemosyne assembles documentation from all three repos into a single MkDocs Material site.
┌────────────────────────┐ ┌──────────────────────────┐
│ aletheia/repo/docs/ │ │ │
│ aletheia/repo/ │───▶│ │
│ guidelines/ │ │ build.sh (assembler) │
├────────────────────────┤ │ │
│ helios/repo/docs/ │───▶│ + extract_infra.py │
│ helios/repo/content/ │ │ (config → snippets) │
├────────────────────────┤ │ │
│ aether/repo/docs/ │───▶│ + mkdocs build │
│ aether/repo/*.md │ │ │
└────────────────────────┘ └────────────┬─────────────┘
│
▼
/opt/docker/mnemosyne/site/
→ https://docs.groupe-suffren.com
- Config source (tracked in git):
aether/repo/mnemosyne/ - Runtime output (not tracked):
/opt/docker/mnemosyne/ - Served by nginx at
docs.groupe-suffren.com
Build and Preview¶
cd /opt/docker/aether/repo
make docs-build # assemble + build static site
make docs-serve # assemble + dev server on http://localhost:8888 (live reload)
make docs-deploy # build + deploy nginx config for the site
make docs-check # validate alert→runbook coverage
make docs-serve is the fastest inner loop — edit a markdown file, save, reload the browser.
Where to Put a New Page¶
| Topic | Source location | Appears in nav under |
|---|---|---|
| Developer / infra ops | aether/repo/docs/maintenance/ |
Developer Guide → Maintenance |
| Monitoring | aether/repo/docs/monitoring/ |
Developer Guide → Aether → Monitoring |
| Aether dev conventions | aether/repo/docs/development/ |
(add to mkdocs.yml nav) |
| Aletheia dev / guidelines | aletheia/repo/docs/ or aletheia/repo/guidelines/ |
Developer Guide → Aletheia |
| Helios dev / content | helios/repo/docs/ or helios/repo/content/ |
Developer Guide → Helios |
| French user guide | aletheia/repo/docs/guide-utilisateur/ |
Guide Utilisateur |
| French admin guide | aletheia/repo/docs/guide-admin/ |
Guide Administrateur |
After adding a markdown file, also add it to the nav: block in aether/repo/mnemosyne/mkdocs.yml
so it shows up in the navigation.
Convention: Code Comments Hold the "Why"¶
The authoritative source for why a config value exists is a comment in the config file, not the documentation. This keeps rationale co-located with the setting it explains.
Good:
# 1-hour ban is long enough to deter bots but short enough that a
# self-ban doesn't require on-call intervention (just wait it out).
bantime = 1h
Bad (rationale only in docs):
When editing a config file, enrich the comments if you change a value or notice missing rationale. Future readers — including Claude — use those comments to judge whether a change is safe.
Convention: Docs Include, Don't Duplicate¶
Factual data (container names, versions, memory limits, ports, retention values, alert names, thresholds) must never be hardcoded in docs. Use auto-generated snippets instead.
Good:
## Monitoring Stack
<!-- Auto-generated from monitoring/docker-compose.yml -->
<!-- Auto-generated by extract_infra.py — do not edit -->
| Container | Image | Memory Limit |
|---|---|---|
| `monitoring_prometheus` | `prom/prometheus:v3.10.0` | 384m |
| `monitoring_grafana` | `grafana/grafana:12.4` | 384m |
| `monitoring_node_exporter` | `prom/node-exporter:v1.10.2` | 64m |
| `monitoring_cadvisor` | `gcr.io/cadvisor/cadvisor:v0.55.1` | 128m |
| `monitoring_postgres_exporter` | `prometheuscommunity/postgres-exporter:v0.19.1` | 48m |
| `monitoring_redis_exporter` | `oliver006/redis_exporter:v1.82.0` | 48m |
| `monitoring_blackbox_exporter` | `prom/blackbox-exporter:v0.26.0` | 64m |
| `monitoring_loki` | `grafana/loki:3.6` | 384m |
| `monitoring_alloy` | `grafana/alloy:v1.14.1` | 384m |
| `monitoring_nginx_exporter` | `nginx/nginx-prometheus-exporter:1.4` | 32m |
| `monitoring_celery_exporter` | `danihodovic/celery-exporter:0.10.10` | 128m |
Bad:
## Monitoring Stack
| Container | Image | Memory |
|---|---|---|
| prometheus | prom/prometheus:v3.10.0 | 384m |
...
The first pattern auto-updates when configs change. The second drifts silently.
Available snippets¶
Generated into _generated/ on every make docs-build. Include with --8<-- "_generated/<name>.md".
| Snippet | Source |
|---|---|
monitoring-stack.md |
monitoring/docker-compose.yml |
shared-services.md |
shared/docker-compose.yml |
alert-catalog.md |
monitoring/prometheus/alerts/*.rules.yml |
backup-scope.md |
backups/scripts/backup.sh |
makefile-targets.md |
Makefile help text |
retention-periods.md |
multiple (docker-compose, loki, backup) |
monitored-domains.md |
monitoring/prometheus/prometheus.yml |
ssh-config.md |
security/sshd-00-hardening.conf |
fail2ban-jails.md |
security/fail2ban-aletheia.conf |
kernel-hardening.md |
security/sysctl-hardening.conf |
firewall-rules.md |
security/iptables-setup-docker.sh |
Adding a new extractor¶
If you need a snippet for data that's not yet covered:
- Add a function to
mnemosyne/scripts/extract_infra.pyfollowing the existing pattern - Register it in the
EXTRACTORSdict at the bottom of the file - Run
python3 mnemosyne/scripts/extract_infra.py <repo> /tmp/checkto verify output - Include the new snippet in the relevant doc via
--8<--
Convention: Alert Rules Need Runbooks¶
Every alert defined in monitoring/prometheus/alerts/*.rules.yml must have a matching entry in
docs/monitoring/runbooks.md. The make docs-check target validates this, and the pre-commit
hook runs it automatically when alert rule files are staged.
When adding a new alert rule:
- Define the rule in the appropriate
*.rules.ymlfile - Add a runbook section to
docs/monitoring/runbooks.md— at minimum, what the alert means and the first thing to check - Commit together. If you forget step 2, the pre-commit hook will warn.
Markdown Conventions¶
- Heading hierarchy: top-level
#matches the page title once. Use##for sections. - Admonitions: use
!!! warning,!!! danger,!!! note,!!! tip,!!! info. Reservedangerfor data-loss or security risks. - Code blocks: always specify the language (
```bash,```yaml,```markdown) for syntax highlighting. - Commands: show the full command with the directory context if it matters.
Prefer
cd /opt/docker/aether/repo && make fooovermake foo. - File paths: use backticks for inline paths (
`docs/maintenance/backups.md`). - Links: use relative markdown links within the same section (
[backups](backups.md)); absolute paths only for external references.
Testing Locally¶
Always preview changes before committing:
The dev server re-assembles on every file change, so edits show up immediately.
Build Warnings¶
make docs-build emits warnings for broken links, missing nav entries, and bad references.
Some are pre-existing (cross-repo archive links) but don't add new ones. Fix new warnings
before committing.
Enforcement Summary¶
| Rule | Enforced by |
|---|---|
| Every alert has a runbook | make docs-check + pre-commit hook |
| Factual data comes from configs, not hardcoded | Code review + docs_check.sh drift detection |
| Config rationale lives in comments | Code review |
| New page appears in nav | make docs-build warnings |
| Links resolve | make docs-build warnings |