Develop using Mirror¶
Borrow an installed estate’s data for development, then materialise only the objects your changes need. Keep the same project documents and logical identities while the development configuration selects different physical targets.
Use Mirror only after the ordinary development loop is understood. It empties and reconstructs the destination catalogue and every selected destination target, including local materialisations there. Source items remain untouched. It is a baseline reset, not an iteration command.
Prepare existing destinations in the same workspace¶
Mirror works between existing Fabric items in one workspace. Here the source is the estate you have been building: the Catalogue Warehouse and the Operations Warehouse it records. Mirror needs an empty destination for each, and it does not create Fabric items.
- In the Fabric portal, create two Warehouses in
Parcel Development:CatalogueDevandOperationsDev. - Add a separate configuration beside the project. Keep
workspace-development.ymlas it is; this file describes the mirrored copy:
workspace: Parcel Development
catalogue: Warehouse/CatalogueDev
mirror: Warehouse/Catalogue
targets:
Warehouse/Operations: OperationsDev
mirror names the source catalogue; catalogue and targets name the destinations. The source physical item, Operations, comes from the source catalogue's recorded binding, not from this file. Only the items listed under targets are rebound to development copies.
In the Terminal, Weaver shows the source catalogue, destination catalogue and each target mapping, then asks once before emptying the destinations. Compare the plan with the names above; answer y only if they match. Declining changes nothing. In a Notebook, review the plan in the first cell before running the second. Mirror has no dry-run mode.
Run Mirror:
The command returned:
Mirror
Workspace Parcel Development
Source catalogue Warehouse/Catalogue
Destination catalogue Warehouse/CatalogueDev
Targets
Warehouse/Operations → Warehouse/OperationsDev
Empty these targets? This cannot be undone. [y/N] y
Mirror
Planning the mirror 1.8s
→ Wipe Warehouse/CatalogueDev · 1 action
→ Wipe Warehouse/OperationsDev · 1 action
✓ Wipe Warehouse/CatalogueDev · 1 action 0.7s
→ Warehouse/CatalogueDev · Catalogue: creating schemas · 1 action
✓ Wipe Warehouse/OperationsDev · 1 action 0.7s
✓ Warehouse/CatalogueDev · Catalogue: creating schemas · 1 action 0.0s
→ Warehouse/CatalogueDev · Catalogue: building objects · 24 actions
→ Reconstruct Warehouse/OperationsDev · 2 actions
→ Recreate views over other items in Warehouse/OperationsDev · 1 action
✓ Reconstruct Warehouse/OperationsDev · 2 actions 0.2s
✓ Recreate views over other items in Warehouse/OperationsDev · 1 action 0.4s
✓ Warehouse/CatalogueDev · Catalogue: building objects · 24 actions 6.9s
→ Warehouse/CatalogueDev · Catalogue: updating catalogue definitions · 1 action
✓ Warehouse/CatalogueDev · Catalogue: updating catalogue definitions · 1 action 4.4s
→ Warehouse/CatalogueDev · Catalogue: finalising catalogue · 1 action
✓ Warehouse/CatalogueDev · Catalogue: finalising catalogue · 1 action 0.7s
→ Recreate catalogue views in Warehouse/OperationsDev · 1 action
✓ Recreate catalogue views in Warehouse/OperationsDev · 1 action 0.1s
→ Copy procedures and functions into Warehouse/OperationsDev · 1 action
✓ Copy procedures and functions into Warehouse/OperationsDev · 1 action 0.3s
→ Warehouse/CatalogueDev · Forking the catalogue and binding items · 1 action
✓ Warehouse/CatalogueDev · Forking the catalogue and binding items · 1 action 7.8s
Mirroring 20.9s
✓ Mirror 24.4s
Mirror complete
Catalogue Warehouse/Catalogue → Warehouse/CatalogueDev
1 item mirrored
2 destinations emptied
The command returned:
{'workspace': 'Parcel Development',
'source_catalogue': 'Warehouse/Catalogue',
'destination_catalogue': 'Warehouse/CatalogueDev',
'wiped': ['Warehouse/CatalogueDev',
'Warehouse/OperationsDev'],
'copied': {'SchemaDictionary': 10,
'FolderDictionary': 3,
'TableDictionary': 28,
'ColumnDictionary': 165,
'KeyDictionary': 26,
'ForeignKeyDictionary': 0,
'TestDictionary': 6,
'SemanticModelTest': 2,
'Dependency': 12,
'Shortcut': 20,
'SemanticModel': 2,
'SemanticModelTable': 7,
'SemanticModelMeasure': 5,
'SemanticModelRelationship': 2,
'SemanticModelColumn': 19,
'Installation': 6,
'Registry': 74,
'Bookmark': 7,
'LoadStatus': 10,
'TestStatus': 6},
'uncopied': ['Log', 'LoadStatistic'],
'items': ['Warehouse/Operations'],
'mirrored': {'Warehouse/Operations': {'source': 'Warehouse/Operations',
'target': 'Warehouse/OperationsDev',
'relations': 2,
'pointers': 0,
'programmables': 5}},
'status': 'succeeded'}
Mirror emptied CatalogueDev and OperationsDev and rebuilt them from the source estate. Unchanged objects start as borrowed source data: OperationsDev presents Operations' Tables through local Views, and _.Mirror in CatalogueDev lists every borrowed object. The project's logical items and Weaver documents are unchanged.
Inspect the baseline:
The command returned:
Health
Read catalogue 3.4s
Read the mirrored catalogue 1.9s
Check installed items 0.2s
Read installed objects 17.1s
✓ Health 22.6s
Weaver Health Amber
Load Green
Last load activity 0h 1m ago
15 succeeded
Tests Amber
4 succeeded
Amber Warehouse/Operations/Parcel.CurrentStatusMatches
Warehouse/Operations/Parcel.StatusEvent has been loaded since this validation passed
Amber Warehouse/Operations/Parcel.StatusIsKnown
Warehouse/Operations/Parcel.StatusEvent has been loaded since this validation passed
Build Green
Installed estate consistent (67 objects)
Slowest loads
Warehouse/Operations/Parcel.LakehouseCurrentStatus 6.6s
Warehouse/Operations/Parcel.Daily 4.9s
Warehouse/Operations/Parcel.LiveStatus 2.5s
Warehouse/Operations/Parcel.StatusEvent 2.5s
Warehouse/Operations/Reference.Depot 2.2s
Largest changes
Warehouse/Operations/Parcel.StatusEvent read 3 +3 ~0 -0 !0
Warehouse/Operations/Parcel.Daily read 1 +1 ~0 -1 !0
Warehouse/Operations/Parcel.Events read 1 +1 ~0 -1 !0
Warehouse/Operations/Parcel.RawEvents read 1 +1 ~0 -1 !0
Warehouse/Operations/Parcel.Summary read 1 +1 ~0 -1 !0
The command returned:
{'format_version': 3,
'generated_at': '2026-10-17T08:06:27.601048+00:00',
'as_of': '2026-10-16T08:06:27.601048+00:00',
'status': 'red',
'targets': ['Lakehouse/Landing',
'SemanticModel/Parcel',
'SemanticModel/ParcelWarehouse',
'Warehouse/CatalogueDev',
'Warehouse/OperationsDev',
'Warehouse/Reporting'],
'sections': {'load': {'status': 'red',
'subjects': 9,
'counts': {'failed': 1, 'pending': 1, 'succeeded': 7},
'findings': [{'area': 'load',
'code': 'load_failed',
'severity': 'red',
'status': 'failed',
'message': 'the last load failed',
'object_id': 'SemanticModel/ParcelWarehouse',
'target': 'SemanticModel/ParcelWarehouse',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T08:05:18.998066+00:00',
'completed_at': '2026-10-17T08:05:24.091224+00:00',
'failure_count': None},
{'area': 'load',
'code': 'load_pending',
'severity': 'amber',
'status': 'pending',
'message': 'no load has settled since this object was built',
'object_id': 'Warehouse/Reporting/Parcel.DashboardInput',
'target': 'Warehouse/Reporting',
'workflow_id': None,
'started_at': None,
'completed_at': None,
'failure_count': None}]},
'tests': {'status': 'red',
'subjects': 6,
'counts': {'failed': 2, 'succeeded': 4},
'findings': [{'area': 'tests',
'code': 'test_failed',
'severity': 'red',
'status': 'failed',
'message': 'the last run failed',
'object_id': 'SemanticModel/ParcelWarehouse/Parcel.CurrentStatusReconciles',
'target': 'SemanticModel/ParcelWarehouse',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T08:05:26.467209+00:00',
'completed_at': '2026-10-17T08:05:27.010639+00:00',
'failure_count': 2},
{'area': 'tests',
'code': 'test_failed',
'severity': 'red',
'status': 'failed',
'message': 'the last run failed',
'object_id': 'Warehouse/Operations/Parcel.CurrentStatusMatches',
'target': 'Warehouse/OperationsDev',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T07:56:21.202641+00:00',
'completed_at': '2026-10-17T07:56:24.167537+00:00',
'failure_count': 2},
{'area': 'tests',
'code': 'test_stale_dependency',
'severity': 'amber',
'status': 'succeeded',
'message': 'Lakehouse/Landing/Files/Parcel.Events has been '
'loaded since this validation passed',
'object_id': 'Lakehouse/Landing/Parcel.CurrentStatusMatches',
'target': 'Lakehouse/Landing',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T07:38:07.686232+00:00',
'completed_at': '2026-10-17T07:38:22.578059+00:00',
'failure_count': 0},
{'area': 'tests',
'code': 'test_stale_dependency',
'severity': 'amber',
'status': 'succeeded',
'message': 'Lakehouse/Landing/Files/Parcel.Events has been '
'loaded since this validation passed',
'object_id': 'Lakehouse/Landing/Parcel.EventStatusIsKnown',
'target': 'Lakehouse/Landing',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T07:38:07.686598+00:00',
'completed_at': '2026-10-17T07:38:18.443573+00:00',
'failure_count': 0},
{'area': 'tests',
'code': 'test_stale_dependency',
'severity': 'amber',
'status': 'succeeded',
'message': 'Warehouse/Operations/Parcel.StatusEvent has been '
'loaded since this validation passed',
'object_id': 'Warehouse/Operations/Parcel.StatusIsKnown',
'target': 'Warehouse/OperationsDev',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T07:56:21.205343+00:00',
'completed_at': '2026-10-17T07:56:21.908095+00:00',
'failure_count': 0}]},
'build': {'status': 'red',
'subjects': 59,
'counts': {},
'findings': [{'area': 'build',
'code': 'dependency_unresolved',
'severity': 'red',
'status': None,
'message': 'Warehouse/Reporting/Parcel.DashboardInput reads '
'shortcut Parcel.Summary, but its source '
'Warehouse/Operations/Parcel.Summary is not '
'installed. Install the source before building '
'Warehouse/Reporting again.',
'object_id': 'Warehouse/Reporting/Parcel.DashboardInput',
'target': 'Warehouse/Reporting',
'workflow_id': None,
'started_at': None,
'completed_at': None,
'failure_count': None}]}},
'current_load': {'workflow_ids': ['[run-id]',
'[run-id]',
'[run-id]',
'[run-id]'],
'started_at': '2026-10-17T07:45:09.855827+00:00',
'completed_at': '2026-10-17T08:05:24.091224+00:00',
'counts': {'failed': 1, 'pending': 1, 'succeeded': 7}},
'load_activity': [{'object_id': 'Warehouse/Operations/Parcel.StatusEvent',
'target': 'Warehouse/OperationsDev',
'workflow_id': '[run-id]',
'started_at': '2026-10-17T08:00:27.828026+00:00',
'completed_at': '2026-10-17T08:00:31.765218+00:00',
'duration_ms': 3937,
'rows_read': 3,
'rows_inserted': 0,
'rows_updated': 0,
'rows_deleted': 0,
'rows_rejected': 0,
'is_reload': False,
'is_static_skip': False}]}
Health reads borrowed objects' Load state from the source catalogue, so the mirrored estate starts with the source's history and findings.
See Mirrors for borrowed and local data. Exact Mirror selection, authorisation and failure boundaries are in Mirror operation behaviour.
Change only the work that needs to become local¶
After a successful Mirror, keep the same project source and pass --workspace-config workspace-mirror.yml to Build, Load, Test and Health. The development cycle is unchanged.
Build compares source with copied installed declarations. Unchanged borrowed objects stay borrowed. A changed selected object, or an affected selected descendant, becomes local after successful installation and loses its _.Mirror row. Items outside the Build selection do not materialise just because another item changed. Load operates local materialisations; borrowed data continues to be loaded and owned at its source.
For example, if you added the selection example's Reference.Service, change its ServiceName constant and run:
weaver build --item Warehouse/Operations --workspace-config workspace-mirror.yml
weaver load Warehouse/Operations --stale --workspace-config workspace-mirror.yml
Reference.Service becomes a local Table in OperationsDev and leaves _.Mirror. Reference.Depot stays borrowed, and the source Operations Warehouse keeps its original value.
Warehouse borrowed Tables/Views are presented through local Views. Lakehouse stored Tables/Folders use shortcuts, with local wrapper Views for source Views. Health reads borrowed current Load state from the source catalogue and local state from development. A mixed estate is an ordinary result, not evidence that every object has been copied.
Selected changed or impacted protected Tables/Folders use preserving materialisation rather than empty reconstruction: Warehouse CTAS, Delta shallow clone or native recursive Folder copy. That path retains the established bookmark but is not an atomic estate snapshot; shallow clones require source file retention. Protection does not protect against Wipe or deliberate re-mirroring. Keep irreplaceable source data outside ordinary managed target ownership. See Protecting data.
Reset only when a new source baseline is intended¶
Run Mirror again only when the displayed destination catalogue and selected targets should be replaced. Local work inside that boundary is not preserved as a fallback. Preflight failures leave destinations unchanged; a failure after mutation begins does not restore the old catalogue or targets and does not undo already completed destinations. Inspect remaining state before retrying.
Selective mirroring still copies the destination catalogue, but only selected items are rebound to development targets; unselected copied installations remain source-bound. A catalogue-only Mirror copies installed/current state without emptying an item target, and destination Log/LoadStatistic history starts empty. It is not an isolated writable copy of every source binding. Rebinding from an already mirrored source is refused rather than chaining borrowing hops.
Mirror and materialisation strategies explains these narrower estate shapes. Mirror behaviour owns exact selection, binding and failure rules. Once the baseline is in place, return to ordinary development, not another reset.