Conversation
Test Results 43 files + 7 43 suites +7 20m 29s ⏱️ + 14m 19s For more details on these failures, see this check. Results for commit 10ed4fa. ± Comparison against base commit f6c2dea. This pull request removes 261 and adds 2017 tests. Note that renamed tests count towards both.This pull request removes 7 skipped tests and adds 6 skipped tests. Note that renamed tests count towards both.This pull request skips 1 and un-skips 6 tests.♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
Pull request overview
This PR bundles several long-running feature and stability tracks across MeshWeaver core + Memex: social publishing foundations, in-process #r "nuget:..." compilation support (node-type + interactive markdown), move-operation performance/timeout hardening, and multiple UI/stream reliability improvements. It also standardizes the code folder naming from _Source/_Test to Source/Test across code, tests, docs, and samples.
Changes:
- Introduces
MeshWeaver.Social(options, DI wiring, publish queue, credential model) plus initial Memex wiring (LinkedIn connect entry points + user menu hooks). - Adds
MeshWeaver.NuGetresolver + directive parser and integrates it into script compilation (#r "nuget:Pkg, Version"), including cache backends and tests. - Improves operational robustness: parallelized recursive moves, default 30s mesh-op timeout, “no endless spinner” navigation status UI, and remote stream resubscribe behavior.
Reviewed changes
Copilot reviewed 159 out of 265 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/MeshWeaver.StorageImport.Test/StorageImporterTests.cs | Updates test expectations/docs to Source/ naming. |
| test/MeshWeaver.Social.Test/PostStatsRefresherTest.cs | Adds stats refresher test coverage (needs deterministic timeout handling). |
| test/MeshWeaver.Social.Test/MeshWeaver.Social.Test.csproj | Adds new Social test project referencing Social + Fixture. |
| test/MeshWeaver.Social.Test/InMemoryPublishQueueTest.cs | Adds unit tests for publish queue due-drain + dedup. |
| test/MeshWeaver.Persistence.Test/FileSystemPersistenceTest.cs | Updates partition tests to Source/ naming. |
| test/MeshWeaver.MathDemo.Test/TestPaths.cs | Adds helper paths for MathDemo sample test assets. |
| test/MeshWeaver.MathDemo.Test/MeshWeaver.MathDemo.Test.csproj | Adds MathDemo test project and copies sample graph data to output. |
| test/MeshWeaver.Hosting.PostgreSql.Test/SatelliteQueryTests.cs | Updates code-path routing tests to Source/ naming. |
| test/MeshWeaver.Hosting.Monolith.Test/UserActivityAreaTest.cs | Updates regression test docs to Source/ naming. |
| test/MeshWeaver.Hosting.Blazor.Test/NavigationServiceTest.cs | Adjusts test to assert “no 404 flash” during retries. |
| test/MeshWeaver.Graph.Test/NuGetDirectiveParserTest.cs | Adds unit tests for parsing/stripping #r "nuget:...". |
| test/MeshWeaver.Graph.Test/NuGetAssemblyResolverTest.cs | Adds networked NuGet restore end-to-end tests (skippable via env var). |
| test/MeshWeaver.Graph.Test/MeshWeaver.Graph.Test.csproj | References new MeshWeaver.NuGet project. |
| test/MeshWeaver.FutuRe.Test/MeshWeaver.FutuRe.Test.csproj | Updates compile-included sample sources to Source/ paths. |
| test/MeshWeaver.Content.Test/CompilationErrorTest.cs | Updates broken-code test to Source/ path. |
| test/MeshWeaver.AI.Test/MeshPluginTest.cs | Updates MCP tool count expectations (adds RunTests/Move/Copy). |
| src/MeshWeaver.Social/SocialOptions.cs | Adds configurable knobs for publishing/stats/ingest scheduling. |
| src/MeshWeaver.Social/SocialExtensions.cs | Adds DI wiring for social publishing subsystem and hosted services. |
| src/MeshWeaver.Social/PlatformCredential.cs | Adds credential record model (access/refresh/expiry metadata). |
| src/MeshWeaver.Social/MeshWeaver.Social.csproj | Introduces Social library project. |
| src/MeshWeaver.Social/IPublishQueue.cs | Adds publish queue abstraction + in-memory implementation. |
| src/MeshWeaver.Social/IApprovalPublishBridge.cs | Defines bridge contract and PublishableSnapshot model. |
| src/MeshWeaver.NuGet/ResolvedPackageSet.cs | Adds resolver output model (assemblies, probing dirs, versions). |
| src/MeshWeaver.NuGet/NuGetServiceCollectionExtensions.cs | Adds DI extension to register resolver + cache. |
| src/MeshWeaver.NuGet/NuGetPackageReference.cs | Adds package reference model (id + version range). |
| src/MeshWeaver.NuGet/NuGetDirectiveParser.cs | Implements #r "nuget:..." extraction + source stripping. |
| src/MeshWeaver.NuGet/MeshWeaver.NuGet.csproj | Introduces NuGet resolver project and dependencies. |
| src/MeshWeaver.NuGet/INuGetPackageCache.cs | Adds optional persistent cache interface + null implementation. |
| src/MeshWeaver.NuGet/INuGetAssemblyResolver.cs | Adds resolver interface returning ResolvedPackageSet. |
| src/MeshWeaver.NuGet.AzureBlob/MeshWeaver.NuGet.AzureBlob.csproj | Adds Azure Blob cache backend project. |
| src/MeshWeaver.NuGet.AzureBlob/BlobNuGetPackageCacheExtensions.cs | Adds DI helper to register blob-backed cache. |
| src/MeshWeaver.Mesh.Contract/Services/MeshOperationOptions.cs | Adds mesh operation timeout options (default 30s). |
| src/MeshWeaver.Mesh.Contract/Services/IStorageAdapter.cs | Updates docs/examples to Source/ naming. |
| src/MeshWeaver.Mesh.Contract/Services/INavigationService.cs | Adds Status observable contract for UI progress reporting. |
| src/MeshWeaver.Mesh.Contract/Services/IIconGenerator.cs | Adds icon generator abstraction returning an observable SVG. |
| src/MeshWeaver.Mesh.Contract/PartitionDefinition.cs | Updates standard table mappings (Source/Test → code) and clarifies semantics. |
| src/MeshWeaver.Mesh.Contract/MeshExtensions.cs | Adds timeout override + move timeout enforcement + grain dispose on delete. |
| src/MeshWeaver.Mesh.Contract/CodeConfiguration.cs | Updates docs to Source/ naming. |
| src/MeshWeaver.Kernel.Hub/MeshWeaver.Kernel.Hub.csproj | Removes Interactive package mgmt dependency; references MeshWeaver.NuGet. |
| src/MeshWeaver.Hosting/Persistence/MigrationUtility.cs | Updates migration heuristics to include Source/Test + legacy _Source/_Test. |
| src/MeshWeaver.Hosting/Persistence/FileSystemStorageAdapter.cs | Treats Source/Test as code paths + keeps legacy compatibility. |
| src/MeshWeaver.Hosting/Persistence/FileSystemPersistenceService.cs | Parallelizes descendant move I/O (with concurrency implications). |
| src/MeshWeaver.Hosting/Persistence/CachingStorageAdapter.cs | Updates code sub-namespace detection (Source/Test + legacy). |
| src/MeshWeaver.Hosting.PostgreSql/PostgreSqlPartitionedStoreFactory.cs | Guards against source/test mistakenly becoming schemas. |
| src/MeshWeaver.Hosting.PostgreSql/PostgreSqlCrossSchemaQueryProvider.cs | Filters malformed parameters to avoid NRE during SQL interpolation. |
| src/MeshWeaver.Hosting.Blazor/MeshWeaver.Hosting.Blazor.csproj | Adds NU1510 suppression. |
| src/MeshWeaver.Graph/PartitionTypeSource.cs | Updates docs to Source/ naming. |
| src/MeshWeaver.Graph/MeshWeaver.Graph.csproj | References MeshWeaver.NuGet. |
| src/MeshWeaver.Graph/MeshNodeLayoutAreas.cs | Improves create href behavior + reactive/grouped children catalog. |
| src/MeshWeaver.Graph/MeshDataSource.cs | Updates docs to Source/ naming. |
| src/MeshWeaver.Graph/Configuration/ScriptCompilationService.cs | Integrates NuGet directive parsing + resolver into compilation. |
| src/MeshWeaver.Graph/Configuration/NodeTypeDefinition.cs | Updates docs/examples to Source/ naming. |
| src/MeshWeaver.Graph/Configuration/MeshDataSourceNodeType.cs | Changes sources namespace constant to Source. |
| src/MeshWeaver.Graph/Configuration/GraphConfigurationExtensions.cs | Registers NuGet resolver and uses Source code path. |
| src/MeshWeaver.Graph/Configuration/CodeNodeType.cs | Treats Code nodes as primary content; defines Source/Test constants. |
| src/MeshWeaver.Documentation/Data/DataMesh/UnifiedPath.md | Documents @/ semantics and HTML-href pitfalls. |
| src/MeshWeaver.Documentation/Data/DataMesh/SocialMedia/Profile/Source/SocialMediaProfileLayoutAreas.cs | Adds SocialMedia profile layout areas example. |
| src/MeshWeaver.Documentation/Data/DataMesh/SocialMedia/Profile/Source/SocialMediaProfile.cs | Adds SocialMedia profile content model example. |
| src/MeshWeaver.Documentation/Data/DataMesh/SocialMedia/Post/Source/SocialMediaPost.cs | Adds SocialMedia post content model example. |
| src/MeshWeaver.Documentation/Data/DataMesh/SocialMedia/Post/Source/Platform.cs | Adds SocialMedia platform reference-data example. |
| src/MeshWeaver.Documentation/Data/DataMesh/SocialMedia.md | Updates docs to Source/ naming and authoring guidance. |
| src/MeshWeaver.Documentation/Data/DataMesh/SatelliteEntities.md | Clarifies Source/Test are primary content, not satellites. |
| src/MeshWeaver.Documentation/Data/DataMesh/NodeTypes.md | Adds Node Types documentation index page. |
| src/MeshWeaver.Documentation/Data/DataMesh/NodeTypeConfiguration.md | Updates docs to Source/ naming. |
| src/MeshWeaver.Documentation/Data/DataMesh/NodeOperations.md | Updates docs to Source/ naming. |
| src/MeshWeaver.Documentation/Data/DataMesh/DataConfiguration.md | Updates docs to Source/ naming. |
| src/MeshWeaver.Documentation/Data/DataMesh/CreatingNodeTypes.md | Updates docs to Source/Test naming throughout. |
| src/MeshWeaver.Documentation/Data/DataMesh.md | Updates TOC links and adds NuGet packages bullet. |
| src/MeshWeaver.Documentation/Data/Architecture/PartitionedPersistence.md | Updates persistence routing docs for Source/Test. |
| src/MeshWeaver.Documentation/Data/Architecture/MeshGraph.md | Updates examples to Source/ naming. |
| src/MeshWeaver.Documentation/Data/Architecture/BusinessRules/Cession/Source/CessionSampleData.cs | Adds cession sample dataset for docs/demo. |
| src/MeshWeaver.Documentation/Data/Architecture/BusinessRules/Cession/Source/CessionResultsArea.cs | Adds reactive charting layout area example. |
| src/MeshWeaver.Documentation/Data/Architecture/BusinessRules/Cession/Source/CessionEngine.cs | Adds pure business logic sample for cession calculations. |
| src/MeshWeaver.Documentation/Data/Architecture/BusinessRules/Cession/Source/CessionData.cs | Adds content models for cession example. |
| src/MeshWeaver.Data/Serialization/SyncStreamOptions.cs | Adds configurable heartbeat interval for sync streams. |
| src/MeshWeaver.Data/Serialization/JsonSynchronizationStream.cs | Implements resubscribe-on-owner-dispose logic. |
| src/MeshWeaver.Blazor/Pages/ApplicationPage.razor | Switches to NavigationStatus-driven progress/not-found/error UI. |
| src/MeshWeaver.Blazor/Components/NavigationProgressBar.razor.css | Adds styling for full-page vs compact overlay progress bar. |
| src/MeshWeaver.Blazor/Components/NavigationProgressBar.razor | Adds reusable “spinner + message” component. |
| src/MeshWeaver.Blazor/Components/MeshSearchView.razor.cs | Adds Category grouping fallback to NodeType. |
| src/MeshWeaver.Blazor/Components/LayoutAreaView.razor.cs | Adds stream lifecycle logging and additional diagnostics. |
| src/MeshWeaver.Blazor/Components/LayoutAreaView.razor | Surfaces compilation progress indicator before first stream emission. |
| src/MeshWeaver.Blazor/Components/CompileProgressIndicator.razor.css | Adds styling for compilation progress banner. |
| src/MeshWeaver.Blazor/Components/CompileProgressIndicator.razor | Adds polling UI component for active NodeType compilation. |
| src/MeshWeaver.Blazor.Portal/MeshWeaver.Blazor.Portal.csproj | Adds NU1510 suppression. |
| src/MeshWeaver.Blazor.AI/MeshWeaver.Blazor.AI.csproj | Adds NU1510 suppression. |
| src/MeshWeaver.Blazor.AI/McpMeshPlugin.cs | Adds Patch/Move/Copy MCP tools and improves tool descriptions. |
| src/MeshWeaver.AI/ThreadLayoutAreas.cs | Adds debug logging around streaming view emission. |
| src/MeshWeaver.AI/IconGenerator.cs | Adds default AI-backed IIconGenerator implementation. |
| src/MeshWeaver.AI/DelegationCompletedEvent.cs | Removes delegation tracker/event types. |
| src/MeshWeaver.AI/Data/Agent/Worker.md | Updates @/ link guidance (no raw HTML href with @/). |
| src/MeshWeaver.AI/Data/Agent/ToolsReference.md | Updates @/ link guidance and provides correct/incorrect table. |
| src/MeshWeaver.AI/Data/Agent/Orchestrator.md | Updates @/ link guidance for agent outputs. |
| src/MeshWeaver.AI/AIExtensions.cs | Removes old type registration; registers IIconGenerator. |
| memex/aspire/Memex.Portal.Distributed/Program.cs | Registers blob-backed NuGet package cache in distributed deployment. |
| memex/aspire/Memex.Portal.Distributed/Memex.Portal.Distributed.csproj | References MeshWeaver.NuGet.AzureBlob. |
| memex/aspire/Memex.Database.Migration/Program.cs | Adds source/test to reserved schema list. |
| memex/aspire/Memex.AppHost/Program.cs | Adds LinkedIn secret/env wiring + sets NUGET_PACKAGES cache dir. |
| memex/Memex.Portal.Shared/Social/SocialMediaUserMenuProvider.cs | Adds “Social Media” shortcut on a user’s own node (lazy hub creation). |
| memex/Memex.Portal.Shared/Social/ApiCredentialNodeType.cs | Adds NodeType for PlatformCredential stored under _ApiCredentials. |
| memex/Memex.Portal.Shared/Pages/Login.razor | Adds “Connect LinkedIn for publishing” CTA on login page. |
| memex/Memex.Portal.Shared/OrganizationNodeType.cs | Switches to default layout areas registration. |
| memex/Memex.Portal.Shared/MemexConfiguration.cs | Adds LinkedIn publisher wiring, @/ redirect middleware, and routes. |
| memex/Memex.Portal.Shared/Memex.Portal.Shared.csproj | References MeshWeaver.Social. |
| memex/Memex.Portal.Monolith/appsettings.Development.json | Enables debug logging for LayoutAreaView. |
| MeshWeaver.slnx | Adds new projects (NuGet, NuGet.AzureBlob, Social, new test projects). |
| Directory.Packages.props | Adds NuGet.* package versions for resolver implementation. |
| CLAUDE.md | Documents @/ local-only rule and href/URL restrictions. |
| (Various) samples/Graph/... | Adds/updates many sample NodeTypes and content under Source/ to reflect new conventions and demos. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…+ test helpers Recursive DeleteNodeRequest handled on a node's own hub was deadlocking: the final DeleteSelfFromStorage posted Ok and DisposeRequest from the dying hub, so the Ok raced callback disposal on the caller and was lost. Introduce CommitNodeDeletionMessage and forward the terminal commit (storage delete + reply + grain dispose) to the resolved mesh hub (walking ParentHub upward) — Sender becomes the stable mesh hub, FIFO on the caller's inbound queue guarantees Ok resolves the RegisterCallback before DisposeRequest arrives. Also addresses two Copilot review comments on PR #95: - FileSystemStorageAdapter.DeleteAsync empty-directory ascent is now concurrency- tolerant: wraps the enumerate + Directory.Delete in try/catch, swallowing the DirectoryNotFoundException race and breaking on IOException (non-empty / in-use). Required because FileSystemPersistenceService.MoveNodeAsync now parallelizes descendant deletes via Task.WhenAll. - PostStatsRefresherTest.WaitUntilAsync throws TimeoutException with a descriptive message instead of returning silently on deadline, so the test cannot green-tick a stats-refresh that never happened. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@copilot resolve the merge conflicts in this pull request |
Resolved. The merge with Conflicts resolved:
|
Code review — recent stability batch
Manual review of the last ~20 commits since Correctness — should fix before merge1. ✅ foreach (var (k, v) in perParams)
{
var newKey = "@" + prefix + k.TrimStart('@');
renamedSql = renamedSql.Replace(k, newKey);
renamedParams[newKey] = v;
}
Fix: single regex pass keyed on 2. ✅ Fix: 3. ✅ Fix: parse every query in 4. ✅ Fix: Race / lifecycle hazards5. ✅ Fix: drop the time-based heuristic in favour of a structural one — skip recovery only when the thread is still an auto-execute candidate ( 6. ✅ 7. ✅ 8. ✅ Fix: pre-allocate the Style / consistency9. ✅ 10. ✅ 11. ✅ Fix: drop the per-query Limit injection. Limit is enforced post-union via ✅ Looks good (no action needed)
|
Code review — part 2: rest of the PR
Continuing review on the bulk of the PR (everything before the recent stability batch). Focused on the new projects ( Correctness — should fix before merge12. ✅ return _cache.GetOrAdd(key, _ => ResolveCoreAsync(requested, framework, ct));If Fix: evict faulted/cancelled tasks from the cache before returning. Also pass 13. ✅ Fix: switched to 14. ✅ Fix: post-hydration, the resolver opens the package folder via 15. ✅ Fix: defensive 16. ✅ Race / lifecycle hazards17. ✅ 18. ✅ 19. ✅ Fix: replaced with a single bounded Style / consistency20. ✅ Fix: register the publisher as a true singleton via 21. ✅ Fix: gate hosted-service registration on 22. ✅ 23. ✅ ✅ Looks good (no action needed)
Areas not covered in this reviewPersistence-service refactors ( |
Review fixes applied — all 23 items addressed5 commits, organised by batch. Locally committed, not pushed yet.
Verification
Notes
Ready to push when you want. |
|
Done — review item #14 is now closed in commit |
…fix DI lifetimes, redact PII, drop dynamic - ThreadExecution: collapse triple-stacked <summary> blocks on WatchForExecution and NotifyParentCompletion. Tooling kept the last one anyway; the dead scaffolding was just noise. - SocialExtensions: register LinkedInPublisher / XPublisher as TRUE singletons (factory-resolved with named HttpClient). The previous AddHttpClient<T>+AddSingleton<IPlatformPublisher> mix made the concrete type transient while the interface alias was singleton — direct vs via-interface resolution returned different instances. Also gate hosted-service registration on at least one platform being configured (the "all-or-nothing" comment was wrong; with zero platforms the four hosted services started anyway and faulted on first tick). - LinkedInPublisher: replace `(dynamic)media.shareMediaCategory` peek with two concrete payload shapes — typo turns into a compile error instead of a RuntimeBinderException. - LinkedIn / X publishers: cap error-body logs at 200 chars to bound PII exposure (the body can echo the user's post text on validation rejection). Full body still goes to PublishResult.Error for the caller. Addresses PR #95 review items #9, #20, #21, #22, #23. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… in-memory engines
PostgreSqlStorageAdapter.QueryNodesAsync(IReadOnlyList<ParsedQuery>):
- Replace order-dependent `string.Replace` parameter rename with a
single `Regex.Replace` keyed on @<name> word boundary that gates
on perParams.ContainsKey. Sequential Replace was mangling adjacent
tokens (renaming `@p` after `@p1` produced `@q0_q0_p1`) and could
clobber `@…` substrings inside string literals / JSONB paths.
- Switch from `UNION` to `UNION ALL` wrapped in
`SELECT DISTINCT ON (namespace, id) ... ORDER BY namespace, id, last_modified DESC`.
Plain UNION dedupes whole rows — two queries observing the same
node at slightly-different last_modified would BOTH appear in the
output. Path-keyed dedup (= MeshNode identity) with newest-wins
tie-break collapses them correctly.
PostgreSqlMeshQuery.ObserveQuery<T>:
- Parse EVERY query in request.EffectiveQueries and build per-query
(basePath, scope) filters; the change-notifier subscription
OR-joins them so multi-query observations get delta refreshes
triggered by ANY query's path/scope, not just query #0's. The
previous shape silently lost live updates from queries #1+.
PostgreSqlMeshQuery.QueryNodesUnionAsync + MeshQueryEngine:
- Drop the per-query `parsedList[0].Limit = request.Limit` injection.
Query #0 hit its limit before yielding the union's most relevant
rows, while queries #1+ contributed unbounded — making the result
iteration-order dependent. Limit is now enforced post-union via
MinLimit(request.Limit, firstParsed.Limit) so a request-level cap
can't be circumvented and an in-query `limit:N` still wins when
smaller.
- MeshQueryEngine: CollectMatchedAsync returns the LIST of every
query's basePath; the source:activity post-filter scans every
base path's descendants and unions activity-main-paths so
queries #1+ aren't filtered against query #0's subtree only.
Addresses PR #95 review items #1, #2, #3, #4, #11.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ThreadExecution stability fixes ThreadExecution.cs (already in commit 478fdaa — recapping here for the review-item index): - RecoverStaleExecutingThread: drop the 2-minute "fresh execution" window in favour of a structural check (skip when PendingUserMessage + ActiveMessageId are still set, i.e. the thread is an auto-execute candidate WatchForExecution will pick up). Closes the "long-running agent crashed at minute 5 → IsExecuting=true forever" gap; the time-based heuristic contradicted commit 6dc436b's "no time limits" stance. - Subject<StreamingSnapshot>: declare with `using var` so the Subject itself disposes alongside its subscription. Minor leak per execution previously. - HandleSubmitMessage: pre-allocate the per-round CancellationTokenSource and store it on the thread hub BEFORE posting SubmitMessageResponse — closes the race where an early Stop click between IsExecuting=true and ExecuteMessageAsync's `parentHub.Set(executionCts)` found a null CTS slot and silently no-op'd. ExecuteMessageAsync now reuses the pre-allocated CTS (with a fallback for the auto-execute path that bypasses HandleSubmitMessage). IsExecutingLifecycleTest.cs: - Migrate the response-text wait from text-pattern matching (skipping placeholders "Allocating agent..." etc.) to `ThreadMessage.CompletedAt is not null`, which ExecuteMessageAsync sets only on the terminal PushToResponseMessage call. Same pattern adopted in ChatHistoryTest in commit ab3af8b. - Add a regression assertion that final ThreadMessage.Status == Completed. The terminal-status guard in PushToResponseMessage prevents the late Sample(100ms)-flushed Streaming push from regressing the cell from Completed back to Streaming; this assertion catches any future regression of that guard. Addresses PR #95 review items #5, #6, #7, #8, #10. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…, parallelism, backoff)
NuGetAssemblyResolver:
- Evict faulted/cancelled tasks from the per-key cache before
returning. A transient feed failure (network, throttle, cancelled
in-flight resolve) used to poison the cache for the resolver's
lifetime — every subsequent call replayed the same exception.
- Pass CancellationToken.None to the shared core task so a single
caller's cancellation can't take down the resolution for
others; per-caller `ct` projects via `task.WaitAsync(ct)`.
- Switch DependencyBehavior from `Lowest` to `HighestMinor` so
`#r` directives pick up patch-level security fixes via
transitive dependencies without silently jumping major/minor.
- Document that hydrated cache content is trusted to match
(id, version) — flag for future content-hash verification if
cache poisoning becomes a concern.
LinkedInPublisher / XPublisher (LinkedIn already committed in batch A
for the dynamic+PII parts; this commit adds the 401 retry):
- SendWith401RetryAsync: on the FIRST 401 response from a publish,
force-refresh the token (zero ExpiresAt before EnsureFreshAsync)
and retry once. Closes the race where the access token's TTL
expired between EnsureFreshAsync and the actual API call.
PostStatsRefresher:
- Process due-refresh targets via Parallel.ForEachAsync bounded
by SocialOptions.StatsRefreshDegreeOfParallelism (default 8),
so a slow API + large refresh window can't let one tick
overshoot the next interval.
- Per-target failure backoff via a ConcurrentDictionary of
last-failure timestamps — targets that failed within
StatsRefreshFailureBackoff (default 15 min) skip the next tick.
Stops a degraded platform from generating thousands of repeat
warnings every cycle while the underlying issue is fixed.
Success clears the backoff entry.
SocialOptions: add StatsRefreshDegreeOfParallelism (8) and
StatsRefreshFailureBackoff (15 min) knobs.
Addresses PR #95 review items #12, #13, #14, #16, #17, #18.
(#15 XPublisher defensive parse + the LinkedIn dynamic / PII items
were already in commit 478fdaa.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… file lock The MESHWEAVER_DISPOSE_TRACE=1 trace took a global lock per call (`File.AppendAllText` under `lock (DisposeTraceLogLock)`), serialising hub teardown under load when many hubs disposed concurrently. Replaced with a single bounded `Channel<string>` (capacity 4096, FullMode = DropWrite) drained by one writer task started in the type initialiser. Producers `TryWrite` non-blocking — if the disk is slow / locked, lines drop on full instead of putting back-pressure on dispose. Single-reader semantics avoid contention on the file handle. Addresses PR #95 review item #19. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replaces the TODO from commit 512adb4. After a successful INuGetPackageCache.TryHydrateAsync, the resolver now opens the hydrated folder via PackageFolderReader and compares the package's own .nuspec-declared (id, version) against the expected (id, version). On mismatch the directory is purged and the resolver falls back to the feed. This catches the failure modes #14 was about: wrong package stored under right key (cross-tenant blob, accidental copy, drift after a manual edit). The .nuspec is the canonical NuGet source of truth, so a tampered cache entry can't fake the identity without rewriting the nuspec — which we'd then catch at hydration time. No INuGetPackageCache contract change; validation lives entirely in the resolver. Closes the last open item from PR #95 review (item #14). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@copilot resolve the merge conflicts in this pull request |
Test Results (shard 1)962 tests 960 ✅ 4m 21s ⏱️ For more details on these failures, see this check. Results for commit 10ed4fa. ♻️ This comment has been updated with latest results. |
Test Results (shard 0) 13 files 13 suites 11m 31s ⏱️ For more details on these failures, see this check. Results for commit 10ed4fa. ♻️ This comment has been updated with latest results. |
Test Results (shard 3)322 tests 318 ✅ 2m 35s ⏱️ For more details on these failures, see this check. Results for commit 10ed4fa. ♻️ This comment has been updated with latest results. |
Test Results (shard 2)987 tests 986 ✅ 2m 1s ⏱️ Results for commit 10ed4fa. ♻️ This comment has been updated with latest results. |
…eetTest referencing the deleted helper The #r-decoupling revert (git checkout d0b80ea) restored PensionFundBalanceSheetTest.cs but not the TestPaths.cs helper it references (CS0103), failing the CI build job → all shards skipped. Restore the helper from the same revert baseline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…clear message + Monaco error overlay A NodeType whose source fails to compile no longer renders an indefinite spinner / silent wedge. The Settings → Progress error branch now shows, per affected source file, a link to the Code node and a read-only Monaco editor with the Roslyn errors MARKED at their exact line/column (the IDE-style overlay), driven by structured per-file diagnostics captured from the compile. - NodeTypeDefinition.CompilationDiagnostics: structured per-file DiagnosticInfo kept in native form (id/severity/message/position), not flattened to a string. - MeshNodeCompilationService: on compile FAILURE ONLY, capture per-file diagnostics from one LSP-style per-file-tree compilation (reuses CompilationInputs); the working success emit is untouched. Threaded via NodeCompilationResult.Diagnostics into both compile write-back sites. - CodeEditorControl.Diagnostics (+ CodeEditorDiagnostic): static markers rendered through the existing Monaco pushDiagnostics path — no JS change (enableDiagnostics fires an initial pass on load). - NodeTypeLayoutAreas.BuildCompileErrorSourceViews: pure, testable builder for the ordered link+editor views per source file. - Test: CompileErrorPageTest covers ordering, the source link, the clear message, and the marked editor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…FX example Adds a 'Scope' NodeType (ScopeNodeType) whose Content is the IScope<,> C# source (CodeConfiguration), registered in AddGraph. CSharpFileParser now honours a '// NodeType: Scope' header so a Source .cs can declare itself a first-class scope. Pairs with the generator gate (already in HEAD, 94ee0d9): the BusinessRules scope generator runs only for IScope-bearing compiles, not every Code compile. Includes an FX cross-rate conversion example (ICurrencyConversion : IScope<FxTrade, FxRates>) + test. NOTE: folded-Scope source discovery (so a '// NodeType: Scope' Source node is pulled into the parent compile) and STANDALONE scope compilation — the real fix for both the runtime-compile slowness (semantic binding over the whole reference set) AND decoupling BusinessRules from low-level Graph — are the next step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GetContentSchema resolved the content type from tempHub's TypeRegistry but generated the JSON schema with the PARENT hub's JsonSerializerOptions. That options object carries a PolymorphicTypeInfoResolver bound to the parent's registry, which does not own the compiled content type — so GetOrAddType fell back to TypeRegistry.FormatType and emitted the namespace-qualified, capitalized Type.FullName as every $type discriminator (e.g. "MeshWeaver.AI.Test.TestProduct" instead of "TestProduct"). Generate the schema with the type-owning tempHub's options so references resolve to the registered short name. Repro pinned in SchemaValidationTest: the schema must not contain the CLR FullName for the registered content type. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ph — kills build bloat The generator is a Roslyn analyzer (IsRoslynComponent); a plain ProjectReference from the foundational MeshWeaver.Graph propagated it to all 40+ downstream projects and ran it on every compile — the project_graph_generator_build_bloat regression the 01a31ad revert reintroduced. - Graph.csproj: remove the BusinessRules + BusinessRules.Generator references (Graph no longer has a compile-time dependency on either). - RunSourceGenerators: load ScopeCodeGenerator at runtime BY NAME via reflection (TryCreateScopeGenerator) instead of `new ...ScopeCodeGenerator()`. No compile-time ref; the generator reaches the runtime via the node Source `#r nuget:MeshWeaver.BusinessRules.Generator` resolution / the deployed mesh-local package. Not resolvable -> scope generation skipped and the compile error surfaces on the NodeType Progress page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that BusinessRules + BusinessRules.Generator are no longer ProjectReferenced by the framework (they were the build-bloat source — a Roslyn analyzer propagating across Graph's 40+ consumers), node compilation must resolve them at runtime via `#r nuget:MeshWeaver.*`. The committed root nuget.config already maps MeshWeaver.*/Memex.* to a local `dist/packages` folder source; this ships that feed inside the container so the runtime resolver (NuGetAssemblyResolver → Settings.LoadDefaultSettings from the app dir) resolves offline. - Memex.Portal.Distributed.csproj: copy nuget.config + dist/packages/**/*.nupkg into the published /app (next to the app) so they're present at the resolver's working dir. - The nupkgs are packed into dist/packages by the build process BEFORE publish — the `Pack mesh-local #r packages` step (dotnet pack BusinessRules + Generator -o dist/packages -p:PackageVersion=3.0.0-preview1), mirrored from .github/workflows/dotnet-test.yml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…me (not a framework ref) Completes the BusinessRules.Generator decoupling: the generator is supplied to dynamic node compilation through the node Source `#r nuget:MeshWeaver.BusinessRules.Generator` (auto-injected when the unit declares IScope<,>), resolved from the mesh-local feed, and discovered + run via SourceGeneratorLoader — never a framework ProjectReference (which propagated the analyzer + bloated builds). - SourceGeneratorLoader: discover [Generator] types from the node's #r-resolved assemblies (no static cache). - RunSourceGenerators: DeclaresScope-gated; discovers from the #r-resolved paths (replaces the Type.GetType bridge). - InjectScopeGeneratorReference: auto-prepend the generator #r for IScope units so existing Scope nodes compile without author boilerplate. Node-generation-only. - BusinessRules.Generator.csproj: ALSO pack the generator under lib/ — the runtime #r resolver reads lib/ ONLY (NuGetAssemblyResolver -> GetLibItemsAsync); analyzers/dotnet/cs stays for OutputItemType=Analyzer consumers. - Failure-diagnostics (DiagnoseInputs) pass no generator candidates (best-effort; the flat summary covers it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…), never wedges; scope generator is explicit-#r only THE atioz wedge root cause: CompileResultFromAssembly swallowed an assembly LOAD / type-extract failure (e.g. BalanceSheet missing the MeshWeaver.Charting dependency at runtime) into a result with a non-null AssemblyLocation + empty configurations. Both compile watchers classify success as `Error is null && !IsNullOrEmpty(AssemblyLocation)` → that read as Status=Ok, so the emergency compilation-error overlay (gated on Error) never fired, and the per-node hub tried to activate against an unusable assembly → every Subscribe/GetData parked → wedge. Fix, per the three rules: - No assembly if it cannot build: both failure paths return AssemblyLocation=null. - Build failed + no release: null location → ok=false → CompilationStatus=Error; release creation is already gated on ok, so none is written. - No retry: the first-build kickoff is gated on CompilationStatus==null, so a settled Error never re-fires. The emergency overlay renders the failure on the Overview instead of parking. - Surface the real problem: the extract-failure catch now includes ReflectionTypeLoadException .LoaderExceptions, so the Overview names the missing dependency. Also (per directive): the BusinessRules scope generator is injected ONLY when the node Source EXPLICITLY declares `#r nuget:MeshWeaver.BusinessRules.Generator` — removed the IScope text-scan auto-inject that forced generator resolution on the compile path. Resolved from the baked mesh-local feed, discovered by SourceGeneratorLoader. Never a framework reference. Test: CompileErrorOverviewTest — a broken-type instance's Overview COMES BACK (bounded timeout, no hang) SAYING it had a compilation error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…) + fold content checks into reactive Match Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…emoryPersistence) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Opus 4.8) The Anthropic provider's bootstrap model list (DefaultModelIds, shown on Settings/Models) listed the stale claude-opus-4-7. EffectiveModelIds is the code default with no config override, so this is the source of truth for the card list. sonnet-4-6 and haiku-4-5-20251001 are current. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…point), not a pinned list Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…r rows The picker showed each node's full path as a secondary line under the name; for models that path is _Provider/Anthropic/<id> (the provider), which is not a title and just confuses. Show name + category only; keep the full path as a hover tooltip for disambiguation. /model already queries nodeType:LanguageModel, so only models are listed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…MCP writes raw create rejects Raw MCP create/patch validate content.$type against the hub they run on, so they reject content types registered only on a dedicated per-type hub (e.g. Invitation) and writes into restricted partitions (e.g. Admin). Document the canonical work-through: a throwaway executable Code node + execute_script calling the typed service (InvitationService.CreateInvitation), plus a pitfalls-table row. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ock wedges The per-key MessageStormBreaker only trips when ONE (sender,target,type) tuple storms; every portal wedge this session was MANY DISTINCT keys whose aggregate saturated the single-threaded action block. Add a per-hub inbound-depth watermark (MessageStormBreaker.ShouldShedAggregate) that sheds sheddable ([CanBeIgnored], non-lifecycle) traffic once the queue crosses the watermark, keeping the turn loop draining user-facing + lifecycle work. WithAggregateWatermark config; wired in MessageService.ScheduleNotify right after the per-key drop. Invariants + acceptance tests are documented in ActionBlockWedgePrevention.md. Tests (both green): ManyDistinctMissingSubscribes_DoNotWedge (the canonical wedge repro) and Aggregate_ShedsOnlySheddable_AboveWatermark. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A post that fails (e.g. the never-null AccessContext guard) already becomes a DeliveryFailure routed back to the sender, but nothing surfaced it to the user — the area silently treated it as a fatal load error and the composer vanished. Add PortalErrorSink (a circuit-scoped bridge) + WithPortalErrorReporting (a WithHandler<DeliveryFailure> on the portal hub) wired into DefaultPortalConfig; PortalErrorModal subscribes and shows an OK-gated modal, draining a failure burst sequentially instead of stacking dialogs. This is the proper failed-message pipe — no throw, the hub survives, the user sees the error. Test FailedPortalPost_SurfacesToTheErrorSink drives the real Failed-delivery path (d.Failed -> ReportFailure -> DeliveryFailure -> portal hub -> sink) and asserts the sink (the modal's source) emits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…I signal The per-build version churn in Directory.Build.props re-stamped AssemblyVersion/ FileVersion/InformationalVersion on every build (clock-based _BuildNumber = secondsSinceMidnight/2), regenerating AssemblyInfo and defeating incremental builds — the whole tree rebuilt every time (3-min builds became full rebuilds + a hot machine). It churned because NodeType ABI invalidation derived FrameworkVersion from the version STRING. Decouple the two: NodeTypeCompilationHelpers.FrameworkVersion now uses the Graph assembly's MVID (a content hash — stable when the bytes are identical, changes on a real rebuild), so the version string can be STABLE for local dev (CIRun != true) and incremental builds come back. CI keeps the per-build number (clean builds anyway; distinguishable continuous packages). ABI invalidation stays correct and actually recompiles LESS on deploy (only when framework content changes, not every deploy). Verified: a leaf project's 2nd build is a no-op (0.85s, no recompile); Graph compiles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…; bake mesh-local feed into the AKS image The scope source generator is #r-pluggable (decoupled from Graph in ef2e756 to kill build bloat), but the PensionFund BalanceSheet sample was never migrated to declare the #r — so its IScope<,> implementations were never generated: AddBusinessRules found none, the node hub config failed, and every BalanceSheet area (statement / key-figures / asset-allocation) timed out rendering. - BalanceSheetScopes.cs: declare `#r "nuget:MeshWeaver.BusinessRules.Generator"` (version-less — one global PlatformVersion, no drift). BusinessRules itself is already in the node-compile references (the portal ships it via MeshWeaver.Documentation), so it is NOT #r'd (would be a duplicate identity). - PensionFund.Test.csproj: drop BalanceSheetScopes.cs from <Compile> — #r is illegal in a regular (non-script) compilation (CS7011). Scope codegen stays covered by FxConversionScopeTest + the runtime render tests + the resolver test. - Distributed.csproj: BakeMeshLocalFeed target (Release publish only) packs the curated set (BusinessRules + .Generator) into dist/packages so the AKS image ships them offline — they are not on nuget.org; without it a deployed scope node resolves on no source. - NuGetAssemblyResolverTest: new test pinning the #r-feed mechanism end to end. - DeploymentAKS.md + AGENTS.md: document the auto-baked feed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ection; drop hand-built HTML - Replace the RenderHtml string-building in the token-cost + thread layout areas with framework controls — a DataGrid bound to plain row records (new TokenCostGrid) composed with Stack/Title/Markdown. Hand-built HTML is forbidden (and the string-interpolation + LINQ was the cause of the >10-min MeshWeaver.AI compile regression e30e9b5). AGENTS.md documents the rule (rendering goes through a control, never a hand-built HTML string). - Extract the chat agent/model picker's queries + projection into AgentPickerProjection — one source of truth the chat view and AgentPickerProjectionTest both drive, so a regression that empties the dropdowns (null ambient context / server-side-hub RLS) fails the tests, not just the runtime. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… compile The token-cost overview (e30e9b5) drove MeshWeaver.AI's clean compile from ~7s to many minutes. Rewriting it five ways - hand-rolled HTML table -> DataGrid, dropping the IObservable<Func<string,ModelPriceRate?>> resolver stream, LINQ -> plain loops - never moved it, so it is a deeper Roslyn binding cost in how this code combines, not any one construct. Removing the UI restores the 7.5s compile. Removed: TokenCostSummary, TokenCostGrid, TokenCostSettingsTab, the thread Token-cost area and its menu/view wiring (ThreadLayoutAreas / ThreadNodeType), and TokenCostTest. KEPT the accounting (Thread.TokensByModel recording, ModelPricing, the ModelDefinition price fields) so usage is still tracked, just not displayed. The full feature is recoverable from e30e9b5 for a focused follow-up. Also lands the ABSOLUTE ban on hand-rolled HTML / UI (use Controls.DataGrid + layout areas, never a RenderHtml-shaped helper or Controls.Html(markup) for structured data) in AGENTS.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…l commit 166e612 deleted TokenCostSummary but TokenCostGrid.cs (which references it) was still tracked, so MeshWeaver.AI did not compile on that commit. Removing it restores the build to the intended 7.5s state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…read A small standalone Blazor component for the chat progress area: renders ↑<in> ↓<out> · $<cost> (total input/output tokens, k/M-abbreviated, plus the summed cost from the built-in ModelPricing table) and expands on click into a per-model ↑in ↓out breakdown. Reads — never recomputes — Thread.TokensByModel off the node stream; fully reactive (GetMeshNodeStream + Subscribe), no async. Standalone for now: wire into ThreadChatView's progress area with <ThreadTokenChip ThreadPath="@threadPath" />. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…st UI removal 166e612 removed the token-cost overview UI (and its AddTokenCostSettingsTab extension) but left the call in ConfigureDefaultNodeHub's settings-tab chain, so the whole solution failed to compile (CI build job red, blocking every test). Remove the orphaned call; the chain stays valid. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…AI ~9min compile (revert after)
… the Csc compile cliff MeshWeaver.AI's C# core compile is the build long pole — ~10 min (Project Performance Summary: 613,819 ms), build step 259s → 676s exactly at e30e9b5. ReportAnalyzer showed NO analyzer/generator time (none run on MeshWeaver.AI), so it is Csc core on the ~1400-line reactive ExecuteMessageAsync: e30e9b5 tipped it over a Roslyn super-linear cliff by adding a mutable-capturing NormalizeTotalTokens LOCAL FUNCTION (+ nullable token locals) threaded through its many branches. Lift it into a static NormalizeTotal helper (no closure; nullable flow contained); the three terminal-path call sites now assign totalTokens from it. Logic identical. Also reverts the temporary ReportAnalyzer/PerformanceSummary CI diagnostic. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… never mid-round InstallServerWatcher subscribed to the raw node stream with no DistinctUntilChanged, so it re-ran on EVERY emission — including the hundreds of StreamingText/Messages updates a round produces while Executing — and on each one called ReconcileUserMessageIds (an own-write self-heal) and re-evaluated dispatch. So the state engine was reacting to, and could write state during, an in-flight round. Gate the stream on SubmissionFingerprint — Status + the pending / ingested / user-message id sets ONLY (excludes StreamingText/StreamingToolCalls/Messages/Summary/ExecutionStartedAt). An Executing round produces no fingerprint change, so the watcher stays dormant until a real submit / ingest / dispatch / terminal transition. Dispatch stays additionally guarded by NeedsDispatch (Idle/Cancelled only). The fingerprint captures exactly the reaction's dependencies, so no reconcile/dispatch is missed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s out of Thread
Introduces TokenUsage: a per-(thread, model) satellite at {threadPath}/_Usage/{modelKey} that
will hold input/output token counts (UserId + ThreadId + Model denormalized for cross-thread /
per-model / per-user querying). Cost is derived on read from ModelPricing, never stored.
This is step 1 (type + satellite NodeType + AddAITypes registration + SatelliteAccessRule —
access delegated to the thread). Next steps: write it per round from ExecuteMessageAsync (replacing
the Thread.TokensByModel/TokensUsed with-mutations), remove those fields from Thread, and rewire
ThreadTokenChip/ThreadViewModel to read _Usage. Goal: NO token state on the Thread node.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nUsage satellites Steps 2-4 of the TokenUsage refactor (step 1 = 4911862 added the type + registration): - WRITE: ExecuteMessageAsync's three terminal paths (Completed/Cancelled/Error) no longer mutate the thread; each calls TokenUsageNodeType.RecordUsage(parentHub, threadPath, partition, model, in, out), which accumulates onto the per-model satellite {threadPath}/_Usage/{model} via an authoritative GetMeshNodeStream().Take(1).Timeout().Catch(->fresh) read + CreateOrUpdateNodeRequest (NOT a point-read .Update). Rounds are serial per thread, so the read-modify-write is race-free. - REMOVE: Thread.TokensUsed, Thread.TokensByModel and the ModelTokenUsage record are gone; the thread node carries NO token state. Updated ThreadLayoutAreas + ThreadViewModel (dropped the TokensUsed VM field) and the stale comments in ThreadExecution/ThreadSubmission + ModelPricing doc. - CHIP: ThreadTokenChip now subscribes to a LIVE query of {threadPath}/_Usage/* and sums per model (cost via ModelPricing) instead of reading Thread.TokensByModel. Wired into ThreadChatView's status row, replacing the now-removed inline ViewModel.TokensUsed display. - TESTS: ThreadTokenUsageTest asserts the per-model satellites (incl. cumulative accumulation across rounds) on Completed/Cancelled/Error/no-total; InboxTool test drops the TokensUsed field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n the _Usage satellites Global-admin Settings tab (gated via AdminMenuGate.IsPlatformAdmin, Administration group). Queries nodeType:TokenUsage and renders, with framework controls only (no hand-built HTML): - a button toolbar: group by Model / Person / Thread + time window 7d/30d/90d/All, - a DataGrid (group, input, output, total, est. cost) + a headline totals line. Cost is derived on read from ModelPricing (never stored). RLS-scoped to the viewer's read access. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…SettingsTab CS1061 — ToCamelCase (MeshWeaver.Utils.CamelCaseExtensions) wasn't imported; the sample that uses it imports MeshWeaver.Utils. Only the DataGrid column Property lines were affected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
77 commits of long-running work on
bug_fix— grouped by theme:MeshWeaver.Social+ LinkedIn publisher + scheduled publishing pipeline (engine/queue/stats), LinkedIn OAuth connect + past-post ingest in Memex portal, per-user linked-account menu items.#r "nuget:Pkg, Version"at the top of_Source/*.csresolves via public NuGet.Protocol without an SDK on the container. Same resolver serves interactive markdown code cells.FileSystemPersistenceService.MoveNodeAsyncruns per-descendantWriteAsync/DeleteAsyncthroughTask.WhenAll; newMeshOperationOptions(defaultTimeout = 30s) +WithMeshOperationTimeout(TimeSpan)override;HandleMoveNodeRequestchains.Timeout()on the persistence Observable so a stuck adapter can't hang the caller. Prod repro: DAV2026 subtree move that took 240 s and killed the MCP session — now bounded.CompilationCacheService,_Source/edit re-invalidates owning NodeType, cross-silo broadcast viaMeshChangeFeed, grain-dispose on node delete, live "Compiling … (Ns)" progress inLayoutAreaView.Category(falls back toNodeType), reactive Children catalog, self-as-default create location for non-NodeType nodes, sample orgs →Markdownfor search visibility.MeshChangeFeedevents, resubscribe on owner dispose,DeleteLayoutAreaemits a placeholder immediately and times out slow streams.IAsyncEnumerableaggregator fixes (satellite-safeGatherInputsAsync), xunit methodTimeout 30 s → 60 s, Anthropic Opus bump, icon generator, etc.New test suites (selected)
test/MeshWeaver.Persistence.Test/MoveNodeRecursiveTest.cs— 10 tests: recursion, parallelism, source missing / target exists / storage throws / cancellation (all must not hang), RxTimeout()contract, default-30s config.test/MeshWeaver.Social.Test/*—InMemoryPublishQueueTest,LinkedInPublisherEngagementTest,PostStatsRefresherTest,ScheduledPostPublisherTest,FakePublisher.test/MeshWeaver.Persistence.Test/WorkspaceCacheEvictionTest.cs,ResubscribeOnOwnerDisposeTest.cs,DeleteLayoutAreaIntegrationTest.cs.test/MeshWeaver.Markdown.Test/PathUtilsTest.cs,test/MeshWeaver.MathDemo.Test/MatrixViewsTest.cs.Contributors
dist/cleanup, fix: sample orgs invisible in search due to wrong NodeType #94 sample-org search-visibility fixUpstream already merged into this branch
refactor: reactive persistence — IMeshStorage writes return IObservable(merged)Test plan
dotnet buildsucceedsdotnet test test/MeshWeaver.Persistence.Test --filter MoveNodeRecursiveTest— 10/10 green (~8 s)dotnet test test/MeshWeaver.Hosting.Monolith.Test --filter MoveNodeAsync— 5/5 green (regression guard)dotnet test test/MeshWeaver.Social.Test— publish queue / scheduling / stats green_Source/*.csusing#r "nuget:MathNet.Numerics, 5.0.0"— compiles & renders (cold + warm cache)/social/connect/linkedin→ profile linked; menu shows connected accountScheduledPostPublisher→ LinkedIn publisher posts;PostStatsRefresherpulls stats🤖 Generated with Claude Code