Skip to content

Stabilize public API, contracts, and compatibility policy for v1.0.0#115

Merged
blindzero merged 14 commits intomainfrom
copilot/stabilize-public-api-v1-0-0
Jan 25, 2026
Merged

Stabilize public API, contracts, and compatibility policy for v1.0.0#115
blindzero merged 14 commits intomainfrom
copilot/stabilize-public-api-v1-0-0

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 25, 2026

Summary

Establishes v1.0 API surface, enforces it with stability tests, implements capability ID migration with deprecation mapping, and documents compatibility guarantees.

Motivation

Pre-1.0 baseline: consumers need clear contracts defining what's supported, what may change, and how deprecation works. Without enforcement, accidental API drift creates compatibility risks.

Type of Change

  • New feature
  • Documentation update

Changes

API Surface Enforcement

  • Stability tests integrated into existing tests/ModuleSurface.Tests.ps1: enforces exact export list—no more, no less
  • v1.0 supported commands: Test-IdleWorkflow, New-IdleLifecycleRequest, New-IdlePlan, Invoke-IdlePlan, Export-IdlePlan, New-IdleAuthSession (new wrapper function)
  • Created New-IdleAuthSession wrapper in src/IdLE/Public/New-IdleAuthSession.ps1 to expose auth session broker from meta-module with cleaner naming (Core retains New-IdleAuthSessionBroker)

Defense-in-Depth: Internal Module Warnings

  • IdLE.Core and IdLE.Steps.Common emit warnings on direct import:
    WARNING: IdLE.Core is an internal/unsupported module. Import 'IdLE' instead for the supported public API.
    To bypass: $env:IDLE_ALLOW_INTERNAL_IMPORT = '1'
    
  • Uses ScriptsToProcess mechanism: IdLE.Init.ps1 sets $env:IDLE_ALLOW_INTERNAL_IMPORT = '1' before NestedModules load
  • Warnings appear by default on direct import; suppressed during correct Import-Module IdLE
  • Bypass available via $env:IDLE_ALLOW_INTERNAL_IMPORT = '1' (environment variable syntax, not Set-Variable)
  • Tested warning emission and bypass mechanism in ModuleSurface.Tests.ps1

Capability Rename: IdLE.Mailbox.ReadIdLE.Mailbox.Info.Read

  • Normalization function in New-IdlePlanObject.ps1: maps deprecated IDs during planning
  • Deprecation warning: "DEPRECATED: Capability 'IdLE.Mailbox.Read' is deprecated in v1.0 and will be removed in v2.0. Use 'IdLE.Mailbox.Info.Read' instead."
  • Updated provider, step metadata catalog, tests to use new ID
  • Fully backward-compatible via automatic mapping

Example:

# Provider still advertising old capability
$provider.GetCapabilities() # Returns @('IdLE.Mailbox.Read')

# Planning auto-normalizes and warns
$plan = New-IdlePlan -WorkflowPath $wf -Request $req -Providers @{ P = $provider }
# WARNING: DEPRECATED: Capability 'IdLE.Mailbox.Read' is deprecated in v1.0...
# Plan uses 'IdLE.Mailbox.Info.Read' internally

Documentation

  • v1.0 contracts merged into existing docs for better discoverability:
    • docs/advanced/architecture.md: Added "v1.0 Public API and Contracts" section covering supported commands, command contracts, data contracts, and capability ID baseline (14 IDs frozen for v1.0)
    • docs/advanced/releases.md: Added semantic versioning policy and deprecation mechanism format
  • Created cmdlet reference for New-IdleAuthSession at docs/reference/cmdlets/New-IdleAuthSession.md
  • Updated docs/index.md and docs/_sidebar.md
  • Removed standalone docs/advanced/compatibility.md (content integrated into architecture.md and releases.md)

Testing

  • Unit tests
  • Contract tests
  • Manual testing

How to test & review

# Module surface tests: enforce exact export list and internal module warnings
pwsh -File ./tools/Invoke-IdlePesterTests.ps1 -TestPath tests/ModuleSurface.Tests.ps1

# Deprecation tests: verify warning + mapping
pwsh -File ./tools/Invoke-IdlePesterTests.ps1 -TestPath tests/CapabilityDeprecation.Tests.ps1

# Full suite: 323 tests passing
pwsh -File ./tools/Invoke-IdlePesterTests.ps1

Checklist

  • Code follows STYLEGUIDE.md
  • Tests added or updated
  • Documentation updated
  • No UI/auth logic added to IdLE.Core
  • No breaking changes without discussion

Related Issues

Issue #16 (v1.0 API stabilization)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits January 25, 2026 16:44
- Added StabilityContract.Tests.ps1 to enforce v1.0 API surface
- Added internal module import warnings with IDLE_ALLOW_INTERNAL_IMPORT bypass
- Implemented capability rename: IdLE.Mailbox.Read → IdLE.Mailbox.Info.Read
- Added deprecation mapping with warnings during planning
- Updated provider, step metadata, and tests to use new capability ID
- Added CapabilityDeprecation.Tests.ps1 to validate migration behavior
- Created New-IdleAuthSessionBroker wrapper in IdLE module

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
- Created docs/advanced/compatibility.md with comprehensive v1.0 contracts
- Documented supported API surface and enforcement
- Documented stability contracts (command, data, non-contracts)
- Documented capability ID baseline and deprecation
- Documented deprecation mechanism
- Updated docs/index.md and docs/_sidebar.md to reference new doc
- Fixed ModuleSurface.Tests.ps1 to include New-IdleAuthSessionBroker

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
- Updated capability deprecation warning to include specific version info
- Format: 'DEPRECATED: <Item> is deprecated in v1.0 and will be removed in v2.0'
- Follows the documented deprecation mechanism from compatibility.md

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copilot AI changed the title [WIP] Define stable public API and contracts for v1.0.0 Stabilize public API, contracts, and compatibility policy for v1.0.0 Jan 25, 2026
Copilot AI requested a review from blindzero January 25, 2026 16:51
- Merged internal module warning tests into ModuleSurface.Tests.ps1
- Removed StabilityContract.Tests.ps1 (duplicate functionality)
- Merged compatibility.md content into architecture.md and releases.md
- Removed standalone compatibility.md file (clearer doc structure)
- Updated navigation in docs/index.md and docs/_sidebar.md
- All 322 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
- Renamed src/IdLE/Public/New-IdleAuthSessionBroker.ps1 to New-AuthSessionBroker.ps1
- Avoids confusion with IdLE.Core\New-IdleAuthSessionBroker.ps1
- Wrapper remains minimal with concise help pointing to full docs in Core
- All 322 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
- Renamed src/IdLE/Public/New-AuthSessionBroker.ps1 to New-IdleAuthSession.ps1
- Follows the *-Idle*.ps1 naming convention used by other public files
- Updated comment to clarify why wrapper is necessary: PowerShell's Export-ModuleMember
  can only export functions in the current module's scope, not from nested modules
- All 322 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
- Filename is New-IdleAuthSession.ps1 (avoids collision with Core implementation)
- Function name remains New-IdleAuthSessionBroker (v1.0 public API requirement)
- This matches the pattern used by other wrappers
- All 322 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copy link
Copy Markdown
Owner

@blindzero blindzero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure cmdlet and steps reference is updated with internal tools

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request stabilizes the public API surface and contracts for IdLE v1.0.0 by implementing a comprehensive set of changes to prepare for the first major release.

Changes:

  • Introduced New-IdleAuthSession as the new public API wrapper for New-IdleAuthSessionBroker, providing a cleaner function name while maintaining backward compatibility at the internal level
  • Renamed capability identifier IdLE.Mailbox.Read to IdLE.Mailbox.Info.Read across all providers, steps, and tests, with automatic deprecation mapping and warning emission during plan creation
  • Added internal module import warnings to IdLE.Core and IdLE.Steps.Common to discourage direct imports and guide users to the supported public API, with a bypass mechanism via IDLE_ALLOW_INTERNAL_IMPORT environment variable
  • Documented the v1.0 public API contract, command contracts, data contracts, and capability ID baseline in architecture documentation
  • Established comprehensive versioning policy and deprecation mechanism guidelines in releases documentation
  • Consolidated and expanded module surface stability tests to verify exact exports and internal module behavior

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/Providers/ExchangeOnlineProvider.Tests.ps1 Updated test to verify the new capability name IdLE.Mailbox.Info.Read
tests/ModuleSurface.Tests.ps1 Added New-IdleAuthSession to expected exports and comprehensive internal module import warning tests
tests/CapabilityDeprecation.Tests.ps1 New test file validating deprecation mapping and warning emission for old capability ID
src/IdLE/Public/New-IdleAuthSession.ps1 New public wrapper function delegating to Core implementation
src/IdLE/IdLE.psm1 Added New-IdleAuthSession to module exports
src/IdLE/IdLE.psd1 Added New-IdleAuthSession to manifest exports
src/IdLE.Steps.Mailbox/Public/Get-IdleStepMetadataCatalog.ps1 Updated all mailbox step capability requirements to use new capability ID
src/IdLE.Steps.Common/IdLE.Steps.Common.psm1 Added internal module import warning with bypass mechanism
src/IdLE.Provider.ExchangeOnline/Public/New-IdleExchangeOnlineProvider.ps1 Updated provider to advertise new capability ID
src/IdLE.Core/Public/New-IdlePlanObject.ps1 Implemented capability normalization and deprecation mapping with warning emission
src/IdLE.Core/IdLE.Core.psm1 Added internal module import warning with bypass mechanism
docs/reference/providers/provider-entraID.md Updated all examples to use New-IdleAuthSession
docs/reference/providers/provider-ad.md Updated all examples to use New-IdleAuthSession
docs/reference/cmdlets/New-IdleAuthSession.md Generated documentation for new public cmdlet
docs/reference/cmdlets.md Added new cmdlet to index
docs/advanced/releases.md Documented versioning policy and deprecation mechanism
docs/advanced/architecture.md Documented v1.0 public API contracts and capability baseline

- Changed warning behavior to opt-in via IDLE_WARN_INTERNAL_IMPORT
- Avoids false positives when IdLE.Core/IdLE.Steps.Common load as nested modules
- Prevents failures in warning-as-error environments ($WarningPreference = 'Stop')
- Updated tests to reflect new behavior
- All 322 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 25, 2026

make sure cmdlet and steps reference is updated with internal tools

Already completed in commit 8c9d427. Ran Generate-IdleStepReference.ps1 (already up to date) and created cmdlet reference documentation for New-IdleAuthSession at docs/reference/cmdlets/New-IdleAuthSession.md and updated the index.

Copy link
Copy Markdown
Owner

@blindzero blindzero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot are you sure about the latest changes? For me the if (-not $env:IDLE_ALLOW_INTERNAL_IMPORT) sounds logically better then the new if ($env:IDLE_WARN_INTERNAL_IMPORT -eq '1')?
We just need to make sure that it is set correctly, right?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 25, 2026

@copilot are you sure about the latest changes? For me the if (-not $env:IDLE_ALLOW_INTERNAL_IMPORT) sounds logically better then the new if ($env:IDLE_WARN_INTERNAL_IMPORT -eq '1')?
We just need ...

The opt-in approach (IDLE_WARN_INTERNAL_IMPORT) is intentional to solve the technical limitation: PowerShell loads NestedModules (IdLE.Core) before the parent module (IdLE.psm1) executes, so we cannot set an environment variable from IdLE.psm1 to suppress warnings during nested load. With opt-out (IDLE_ALLOW_INTERNAL_IMPORT), correct usage (Import-Module IdLE) would still emit warnings, breaking warning-as-error environments. The opt-in approach ensures clean imports by default while still documenting internal modules as unsupported. If you prefer opt-out, we'd need a different detection mechanism (which proved unreliable in testing).

blindzero

This comment was marked as duplicate.

Copy link
Copy Markdown
Owner

@blindzero blindzero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot irgendwie funktioniert das Warning nun gar nicht mehr? Wenn ich IdLE.Core oder IdLE.Steps.Common direkt importiere kommt keine Warnung. Prüfe ob die Warnung wirklich so funktioniert wie gewünscht.

- Reverted to opt-out approach: warnings appear by default on direct import
- Added IdLE.Init.ps1 script that runs via ScriptsToProcess before NestedModules load
- IdLE.Init.ps1 sets IDLE_ALLOW_INTERNAL_IMPORT=1 to suppress warnings during correct import
- Direct imports of IdLE.Core/IdLE.Steps.Common now warn as intended
- Importing IdLE correctly produces no warnings
- Updated tests to verify new behavior
- All 323 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 25, 2026

@copilot irgendwie funktioniert das Warning nun gar nicht mehr? Wenn ich IdLE.Core oder IdLE.Steps.Common direkt importiere kommt keine Warnung. Prüfe ob die Warnung wirklich so funktioniert wie gew�...

Fixed in commit 63bc5f6. The warnings now work as expected:

  • Direct import of IdLE.Core or IdLE.Steps.Common shows warning
  • Import via Import-Module IdLE shows no warning (ScriptsToProcess sets IDLE_ALLOW_INTERNAL_IMPORT=1 before nested modules load)
  • Bypass still available via $env:IDLE_ALLOW_INTERNAL_IMPORT = '1'

All 323 tests passing.

@copilot irgendwie funktioniert das Warning nun gar nicht mehr? Wenn ich IdLE.Core oder IdLE.Steps.Common direkt importiere kommt keine Warnung. Prüfe ob die Warnung wirklich so funktioniert wie gew�...

Fixed in commit 63bc5f6. The warnings now work as expected:

  • Direct import of IdLE.Core or IdLE.Steps.Common shows warning
  • Import via Import-Module IdLE shows no warning (ScriptsToProcess sets IDLE_ALLOW_INTERNAL_IMPORT=1 before nested modules load)
  • Bypass still available via $env:IDLE_ALLOW_INTERNAL_IMPORT = '1'

All 323 tests passing.

Copy link
Copy Markdown
Owner

@blindzero blindzero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot the general behavior works as intended: direct import throws warning, tools like invoke-pester PSSA etc. dont.
However, if I follow the avoid instruction I still get a warning

Set-Variable -Name IDLE_ALLOW_INTERNAL_IMPORT -Value 1
Import-Module .\src\IdLE.Core\IdLE.Core.psd1 -Force   
WARNING: IdLE.Core is an internal/unsupported module. Import 'IdLE' instead for the supported public API. To bypass: set IDLE_ALLOW_INTERNAL_IMPORT=1.

- Updated warning messages to show correct PowerShell syntax: `$env:IDLE_ALLOW_INTERNAL_IMPORT = '1'`
- Previous message was ambiguous ("set IDLE_ALLOW_INTERNAL_IMPORT=1")
- Users were incorrectly using Set-Variable instead of $env:
- Updated tests to verify correct syntax appears in warnings
- All 323 tests passing

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 25, 2026

@copilot the general behavior works as intended: direct import throws warning, tools like invoke-pester PSSA etc. dont.
However, if I follow the avoid instruction I still get a warning

The issue was the warning message showing ambiguous syntax. Fixed in commit 9d906c2 - the warning now displays the correct PowerShell syntax: $env:IDLE_ALLOW_INTERNAL_IMPORT = '1' instead of the previous "set IDLE_ALLOW_INTERNAL_IMPORT=1". The bypass works correctly when using $env: (environment variable) rather than Set-Variable (PowerShell variable).

@blindzero blindzero merged commit 93f78cb into main Jan 25, 2026
5 checks passed
@blindzero blindzero linked an issue Jan 25, 2026 that may be closed by this pull request
@blindzero blindzero deleted the copilot/stabilize-public-api-v1-0-0 branch January 25, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stabilize public API, contracts, and compatibility policy for 1.0.0

3 participants