@unified-product-graph/core 0.9.20 → 0.9.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.9.22] - 2026-06-11
11
+
12
+ **Stops silent data duplication from re-delivered MCP writes, and stops dedupe from destroying structure.** Three fixes for a HIGH-severity report where a mutating call was applied twice (the duplicate landing a few calls later, past any immediate recount).
13
+
14
+ ### Fixed
15
+ - **Idempotent MCP writes (primary).** A re-delivered mutating tool call (the same JSON-RPC request id, e.g. a transport-level resend) re-ran the handler, minted fresh ids, and wrote a second copy. The local MCP server now memoises the result per request id and replays it, so a re-delivery (in flight or already finished) is a no-op that returns the original response instead of duplicating the write.
16
+ - **Watcher self-write guard (`@unified-product-graph/sdk`).** The file watcher's 150ms self-write flag expired before chokidar's 200ms `awaitWriteFinish` fired, so every server write looked like an external change and triggered a needless reload/merge. The guard is now a content-hash check: if the changed file equals what we last wrote, it is not external. Timing-independent.
17
+ - **`deduplicate_nodes` no longer drops structural edges.** The merge used a constant sort comparator (not a real `created_at` sort) and redirected inbound edges best-effort with a silent catch, then cascade-removed the originals, so a kept node could lose its inbound containment edge and vanish from the tree. Rewritten: a real keeper sort, a group-wide redirect map that re-homes every edge onto the keeper before removing any node (identical edges union, not multiply), and a structural-parent assertion that surfaces any inbound parent edge not preserved (`structural_warnings`).
18
+
19
+ No entity, domain, region, edge, or tool-count change (entities 315, edges 980, local tools 123). The cloud server (Postgres-backed, no file watcher, separate SQL dedupe) is unaffected.
20
+
21
+ ---
22
+
23
+ ## [0.9.21] - 2026-06-11
24
+
25
+ **The `get_tree` fallback message no longer contradicts the tree it renders.**
26
+
27
+ ### Fixed
28
+ - A pattern's anchor fallback fires for two reasons, and the message conflated them. Under the most-nodes anchor rule, `get_tree` falls back when the anchor type is ABSENT, but also when it is PRESENT and merely nests under a richer root (e.g. services that all sit under a `bounded_context`). The note always said "No `<anchor>` found", which on a graph with nested services contradicts the services rendered right below it. `assembleTree` now returns **`anchor_present`** (does the anchor type have at least one node), and the CLI `tree --pattern` note and the show-tree skill use it: absent keeps "No `<anchor>` found; rooted on `<fallback>`", present-but-nested says "`<anchor>` present, but `<fallback>` surfaces more of the tree; rooted there." Behaviour was already correct; only the wording is fixed. Generalises to every pattern whose anchor sits below a structural root.
29
+
30
+ No entity, domain, region, edge, or tool-count change (entities 315, edges 980, local tools 123).
31
+
32
+ ---
33
+
10
34
  ## [0.9.20] - 2026-06-11
11
35
 
12
36
  **The tree-pattern catalogue is now introspectable and drift-guarded.** A pattern can no longer cite an edge the grammar lacks, and clients can read the catalogue instead of reverse-engineering it.
package/dist/index.cjs CHANGED
@@ -28431,7 +28431,7 @@ function isCanonical(text) {
28431
28431
  }
28432
28432
 
28433
28433
  // src/index.ts
28434
- var UPG_VERSION = "0.9.20";
28434
+ var UPG_VERSION = "0.9.22";
28435
28435
  var UPG_FORMAT_VERSION = "0.4.0";
28436
28436
  var MARKDOWN_FORMAT_VERSION = "0.1";
28437
28437
  var UPG_TYPES = getTypes();