feat(sdk): close generic MultiPwsh SDK gaps for safe RDM porting - #70
Conversation
Add the generic SDK capabilities identified by the post-0.17 reassessment, keeping the public native ABI at v2 and the payload-local table a single required V1 shape with no optional negotiation. - Composite observed invocation: one invocation carries typed results and bounded diagnostic records on independently acknowledged channels. An unacknowledged full channel applies backpressure instead of dropping records. Payload-table growth is guarded by header-first validation so an older, smaller managed table is rejected before any extended slot is read. - Non-executing session preflight: ValidateSessionConfiguration resolves module roots, imports, and the working directory, and reads manifests AST-only. Manifests that declare module-loading paths outside an approved root report ManifestDeclaresExternalPath and are refused at creation. - Staged intents: a host-owned stage/validate/commit/abort coordinator over the existing capability dispatcher, with no Rust changes and no new callback path. An in-flight commit wins over a racing expiry, and coordinator-initiated termination delivers a best-effort abort so the application can release stage state. Commit acknowledges host acceptance only and promises no cross-resource atomicity. - Ergonomics: PowerShellCompleteResultProjection maps exactly one complete result onto a generated DTO with explicit cardinality, incomplete, and projection failures. PowerShellRuntime.Diagnostics reports descriptive deployment facts only, and documents that its payload directory is the runtime canonicalized path rather than a verbatim echo of an activation argument. - Contract packs stay strict and gain fixtures proving all five distinct rejection reasons end to end through the NativeAOT sample: duplicate identifiers across packs and within one pack, direction violations, reserved identifiers, and unknown pack ABIs. Packs remain coordinated breaking releases with no version negotiation. - Qualification records the resolved PowerShell build instead of asserting a pinned patch. The CI installer verifies the extracted pwsh reports the resolved tag and exports PwshQualifiedVersion; the package harness cross-checks the payload version against the PowerShellFileVersion that runtime diagnostics report. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Expands the in-process SDK with observed invocations, session preflight, staged intents, result projection, and runtime diagnostics while retaining ABI v2.
Changes:
- Adds bounded observed-result and diagnostic channels.
- Adds session preflight, staged-intent coordination, and DTO projection.
- Extends qualification, ABI baselines, samples, CI, and documentation.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/ci.yml |
Runs contract-pack rejection fixtures. |
RELEASE.md |
Documents SDK release qualification. |
crates/pwsh-host/src/bindings.rs |
Exports new host binding types. |
crates/pwsh-host/src/bindings/ffi.rs |
Implements new payload bindings and observed paging. |
crates/pwsh-host/src/lib.rs |
Publishes new host APIs. |
crates/pwsh-host/src/loader.rs |
Exposes payload diagnostics. |
crates/pwsh-sdk-ffi/src/lib.rs |
Implements native SDK exports and orchestration. |
docs/feature-matrix.md |
Records new preview capabilities. |
docs/in-process-ffi.md |
Documents behavior and safety boundaries. |
docs/testing.md |
Documents package qualification. |
dotnet/bindings/FfiBindings.cs |
Implements payload preflight and binding slots. |
dotnet/live-object-incompatible-test-pack/IncompatibleContractPackFixtures.cs |
Adds rejection fixtures. |
dotnet/nativeaot-sample/ConnectionPatchIntentHandler.cs |
Demonstrates staged intent handling. |
dotnet/nativeaot-sample/Program.cs |
Exercises staged intents and contract rejection. |
dotnet/sdk-ffi/NativeMethods.cs |
Declares new native exports. |
dotnet/sdk-ffi/PowerShell.cs |
Negotiates and starts observed invocations. |
dotnet/sdk-ffi/PowerShellCompleteResultProjection.cs |
Adds complete-result DTO projection. |
dotnet/sdk-ffi/PowerShellObservedDiagnosticPage.cs |
Defines diagnostic page DTOs. |
dotnet/sdk-ffi/PowerShellObservedDiagnosticPageHandle.cs |
Manages diagnostic page handles. |
dotnet/sdk-ffi/PowerShellObservedInvocation.cs |
Implements observed page reading. |
dotnet/sdk-ffi/PowerShellObservedInvocationHandle.cs |
Manages observed invocation handles. |
dotnet/sdk-ffi/PowerShellObservedInvocationOptions.cs |
Defines channel bounds. |
dotnet/sdk-ffi/PowerShellRuntime.cs |
Exposes diagnostics, preflight, and staged intents. |
dotnet/sdk-ffi/PowerShellRuntimeDiagnosticReport.cs |
Defines runtime diagnostic reporting. |
dotnet/sdk-ffi/PowerShellSession.cs |
Adds native session preflight. |
dotnet/sdk-ffi/PowerShellSessionPreflightReport.cs |
Defines preflight report DTOs. |
dotnet/sdk-ffi/PowerShellStagedIntent.cs |
Defines staged-intent contracts. |
dotnet/sdk-ffi/PowerShellStagedIntentCoordinator.cs |
Coordinates intent lifecycles. |
dotnet/sdk-ffi/PowerShellStagedIntentSchema.cs |
Validates staged payload schemas. |
dotnet/sdk-ffi/PowerShellTypedResultInvocation.cs |
Reuses typed-value decoding. |
dotnet/sdk-ffi/README.md |
Documents facade APIs. |
scripts/Install-PowerShell74ForCi.ps1 |
Records qualified PowerShell versions. |
tests/PwshFfiApiBaseline.txt |
Updates the public API baseline. |
tests/PwshFfiApiBaselineInspector/Program.cs |
Verifies new feature bits. |
tests/Test-PwshFfiPackage.ps1 |
Expands end-to-end package coverage. |
tests/Verify-PwshFfiApiBaseline.ps1 |
Validates added ABI slots and layouts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| PowerShellValue? immediateResponse = null; | ||
| lock (gate) | ||
| { | ||
| if (!stages.TryGetValue(stageIdentifier!, out entry)) |
There was a problem hiding this comment.
Fixed in 5cba805. Active-stage and retained-terminal lookups now require the matching PowerShellStagedIntentDefinition; a different definition receives unknown-stage. Added a two-definition package-harness regression covering both active and terminal lookup.
| FileSystemInfo info = isDirectory ? new DirectoryInfo(fullPath) : new FileInfo(fullPath); | ||
| FileSystemInfo target = info.ResolveLinkTarget(returnFinalTarget: true); | ||
| string canonicalPath = Path.GetFullPath(target?.FullName ?? info.FullName); |
There was a problem hiding this comment.
Fixed in 5cba805. CanonicalizeExistingPath now resolves every existing path component before the root check, rather than resolving only the final entry. Added a package-harness junction fixture proving a manifest RootModule beneath an in-root junction targeting an external directory is rejected.
| if (!TryGetManifestLoadPaths(pair.Item2, out string[] declaredPaths)) | ||
| { | ||
| declarationsUnavailable = true; | ||
| continue; |
There was a problem hiding this comment.
Fixed in 5cba805. Non-static values for any module-loading manifest key now fail closed as ManifestInvalid, which causes both preflight and session creation rejection. Added a package-harness regression using a computed RootModule declaration.
- Scope staged intent lookups and retained terminal metadata to their owning definition so one capability cannot invoke another definition's handler. - Canonicalize every existing path component before authorizing module or manifest paths, closing junction and symlink ancestor escapes. - Reject non-static module-loading manifest declarations rather than allowing an unverified computed path to reach module import. - Require a dot-delimited PowerShell file-version suffix when matching the qualified payload version. Add package-harness regressions for cross-definition access, dynamic manifest loads, and junction escapes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
a873ae8
into
master
Summary
Implements the generic SDK capabilities identified after the 0.17 qualification merge while preserving the public native ABI v2 and the required payload-local V1 table.
stage/validate/commit/abort) without new callback paths or cross-resource atomicity guarantees.Validation
cargo fmt --all --checkcargo clippy --workspace --all-targetscargo build --all-targetscargo test --all-targets(234 passed, 5 ignored)FFI package consumer: Success)Qualified payload: PowerShell
7.4.17(runtime file version7.4.17.500).