The squad's first sprint. The four-stage architecture was agreed and written down, the import service merged into platform-v3, the boundary-schema contract landed on both sides of the pipeline, and extraction and mapping started for both source firms.
The squad formed on 2 August to move two firms into platform v3: Lawhive Legal off v2, and Woodstock off LEAP. In its first sprint it published 14 design docs that settle the architecture, merged the import service into platform-v3 (23 PRs on develop), and proved the load path end to end by importing a full 714-matter dev firm, tearing it down, and importing it again.
39 of the team's 68 tickets are Done, all verified against trunk. The remaining halves of the pipeline, extraction and mapping for each source firm, are in flight: the first v2 staged slice and the Dagster packet exporter are in review, and the LEAP mapping has been rehearsed over Woodstock's full book. Around the engine, the operational track stood up the programme itself: a migration-project template with phased gates, the RACI, a data dictionary, and testing plans that define what done looks like.
The team does not point tickets, so these are counts, not points. One ticket is closed as a duplicate and excluded.
Two firms are waiting to move onto platform v3, and the engine this project builds is what moves them. Lawhive Legal runs on platform v2: 37,958 cases, 1.65 million files, 1.8 TB of documents. Woodstock runs on LEAP, a third-party practice-management system: 27,005 matters going back to 2014. The engine is deliberately source-agnostic, so every migration after these two reuses the same pipeline and the same import service.
The pipeline has four stages. The first three live in the data platform and turn whatever a source firm can give us into a standard package. The fourth lives in platform-v3 and loads that package into the product. The two halves only meet at the package, so each half is built and tested on its own.
The isolation is the point: the pipeline side never touches a production database, the import service never needs to know what LEAP or v2 look like, and any future source that can produce the package can be migrated.
The squad formed and planned inside this window, so its goals were set at the programme kick-off as end-of-August targets rather than sprint commitments. These are the four engine fronts the work organised around, each validated against trunk; the operational track has its own section below.
14 design docs published to firm-migrations by Lukas, Daniele and Adolfo. The import service v2 plan is the build reference: it folded a full review round and a working MVP into one document before the code merged, so code review was about code, not direction.
Lukas built the service as a 13-PR stack; it was hardened through review and security review, and the full stack merged on 18 August. It reads a package through forward-only cursors, assembles and validates one unit at a time, writes each unit and its provenance in a single transaction, derives a per-cell run report, and can tear a run down to zero. Dry run and real run share the same code path.
Daniele landed the contract in both repos. The 17 boundary Zod schemas merged in platform-v3 (DM-25, DM-30), the zod-to-dbt generator merged alongside them (#13585), and the receiving dbt package landed in data-dbt (DM-64). The GitHub Action that keeps the two repos in sync automatically is in review (DM-66, DM-17).
The platform work that has to exist before any firm's data arrives. Matter references (humanReadableId) became per-firm strings across the whole product, so an imported matter keeps the reference its firm has always cited (8 PRs, DM-5, DM-7–13). Every service database gained the ImportedRecord provenance table. Imported matters carry their own origin (MatterSource.IMPORT).
Stage 1 and 2 work, per source firm. This is where Cesar's pipeline work and the mapping investigations live.
The programme is deliberately not run as a purely technical project; the Data Migration Hub names that as its highest risk. Alongside the engine there is a second pillar, Migration Projects: one operational workstream per source firm, coordinated by Cameron with Aadam, Sally and Kha-Ai. Its job is the business half of a migration: data-quality agreements, mappings someone who uses the data has signed, validation the firm's own people can read, and named sign-offs. This sprint it stood up the programme scaffolding on Notion:
The Data Migration Hub is the programme home: goals, the two pillars, and where each kind of truth lives (Notion for owners and status, Linear DM for current work, firm-migrations for design decisions). The Migration Projects template defines the five phases every migration runs, discovery through cutover, with ten gates, each carrying an exit condition and a named deliverable, and a per-phase table of what the business track owes versus what the technical track owes.
The RACI names who owns what across the project, engine, enablement, product, engineering, data and the business side. A v2 → v3 data dictionary gives everyone the same vocabulary. Testing plans per track define what done looks like for the first slice: one matter run end to end in dev, every automated check green, run twice with the same result, and a lawyer can open the migrated matter and work with it. A pre-mortem lists the risks with actions.
One rule from the template worth repeating, because it de-risks Woodstock: discovery does not close until extraction has been proven by a spike, and the LEAP contract is never terminated until the extract is verified — LEAP allows only a 30-day window from termination.
Milestone progress from the Linear project after the close-of-sprint status sync. Milestones are delivery goals that pull tickets across areas; the project targets 20 October for the full LLL load.
| Ticket | What | State |
|---|---|---|
| DM-46 / 49 | Dagster JSONL packet exporter + canonical models as a source-parameterized dbt package (data-dbt #3823–#3826) | In review |
| DM-17 / 66 / 69 | Zod→dbt: PK/parent tests, dump ordering, the cross-repo sync GitHub Action, and dbt-parse validation of the generated models | In review |
| DM-47 / 53 / 54 | Idempotency semantics, the adapter contract for new sources, and reconciliation models so nothing is silently dropped | In progress |
| DM-44 / 16 / 65 | Dagster job shape for the canonical dbt build, and the GitHub App auth for the sync workflow | In progress |
Pending sprint planning; these are the fronts the backlog already points at.
| Front | Work |
|---|---|
| First slice end to end | One v2 matter through all four stages into v3 on dev (DM-68): the first time the pipeline and the import service meet on a real environment |
| Pipeline | Land the in-review dbt stack · v2 staging models for all in-scope entities (DM-62) · the packet exporter running inside Dagster (DM-43/44) |
| Import service | Deployment wiring so the service actually ships · a real file store so imported file rows carry bytes · the walker and cursor tickets that survived into the backlog (DM-19/20) |
| Verification | Reconciliation models (DM-54) · the coverage loop over the full Lawhive Legal book · fixture-driven integration tests (DM-58) |