Changelog
0.7.0, 2026-09-25
Mapping between systems: each list gets its own screen that shows which codes are mapped and replaces a mapping in one step.
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-25. 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.
Added
-
Base 0.7 WP-9: composed acceptance for SC-07 and SC-15.
test:browser:sc07resolves unmapped, differently mapped and 25-target ambiguous rows (candidates beyond page one, bounded previews with continuation), survives a racing generic relation write with the attempted choice kept, proves an independent binding with a typed relation attribute is untouched, and refuses draft activation when live changed the draft's mapping set.test:browser:sc15prepares one draft on an installed candidate release while another stays on the active one, refuses incompatible and unavailable releases without touching live data, history or another workspace, then publishes the prepared draft after the candidate is activated and discards the other.test_build07_wp9_acceptance.pyadds corrupt and unsupported releases at the HTTP boundary. The browser harness accepts a model variant (transformModel). -
Base 0.7 WP-13C:
docs/testing/UI_ACCEPTANCE.mdnames the existing reference pattern for each kind of UI element and inventories the states of every 0.7 surface with its evidence. The new browser runnertest:browser:wp13cchecks mapping and draft states against a real backend: outages with Retry, empty and no-match results, conflict review, the inverse mapping in a draft, a draft on a non-active model release, keyboard focus and phone width. UI changes now report functional, accessibility and visual evidence separately. Found and scoped WP-10F and WP-10G. -
Base 0.7 WP-13B:
docs/testing/EXECUTION_GUIDE.mdmaps each changed production boundary to its focused checks and shared-boundary expansion, lists the WP-9 comprehensive command set and records measured before/after costs. Backend tests carry contract-group markers (pytest -m mapping, …) from one manifest inconftest.py; an unclassified test module or unknown marker fails collection. Vitest runs pure.test.tsfiles in aunitproject without jsdom and components indom. The gate-helper check (now in CI) refuses an unlisted browser runner, and the browser harness prints its setup phase timings. -
Base 0.7 WP-13A:
docs/testing/COVERAGE_MAP.mdlinks product invariants and capability contracts to their test evidence, boundary and cost tier, ranks risk and records audit status, residual risk and consolidation decisions. New regression evidence: mapping replacement refuses foreign-workspace drafts, unknown workspaces, a revision context and retired workspaces without changing data; draft relation update/delete advance both draft anchors' set versions only; runtime sources contain no starter-model key literal; livedatevalues keep their type through write, boundary filters and sort; the mapping conflict retry sends the user's attempted target. Two confirmed defects are reproduced and fixed as WP-10C and WP-10D, and a third as WP-10E (see Fixed). One relation-set test duplicating stronger evidence was removed. -
Base 0.7 WP-12:
GET /api/v1/model-releases/{releaseId}/activationsreads a release's recorded activations (oldest first, with the release each replaced). Models release details move the Release ID and content hash into an explained, copyable Technical details disclosure; release history compares an earlier baseline (Before) with the selected release (After), including the active release, defaulting to the recorded predecessor, otherwise the labelled preceding installed release of the same key, with an explicit Compare with selector and truthful first-release, identical-content and unsupported-baseline states. Activation readiness is shown separately and always checks the current active release against the candidate. -
Dark mode: a complete dark token set that follows the system preference by default, with an explicit System / Light / Dark choice saved per browser and applied before first paint.
-
Settings control at the bottom of the navigation rail with the appearance choice and an Account placeholder (local single-user session, disabled Sign in) for the planned multi-user authentication.
-
Dark accessibility scenarios (core pages and the settings menu) and four dark visual baselines.
-
Build 0.7 WP-7 browser draft version selection (ADR-028 frontend). Draft creation offers an optional model-release selector when multiple releases are installed; default is the active release. Draft list cards and detail header show each draft's model release key and version. An informational banner explains the state when a draft's version differs from the active release, and activation is disabled with a tooltip. A "Change model version" action in secondary draft actions loads available releases, attempts the pin change via the WP-6 PATCH endpoint, shows incompatibility diagnostics on failure and reloads the model context on success. Dirty-input protection via the existing
allowNavigation()guard before applying version changes. Model-context refresh after pin change reloads the draft, pinned model and active release state; external pin change detection viauseEffect+useRefinLoadedDraft.WorkspaceDrafttype extended withmodelReleaseKeyandmodelReleaseVersion. 169 frontend tests (5 new), zero lint errors, production build passes. -
Build 0.7 WP-5 atomic mapping replacement API:
PUT /api/v1/workspaces/{workspaceKey}/mappingsatomically creates, replaces or removes a mapping for one source in a configured relation binding. Supports live and draft contexts with optimistic concurrency viaexpectedMappingVersionandexpectedWorkspaceDraftVersion. Direction-aware cross-cardinality enforcement (one-to-one always, one-to-many outgoing only). Retained relation identity when resolving ambiguous→mapped. Typed attribute semantics: omitted preserves retained edge values, explicit replaces,{}clears. Null target with non-empty attributes rejected. Idempotent no-ops with valid tokens produce no version increment or audit event. Stale tokens return409 mapping_version_conflictwith bounded preview. Single-direction set version increments avoid double counting. Containment and required-ownership bindings rejected. Mapping-transition audit events with old/new targets and relation identities. After acceptance follow-up: 73 replacement/activation integration tests; 486 backend tests pass on SQLite. -
Build 0.7 mapping list API:
GET /api/v1/workspaces/{workspaceKey}/mappingsreturns cursor-paged live/draft edges with optional binding, direction and name filters, directional set tokens, stored typed relation attributes and optional view-specific projections. Omitting direction returns both orientations of each edge; this supplements source-grouped coverage for integration reads. -
Build 0.7 WP-4 mapping query APIs: workspace-scoped coverage, candidate search and version-bound target details resolve the selected
mappingGridview under the live or draft-pinned model. SQL pagination and batched reads return typed projections, mapped/unmapped/ambiguous states, exact counts and at most 20 target summaries with explicit continuation. Cursors bind workspace, context, model release, view, direction and query configuration. -
Schema 0.6
mappingGridview contract (Build 0.7 WP-2). The model language now acceptsschemaVersion: "0.6"alongside"0.5".MappingGridViewDefinitionjoinsTableViewDefinitionin a Pydantic discriminated union onViewDefinition.type. Backend validation checks relation binding existence, rejects containment (parentOf) and required-ownership bindings, validates source/target columns against attached attributes, and verifies candidate search fields are searchable target-type attributes. The starter model advances to schema 0.6 / content release 0.7.0 with two mapping grid views:system-to-master-mapping(outgoing) in RDM Systems andmaster-to-system-mapping(incoming) in RDM Master. FrontendViewDefinitionis a TypeScript discriminated union with type-safe narrowing; its initial placeholder was subsequently replaced by the WP-8/WP-14 contextual lens. 11 new backend tests cover parse, activation, backward compatibility and all validation rejection paths. -
Relation-set version persistence and generic participation (Build 0.7 WP-3). Every generic relation write (create, update, delete) now atomically maintains exact-binding set versions in both the outgoing and incoming directions. The
relation_set_versionstable tracks the optimistic version of each (workspace, optional draft, relation type, from/to object-type pair, anchor object, direction) combination. Rows are created lazily on first touch with version 1; untouched sets have implicit version 0. Draft-scoped and live-scoped versions are independent. Draft deletion cascades set-version rows; draft activation merges draft mutation counts into live set versions. A partial unique index protects live-context uniqueness whereworkspace_draft_id IS NULL. 9 focused tests cover all mutation paths, independent bindings, draft/live isolation, cascade and activation merge. All 379 backend tests pass. -
UI-07 automated accessibility and visual-regression gates (WP-1).
npm run test:a11yruns axe-core WCAG 2.1 AA checks on 9 core page types across two object types;npm run test:visualcompares viewport screenshots against committed baselines using pixelmatch. ~16 color-contrast violations fixed, definition-list structure corrected, sidebar landmark added. Two known violations allowlisted with tracked references. Light-theme baselines committed; dark baselines followed with dark mode.
Changed
-
Backend tests that need a private database copy a once-migrated template instead of running every Alembic migration per test; startup and migration tests still migrate for real. The sampled backend selection runs in 22.7 s instead of 46.8 s with the same cases. A pagination test that failed when run alone now owns its database.
-
Models page aligned with the rest of the UI: the release/draft catalogue is now sidebar navigation, and the main column uses the shared context bar, page header and surfaces.
-
Base 0.7 UX pass over the generic frontend, with routes, data contexts and API contracts unchanged: applications as header tabs with model icons; a segmented Live / Drafts / History control; collection list plus a collapsed-by-default record tree that opens toward the active record; one Filter popover with an applied count; lens tabs, scope banner and page count beside pagination; whole-row open; a record header with one breadcrumb line and a visible Edit record action; readable record activity without identifiers or concurrency tokens; a compact draft bar; and a rewritten design-token stylesheet with a 12–14px minimum text scale.
-
Mapping lenses: segmented coverage filter, row-click to map, a searchable radio list of candidates, Save and next, and an explicit Remove mapping action. Selecting nothing no longer turns the primary button into a clear operation.
-
Build 0.7 WP-14 composes model-defined table and mapping views as lenses of one contextual collection. One application browser now presents virtual collection groups alongside runtime hierarchy records, replacing the separate Browse hierarchy / Views modes. Direct-parent scope, typed field facets and mapping coverage state are visible and URL-backed. Mapping coverage applies parent/state filters before cursor pagination in live, draft and immutable-revision contexts, and cursor fingerprints bind both values. This remains generic over configured applications, object types, relations and renderers; Master, Systems and Translations remain starter examples.
-
The WP-8A/WP-8B review retained atomic mapping actions while removing duplicate configured name columns and requiring explicit review before retrying after a mapping-version conflict. Historical mapping reads now use revision projections and expose no mutation controls. Focused package evidence covers both configured mapping directions, direct-parent scope, visible mapping-state filtering, live replacement, narrow layout and the composed page's accessibility.
-
Extended the planned 0.7 design and delivery documentation after plan review: WP-1–WP-3 remain frozen; later packages specify bounded view-based mapping reads, stable retained relation identities, typed attributes, direction-aware constraints and atomic whole-candidate draft compatibility. Mapping UI is split into WP-8A coverage and WP-8B actions; WP-9 expands integration/a11y/visual evidence, with conditional WP-10 for confirmed foundation gaps.
Fixed
-
Base 0.7 WP-10K: records and relations read in a draft or from history no longer show the current time as their created and updated times. These are not recorded there, so the API returns
null(the fields are now nullable), filtering or sorting by them is refused with an explanation instead of matching nothing, and collection views neither offer nor send them outside live data. -
Base 0.7 WP-10H: the mapping dialog no longer offers Remove mapping for a required relationship, which the server refuses; it asks for a replacement instead.
-
Base 0.7 WP-10I: starting a draft on an incompatible model release lists the records that do not fit, as a version change already did, and draft error messages no longer run two sentences together.
-
Base 0.7 WP-10J: missing-required and read-only field errors name the fields (“Required fields are missing: External ID”) instead of printing a list of keys; the keys are in
details.attributeTypeKeys. -
Test reliability: the WP-12 and WP-13C browser runners waited too little for clipboard feedback and focus restore; a current-live base test read another test's draft from the shared database. The Models page visual baselines now show the WP-12 layout.
-
Base 0.7 WP-10E: a live
dateTimewrite keeps its instant. Values are stored in UTC and every context returns them with an explicit offset; decimals read back in one form without trailing zeros (live reads were padded to12.5000000000), so draft uniqueness compares equal decimals as equal. All server timestamps (createdAt,updatedAt,occurredAt, …) now carry an offset on SQLite too, and the browser no longer appends one to zone-less times. -
Base 0.7 WP-10F: Create new … in a mapping lens asks which application the new target belongs to, listing every application that contains its type and defaulting to the lens's own. Parent choices are limited to types in that application, and a notice explains when it has none. The starter can now create a target in both mapping directions.
-
Base 0.7 WP-10G: the mapping dialog's search box keeps its height at phone width, and the draft model-mismatch and historical-revision notices name releases by key and version instead of UUID.
-
Base 0.7 WP-10C:
date,dateTimeanddecimalvalues can be written in a workspace draft (create, update and the field endpoint returned 500) and are published to live on activation, including values captured from live. Draft and revision lists filter and sort these fields and integers by their declared type: numbers no longer sort as text (10before5), date-times sort by instant, and a zone-lessdateTimefilter value is read as UTC. -
Base 0.7 WP-10D: renaming or moving a contained record inherited by a draft no longer adds a second containment relation with a new ID. An unchanged parent keeps its relation; a move replaces it with exactly one. Such drafts now activate instead of refusing with
duplicate_edgeorrelation_cardinality_violation. -
WP1-001: the navigation resize separator is inside the navigation landmark, so its accessibility exception is removed. Collection and settings popovers render inside a landmark (or the open dialog), and zone-less server timestamps are read as UTC.
-
Build 0.7 WP-5 review: enforce ancestor-scoped constraints against the final replacement graph, and reject missing required ancestors in generic draft relation writes as in live writes. Reject required-ownership replacement irrespective of relation orientation. Explicit empty application/view keys fail validation instead of selecting unconfigured reads. Twelve HTTP regressions cover these boundaries, preserved tokens and valid replacements within one ancestor scope.
-
Build 0.7 WP-10B: draft activation now refuses new, removed or updated live relations in exact mutable binding sets the draft touched, including previously unmapped sets. It compares the immutable source/live edge identities and versions before applying any rows. Refusals preserve the draft, live data and revision designation and include bounded mapping-set diagnostics with recovery instructions. Unrelated live mapping work and existing containment/ownership merge behavior remain covered. WP-5 acceptance adds independent-binding isolation, required-ownership and clearing refusals, and overlapping generic create/update/delete versus mapping saves.
-
Build 0.7 WP-10A, found in WP-4 review: confirmed live/draft object cascades now advance both directional relation-set versions for removed edges. Stale mapping target continuations return
409 mapping_version_conflictwith refresh guidance; previews and rejected deletes leave versions unchanged. Regression coverage exercises both directions and contexts. -
Build 0.7 WP-1/WP-2 review fixes: scope accessibility exceptions to known targets and node counts, fail visual comparisons on missing baselines outside explicit update mode, reject
mappingGridunder schema 0.5, and allow the documented offline schema 0.4 recovery to select a compatible schema 0.5 or 0.6 candidate. The CLI reports expected refusals without a traceback, and the draft context regression now checks the current named-draft and version presentation. Visual capture waits for loaded panels, and the model-workbench baseline now covers the loaded release detail.
Let us run it for you.
Backups, upgrades, TLS and monitoring are ours. Your data stays exportable any time.