Runbook for operating, inspecting, backing up, and recovering SQLite-backed profile registry storage.
Run pinocchio/geppetto apps with durable SQLite profile registry storage, verify read and schema discovery endpoints, and keep safe backup/recovery procedures.
/api/chat/profiles...).--profile-registries ./data/profiles.db) or explicit DSN source entry (--profile-registries sqlite-dsn:<dsn>).Preferred file-path form:
pinocchio web-chat --profile-registries ./data/profiles.db
Equivalent DSN form:
pinocchio web-chat \
--profile-registries "sqlite-dsn:file:./data/profiles.db?_journal_mode=WAL&_busy_timeout=5000&_foreign_keys=on"
curl -s http://localhost:8080/api/chat/profiles | jq .
You should see a JSON profile list, not an empty response body or server error.
Verify schema discovery endpoints:
curl -s http://localhost:8080/api/chat/schemas/middlewares | jq .
curl -s http://localhost:8080/api/chat/schemas/extensions | jq .
You should get JSON arrays. If the arrays are empty unexpectedly, check application startup wiring for middleware definitions and extension schema registration.
Quick contract checks:
curl -s http://localhost:8080/api/chat/schemas/middlewares \
| jq '.[0] | {name,version,display_name,description}'
curl -s http://localhost:8080/api/chat/schemas/extensions \
| jq 'map(select(.key | startswith("middleware."))) | .[0].key'
Expected:
name, version, display_name, description, and schema,middleware.agentmode_config@v1).Middleware config is described through the schema endpoints, even when the app keeps registries read-only.
Quick middleware schema check:
curl -s http://localhost:8080/api/chat/schemas/middlewares \
| jq '.[] | select(.name == "agentmode") | {name,version,schema}'
Quick extension schema check:
curl -s http://localhost:8080/api/chat/schemas/extensions \
| jq 'map(select(.key | startswith("middleware.")))'
Expected:
middleware.agentmode_config@v1,Filesystem snapshot backup:
cp ./data/profiles.db ./data/profiles.db.bak.$(date +%Y%m%d-%H%M%S)
Optional SQL check:
sqlite3 ./data/profiles.db "SELECT slug, updated_at_ms FROM profile_registries ORDER BY slug;"
Example:
cp ./data/profiles.db.bak.20260223-220000 ./data/profiles.db
GET /api/chat/profiles returns expected slugs/default.GET /api/chat/schemas/middlewares and GET /api/chat/schemas/extensions return expected schema catalogs.profile still resolve correctly.| Problem | Cause | Solution |
|---|---|---|
profile_registries table missing | DB initialized outside profile store migration path | restart with app-managed SQLite store initialization |
| writes fail with busy/lock errors | concurrent writers and missing timeout/WAL settings | use DSN with WAL + busy timeout and avoid external long-running transactions |
| restored DB loads but profiles seem stale | restored snapshot older than expected | verify backup timestamp and repeat restore with newer snapshot |
| API returns 500 after restore | payload/schema corruption in DB row | inspect payload_json, restore cleaner snapshot, then reapply desired changes |
| middleware schemas endpoint unexpectedly empty | app did not register middleware definitions or extension codecs | check runtime bootstrap wiring for schema catalogs |