v0.5.8
Upgrade notes
Breaking changes
None.
Upgrade notes
The standard flow applies:
cd /opt/pinchy
sed -i 's/PINCHY_VERSION=v0.5.7/PINCHY_VERSION=v0.5.8/' .env
docker compose pull && docker compose up -d && docker image prune -fAutomatic migration off the default database password
The default pinchy_dev database password is public in our repository, so running on it was never real protection. Starting with v0.5.8, installations that never set DB_PASSWORD are migrated automatically on their first boot after the upgrade: Pinchy generates a strong password, persists it in the pinchy-secrets Docker volume (the same place the encryption key already lives), and applies it to PostgreSQL — no action required, no downtime beyond the normal upgrade restart.
- If you set
DB_PASSWORDin.env: nothing changes. Your value always wins — and if you ever set it without updating PostgreSQL itself, Pinchy now applies it for you on the next boot instead of failing to connect. - If you never set
DB_PASSWORD: the migration runs once, invisibly. Settings → Security shows the database password as Auto-generated (Docker volume), andGET /api/healthreports"db_password": "generated". - Backups keep working: the documented
docker compose exec db pg_dump …flow authenticates over the container's local socket and does not need the password. - Heads-up for direct TCP access: if you connect to the database from the host with the old default password (custom scripts, DB GUIs), switch them to the managed credential or pin your own
DB_PASSWORDin.env— Pinchy will apply it on the next restart.
See where your secrets come from
Settings → Security gains a Secrets card showing where each secret comes from — environment variable, persisted file in the Docker volume, or not created yet. The same information is available from the shell via GET /api/health (a new secrets object with provenance values only — never the secrets themselves). This makes the auto-generated file fallback visible from outside the container, so you can tell "secret loaded from the volume" apart from "no secret at all" before rotating anything.
License now fails closed on expiry, with seat grace and renewal prompts
Enterprise licensing was reworked so an expired key can never silently widen access. The change is behavioural — nothing to configure — but worth knowing:
- Fail-closed expiry. When a license lapses, restricted agents stay restricted and group-based access keeps being enforced. Pinchy never falls back to "everything visible to everyone." All data is untouched; entering a new key re-activates management instantly.
- 30-day grace for paid keys. A paid key keeps working for 30 days past its paid-until date (trial keys expire immediately at their expiry). After grace, existing restrictions hold and management operations (creating/editing groups, changing agent visibility, analytics export) lock until a new key is entered. Restriction-tightening always works without a license — an admin can still remove users from groups or deactivate them at any time.
- Seat grace. Invites keep working up to 20% over your seat count; beyond that, new invitations pause (existing users are never deactivated). The seat counter and an inline notice make the headroom visible.
- Renewal prompts. The license banner now shows trial days remaining (dismissible per session) and a renewal reminder starting 14 days before a paid key expires; gated feature cards link to renewal.
Chat survives tab switches and reconnects without crashing
Backgrounding a chat tab mid-reply and returning to it — or any reconnect while a run is still streaming — no longer trips the "Something went wrong" error screen. The chat view now keeps a stable in-flight assistant slot across the WebSocket reconnect, so disconnect, timeout, and resume transitions never leave the message list in the index-mismatch state that produced the crash. Nothing to configure; reload any chat tab left open across the upgrade once.
Smarter model and attachment handling
- PDFs are never wrongly blocked. Pinchy used to gate PDF attachments on a model "documents" capability that didn't reflect reality — PDFs are routed through OpenClaw's
pdftool, not the model's native input. The false block is gone; PDFs attach and work regardless of the model's native document support. - Model changes are validated. Updating an agent's model now rejects a model whose provider isn't configured (no API key) with a clear
400, instead of silently leaving the agent unable to chat. Leaving the model unchanged (e.g. a name-only edit) still works even if its provider was since disconnected. - Ollama Cloud catalog reconciled with the live model list — newly tool-reliable models added, known-broken ones kept out. No action required; the list refreshes from the built-in catalog.
Sturdier DOCX ingestion
DOCX uploads are now guarded against decompression ("zip bomb") attacks on two layers — a pre-decompress size check and a post-decompress cap — and malformed/ZIP64 archives are rejected fail-closed. Ordinary documents are unaffected.
Dependencies
- OpenClaw 2026.6.5 (was 2026.5.28) — picked up via
Dockerfile.openclaw, surfaced inGET /api/version. Same protocol train; backward-compatible patch bump. - esbuild ≥ 0.28.1 — a transitive build-time dependency, bumped to clear GHSA-gv7w-rqvm-qjhr (CVSS 8.1). Build-tooling only; nothing ships it to production or to operators.
Database migrations
0038 drops the unused documents/audio/video columns from the models capability table (they had no consumer — see the PDF-routing note above). Additive cleanup, runs automatically on startup, no manual steps and no data you'd miss.
What's Changed
- ci: retry GHCR pulls of pre-built images via composite action by @clemenshelm in #485
- fix(chat): own in-flight placeholder kills the optimistic-message crash class (tab-refocus tapClientLookup) by @clemenshelm in #488
- fix(pinchy-files): bound DOCX decompressed size against zip bombs by @clemenshelm in #486
- fix(openclaw): bump runtime to 2026.6.5 and de-flake the E2E suite at root cause by @clemenshelm in #467
- fix(attachments): PDFs are tool-routed — delete the documents capability, fix the recovery dropdown, validate model updates by @clemenshelm in #491
- docs(model-resolver): pin gemini tool-block rationale to family-level leak evidence by @clemenshelm in #492
- feat(security): fail closed on default DB password + secret provenance in /api/health & Settings by @clemenshelm in #487
- feat: in-app conversion CTAs, seat grace, and fail-closed license expiry (pricing Phase A) by @clemenshelm in #490
- fix(models): reconcile Ollama Cloud catalog with the live model list by @clemenshelm in #489
- docs(connect-odoo): App-Store-Modul Pinchy Connector erwähnen by @clemenshelm in #493
- fix(security): bump esbuild to >=0.28.1 (GHSA-gv7w-rqvm-qjhr) — unblock osv-scan on main by @clemenshelm in #494
- docs(upgrading): complete v0.5.8 upgrade notes by @clemenshelm in #495
- fix(models): gate the tools-blocklist in the agent model picker and write path by @clemenshelm in #497
- fix(openclaw): disable native pre-compaction memory flush by @clemenshelm in #496
- docs(glossary): AI agent concept hub (5 GEO definition pages) by @clemenshelm in #499
- docs(readme): marketing overhaul (badges, hero, comparison table, quick-start, star-history) by @clemenshelm in #498
- docs(glossary): batch 2 — 5 more definition pages (GEO data-void) by @clemenshelm in #502
- fix(deps): clear 10 OSV advisories (js-yaml, vite, @babel/core, protobufjs, tar) by @clemenshelm in #505
- feat(usage): lossless per-turn token accounting from the trajectory (#483) by @clemenshelm in #504
- fix(attachments): read PDFs via pinchy_read, not OpenClaw's broken built-in pdf tool by @clemenshelm in #500
- docs(releases): Releases page pulled live from GitHub Releases (DRY) by @clemenshelm in #503
- fix(deps): bump docs dompurify override to >=3.4.6 (GHSA-hpcv-96wg-7vj8, GHSA-r47g-fvhr-h676) by @clemenshelm in #506
- ci: add workflow_dispatch trigger to the CI workflow by @clemenshelm in #507
Full Changelog: v0.5.7...v0.5.8