Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/advanced/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Planning creates a deterministic plan:
- evaluates declarative conditions
- validates inputs and references
- produces data-only actions
- captures a **data-only request intent snapshot** (e.g. IdentityKeys / DesiredState / Changes) for auditing and export

### Execute

Expand All @@ -44,6 +45,14 @@ The canonical contract format is defined here:

- [Plan export specification (JSON)](../specs/plan-export.md)

The exported artifact is intended for **approvals, CI checks, and audits**.
To keep exports deterministic and review-friendly, the contract intentionally omits volatile information
such as engine build versions and timestamps. When required, hosts SHOULD attach build/time metadata
outside the exported plan artifact.

Because IdLE separates planning from execution, the plan retains a **request intent snapshot** so that
exports can include `request.input` even after the original request object is no longer available.

## Declarative conditions

Conditions are data-only objects.
Expand Down
1 change: 1 addition & 0 deletions docs/reference/cmdlets.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This page links the generated per-cmdlet reference pages and includes their syno

| Cmdlet | Synopsis |
| --- | --- |
| [Export-IdlePlan](cmdlets/Export-IdlePlan.md) | Exports an IdLE LifecyclePlan as a canonical JSON artifact. |
| [Invoke-IdlePlan](cmdlets/Invoke-IdlePlan.md) | Executes an IdLE plan. |
| [New-IdleLifecycleRequest](cmdlets/New-IdleLifecycleRequest.md) | Creates a lifecycle request object. |
| [New-IdlePlan](cmdlets/New-IdlePlan.md) | Creates a deterministic plan from a lifecycle request and a workflow definition. |
Expand Down
131 changes: 131 additions & 0 deletions docs/reference/cmdlets/Export-IdlePlan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
external help file: IdLE-help.xml
Module Name: IdLE
online version:
schema: 2.0.0
---

# Export-IdlePlan

## SYNOPSIS
Exports an IdLE LifecyclePlan as a canonical JSON artifact.

## SYNTAX

```
Export-IdlePlan [-Plan] <Object> [[-Path] <String>] [-PassThru] [-ProgressAction <ActionPreference>]
[<CommonParameters>]
```

## DESCRIPTION
This cmdlet is the **user-facing** wrapper exposed by the IdLE meta module.

It delegates to IdLE.Core's \`Export-IdlePlanObject\`, which implements the canonical
plan export contract.

By default, the cmdlet returns a pretty-printed JSON string.
If -Path is provided,
the JSON is written to disk as UTF-8 (no BOM).
Use -PassThru to also return the JSON
string when writing a file.

## EXAMPLES

### EXAMPLE 1
```
$plan = New-IdlePlan -Request $request -Workflow $workflow -StepRegistry $registry
$plan | Export-IdlePlan
```

Exports the plan and returns the JSON string.

### EXAMPLE 2
```
New-IdlePlan -Request $request -Workflow $workflow -StepRegistry $registry |
Export-IdlePlan -Path ./artifacts/plan.json
```

Exports the plan and writes the JSON to a file.

### EXAMPLE 3
```
New-IdlePlan -Request $request -Workflow $workflow -StepRegistry $registry |
Export-IdlePlan -Path ./artifacts/plan.json -PassThru
```

Writes the file and also returns the JSON string.

## PARAMETERS

### -Plan
The LifecyclePlan object to export.
Accepts pipeline input.

```yaml
Type: Object
Parameter Sets: (All)
Aliases:

Required: True
Position: 1
Default value: None
Accept pipeline input: True (ByValue)
Accept wildcard characters: False
```

### -Path
Optional file path to write the JSON artifact to.

```yaml
Type: String
Parameter Sets: (All)
Aliases:

Required: False
Position: 2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -PassThru
When -Path is used, returns the JSON string in addition to writing the file.

```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: False
Accept pipeline input: False
Accept wildcard characters: False
```

### -ProgressAction
{{ Fill ProgressAction Description }}

```yaml
Type: ActionPreference
Parameter Sets: (All)
Aliases: proga

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).

## INPUTS

## OUTPUTS

### System.String
## NOTES

## RELATED LINKS
15 changes: 6 additions & 9 deletions docs/reference/steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This page documents built-in IdLE steps discovered from `Invoke-IdleStep*` funct

---

### EmitEvent
## EmitEvent

- **Step Name**: $stepType
- **Implementation**: $commandName
Expand All @@ -29,10 +29,9 @@ to write structured events.

_Unknown (not detected automatically). Document required With.* keys in the step help and/or use a supported pattern._


---

### EnsureAttribute
## EnsureAttribute

- **Step Name**: $stepType
- **Implementation**: $commandName
Expand All @@ -56,11 +55,9 @@ The step is idempotent by design: it converges state to the desired value.
**Inputs (With.\*)**

| Key | Required |
|---|---|
| $k | Yes |
| $k | Yes |
| $k | Yes |

| --- | --- |
| IdentityKey | Yes |
| Name | Yes |
| Value | Yes |

---

58 changes: 48 additions & 10 deletions docs/specs/plan-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ The plan export MUST NOT contain:
{
"schemaVersion": "1.0",
"engine": {
"name": "IdLE",
"version": "0.4.0"
"name": "IdLE"
},
"request": { },
"plan": { },
Expand All @@ -57,37 +56,75 @@ The plan export MUST NOT contain:
Version of this JSON schema (this contract).
Independent from the IdLE engine version.

### engine

Identifies the engine that produced the exported plan.
The engine object is informational only and MUST NOT be used for contract compatibility decisions.

- engine.name is required and identifies the producing engine (e.g. IdLE).
- engine.version is intentionally omitted in this specification.

The engine version is not part of the contract to ensure stable, deterministic exports across engine version bumps.
Contract compatibility and evolution are tracked exclusively via schemaVersion.

Hosts that require engine build or release information SHOULD attach it as external metadata outside of the exported plan artifact.

---

## Request Object

Represents the **business intent** that produced the plan.

The request object captures *why* a plan was created, independent of *how* it will be executed.

```json
"request": {
"type": "Joiner",
"correlationId": "123e4567-e89b-12d3-a456-426614174000",
"actor": "HR-System",
"input": {
"userId": "jdoe",
"department": "IT"
"identityKeys": {
"userId": "jdoe"
},
"desiredState": {
"department": "IT"
},
"changes": null
}
}
```

Rules:
### Fields

| Field | Description |
| ------ | ------------- |
| type | Logical lifecycle request type (e.g. Joiner, Mover, Leaver) |
| correlationId | Stable identifier correlating request, plan, and execution |
| actor | Originator of the request (system or human), if available |
| input | Business intent payload (data-only) |

- `input` is opaque to the engine
- No validation logic is implied by the export
### Rules

---
- The `request` object represents **business intent**, not execution details.
- `input` is treated as **opaque by the engine**:
- the engine MUST NOT rely on input semantics
- no validation logic is implied by the export
- `input` MUST contain **data-only content**:
- no script blocks
- no executable expressions
- no runtime handles
- For **IdLE-native lifecycle requests**, `input` SHOULD contain:
- `identityKeys` – identifiers of the target identity
- `desiredState` – intended target state
- `changes` – explicit deltas, if applicable
- Hosts MAY include additional fields in `input`.
- The request payload is exported for **audit, approval, and traceability purposes** and MUST remain stable once the plan is created.

## Plan Object

```json
"plan": {
"id": "plan-001",
"createdAt": "2025-01-01T10:15:00Z",
"mode": "PlanOnly",
"steps": []
}
Expand All @@ -98,7 +135,7 @@ Rules:
| Field | Description |
| ------ | ------------ |
| id | Unique identifier of the plan |
| createdAt | ISO-8601 UTC timestamp |
| createdAt | (Optional) ISO-8601 UTC timestamp |
| mode | Plan lifecycle state |
| steps | Ordered list of step objects |

Expand Down Expand Up @@ -207,6 +244,7 @@ The engine MUST NOT rely on metadata semantics.
- LF line endings
- Pretty-printed JSON
- Stable property ordering
- createdAt MAY be omitted for deterministic exports.

---

Expand Down
3 changes: 2 additions & 1 deletion src/IdLE.Core/IdLE.Core.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
'New-IdleLifecycleRequestObject',
'Test-IdleWorkflowDefinitionObject',
'New-IdlePlanObject',
'Invoke-IdlePlanObject'
'Invoke-IdlePlanObject',
'Export-IdlePlanObject'
)
CmdletsToExport = @()
AliasesToExport = @()
Expand Down
3 changes: 2 additions & 1 deletion src/IdLE.Core/IdLE.Core.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ Export-ModuleMember -Function @(
'New-IdleLifecycleRequestObject',
'Test-IdleWorkflowDefinitionObject',
'New-IdlePlanObject',
'Invoke-IdlePlanObject'
'Invoke-IdlePlanObject',
'Export-IdlePlanObject'
) -Alias @()
Loading