Changelog

0.6.0, 2026-09-11

Everyday editing: find records, change them directly, or gather changes in a change set and publish them together.

Releases are numbered by plan, not by date, so a higher number can ship before a lower one. All releases

Full changelog

Released 2026-09-11. This release was not tagged in the repository. This is the changelog's own text for the release; its links to files point at those files at the tag.

Changed

  • Implemented WP8.1-A model authority boundaries. Compatibility now examines all authoritative live objects, attributes and relations, including catalogue-retired workspaces. Draft and historical reads resolve their pinned supported model before filters, typed responses and relation expansion; missing, corrupt or unsupported pins and workspace-context mismatches return structured errors.

  • WP8.1-B captures an immutable current-live draft base including post-publication edits, model and record versions, with live data that has no prior publication. Historical source remains separate.

  • WP8.1-C delivers newest-first revision history with deterministic cursor retry. Designation retirement preserves live access and history; catalogue retirement rejects writes.

  • Reviewed the uncommitted WP8 implementation against the live/draft API contracts. Corrected activation and cascade deletion ordering, association confirmation and ownership checks, atomic draft version claims, public relation UUID reads, retired-workspace publication guards, and read-only attribute handling, draft containment validation and cross-workspace ID collisions. Added request-boundary and audit-migration regression coverage. Cascade confirmation now requires the signed token from the exact displayed preview and rejects any intervening hierarchy change with no deletion or audit side effects. Missing tokens are rejected before stale-version checks, draft deletion verifies the route object type, live deletion serializes against workspace retirement and inconsistent cross-workspace graph edges are refused. The frontend adapter carries both live and draft confirmation context.

  • Reconciled technical documentation and delivery planning with the accepted product stories and GAP-01–GAP-08 answers. ADR-027 consolidates live data, optional copied drafts, immutable history, truthful publication retirement and newest-first history. Corrected API documentation against current payloads and cursor behavior.

  • Implemented ADR-026 live active data writes: the active workspace is live-writable for data. workspaceDraftId is optional on record writes — present stages into the design draft; absent writes directly to the live active object store (record expectedVersion claim + audit, no workspace revision). Active reads resolve the live projection; activation is a delta-merge of the draft onto current live content with per-record version conflict detection (version_mismatch / id_collision / duplicate_edge), merged-graph validation and a merged revision snapshot that preserves live-only records. Restored services/objects.py CRUD functions, services/relations.py helpers and services/deletion.py as the live write path basis; added the workspace-audit seam and a corrective migration widening the audit aggregate_id column to host live object/relation ids. Amends ADR-024/ADR-025 write-context clauses for data content.

  • Corrective Base 0.6 WP6 persistence: workspace drafts and immutable workspace revisions own the staged/historical graph; ADR-026 subsequently restores live-row current-data authority. The migration converts only unambiguous Base 0.5/rejected-WP4 workspace graphs, preserves public object and relation UUIDs, and removes per-object lifecycle persistence.

  • The backend now requires Python 3.14. The local version pin, package metadata, Ruff target, CI runtime, container base image and development documentation all use 3.14; Python 3.12 compatibility is no longer maintained.

  • Frontend structure refactor, phases 0–4 of docs/FRONTEND_STRUCTURE_REFACTOR.md. No API contract, model contract or architectural change. frontend/src is reorganized into app/, features/, ui/, model/, routing/, lib/, types/ and styles/, with every internal import going through an @/ alias. types.ts and utils/model.ts are split by concern behind a barrel, the four overloaded components are split into 28 modules, and styles.css becomes four layers whose built output is byte-identical.

  • The generic view and panel registries are rendered as elements rather than called as functions. Nothing was broken, but a panel component gaining state would have made ObjectDetail's hook order depend on which panels a model declares as visible. The panel registry is keyed by the PanelDefinition discriminant, removing its per-entry casts, and both registries now live in their own modules.

  • Client error handling is consolidated in api/errors. isApiError replaces five untyped casts used to detect optimistic-concurrency conflicts, and errorMessage replaces 36 inline expressions. Seven messages that reached the UI as Error: … now read like every other message.

  • Cursor paging and search debouncing are consolidated into useCursorPages, useCursorFeed and useDebouncedValue, replacing two incompatible paging implementations across seven components.

  • Every dialog shares one modal shell, ui/Modal. Five dialogs previously rebuilt the same backdrop and disagreed about its behavior. ObjectFormDialog, AttributeValueDialog and RelationFormDialog now close on Escape and return focus to whatever opened them; Tab is trapped inside an open dialog; the page no longer scrolls behind one; and two dialogs that carried hardcoded aria-labelledby ids now generate them, so opening two cannot produce duplicate ids.

  • Frontend redesign (UI-01–UI-06). Compact neutral sidebar with workspace/application/view navigation; Browse hierarchy default with browser-local expand/collapse persistence; accessible mobile navigation drawer. Focused collections with search, typed filter popover, sort, display controls, sticky headings, comfortable/compact density and mobile-aware column prioritisation. Full-width record inspector with collection-origin preservation through reload/Back/Forward, contextual action menus, dirty-edit navigation guards and cross-application related-record return. Inline typed field editing with explicit save/cancel, null/removal distinction, saved/error feedback and retained coherent multi-field forms. Pointer and keyboard resizable navigation rail, inspector and table columns with browser-local display preferences. Refined draft catalogue, named-draft strip, consistent error/loading/empty/confirmation treatment and composed desktop/mobile visual review. UI-07 (automated accessibility and visual-regression gates) is deferred to 0.7.

Added

  • WP9 complete generic browser tasks in live, draft and history contexts. Slice A implements live workspace navigation with cursor-position restoration and retry/content preservation. Slice B implements direct live Add/Edit/Delete with typed fields, ordinary relationships and translations, conflict reconciliation and signed deletion confirmation. Slice C implements optional current-live drafts, shared draft authoring, validation, activation and discard with aggregate concurrency and conflict feedback. Slice D implements newest-first immutable history, pinned-model reads, historical draft sources and truthful publication retirement. SC-01–SC-06 and SC-08 have isolated real-backend browser evidence with two configured object types at desktop and 390px mobile widths.

  • WP10 composed release validation: product scenarios exercised against a real browser and backend, including live CRUD without a draft, optional staging, current-live draft bases, concurrency and delta merge, whole-graph atomic failure, live-only compatibility and pinned historical typing. Keyboard/focus/narrow-layout journeys, migration/lifespan, packaging and public-contract checks. Automated accessibility and visual-regression tooling (UI-07) is deferred; manual keyboard and focus checks are recorded.

  • Base 0.6 WP7 corrective CRUD restoration: the established generic object, attribute, relation and translation CRUD contract is restored over WP6 workspace storage. Originally draft-scoped, it was extended by ADR-026 to direct live writes plus optional drafts. No per-record lifecycle or nested public CRUD resources are introduced, and the original CRUD, attribute, cascade and translation suites are restored and enabled.

  • Base 0.6 WP8 workspace lifecycle orchestration. Root and history-derived workspace drafts, whole-graph validation, atomic activation that writes one immutable workspace revision of the merged live graph and applies authored changes in one transaction after the ADR-026 correction, cursor-paged immutable revision history, and publication retirement under an expected active-revision claim. Draft/revision/validation/activation/retirement events use dedicated workspace aggregates with bounded identity payloads, kept separate from record-level object-draft and relation audit events. Objects, typed attributes, containment and relations remain ordinary records through the canonical generic CRUD routers; no per-object lifecycle or nested workspace-draft CRUD resources exist.

  • Database migration failures now produce a credential-safe operator message with the current and target revisions, recovery command, backup requirement and escalation details. Startup enters maintenance mode without a traceback, and the WP4 migration safely retries recognized empty SQLite DDL left by an interrupted attempt. Real-database startup, restart and interruption regression tests cover the failure that previously left the development application unable to boot.

  • Base 0.6 authoritative runtime-object revisions. Stable logical objects now own model-pinned, optimistic drafts and immutable active/retired snapshots with separate derivation and supersession lineage. Root and historical drafts, explicit activation, cursor-paged history, retired discovery, direct retirement and ownership-cascade retirement are public API contracts. Activation publishes core fields, typed attributes, containment and required relationships atomically; independent associations and published identity survive retirement. The Alembic transition preserves object UUIDs, migrates known active/draft/retired rows and rejects unknown legacy states with counts. Post-implementation hardening conditionally claims the final draft version during activation, prevents compatibility adapters from drifting the lifecycle projection and rejects corrupt cross-workspace retirement graphs. This pre-release design was subsequently rejected as the wrong publication boundary. ADR-024 and corrective WP5 froze workspace-level journeys, fixtures and API design; WP6 supplied the corrected persistence, WP7 restored generic CRUD and WP8 completed workspace orchestration, with WP9-WP10 delivering the UI and release validation. These object-lifecycle APIs are not a compatibility commitment.

  • Frontend lint and format tooling: ESLint 10 with typescript-eslint and eslint-plugin-react-hooks, and Prettier. AGENTS.md listed "linting passes" in the definition of done, but the frontend had no linter. Dependencies are pinned instead of "latest", build tooling moves to devDependencies, and the Dockerfile uses npm ci; TypeScript is pinned to 6.x because typescript-eslint cannot yet parse with the TypeScript 7 native compiler.

  • An application-level smoke test covering the extracted router: model-driven shell rendering, deep collection URLs, fallback when a URL names a retired application, and returning from an object to the collection and workspace it was opened from.

Fixed

  • A detail panel naming an object type that a later release retired now reports it instead of crashing the detail screen through a non-null assertion.
  • Modals restore focus to their opener even when a form field uses autoFocus; cursor feeds ignore late load-more responses after their query changes or reloads; and cancelling a failed relationship deletion clears its action-specific error without blocking relation paging.

Run it today.

One Compose file, your PostgreSQL, every feature.