Skip to content

Keep kit variables out of worker callbacks; find drives made in a function - #28

Merged
HalRiveria merged 2 commits into
mainfrom
fix/worker-callback-scoping
Nov 2, 2026
Merged

HalRiveria merged 2 commits into
mainfrom
fix/worker-callback-scoping

Conversation

@HalRiveria-Bot

Copy link
Copy Markdown
Collaborator

What was wrong

Two gaps were left after the kit became an in-memory module in #27:

  • Callbacks inside a worker runspace. There the kit's functions are plain copies, not a module. A closure-less -OnComplete given to Invoke-PkProcessBatch in a worker could still add to the batch's own $results, write to its $state, and read its $TimeoutSeconds, with silently wrong results. Dispatcher callbacks had the same problem, for example reading the kit's $running.
  • A drive made with New-PSDrive inside a function. It can only be seen from that function, so the module couldn't resolve a WorkingDirectory or FilePath on it.

Generated lookup script (added in #27) also quoted names and paths by doubling ASCII single quotes only. PowerShell also treats curly quotes as string delimiters, so a curly quote could end the literal early. A new check showed a path running as code in the caller's scope.

What changed

  • pk-prefixed variables in Invoke-PkProcessBatch, Invoke-PkProcessDispatch, Invoke-PkProcessDispatchCore and the group-building helper. Locals are renamed, and parameters are copied to pk names and removed. Public parameter names don't change. The diff is large, but the rename itself was done mechanically from the syntax tree.
  • The drive lookup falls back to the caller's session. When the module's own lookup fails, the path is resolved again from where the kit was called. Start-PkProcess is now a thin wrapper over an internal function that takes the caller's session, and Invoke-PkProcessWithTimeout, the dispatcher's default starter and the batch pass theirs. Paths the module can already resolve take the same route as before.
  • Quoting uses CodeGeneration.EscapeSingleQuotedStringContent, in the function lookup and the path lookup.
  • README: plain callbacks no longer need .GetNewClosure() inside a worker, and the -Scope Script advice for drives is gone.

Still true: a closure-less callback in a worker can see a kit function's automatic variables, such as $PSBoundParameters, and a variable of the worker's own named with the pk prefix could collide.

Testing

  • New harness section AA, 7 checks:
    • in a worker, plain callbacks reach the worker's $results, $state, $TimeoutSeconds and $running;
    • a guard lists every variable visible from plain batch and dispatcher callbacks in a worker, and fails on any kit variable without the prefix;
    • a WorkingDirectory on a function-local drive works from Invoke-PkProcessWithTimeout, Start-PkProcess, the batch, the batch under Invoke-PkRun and the dispatcher;
    • a FilePath on that drive works;
    • a drive that doesn't exist still gives a clear start error;
    • a path with a curly quote stays a path.
  • Against main's kit (5.1), the worker and drive checks fail (5 FAILED, 1 passed, run before the curly-quote check existed). The nonexistent-drive check passes on both, as a guard. The curly-quote check failed before its fix on this branch.
  • With the change: ALL PASSED (288 assertions) on Windows PowerShell 5.1 and PowerShell 7.

🤖 Generated with Claude Code

HalRiveria and others added 2 commits November 2, 2026 11:11
…ction

Loading the kit as a module fixed closure-less callbacks on the main
thread, but inside a worker runspace the kit's functions are plain copies,
not a module. So a plain -OnComplete in a worker could still reach the
batch's own $results or $state, and read its $TimeoutSeconds. Batch,
Dispatch, DispatchCore and the group-building helper now use only
pk-prefixed variables: locals are renamed, and parameters are copied and
removed. Public parameter names don't change. A callback there now sees
the worker's variables, so .GetNewClosure() isn't needed for that anywhere.

A drive made with New-PSDrive inside a function stopped working when the
kit became a module, since a module can't see it. When the module's own
lookup fails, the path is now resolved again in the caller's session.
Start-PkProcess became a thin wrapper over an internal function that takes
that session, and the entry points pass theirs down. This adds nothing to
paths the module can already resolve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@HalRiveria
HalRiveria merged commit 31cac86 into main Nov 2, 2026
2 checks passed
@HalRiveria
HalRiveria deleted the fix/worker-callback-scoping branch November 2, 2026 16:37
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.

2 participants