Skip to content

Sync Preview: complete the destructive cascade and ship the per-object administrator surface (portal, REST, PowerShell) #1519

Description

@JayVDZ

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 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.

Related

Implementation plan

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions