Releases: loobric/loobric-server
Release list
loobric-server 0.15.2 — Docker volume fix
Packaging fixes for the container images introduced in 0.15.1.
Fixed
- Named-volume permissions.
/app/datais now created inside the image owned by the app user, so the README quickstart (docker run -v loobric-data:/app/data …) works out of the box. The 0.15.1 image died withunable to open database fileon a fresh named volume (Docker created it root-owned; the server runs as uid 1000). - Runtime version string. 0.15.1 shipped self-reporting as 0.15.0 (
loobric_server/version.pywasn't bumped)./api/healthand/api/v1/versionnow agree with the release.
Added
- Published images bake the build commit (
LOOBRIC_COMMIT), so/api/v1/versionreports the exact commit instead ofunknown.
If you pulled the 0.15.1 image, replace it with 0.15.2.
loobric-server 0.15.1 — Docker images
Packaging-only release: the server now ships as a container with every release.
Added
- Docker images as release assets. A multi-arch (amd64 + arm64) image is published to GitHub Container Registry —
ghcr.io/loobric/loobric-servertagged0.15.1,0.15,latest— and the same image is attached below as adocker savetarball (loobric-server-0.15.1-docker-amd64.tar.gz) for offline / air-gapped installs (docker load < …). - README "Run with Docker" section: a single
loobric-datavolume holds both the SQLite database and the media store (MEDIA_DIR=/app/data/media).
Fixed
.dockerignoreleak. The build excluded*.dbbut notloobric.db.pre-migration-*.bakbackups,.git/, or the local media directory. All are now excluded from the image.
No server behavior changes.
loobric-server 0.15.0 — batch sync doors
Added
- Batch sync doors (
docs/BATCH_SYNC.md, grilled 2026-08-17):POST /tool-instance-records/syncandPOST /tool-catalog-records/sync— upsert many records in ONE transaction per batch (cap 200). Items compose the existing doors:data(sync lane),asserts(the assert door's shared code path, every guard included),presets(the contribution door: floor + replace-own). Per-item outcomes (created | updated | unchanged | exists | error) in request order;?include=recordsopt-in; merge-only — deliberately no snapshot mode. Scopes compose per lane: a sync-only key gets blocked/skipped counts, never a rejected batch. Catalog natural-key matches areexists: no canonical writes, but the client's own section still syncs. OneSYNC_BATCHaudit row per batch plus the per-entity rows as before.
Changed
- Same-value asserts are now no-ops on the single-record assert doors (value + unit + actor all matching the stored leaf): re-syncs are idempotent end to end — no source overwrite, no version bump, no audit churn. A different actor's identical value still applies in full, so corroboration stays a recorded provenance claim. This is the release's one behavior change.
Why: a 327-tool CAM library import was ~2,600 requests ≈ 11 minutes against SQLite's single writer even with 8 parallel client workers; through the door it is 3 requests ≈ 4 seconds. Pairs with loobric-cli 1.8.0 (sync_tool_records() / sync_catalog_records()).
loobric-server 0.14.0 — catalogs, dashboard, account backup
Added
- Catalogs: named collections of catalog records (grilled 2026-08-16 — the one-giant-pile problem). A Catalog is a sectioned record (
canonical.name+ provenance-taggedmembers) at/api/v1/catalogs. Membership is organization, never identity: many-to-many, uncataloged records allowed (surfaced as Uncataloged), deleting a catalog deletes no records, and the account-wide natural key is untouched. Importers auto-catalog each run — records land in a catalog named from the source, idempotently. The Web UI Catalog tab groups by catalog; each record's page gets a membership checklist. - Account backup:
GET /api/v1/account/export— the owner-operated escape hatch (first slice of #46): one zip with every record collection as sectioned JSON, labels, referenced media blobs, and a manifest. The Account tab gains a "Download backup (.zip)" card.
Changed
- Web UI:
/ui/lands on a dashboard — attention first (pending proposals, NOT READY setups), then count cards per area, then a map of how the pieces fit. - Web UI: every list is a table (presets-table style) with browse-level row actions: tools (rename/retire/delete), machines, tool sets, catalog records, set members, and the Labels lists.
- Web UI: all label printing lives on the Labels tab — blank labels plus a spec-label section with one kind combo (spec QR+specs / spec plaque / inventory QR-only), stock picker, and tool multiselect with select-all/deselect-all.
- DEPLOYMENT.md: media persistence is part of the sample compose — the database volume alone does not persist media; a redeploy without a
MEDIA_DIRvolume silently discards every blob.
Removed
- The v1
ManufacturerCatalogtable and router (an R6 slice): deep-model substrate unreachable from the v2 facade, squatting on the name and route the first-class Catalog needed. Migration 0008 drops the table; v1 rows are pre-facade data, deliberately not migrated.
loobric-server 0.13.0 — cutting data presets
Added
- Cutting data presets (
docs/PRESETS.md; grilled & ratified 2026-08-16) — F&S as recommendations with a source, never facts about the tool. Canonicalpresetson catalog and instance records is a derived, normalized union of source-preserved contributions (derived:preset-union): the server never reconciles — FreeCAD's conservative chipload and the manufacturer's aggressive chart both stay, origin-tagged, and identical values from two origins are corroboration, not duplicates. Normal formpreset_schema: 1= G5 engineering values (Vc, Fz, vertical-feed ratio, verbatim material, ratifiedop_type) + a verbatim extras bag; raw feed/RPM are never persisted. Contributions enter through the audited doorPOST /tool-{catalog,instance}-records/{id}/presets(assert scope; replace-own on(origin, label); removal rides the delete door), with clients promoting their own translations — the sync lane stays pure passthrough. Instance preset listings union the linked catalog type's entries at read time, scope-marked. The Web UI record detail gains a full-CRUD preset table. Migration 0007 adds the contribution table; "cutting data preset" and the op_type taxonomy join the glossary; design details indocs/TOOL_SCHEMA.md§7.9.
Fixed
- Web UI unusable with
AUTH_ENABLED=false: the audit-logs and changes routers 401'd under disabled auth, and the SPA treats any single 401 as signed-out. Both now honor all three auth modes (enabled / solo / disabled).
loobric-server 0.12.0 — wider cut, honest silhouettes
Changed
thermal-4x6-wideis now 57×32mm, 4-up (was 50×25mm, 6-up): the single column matches the thermal-57x32 roll footprint, so spec labels on it get the roomy layout — full DIA/FL/LOC/OAL table and the silhouette — instead of the compact one-liner.- Silhouette shape families —
probe(stylus + ball tip),slittingsaw(thin blade on an arbor),dovetail(reverse taper), andbullnose(rounded corners) now draw honest profiles instead of the generic endmill rectangle;countersink,engraver, andtapjoin the pointed family. Probes and saws skip flute-line hatching, and their missing shank-diameter/LOC values get shape-appropriate defaults.
loobric-server 0.11.0 — spec labels
Added
- Spec labels (docs/SPEC_LABELS.md; grilled & ratified 2026-08-15) — printed spec plates for at-the-toolbox identification: a spec label is a rendering of a record (not a Label; the QR is one optional element).
POST /api/v1/spec-labels/sheet(read door — printing never mints) renders owned instance records with two canned templates (qr-specs,spec-plaque) on the existing sticker stocks plus three provisional plaque stocks, or exports the resolved print data as JSON/CSV for bring-your-own-layout printing. Values are the merged view (measured wins over nominal, differences marked*), T# is the bound entry's snapshot, and the tool image is a silhouette derived from geometry. Unlabeled records under a QR template are a 400 naming the ids; a record's newest label prints by default, overridable per record. The Web UI Tools tab grows a "Print spec labels" bar (multi-select, template + stock, inline label-these-first prompt). Ratified printed vocabulary (DIA/FL/LOC/OAL/T#/Ø/*,length= OAL,cutting_edge_height= LOC) added toUBIQUITOUS_LANGUAGE.md. thermal-4x6-widestock — the 4″×6″ thermal sheet cut as a single column of six 50×25mm labels (the plaque-50x25 footprint), with cut guides including the grid outline. Available to both/labels/sheetand/spec-labels/sheet.
Removed
- Legacy
/api/v1/tool-presetsand/api/v1/tool-usagerouters, ORM models, and tables (first REBOOT R6 slice). Both were retiring v1 substrate, already hidden from the OpenAPI contract. Migration 0006 drops both tables; v1 rows are pre-facade data and are deliberately not migrated.
🤖 Generated with Claude Code
loobric-server 0.6.1 — security assumptions ledger
Added
docs/SECURITY_ASSUMPTIONS.md— every security assumption mapped to the test that proves it, with the standing rule: a new assumption lands with its row and its test in the same commit. Includes the ranked not-yet-covered list (rate limiting doesn't exist; CSRF untested) and the post-mortem of how unenforced scopes shipped.- Missing security tests closed: bind door, negative sync, admin door, and first-ever cross-account isolation tests over HTTP (session + fully-scoped key, all five entities). All passed on first run — correct but previously unproven.
Deploy note: this includes 0.6.0's BREAKING scope enforcement — existing API keys become read-only until rotated (loobric create-key --preset agent|controller|cam|full).
loobric-server 0.6.0 — API key scopes enforced (BREAKING)
⚠️ BREAKING: API key scopes are now enforced — legacy keys become READ-ONLY
Scopes existed since v1 but no v2 endpoint ever checked them. 0.6.0 makes scopes real, aligned with the doors (SCOPES_PLAN, grilled 2026-07-27):
- The seven scopes ARE the doors:
read,sync,observe,assert,bind,delete,admin. Every public endpoint checks the calling key; the 403 names the missing scope. - The canonical AI-agent key is
read sync assert— an agent's credential physically cannot observe, bind, or delete, even through a raw client that bypasses the MCP surface. "Agents assert, never observe" is now a credential property. - Legacy keys degrade to read-only with a message telling you to create a new key. Rotate your keys after upgrading (controller push keys, MCP keys, importer keys).
- Creating a key requires explicit door scopes (400 otherwise); the Web UI gains presets (AI agent / Controller / CAM client / Full) and a "legacy · read-only" badge.
- Keys cannot manage keys — key creation/revocation and password change require a session (or solo mode); a key can never create itself a stronger key.
- Composite rule:
qaon create-instance (writesobserved:manufacturer@…) additionally requiresobserve. Tool-table-entry create/push requiresobserve— an agent key cannot fabricate machine state. - Sessions and solo mode are unscoped — a signed-in human may use every door; admin surface still requires the admin role.
Added
- Audit rows record the acting credential:
channel(session / api-key / solo) +api_key_id(migration 0002). The declared actor is client-supplied; these are server truth — a spoofed actor is detectable with one query. GET /auth/mereturns the calling key's effective scopes (API-key auth), so clients likeloobric-mcpcan introspect their own credential.- Glossary Scope (API key) entry;
docs/AUTHENTICATION.mdrewritten for the door model.
loobric-server 0.5.1 — client data visible in the Web UI
Added
- Web UI: client sections are now visible. The catalog detail view gains a Client data section showing what each client recorded in its own section — importer source attributes, agent caveats ("part number unconfirmed"), prices, source URLs — verbatim, outside the canonical spec. Previously stored but invisible outside the raw schema JSON.
Fixed
- Web UI copy named the CLI
loobric_serverin four places; it isloobric.