You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Give administrators per-object Sync Preview: click a Connected System Object (or Metaverse Object) and see what synchronising it now would do, rendered as the full causality chain; projection or join, Attribute Flow, then every downstream consequence (provisioning, updates, disconnection, Metaverse Object deletion, downstream deprovisioning).
Scope decision (25 Aug 2026): the whole-system preview surface (PreviewFullSyncAsync) is deferred to #1530 as a nice-to-have. This issue is per-object only, which settles two of the original open questions: per-object previews run synchronously in-process, and results are transient (re-running is cheaper than storing a troubleshooting read).
What exists today
JimApplication.SyncPreview (src/JIM.Application/Servers/SyncPreviewServer.cs), read-only and side-effect free (three independent layers, documented in engineering/SYNC_PREVIEW_ZERO_SIDE_EFFECTS.md):
PreviewSyncForCsoAsync - scope check, join probe or prospective projection, Attribute Flow onto a cloned working Metaverse Object, then the outbound decisions the prospective state would produce (provision, update, deprovision per export Synchronisation Rule), returned as a speculative SyncOutcomeNode tree with programmatic Errors and Warnings.
PreviewSyncForMvoAsync - the outbound chain for one Metaverse Object.
SyncOutcomeNode was designed for display reuse: it is the unpersisted counterpart of the recorded outcome (ActivityRunProfileExecutionItemSyncOutcome), carries the same outcome-type enum, and the paired fidelity tests stop preview and reality drifting apart. The portal already has a full causality visualisation (src/JIM.Web/Causality/) rendering recorded outcome trees.
Gaps this issue closes
1. Engine: walk the destructive cascade to its end (currently one hop deep)
The happy path is complete, but the destructive chain stops at the first hop. When a preview finds the object out of scope of every import Synchronisation Rule, it names the out-of-scope action ("a synchronisation would apply 'Disconnect'") and returns; it does not continue the chain the real synchronisation would execute:
CSO falls out of scope
→ would disconnect from its Metaverse Object
→ Deletion Rule evaluates (e.g. WhenLastConnectorDisconnected): MVO would be deleted
→ n downstream CSOs would be deprovisioned (Disconnect or Delete per rule)
Extend the preview to walk this speculatively: evaluate the Deletion Rule against the prospective connector set, and when the Metaverse Object would delete, evaluate the downstream deprovisioning fan-out, all within the existing guard and rollback backstops. The #1114 (deletion settings) and #1115 (destructive toggles) adapters evaluate closely related eligibility questions; reuse before writing new evaluation.
2. Portal
"Preview Sync" on the Connected System Object detail page; "Preview outbound" on the Metaverse Object detail page.
Render the SyncOutcomeNode tree through the existing causality visualisation (an adapter or CausalityModelBuilder overload for the unpersisted tree; the model was designed for this). One visual language, clearly marked as speculative ("would", not "did"), following Configuration Change Preview reads like a debug view, not a decision aid #1275's decision-aid vocabulary.
Synchronous in-process; no Activity, no persistence.
3. REST
Read-only preview endpoints for CSO and MVO, DTOs for SyncPreviewResult, [Authorize], OpenAPI regenerated.
4. PowerShell
Cmdlets for both operations with documented output shapes and Pester tests.
Settled questions (were open on this issue's original form)
Question
Answer
Dispatch
Synchronous in-process; per-object evaluation is cheap. Worker dispatch belongs to the deferred full-system tier (#1530)
Retention
Transient; nothing persisted. Audit-grade retention belongs to #1530
Framing
Instrument, not gate: a troubleshooting and what-if tool on object pages. Save-time gating of configuration changes is #827's job
Acceptance criteria
The destructive cascade previews to its end: disconnect, Metaverse Object deletion eligibility, downstream deprovisioning fan-out, with fidelity tests pairing preview against a real run of the same scenario.
Portal, REST and PowerShell all ship in this issue; no surface deferred.
The preview renders through the existing causality visualisation, visually distinguished as speculative.
Tests at each layer (bUnit for display logic, API tests, Pester).
Public documentation under docs/ and a CHANGELOG.md entry.
Zero-side-effect guarantees hold with the new callers; no persisting path introduced.
See engineering/plans/SYNC_PREVIEW_SURFACE.md (branch feature/sync-preview-surface): Phase 1 completes the cascade as the bottom stack layer, Phase 2 ships the three surfaces on top.
Summary
Give administrators per-object Sync Preview: click a Connected System Object (or Metaverse Object) and see what synchronising it now would do, rendered as the full causality chain; projection or join, Attribute Flow, then every downstream consequence (provisioning, updates, disconnection, Metaverse Object deletion, downstream deprovisioning).
Scope decision (25 Aug 2026): the whole-system preview surface (
PreviewFullSyncAsync) is deferred to #1530 as a nice-to-have. This issue is per-object only, which settles two of the original open questions: per-object previews run synchronously in-process, and results are transient (re-running is cheaper than storing a troubleshooting read).What exists today
JimApplication.SyncPreview(src/JIM.Application/Servers/SyncPreviewServer.cs), read-only and side-effect free (three independent layers, documented inengineering/SYNC_PREVIEW_ZERO_SIDE_EFFECTS.md):PreviewSyncForCsoAsync- scope check, join probe or prospective projection, Attribute Flow onto a cloned working Metaverse Object, then the outbound decisions the prospective state would produce (provision, update, deprovision per export Synchronisation Rule), returned as a speculativeSyncOutcomeNodetree with programmatic Errors and Warnings.PreviewSyncForMvoAsync- the outbound chain for one Metaverse Object.SyncOutcomeNodewas designed for display reuse: it is the unpersisted counterpart of the recorded outcome (ActivityRunProfileExecutionItemSyncOutcome), carries the same outcome-type enum, and the paired fidelity tests stop preview and reality drifting apart. The portal already has a full causality visualisation (src/JIM.Web/Causality/) rendering recorded outcome trees.Gaps this issue closes
1. Engine: walk the destructive cascade to its end (currently one hop deep)
The happy path is complete, but the destructive chain stops at the first hop. When a preview finds the object out of scope of every import Synchronisation Rule, it names the out-of-scope action ("a synchronisation would apply 'Disconnect'") and returns; it does not continue the chain the real synchronisation would execute:
Extend the preview to walk this speculatively: evaluate the Deletion Rule against the prospective connector set, and when the Metaverse Object would delete, evaluate the downstream deprovisioning fan-out, all within the existing guard and rollback backstops. The #1114 (deletion settings) and #1115 (destructive toggles) adapters evaluate closely related eligibility questions; reuse before writing new evaluation.
2. Portal
SyncOutcomeNodetree through the existing causality visualisation (an adapter orCausalityModelBuilderoverload for the unpersisted tree; the model was designed for this). One visual language, clearly marked as speculative ("would", not "did"), following Configuration Change Preview reads like a debug view, not a decision aid #1275's decision-aid vocabulary.3. REST
SyncPreviewResult,[Authorize], OpenAPI regenerated.4. PowerShell
Settled questions (were open on this issue's original form)
Acceptance criteria
docs/and aCHANGELOG.mdentry.Related
Implementation plan
See
engineering/plans/SYNC_PREVIEW_SURFACE.md(branchfeature/sync-preview-surface): Phase 1 completes the cascade as the bottom stack layer, Phase 2 ships the three surfaces on top.