chore: sanitize MobilityOps operational evidence and public boundary #8

Merged
Jens merged 17 commits from chatgpt/repo-hygiene-mobilityops into master 2026-09-01 12:29:26 +00:00
Showing only changes of commit 97b8cd1c8c - Show all commits
+38 -62
View File
@@ -1,88 +1,64 @@
# Demo runbook
## Starting the demo (any environment)
## Starting the demo
Open the deployed URL (Unraid review: `http://192.168.10.150:1236`; local:
`http://localhost:1228`). The login screen names the fictional organisation, states that
all data is synthetic and all workflows are really implemented, and offers:
Open the configured deployment URL, for example `https://fleetops.example.com`, or `http://localhost:1228` for local development. The login screen names the fictional organisation, states that all data is synthetic and offers:
- **Start begeleide demo** — logs in as Operations Manager and opens the Demo Guide at
step 1.
- **Verken als Operations Manager** / **Verken als Rental Employee** — free exploration,
no guide.
- **Start begeleide demo** — logs in as Operations Manager and opens the Demo Guide at step 1;
- **Verken als Operations Manager** / **Verken als Rental Employee** — free exploration without the guide.
No password is shown or required for either path.
No password is shown or required for either synthetic-demo path.
## Five-minute demo (guided)
## Five-minute demo
1. Click **Start begeleide demo**.
2. Follow steps 13: dashboard → the booking needing attention → confirm the pre-filled
odometer-anomaly return.
3. Step 4: resolve the data-quality issue the return just created (any decision is fine
for a quick pass — "Retain canonical" is the fastest).
4. Step 6: ask a suggested knowledge question and show the cited source.
5. Step 7: show the automation/audit trail link-through.
6. Close with step 8, the About page's honest real/synthetic/not-connected breakdown.
2. Follow steps 13: dashboard, booking needing attention, and the pre-filled odometer-anomaly return.
3. Resolve the data-quality issue created by the return. “Retain canonical” is the fastest demonstration path.
4. Ask a suggested knowledge question and show the cited source.
5. Show the automation/audit-trail link-through.
6. Close with the About pages real/synthetic/not-connected breakdown.
## Ten-minute demo (guided + one extra scenario)
## Ten-minute demo
Do the five-minute path above, then from `/scenarios`:
Complete the five-minute path, then use `/scenarios`:
- Run **scenario 2** (duplicate customer merge) if not already done via the guide's own
step 5.
- Run **scenario 3** (booking overlap) — `/data-quality`, resolve `DQ-DEMO-OVERLAP`.
- Run **scenario 4** (failed automation retry) — `/automation`, filter to failed, retry.
- scenario 2: duplicate customer merge;
- scenario 3: booking overlap, resolved through `/data-quality`;
- scenario 4: failed automation retry through `/automation`.
All five scenarios can be run in any order and are independent of each other.
All scenarios are deterministic and independent after a reset.
## Resetting the environment
Any Operations Manager can reset from: the sidebar ("Reset demo data"), the Demo Guide
panel ("Demo opnieuw voorbereiden"), or the About page (points to the sidebar control).
Reset requires confirmation, rebuilds the deterministic dataset with a fresh date anchor,
runs a server-side scenario-integrity check, and signs the acting session out (the server
invalidates the session as part of reset). It only ever touches MobilityOps's own tables
— never shared n8n, RAGcore, or MCP data, other containers, or volumes. It can be
disabled entirely via `DEMO_ALLOW_RESET=false` if an environment must not be rebuildable.
An Operations Manager can reset from the sidebar, Demo Guide or About page. Reset requires confirmation, rebuilds only the deterministic MobilityOps dataset, runs a server-side integrity check and invalidates the acting session. It never mutates shared n8n, RAGcore, MCP data, unrelated containers or volumes. Disable reset entirely with `DEMO_ALLOW_RESET=false` where required.
## Redeploying to Unraid
## Deployment contract
```bash
# From a clean local checkout on the exact commit:
git archive --format=tar.gz -o /tmp/mobilityops-source.tar.gz HEAD
sha256sum /tmp/mobilityops-source.tar.gz
scp /tmp/mobilityops-source.tar.gz unraid:/mnt/user/appdata/mobilityops/.deploy/
ssh unraid "/mnt/user/appdata/mobilityops/deploy/unraid/deploy-release.sh \
/mnt/user/appdata/mobilityops/.deploy/mobilityops-source.tar.gz \
<archive-sha256> <full-git-sha>"
```
Create a source archive from the exact reviewed commit, record its SHA-256 and full Git SHA, transfer it through the operator-approved channel, and invoke `deploy/unraid/deploy-release.sh` with those immutable identifiers.
The deployer verifies the archive checksum, extracts into a new commit-named release
directory, builds revision-labelled immutable images, promotes without reseeding, and
checks application, backup and observability health. Reset demo data only as a separate,
deliberate demo-preparation action.
Keep the following values in operator-local configuration rather than repository documentation:
- deployment host or SSH alias;
- SSH key selection;
- persistent appdata directory;
- public application URL;
- n8n and RAGcore endpoints;
- tokens and callback secrets.
An Unraid installation commonly uses a path such as `/mnt/user/appdata/mobilityops`, but that is an example only. See `deploy/unraid/README.md` for the parameterized deployment layout.
The deployer verifies the archive checksum, extracts into a commit-named release directory, builds revision-labelled immutable images, promotes without reseeding and checks application, backup and observability health. Reset demo data only as a separate deliberate action.
## Rollback
`.deploy/source-revision` and `.deploy/release-history.log` record the live commit and
image tags. A failed readiness check automatically restores the previous image IDs.
Database rollback remains a separate, explicitly guarded restore operation.
`.deploy/source-revision` and `.deploy/release-history.log` record the live commit and image tags. A failed readiness check restores the previous image IDs. Database rollback remains a separate explicitly guarded restore operation.
## Server safety (Unraid)
## Server safety
Only touch the `mobilityops` Compose project's own `api`/`web` services (and `db` only
via migrations, never manually). Never stop other containers, run `docker system prune`,
delete unrecognised images/networks/volumes, delete the MobilityOps database, overwrite
the server `.env`, print secrets, start a second permanent n8n instance, or activate
guessed RAGcore/MCP URLs. PostgreSQL is never exposed externally.
Only touch the `mobilityops` Compose projects own `api` and `web` services, and interact with `db` only through migrations or the guarded backup/restore flow. Never stop unrelated containers, run broad Docker pruning, delete unrecognised resources, overwrite the server `.env`, print secrets, start a second permanent n8n instance or activate guessed integration URLs. PostgreSQL must remain unexposed.
## Troubleshooting
- **A scenario shows "Niet beschikbaar" on `/scenarios`**: it has already been resolved
since the last reset (expected once you've worked through it) — reset to restore it.
- **Knowledge question returns "insufficient evidence"**: use a suggested question in
NL, EN or FR and inspect provider health/citations; the adapter refuses ungrounded
answers when RAGcore is slow, unavailable or lacks evidence.
- **n8n shows a failed delivery that isn't the seeded demo one**: check `/automation`'s
filter and retry — bounded retries mean it should self-heal within
`n8n_max_attempts` attempts, or can be retried manually by an Operations Manager.
- **Scenario unavailable:** it was already resolved since the last reset; reset the synthetic dataset.
- **Knowledge question returns insufficient evidence:** use a suggested question and inspect provider health/citations; the adapter refuses ungrounded answers.
- **Unexpected failed n8n delivery:** use the automation view and bounded retry path; inspect operator-side n8n logs without committing them.