Skip to content

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.

  1. In the Fabric portal, create two Warehouses in Parcel Development: CatalogueDev and OperationsDev.
  2. Add a separate configuration beside the project. Keep workspace-development.yml as it is; this file describes the mirrored copy:
workspace-mirror.yml
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:

weaver mirror --workspace-config workspace-mirror.yml

The command returned:

Terminal output exit 0
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

1
2
3
4
5
6
7
8
9
# Review this plan before running the next cell.
import weaver
mirror_plan = weaver.plan_mirror(
    workspace='Parcel Development',
    catalogue='Warehouse/CatalogueDev',
    mirror='Warehouse/Catalogue',
)
mirror_plan = weaver.check_mirror(mirror_plan)
print(mirror_plan.describe())
1
2
3
import weaver
mirror_result = weaver.mirror(plan=mirror_plan)
mirror_result.report()

The command returned:

Notebook output
{'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:

weaver health --workspace-config workspace-mirror.yml

The command returned:

Terminal output exit 1
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

1
2
3
4
5
6
import weaver
health_result = weaver.health(
    workspace='Parcel Development',
    catalogue='Warehouse/CatalogueDev',
)
health_result.report()

The command returned:

Notebook output
{'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.