You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Native Plan edits bypass a custom SessionFs provider #2814
With an absolute SessionStatePath and a custom SessionFsProvider, the native edit tool reports success for the canonical plan.md path but writes an operating-system file instead of updating the provider. SDK Plan readback remains stale.
Configures an absolute SessionStatePath with a custom provider.
Writes # Host plan through Plan.UpdateAsync.
Calls the native edit tool on the exact path returned by Plan.ReadAsync.
Reads the Plan again through the SDK and checks both the provider write count and operating-system path.
Expected
The native edit goes through the configured provider:
SDK readback returns # Native update.
The provider records a second Plan write.
No operating-system file is created at the virtual session-state path.
Actual
The native tool reports success, but state splits:
Observation
Value
SDK content before edit
# Host plan
SDK content after edit
# Host plan
Provider Plan writes before edit
1
Provider Plan writes after edit
1
Operating-system file created
Yes
Operating-system file content
# Native update
A scripted real agent turn reproduces the same behavior. Native create reaches the provider, while the subsequent native edit claims success, bypasses SessionFs, and leaves SDK/provider state unchanged.
This is related to, but distinct from, #2698. The failure is not only permission evaluation: the successful write itself bypasses the registered provider.
What I looked at:dotnet/src/Client.cs (~L2094) and dotnet/src/Types.cs (SessionFsConfig.SessionStatePath), plus the generated RPC sessionFs.setProvider surface in dotnet/src/Generated/Rpc.cs.
Findings: The SDK only registers the provider with the runtime (initialCwd, sessionStatePath, conventions, capabilities) and then services the sessionFs.* callbacks. Which filesystem a native tool such as edit uses is decided by the Copilot CLI runtime, not by SDK code. The SDK has no hook that could route edit to the OS filesystem. Your results match that: create reaches the provider, while edit reports success but writes directly to disk. That points to the runtime's edit tool not resolving the plan path through the SessionFs abstraction.
I couldn't run your Windows repro in this environment, so this comes from code analysis and your table. It is consistent with the documented contract that the runtime uses the provider's session state path when one is configured.
Label:bug. The behavior contradicts the intended SessionFs contract, because writes under the virtual session-state path should go through the provider. The fix is most likely in the runtime's native edit tool and not in the SDK. Related: #2698.
Generated by Bug Handler for #2814 · copilot · auto · 16.4 AIC · ⌖ 5.36 AIC · ⊞ 7.5K · ◷
Activity
github-actions commentedon Oct 6, 2026
Thanks for the detailed report and repro.
What I looked at:
dotnet/src/Client.cs(~L2094) anddotnet/src/Types.cs(SessionFsConfig.SessionStatePath), plus the generated RPCsessionFs.setProvidersurface indotnet/src/Generated/Rpc.cs.Findings: The SDK only registers the provider with the runtime (
initialCwd,sessionStatePath, conventions, capabilities) and then services thesessionFs.*callbacks. Which filesystem a native tool such asedituses is decided by the Copilot CLI runtime, not by SDK code. The SDK has no hook that could routeeditto the OS filesystem. Your results match that:createreaches the provider, whileeditreports success but writes directly to disk. That points to the runtime'sedittool not resolving the plan path through the SessionFs abstraction.I couldn't run your Windows repro in this environment, so this comes from code analysis and your table. It is consistent with the documented contract that the runtime uses the provider's session state path when one is configured.
Label:
bug. The behavior contradicts the intended SessionFs contract, because writes under the virtual session-state path should go through the provider. The fix is most likely in the runtime's nativeedittool and not in the SDK. Related: #2698.