Skip to content

Replace the json-everything family with an in-tree MeshWeaver.Json - #1292

Merged
rbuergi merged 2 commits into
mainfrom
feat/replace-json-everything
Aug 12, 2026
Merged

rbuergi merged 2 commits into
mainfrom
feat/replace-json-everything

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1231. Supersedes #1257 (which dropped only the dead JsonPath.Net reference).

Replaces the whole json-everything family — JsonPatch.Net, JsonPath.Net, and the transitives
Json.More.Net / JsonPointer.Net — with an in-tree implementation, and deletes their four
EXCEPTIONS entries from the licence gate.

What the packages were actually doing

The issue text (and a widely-repeated claim in the codebase) said JsonPatch.Net was "the RFC 7396
merge-patch path behind every cross-hub stream.Update". That is false, and it is why this job
was mis-sized as core-risk:

  • RFC 7396 merge-patch was already ours — hand-written on System.Text.Json.Nodes in
    DataExtensions.MergePatchRecursive and MeshNodePatchMerge. Neither imports anything from
    json-everything. Untouched by this PR.
  • What the package supplied was RFC 6901 (pointer) + RFC 6902 (patch).
  • The RFC 6902 apply on the hot path was already hand-rolled in JsonSynchronizationStream,
    precisely because the library's applier is wrong (below). Also untouched.

Full consumer list

git grep "using Json\.\(Patch\|Pointer\|More\)" → 21 files, all now using MeshWeaver.Json;:

Project Files What it used
MeshWeaver.Data DataExtensions, ReduceManager, StandardReducers, WorkspaceOperations, JsonSynchronizationStream, EntityStoreConverter, InstanceCollectionConverter, DataChangedEventConverter (comment) JsonPatch, PatchOperation, OperationType, JsonPointer, CreatePatch, AsNode
MeshWeaver.Layout LayoutClientExtensions, ModelParameter, LayoutExtensions, EditorExtensions, PropertyViewBuilder JsonPatch, PatchOperation, JsonPointer, Apply, Type.IsNumber
MeshWeaver.Blazor ListBase JsonPointer
MeshWeaver.Graph MeshDataSource JsonPatch (one signature)
MeshWeaver.Data.Contract LayoutAreaReference:187 JsonPointer.Create only
MeshWeaver.Messaging.Hub ImmutableDictionaryConverter:35 AsNode() only
tests EntityUpdateDedupTest, Playground, DomainLayoutServiceTest, LayoutTest mixed

samples/, content/ and modules/ were swept too — no in-mesh source references any of these
namespaces
, so no NodeType breaks.

What was implemented

New MeshWeaver.Json namespace inside MeshWeaver.Utils — a zero-dependency project both
MeshWeaver.Data.Contract and MeshWeaver.Messaging.Hub can reach, so no new NuGet package is
minted. MeshWeaver.Data.Contract gains one ProjectReference.

  • JsonPointer (RFC 6901) — readonly struct backed by the escaped pointer string, plus
    JsonPointerSegment (zero-alloc ref struct view). Parse / Create / Combine / Evaluate /
    TryEvaluate / segment access / JSON converter.
  • JsonPatch, PatchOperation, OperationType, PatchResult + converters (RFC 6902).
  • PatchExtensions.CreatePatch (the diff) and Apply.
  • JsonEquivalence.IsEquivalentTo — value-wise JSON equality, the diff's "changed?" predicate.
  • JsonElementNodeExtensions.AsNode, JsonTypeExtensions.IsNumber/IsInteger/IsFloatingPoint.

Public type names are unchanged (JsonPatch, PatchOperation, JsonPointer, OperationType) —
the $type discriminator is the SHORT type name and typeof(JsonPatch) is registered in the hub
TypeRegistry.

Wire-compatibility evidence

A patch leaves the process as raw RFC 6902 JSON inside DataChangedEvent.Change; the React,
gRPC-web and Python clients parse those bytes and are not built by this repo's CI. Three
independent pieces of evidence:

1. A differential harness ran both implementations side by side — 18,472 assertions, 0 mismatches.
Built while both were still present (a throwaway project; not shipped). Identical pointer
parse/segments/Create/Evaluate/TryEvaluate/Combine; identical operation serialization under
three serializer option sets; identical deserialization including member-order permutations, unknown
members and every malformed-operation rejection by exception type; and identical CreatePatch
output over 73 hand-picked cases plus 8,000 randomly generated document pairs.

2. The diff algorithm was decompiled, not guessed. ilspycmd on JsonPatch.Net 5.0.3 gave the
exact walk, reproduced verb-for-verb: object members in declaration order (recurse, else remove),
then the target's new members as add; arrays whole-replaced when exactly one side is empty,
otherwise positional — ascending-with-add when growing, descending-with-remove when
shrinking. Deliberately not an LCS diff; never emits move/copy/test.

3. A committed golden fixture (test/MeshWeaver.Json.Test/Fixtures/json-everything-golden.json,
132 KB) holds json-everything's literal output for 31 pointer parses, 17 Creates, 35 Evaluates,
961 Combines, 14 operation serializations and 73 diffs. Its provenance is recorded in the file.
JsonPatchWireFormatTest and friends assert against it byte-for-byte, so a later refactor cannot
drift the shape silently.

Property order (op, path, then value or from; nothing more for remove) and the
naming-policy invariance of the verbs have their own dedicated tests.

Test coverage

New test/MeshWeaver.Json.Test (registered in MeshWeaver.slnx + shard-assign.sh):

  • JsonPointerTest — parse, verbatim round-trip, malformed rejection, URI-fragment form, segment
    escaping/decoding, Create, Combine, resolution, array-index rules (-, leading zeros,
    negatives, out of range), equality, serialization, plus four golden-fixture conformance tests.
    Edge cases include keys containing /, ~, ~0, ~1, empty segments, digits, -, unicode,
    emoji, quotes and backslashes.
  • JsonPatchDiffTest — objects, arrays (append/truncate/reorder/whole-replace), null-vs-missing,
    numeric equivalence (1 ≡ 1.0 ≡ 1e0, 0 ≡ -0.0), type changes, escaped paths, the golden
    corpus, and property-style checks: apply(diff(a,b)) == b over 8,000 generated documents,
    1,000 wire round-trips and 1,000 identity diffs — fixed seeds, so a failure reproduces.
  • JsonPatchApplyTest — RFC 6902 semantics per verb, failure messages and the failing-operation
    index, source immutability, operand detachment, and the escaped-key cases the old library got wrong.
  • PointerSegmentCodecTest (in MeshWeaver.Data.Test) pins the DecodePointerSegment fix below.

MeshWeaver.Data.Test, MeshWeaver.Layout.Test, MeshWeaver.Serialization.Test and
MeshWeaver.Graph.Test are the regression net for the sync stream.

Performance

BenchmarkDotNet, .NET 10, -c Release, 3 warmup + 7 iterations, [MemoryDiagnoser]. Documents are
the realistic ones, not toys: a MeshNode content document (markdown body, front matter, tags,
children), a layout-area snapshot (control tree + a /data/rows grid), and an entity-store
projection
whose ids are JSON-encoded paths like "acme/Docs/One" — i.e. the shapes whose keys
actually need RFC 6901 escaping.

“naive ours” is the first working implementation; “ours” is after one optimization pass (below).
Baseline was captured while the package was still referenced — it cannot be reproduced now.

Operation JsonPatch.Net naive ours ours JsonPatch.Net alloc ours alloc
Diff — MeshNode content 2,536 ns 2,093 ns 2,097 ns 1.21× 7,560 B 6,256 B (−17%)
Diff — layout-area snapshot 3,221 ns 2,521 ns 2,665 ns 1.21× 9,568 B 7,744 B (−19%)
Diff — entity-store projection 1,251 ns 1,023 ns 1,228 ns 1.02× 4,936 B 4,048 B (−18%)
Diff + serialize — MeshNode 8,081 ns 2,828 ns 2,820 ns 2.87× 11,808 B 7,600 B (−36%)
Pointer parse 22.2 ns 24.0 ns 9.4 ns 2.36× – –
Pointer evaluate 454 ns 58.2 ns 55.3 ns 8.21× 504 B 0 B (−100%)
Pointer evaluate (escaped key) 97.1 ns 53.4 ns 59.0 ns 1.65× 136 B 32 B (−76%)
Pointer create (2 segments) 50.8 ns 37.3 ns 32.6 ns 1.56× 352 B 128 B (−64%)
Pointer combine 25.1 ns 20.1 ns 8.7 ns 2.90× 96 B 96 B (0%)
Pointer segment enumeration 94.0 ns 42.9 ns 31.5 ns 2.98× – –

Reading this honestly. The host was running several concurrent builds from other sessions, and
the baseline re-measured differently between the two runs — Diff — MeshNode moved 2,936→2,536 ns
and Diff + serialize moved 6,911→8,081 ns (the latter with StdDev 796 ns). So the time ratios
carry maybe ±15% of noise and should be read within a run, not across. The one time result I would
defend without caveat is Diff + serialize, which is 2.4–2.9× across both runs — the diff itself is
only modestly faster, and the win is in the serializer (writing op/path as UTF-8 literals with a
hand-written converter instead of routing every operation and pointer through a source-generated
type-info chain). Allocations are deterministic and repeated exactly across both runs, so the
right-hand columns are the solid numbers.

Diff — entity-store projection is the honest weak spot: 1.02× — parity, inside the noise. It
was 1.26× in the first run and 1.02× in the second; the truthful claim is "no slower, ~18% fewer
allocations", not "faster".

What the optimization pass changed. Only JsonPointer.Parse/Validate: Parse(string) grew an
inline fast path for the ordinary /a/b form (skipping the #-fragment handling and the
TryParse out-parameter round trip), and Validate now counts separators with the vectorised
MemoryExtensions.Count('/') and only walks characters when the pointer actually contains a ~.
That moved exactly the benchmarks that parse — parse 24.0→9.4 ns, combine 20.1→8.7 ns, segment
enumeration 42.9→31.5 ns — and left the diff benchmarks unchanged within noise, which is what it
should do since the diff builds pointers by Combine rather than parsing them.

The structural reasons ours is cheaper at all: the pointer is a readonly struct over the escaped
string
(so ToString(), equality and slicing allocate nothing), Evaluate resolves in a single
forward pass with JsonElement.TryGetProperty(ReadOnlySpan<char>) and only allocates when a segment
actually contains an escape — json-everything re-derives each segment with an O(n) scan per step,
making evaluation O(n²) in pointer length — and Create/Combine write their result in one
string.Create instead of a params array plus an intermediate escaped string per segment.

Re-running it. The harness is a throwaway (not shipped): a console project referencing both
implementations, driven by the same corpus as the differential check. Everything needed to rebuild
it is in this PR's fixture file plus JsonPatch.Net 5.0.3 / JsonPointer.Net 7.0.1.

Three latent defects fixed on the way

Each sits in code the replacement necessarily takes ownership of, and each is on a path that in
practice never fires — which is why nothing had surfaced:

  1. PatchOperation.Move/Copy arguments were swapped at both call sites in
    JsonSynchronizationStream: the factory signature is (from, path) and both passed (path, from).
  2. The move/copy/test fallback serialized the PatchResult object instead of result.Result,
    which would have written {"Result":…,"IsSuccess":…} into the stream's state. It now also fails
    loudly instead of silently corrupting.
  3. DecodePointerSegment unescaped in the wrong order — Replace("~0","~").Replace("~1","/")
    manufactures a ~1 that the second pass then eats, so an entity id containing the literal text
    ~1 decoded to a slash. RFC 6901 §4 is ~1 first, and it must be a single pass; it now uses
    JsonPointerSegment.Decode.

MeshWeaver's own diff emits only add/remove/replace, so (1) and (2) were unreachable from any
patch this codebase produces. The hand-rolled hot-path applier in JsonSynchronizationStream is
deliberately left exactly as is — its lenient semantics (auto-creating intermediate objects,
StaleStreamStateException on an out-of-range array index) are intentional for an
eventually-consistent stream and are not RFC behaviour.

Bonus: an accidental dependency, now declared

JsonPointer.Net was transitively supplying Humanizer.Core 3.0.10 — the only copy in the graph
with net10.0 compile assets — and that was the sole reason using Humanizer; compiled in
MeshWeaver.Graph and MeshWeaver.AI. Roslyn's own Humanizer.Core 2.14.1 tops out at net6.0 and
contributes none. Removing json-everything exposed it, so Humanizer.Core (MIT) is now pinned in
Directory.Packages.props and referenced by the two projects that call DateTime.Humanize().

A full package-closure diff of every project.assets.json against origin/main confirms the only
changes are the four json-everything packages leaving and that Humanizer resolution:

ONLY ON MAIN (dropped):     Json.More.Net/3.0.1, JsonPatch.Net/5.0.3,
                            JsonPath.Net/3.0.2, JsonPointer.Net/7.0.1
ONLY IN MINE (added):       Humanizer.Core/2.14.1

Licence gate

.github/scripts/check-licenses.py no longer carries jsonpatch.net, jsonpath.net,
json.more.net or jsonpointer.net. With them removed:

Licence gate passed: 391 shipping packages checked (40 declared-unused ignored).

6 documented exception(s) still carried - each is tracked debt, not an approval:
  - questpdf: … (tracked by #1230)
  - uglytoad.pdfpig{,.core,.fonts,.tokenization,.tokens}: Apache-2.0 upstream, metadata absent

Verification

All touched projects built INDIVIDUALLY with CI's flags (-c Release -warnaserror) —
MeshWeaver.Utils, .Messaging.Hub, .Data.Contract, .Data, .Layout, .Blazor, .Graph,
.AI, .Hosting.Monolith, Memex.Portal.Distributed, and the five touched test projects:
0 Warning(s), 0 Error(s) on every one.

Review follow-up

Copilot's automatic review raised two findings, both real, both on paths the differential harness
did not reach. Fixed in 09d2082, each pinned by a new test:

  1. GetNumber cast a raw CLR double/float straight to decimal, which throws
    OverflowException for NaN, ±∞ and any magnitude past decimal's range — an equality check that
    crashes. It now returns null for those and the pair falls through to the boxed comparison, which
    still answers correctly. Reachable only for a JsonValue holding a CLR double rather than a
    parsed JsonElement, which is why neither the fixtures nor the 8,000 generated documents hit it.
    json-everything had the identical bug, so this diverges only where it used to throw.
  2. JsonPointerSegment.Equals(string?) threw ArgumentNullException on null though the
    signature permits it (and ==/!= reached straight for the span). Null is now simply "no match".

Two things those tests turned up, recorded because they are counter-intuitive: NaN compares equal
to NaN here — the fallback is object.Equals, and Double.Equals deliberately differs from == —
which is the right answer for a diff; and System.Text.Json refuses to serialize ±∞ at all, so the
typed CreatePatch overload cannot be exercised with it regardless of this code.

Differential re-run after the change: 18,490 assertions, 0 mismatches — the wire shape is
unaffected.

What's New

No entry. This is an internal dependency replacement with no user-visible behaviour change: the
serialized patch bytes are byte-identical, and the three defects fixed above sit on paths no
MeshWeaver-produced patch reaches.

Deletes JsonPatch.Net, JsonPath.Net and the transitives Json.More.Net /
JsonPointer.Net, and their four EXCEPTIONS entries in check-licenses.py.

The issue's premise was wrong: JsonPatch.Net was NOT "the RFC 7396 merge-patch
path behind every cross-hub stream.Update". Merge-patch is already ours
(DataExtensions.MergePatchRecursive, MeshNodePatchMerge) and is untouched here,
as is the hand-rolled RFC 6902 applier on the sync-stream hot path. What the
package actually supplied was RFC 6901 pointers and the RFC 6902 diff.

New MeshWeaver.Json namespace inside MeshWeaver.Utils (zero-dependency, reachable
from both Data.Contract and Messaging.Hub, so no new NuGet package is minted):
JsonPointer + JsonPointerSegment, JsonPatch / PatchOperation / OperationType /
PatchResult with their converters, CreatePatch, Apply, IsEquivalentTo, AsNode and
the Type.IsNumber predicates. Type NAMES are unchanged — the $type discriminator
is the short name and typeof(JsonPatch) is in the hub TypeRegistry.

Wire compatibility is the hard constraint: the patch goes out as raw RFC 6902
JSON that the React, gRPC-web and Python clients parse, and none of them are
built by this repo's CI. Evidence: a differential harness ran both
implementations side by side over 18,490 assertions with 0 mismatches, the diff
algorithm was decompiled rather than guessed, and json-everything's literal
output is committed as a golden fixture the new suite asserts against
byte-for-byte.

Also fixes three latent defects in the code this necessarily takes ownership of,
all on paths no MeshWeaver-produced patch reaches: Move/Copy arguments were
swapped at both call sites, the move/copy/test fallback serialized the
PatchResult object instead of its Result, and DecodePointerSegment unescaped
~0 before ~1 (RFC 6901 §4 requires ~1 first, in a single pass).

Humanizer.Core was riding in as an accidental transitive of JsonPointer.Net — the
only copy in the graph with net10.0 compile assets — so it is now pinned and
referenced by the two projects that call DateTime.Humanize().

Refs #1231.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 12, 2026 12:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the json-everything dependency family (JsonPatch/Pointer/Path + transitives) and replaces their usage with a new in-tree MeshWeaver.Json implementation housed in MeshWeaver.Utils, while adding a dedicated golden-fixture-based test suite to lock wire compatibility for RFC 6901/6902 payloads.

Changes:

  • Introduces MeshWeaver.Json (RFC 6901 JsonPointer, RFC 6902 JsonPatch + diff/apply + converters) in src/MeshWeaver.Utils.
  • Updates all in-repo consumers to use MeshWeaver.Json and removes JsonPatch.Net / JsonPath.Net package references and license-gate exceptions.
  • Adds test/MeshWeaver.Json.Test with embedded golden fixtures and property-style tests to prevent wire-shape drift; declares Humanizer.Core explicitly where it was previously an accidental transitive.

Reviewed changes

Copilot reviewed 44 out of 45 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/MeshWeaver.Layout.Test/LayoutTest.cs Switches JSON patch/pointer usings to MeshWeaver.Json.
test/MeshWeaver.Layout.Test/DomainLayoutServiceTest.cs Switches json-everything usings to MeshWeaver.Json.
test/MeshWeaver.Json.Test/MeshWeaver.Json.Test.csproj New test project referencing MeshWeaver.Utils and embedding the golden fixture resource.
test/MeshWeaver.Json.Test/Fixtures/json-everything-golden.json Golden-wire oracle captured from json-everything to pin byte-identical serialization/diff behavior.
test/MeshWeaver.Json.Test/JsonPointerTest.cs New RFC 6901 parsing/segment/resolve/serialization + golden conformance tests.
test/MeshWeaver.Json.Test/JsonPatchWireFormatTest.cs New byte-for-byte wire-format serialization/deserialization tests for RFC 6902 operations.
test/MeshWeaver.Json.Test/JsonPatchDiffTest.cs New diff correctness + golden diff corpus + apply(diff)==target property tests.
test/MeshWeaver.Json.Test/JsonPatchApplyTest.cs New apply semantics tests (including escaped-key correctness and failure reporting).
test/MeshWeaver.Json.Test/JsonGenerator.cs Random JSON generator/mutator used for property-style diff/apply tests.
test/MeshWeaver.Json.Test/GoldenFixtures.cs Embedded-resource loader for the golden fixture, failing hard if missing/empty.
test/MeshWeaver.Data.Test/PointerSegmentCodecTest.cs New regression tests pinning the RFC 6901 decode-order trap fix.
test/MeshWeaver.Data.Test/Playground.cs Switches JSON patch/pointer usings to MeshWeaver.Json.
test/MeshWeaver.Data.Test/EntityUpdateDedupTest.cs Switches JSON patch using to MeshWeaver.Json.
src/MeshWeaver.Utils/Json/PatchOperation.cs New RFC 6902 operation model + converters (including property-order contract).
src/MeshWeaver.Utils/Json/PatchExtensions.cs New diff (CreatePatch) and typed Apply helpers.
src/MeshWeaver.Utils/Json/JsonTypeExtensions.cs New numeric-type predicates previously sourced from Json.More.
src/MeshWeaver.Utils/Json/JsonPointer.cs New RFC 6901 pointer implementation + segment decode/evaluate + converter + exception type.
src/MeshWeaver.Utils/Json/JsonPatch.cs New RFC 6902 patch container + apply engine and patch converter.
src/MeshWeaver.Utils/Json/JsonEquivalence.cs New structural JSON equivalence logic + JsonElement→JsonNode bridge (AsNode).
src/MeshWeaver.Messaging.Hub/Serialization/ImmutableDictionaryConverter.cs Replaces Json.More dependency with MeshWeaver.Json (AsNode).
src/MeshWeaver.Messaging.Hub/MeshWeaver.Messaging.Hub.csproj Removes JsonPatch.Net package reference.
src/MeshWeaver.Layout/LayoutExtensions.cs Switches JSON patch/pointer usings to MeshWeaver.Json.
src/MeshWeaver.Layout/EditorExtensions.cs Replaces Json.More using with MeshWeaver.Json.
src/MeshWeaver.Layout/DataGrid/PropertyViewBuilder.cs Replaces Json.More using with MeshWeaver.Json.
src/MeshWeaver.Layout/Client/ModelParameter.cs Switches JSON patch using to MeshWeaver.Json.
src/MeshWeaver.Layout/Client/LayoutClientExtensions.cs Switches JSON patch/pointer usings to MeshWeaver.Json.
src/MeshWeaver.Graph/MeshWeaver.Graph.csproj Declares Humanizer.Core explicitly (no longer a transitive).
src/MeshWeaver.Graph/MeshDataSource.cs Switches JSON patch using to MeshWeaver.Json.
src/MeshWeaver.Data/WorkspaceOperations.cs Switches JSON patch using to MeshWeaver.Json.
src/MeshWeaver.Data/StandardReducers.cs Switches JSON patch/pointer usings to MeshWeaver.Json.
src/MeshWeaver.Data/Serialization/JsonSynchronizationStream.cs Switches JSON patch/pointer usings and fixes fallback move/copy arg ordering + result serialization + pointer decode.
src/MeshWeaver.Data/Serialization/InstanceCollectionConverter.cs Replaces Json.More using with MeshWeaver.Json.
src/MeshWeaver.Data/Serialization/EntityStoreConverter.cs Replaces Json.More using with MeshWeaver.Json.
src/MeshWeaver.Data/Serialization/DataChangedEventConverter.cs Updates commented-out using to MeshWeaver.Json.
src/MeshWeaver.Data/ReduceManager.cs Switches JSON patch using to MeshWeaver.Json.
src/MeshWeaver.Data/MeshWeaver.Data.csproj Removes JsonPatch.Net + JsonPath.Net package references.
src/MeshWeaver.Data/DataExtensions.cs Switches JSON patch using to MeshWeaver.Json.
src/MeshWeaver.Data.Contract/MeshWeaver.Data.Contract.csproj Removes JsonPatch.Net and adds MeshWeaver.Utils reference for MeshWeaver.Json.
src/MeshWeaver.Data.Contract/LayoutAreaReference.cs Switches JSON pointer using to MeshWeaver.Json.
src/MeshWeaver.Blazor/Components/ListBase.cs Switches JSON pointer using to MeshWeaver.Json.
src/MeshWeaver.AI/MeshWeaver.AI.csproj Declares Humanizer.Core explicitly (no longer a transitive).
MeshWeaver.slnx Adds the new MeshWeaver.Json.Test project to the solution.
Directory.Packages.props Pins Humanizer.Core and removes json-everything package versions.
.github/scripts/shard-assign.sh Adds shard weight entry for the new MeshWeaver.Json.Test project.
.github/scripts/check-licenses.py Removes json-everything exceptions from the license gate.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/MeshWeaver.Utils/Json/JsonEquivalence.cs
Comment thread src/MeshWeaver.Utils/Json/JsonPointer.cs Outdated
@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

722 tests  +15   722 ✅ +15   11m 50s ⏱️ - 2m 14s
 10 suites ± 0     0 💤 ± 0 
 10 files   ± 0     0 ❌ ± 0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

This pull request removes 36 and adds 51 tests. Note that renamed tests count towards both.
MeshWeaver.Hosting.Sqlite.Test.MemexInstanceBootstrapTest ‑ Instances_are_nodes_and_read_back_via_GetQuery
MeshWeaver.Hosting.Sqlite.Test.SqliteEventLogStoreTest ‑ Append_is_idempotent_by_path_kind_version
MeshWeaver.Hosting.Sqlite.Test.SqliteEventLogStoreTest ‑ ReadFrom_and_cursor_roundtrip
MeshWeaver.Hosting.Sqlite.Test.SqliteMonolithMeshTest ‑ Create_read_and_query_a_node_through_a_monolith_mesh_on_sqlite
MeshWeaver.Hosting.Sqlite.Test.SqliteQueryTests ‑ Query_nodeType_filters_by_type
MeshWeaver.Hosting.Sqlite.Test.SqliteQueryTests ‑ Query_scope_children_returns_only_direct_children
MeshWeaver.Hosting.Sqlite.Test.SqliteQueryTests ‑ Query_scope_descendants_includes_nested_nodes
MeshWeaver.Hosting.Sqlite.Test.SqliteRawBootstrapTest ‑ Raw_monolith_mesh_bootstrap_on_sqlite_creates_and_reads_a_node
MeshWeaver.Hosting.Sqlite.Test.SqliteStorageAdapterTests ‑ Changes_feed_emits_Deleted_on_delete
MeshWeaver.Hosting.Sqlite.Test.SqliteStorageAdapterTests ‑ Changes_feed_emits_Updated_on_write
…
MeshWeaver.ContentCollections.Test.ContentCollectionIngestOrderTest ‑ TornReadFromTheCreatedEvent_CannotOverwriteTheCompleteArticle
MeshWeaver.ContentCollections.Test.ContentCollectionWriteIngestTest ‑ SaveFile_ingests_the_article_without_the_watcher
MeshWeaver.ContentCollections.Test.ContentCollectionWriteReadRaceTest ‑ Write_Succeeds_While_A_Concurrent_Read_Holds_The_File
MeshWeaver.ContentCollections.Test.ContentServiceDelegationTest ‑ ContentService_ShouldDelegateToParent
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ ContentAutocomplete_ExactMatch_Gets_Highest_Priority
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ ContentAutocomplete_Filters_And_Scores_By_Query
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ ContentAutocomplete_Wraps_Spaces_In_Quotes
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ DocSharpContentTransformer_Converts_Docx_To_Markdown
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ FileContentProvider_Auto_Converts_Docx
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ FileContentProvider_Returns_PlainText_For_Md
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

1 885 tests  +68   1 693 ✅ +68   6m 37s ⏱️ - 1m 50s
   11 suites ± 0     192 💤 ± 0 
   11 files   ± 0       0 ❌ ± 0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

This pull request removes 328 and adds 396 tests. Note that renamed tests count towards both.
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ ComparisonBars_render_an_absent_side_as_words_and_a_present_one_as_a_bar
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ ComparisonBars_with_nothing_on_either_side_say_so
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ KpiStrip_renders_a_tile_per_item_with_its_hint
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ KpiStrip_with_no_items_says_so_instead_of_drawing_an_empty_box
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ Tower_band_with_an_href_renders_as_a_link_to_a_root_relative_target
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ Tower_places_each_band_at_its_computed_percentage
MeshWeaver.Hosting.Blazor.Test.AnalysisViewRenderingTest ‑ Tower_with_no_bands_says_so_instead_of_drawing_an_empty_frame
MeshWeaver.Hosting.Blazor.Test.ApplicationPageProgressDecisionTest ‑ ShowFullProgress_Decision(isInteractive: False, isLoading: False, hasContext: False, hasViewModel: False, expected: True)
MeshWeaver.Hosting.Blazor.Test.ApplicationPageProgressDecisionTest ‑ ShowFullProgress_Decision(isInteractive: False, isLoading: False, hasContext: False, hasViewModel: True, expected: True)
MeshWeaver.Hosting.Blazor.Test.ApplicationPageProgressDecisionTest ‑ ShowFullProgress_Decision(isInteractive: False, isLoading: False, hasContext: True, hasViewModel: False, expected: True)
…
MeshWeaver.Hosting.Sqlite.Test.MemexInstanceBootstrapTest ‑ Instances_are_nodes_and_read_back_via_GetQuery
MeshWeaver.Hosting.Sqlite.Test.SqliteEventLogStoreTest ‑ Append_is_idempotent_by_path_kind_version
MeshWeaver.Hosting.Sqlite.Test.SqliteEventLogStoreTest ‑ ReadFrom_and_cursor_roundtrip
MeshWeaver.Hosting.Sqlite.Test.SqliteMonolithMeshTest ‑ Create_read_and_query_a_node_through_a_monolith_mesh_on_sqlite
MeshWeaver.Hosting.Sqlite.Test.SqliteQueryTests ‑ Query_nodeType_filters_by_type
MeshWeaver.Hosting.Sqlite.Test.SqliteQueryTests ‑ Query_scope_children_returns_only_direct_children
MeshWeaver.Hosting.Sqlite.Test.SqliteQueryTests ‑ Query_scope_descendants_includes_nested_nodes
MeshWeaver.Hosting.Sqlite.Test.SqliteRawBootstrapTest ‑ Raw_monolith_mesh_bootstrap_on_sqlite_creates_and_reads_a_node
MeshWeaver.Hosting.Sqlite.Test.SqliteStorageAdapterTests ‑ Changes_feed_emits_Deleted_on_delete
MeshWeaver.Hosting.Sqlite.Test.SqliteStorageAdapterTests ‑ Changes_feed_emits_Updated_on_write
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

2 290 tests  +176   2 289 ✅ +176   7m 14s ⏱️ +22s
   12 suites +  1       1 💤 ±  0 
   12 files   +  1       0 ❌ ±  0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

This pull request removes 188 and adds 364 tests. Note that renamed tests count towards both.
MeshWeaver.ContentCollections.Test.ContentCollectionIngestOrderTest ‑ TornReadFromTheCreatedEvent_CannotOverwriteTheCompleteArticle
MeshWeaver.ContentCollections.Test.ContentCollectionWriteIngestTest ‑ SaveFile_ingests_the_article_without_the_watcher
MeshWeaver.ContentCollections.Test.ContentCollectionWriteReadRaceTest ‑ Write_Succeeds_While_A_Concurrent_Read_Holds_The_File
MeshWeaver.ContentCollections.Test.ContentServiceDelegationTest ‑ ContentService_ShouldDelegateToParent
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ ContentAutocomplete_ExactMatch_Gets_Highest_Priority
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ ContentAutocomplete_Filters_And_Scores_By_Query
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ ContentAutocomplete_Wraps_Spaces_In_Quotes
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ DocSharpContentTransformer_Converts_Docx_To_Markdown
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ FileContentProvider_Auto_Converts_Docx
MeshWeaver.ContentCollections.Test.DocxConversionTest ‑ FileContentProvider_Returns_PlainText_For_Md
…
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ A_single_unkeyed_remote_serves_every_target
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ A_target_owned_by_no_connected_remote_selects_none
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ A_target_that_is_a_remote_itself_selects_it
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ Each_target_routes_to_its_owning_remote
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ No_remotes_or_null_target_selects_none
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ Runtime_added_connections_select_by_owning_remote
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ BadDataTest
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseDefaultFormat.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseEmptyFormat.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseNoFormat.csv\")
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

   11 files  ±  0     11 suites  ±0   8m 12s ⏱️ +24s
1 810 tests  - 330  1 707 ✅  - 330  103 💤 ±0  0 ❌ ±0 
2 059 runs   - 329  1 956 ✅  - 329  103 💤 ±0  0 ❌ ±0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

This pull request removes 371 and adds 41 tests. Note that renamed tests count towards both.
Memex.Portal.Shared.Test.AboutSettingsTabTest ‑ Every_localization_key_the_about_tab_reads_exists_in_the_catalog
Memex.Portal.Shared.Test.AboutSettingsTabTest ‑ ToRows_maps_manifests_to_display_rows
Memex.Portal.Shared.Test.AboutSettingsTabTest ‑ UpdateStatusMarkdown_renders_both_verdicts_and_nothing_when_unknown
Memex.Portal.Shared.Test.AgentSkillSyncServiceTest ‑ BaseInstructions_PointToMcp_VectorSearch_AndOnDemandSkillDiscovery
Memex.Portal.Shared.Test.AgentSkillSyncServiceTest ‑ RenderSkillCatalog_ListsAdvertisedInstructionSkills_WithDescriptionAndLoadPath
Memex.Portal.Shared.Test.AgentSkillSyncServiceTest ‑ RenderSkillCatalog_NoAdvertisedSkills_ReturnsEmpty
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ AiMenu_Entries_Are_Uniquely_Keyed
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ AiMenu_Seeds_NewThread_First
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ Every_Other_AiMenu_Entry_Navigates_By_Href
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ NewThread_Carries_No_Href_So_It_Stays_Imperative
…
MeshWeaver.MathDemo.Test.MatrixViewsTest ‑ Inverse_ShouldRenderForMatrixExample
MeshWeaver.Social.Test.InMemoryPublishQueueTest ‑ DrainDue_ReturnsAndRemovesDueItems
MeshWeaver.Social.Test.InMemoryPublishQueueTest ‑ Enqueue_DedupsByPostPath
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ EntityParameter_NullForUnsupportedShapes(urn: \"7325786486870552578\")
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ EntityParameter_NullForUnsupportedShapes(urn: \"\")
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ EntityParameter_NullForUnsupportedShapes(urn: \"urn:li:activity:123\")
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ EntityParameter_NullForUnsupportedShapes(urn: null)
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ EntityParameter_WrapsShareUrn
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ EntityParameter_WrapsUgcPostUrn
MeshWeaver.Social.Test.LinkedInAnalyticsTest ‑ SumCounts_AcceptsStringCounts
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 809 tests  +489   1 799 ✅ +489   12m 46s ⏱️ +23s
   11 suites ±  0      10 💤 ±  0 
   11 files   ±  0       0 ❌ ±  0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

This pull request removes 27 and adds 516 tests. Note that renamed tests count towards both.
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ A_single_unkeyed_remote_serves_every_target
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ A_target_owned_by_no_connected_remote_selects_none
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ A_target_that_is_a_remote_itself_selects_it
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ Each_target_routes_to_its_owning_remote
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ No_remotes_or_null_target_selects_none
MeshWeaver.Connection.SignalR.Test.SignalRMultiRemoteSelectionTest ‑ Runtime_added_connections_select_by_owning_remote
MeshWeaver.Documentation.Test.CessionExampleTest ‑ CedeIntoLayer_AllSampleClaims_CorrectTotals
MeshWeaver.Documentation.Test.CessionExampleTest ‑ CedeIntoLayer_ClaimAboveLimit_CappedAtLimit
MeshWeaver.Documentation.Test.CessionExampleTest ‑ CedeIntoLayer_ClaimBelowAttachment_FullyRetained
MeshWeaver.Documentation.Test.CessionExampleTest ‑ CedeIntoLayer_ClaimWithinLayer_PartiallyCeded
…
Memex.Portal.Shared.Test.AboutSettingsTabTest ‑ Every_localization_key_the_about_tab_reads_exists_in_the_catalog
Memex.Portal.Shared.Test.AboutSettingsTabTest ‑ ToRows_maps_manifests_to_display_rows
Memex.Portal.Shared.Test.AboutSettingsTabTest ‑ UpdateStatusMarkdown_renders_both_verdicts_and_nothing_when_unknown
Memex.Portal.Shared.Test.AgentSkillSyncServiceTest ‑ BaseInstructions_PointToMcp_VectorSearch_AndOnDemandSkillDiscovery
Memex.Portal.Shared.Test.AgentSkillSyncServiceTest ‑ RenderSkillCatalog_ListsAdvertisedInstructionSkills_WithDescriptionAndLoadPath
Memex.Portal.Shared.Test.AgentSkillSyncServiceTest ‑ RenderSkillCatalog_NoAdvertisedSkills_ReturnsEmpty
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ AiMenu_Entries_Are_Uniquely_Keyed
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ AiMenu_Seeds_NewThread_First
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ Every_Other_AiMenu_Entry_Navigates_By_Href
Memex.Portal.Shared.Test.AiMenuNewThreadTest ‑ NewThread_Carries_No_Href_So_It_Stays_Imperative
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 323 tests   - 32   1 323 ✅  - 32   8m 10s ⏱️ -4s
   11 suites ± 0       0 💤 ± 0 
   11 files   ± 0       0 ❌ ± 0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

This pull request removes 65 and adds 33 tests. Note that renamed tests count towards both.
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ BadDataTest
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseDefaultFormat.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseEmptyFormat.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseNoFormat.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadComplexCaseWithDifferentFormat(fileName: \"ComplexCaseWrongFormat.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadFormat(fileName: \"CustomFormat.csv\", format: \"CustomFormat\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadFormat(fileName: \"EmptyFormat.csv\", format: \"\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadFormat(fileName: \"SpacesBeforeFormat.csv\", format: \"SpacesBeforeFormat\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadManyEmptyTableInDataSet(fileName: \"SeveralEmptyTables.csv\")
MeshWeaver.DataSetReader.Test.CsvReaderTest ‑ ReadManyEmptyTableInDataSet(fileName: \"SeveralEmptyTablesWithCommas.csv\")
…
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"a/b~c\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"acme/Docs/One\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"has~0literal\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"has~1literal\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"has~tilde\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"plain\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"~01\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"~0\")
MeshWeaver.Data.Test.PointerSegmentCodecTest ‑ EscapedId_DecodesBackToItself(id: \"~1\")
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

    66 files  +  1     66 suites  +1   54m 52s ⏱️ - 2m 58s
 9 839 tests +386  9 533 ✅ +386  306 💤 ±0  0 ❌ ±0 
10 088 runs  +387  9 782 ✅ +387  306 💤 ±0  0 ❌ ±0 

Results for commit 09d2082. ± Comparison against base commit ab1ada9.

♻️ This comment has been updated with latest results.

Two real defects, both on paths the differential harness did not reach:

1. GetNumber cast a raw CLR double/float straight to decimal, which throws
   OverflowException for NaN, +/-infinity and any magnitude past decimal's
   range — turning an equality check into a crash. It now returns null for
   those, so the pair falls through to the boxed comparison and still answers
   correctly. Only reachable for a JsonValue holding a CLR double rather than a
   parsed JsonElement, which is why neither the fixtures nor the 8,000 generated
   documents hit it. json-everything had the identical bug, so this diverges
   only where it used to throw.

2. JsonPointerSegment.Equals(string?) threw ArgumentNullException on null even
   though the signature permits it, and the == / != operators reached straight
   for the span. Null is now simply "no match", per normal Equals semantics.

Both are pinned by new tests: RawDoubleValues_CompareWithoutThrowing /
RawDoubleValues_DiffWithoutThrowing and Segment_ComparedWithNull_IsFalseNotAThrow.
Worth recording what those tests taught us — NaN compares EQUAL to NaN here
(the fallback is object.Equals, and Double.Equals deliberately differs from ==),
which is the right answer for a diff, and System.Text.Json refuses to serialize
+/-infinity at all, so the typed CreatePatch overload cannot be exercised with it.

Differential re-run after the change: 18,490 assertions, 0 mismatches — the wire
shape is unaffected.

Refs #1231.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

Decision needed: json-everything (JsonPatch.Net/JsonPath.Net) carries an Open Source Maintenance Fee

2 participants