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
AiSettingsNodeType.AddSkillSource is fire-and-forget — a fast uninstall can be undone by a late install write #683
AiSettingsNodeType.AddSkillSource(hub, services, user, sourceNamespace) returns void and subscribes to its own write internally:
hub.GetWorkspace().GetQuery(...).Take(1).SelectMany(nodes =>meshService.CreateOrUpdateNode(targetwith{Content=merged})).Subscribe(_ =>{}, ex =>logger.LogWarning(...));
The caller gets no completion signal, so the Store's install plan can write its manifest — and report the install finished — before the settings update has landed.
Sequence that loses the fix:
install → AddSkillSource subscribes, write in flight
install plan writes the manifest, reports success
viewer uninstalls promptly → deregistration finds no row to remove, completes cleanly, clears the record
the step-1 write lands → the viewer now has a skill source for a package whose nodes are gone, and no record that says they ever installed it
The result is exactly the stale composer source that MeshWeaver.Plugins#199 set out to eliminate, reachable whenever install and uninstall happen close together.
That PR fixes the uninstall side (withdrawal now propagates failure instead of clearing the record on a silent miss). This one is the install side, and fixing it properly means giving AddSkillSource a completion signal — an IObservable<Unit> overload the install plan can sequence on, so registration is a phase like every other rather than a side effect racing the manifest.
That is a core API change with its own semantics and tests; smuggling it into an uninstall PR would have been the wrong shape.
Suggested fix
Add an observable-returning overload (keeping the void one for existing fire-and-forget callers) and have Localizer's Register skills phase sequence on it, so the manifest — which is deliberately the LAST phase — cannot be written before the skill source is actually registered.
Found by the Copilot review on MeshWeaver.Plugins#199.
Activity
Write the rule down so the trapdoor cannot come back
Merge origin/main — keep #1067's deploy key and tester packing, drop …