@unified-product-graph/core 0.32.1 → 0.32.2
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 +20 -0
- package/dist/index.cjs +40 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -2
- package/dist/index.d.ts +33 -2
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.32.2] - 2026-08-21
|
|
11
|
+
|
|
12
|
+
Patch. No schema change: no entity, edge, property, enum, or lifecycle added or removed. The 0.32.0 base fields become reachable through the write path that was supposed to carry them.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **`UPGFileStore.updateNode` round-trips every `UPGBaseNode` field.** It merged a hand-maintained list of seven names and returned the unchanged node as a SUCCESS for anything outside it, so the three fields 0.32.0 added to the shape (`key`, `archived`, `archived_at`) were accepted and discarded. A caller could not tell a lost write from a landed one; the key-minting contention loop in the local graph-service adapter hit exactly this and spent its whole retry budget re-minting a key that could never move. The mergeable set is now DERIVED from the shape, so a field added to `UPGBaseNode` round-trips with no further edit.
|
|
16
|
+
- **An undeclared top-level field is now REFUSED, not dropped.** `updateNode` throws the new `UnknownNodeFieldError` naming the offending keys, and refuses atomically so the valid half of a patch cannot land beside a silently discarded half. Changing `id` throws `ImmutableNodeFieldError`; restating the current `id` stays legal, so spreading a whole node into a patch keeps working. Type-level callers cannot reach either path, since `Partial<UPGBaseNode>` rejects an undeclared key at compile time; the guards fire on runtime-shaped input such as a parsed argument bag.
|
|
17
|
+
- **Drift detection no longer reports a minted key as non-spec.** The canonical top-level field sets behind `top_level_drift` (the load-time counter in `@unified-product-graph/sdk` and the per-node breakdown in `validate_graph`) were two more hand-maintained copies of the same list, and 0.32.0 updated neither, so every node carrying `key`, `archived`, or `archived_at` was counted as holding non-spec top-level fields. Both derive from the shape now.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **`UPG_BASE_NODE_FIELDS`, `UPG_BASE_NODE_FIELD_SET`, `UPG_BASE_NODE_SPECIAL_MERGE_FIELDS`** on `@unified-product-graph/core`: the `UPGBaseNode` key set as runtime data, and the subset a generic shallow merge must not touch. A TypeScript interface is erased at runtime, which is why four consumers each kept their own copy behind a comment asking the next editor to remember. The list is locked to the interface by a `Record<keyof UPGBaseNode, true>` that is exhaustive in both directions, so adding a field to the shape without extending the list is now a COMPILE error rather than a silent divergence discovered three releases later.
|
|
21
|
+
- `UnknownNodeFieldError` and `ImmutableNodeFieldError` are exported from `@unified-product-graph/sdk`.
|
|
22
|
+
|
|
23
|
+
### Notes
|
|
24
|
+
- Truth unchanged: **324 entities · 1082 edges · 69 cross-edges · 25 anti-patterns · 98 tools · 334 phases**. Zero new tools, zero new checks.
|
|
25
|
+
- Release process: `scripts/upg-release.sh` gains a step that regenerates the five `apps/entopo` spec mirrors from the freshly built train and then re-runs their `--check` forms. Those mirrors sit outside the release train's build filters, so no release ever ran their generators or their gates, and they have gone stale three times; 0.32.1 shipped with the snapshot still reading 0.32.0. The failure resists inspection because the drift test reads a checkout's `dist/`, and against a stale `dist` the comparison is stale-against-stale and reports green.
|
|
26
|
+
- The MCP `update_node` and `batch_update_nodes` tools still do not accept `key`, `archived`, or `archived_at` as arguments, so those fields remain unreachable from the agent surface. Widening a tool's argument schema is additive surface rather than a fix and is deliberately NOT in this patch.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
10
30
|
## [0.32.1] - 2026-08-21
|
|
11
31
|
|
|
12
32
|
Patch. No schema change: no entity, edge, property, enum, or lifecycle added or removed.
|
package/dist/index.cjs
CHANGED
|
@@ -70,6 +70,9 @@ __export(index_exports, {
|
|
|
70
70
|
UPG_APPROACHES_BY_ID: () => UPG_APPROACHES_BY_ID,
|
|
71
71
|
UPG_AREA_TAXONOMY: () => UPG_AREA_TAXONOMY,
|
|
72
72
|
UPG_AREA_TAXONOMY_BY_COVERAGE_KEY: () => UPG_AREA_TAXONOMY_BY_COVERAGE_KEY,
|
|
73
|
+
UPG_BASE_NODE_FIELDS: () => UPG_BASE_NODE_FIELDS,
|
|
74
|
+
UPG_BASE_NODE_FIELD_SET: () => UPG_BASE_NODE_FIELD_SET,
|
|
75
|
+
UPG_BASE_NODE_SPECIAL_MERGE_FIELDS: () => UPG_BASE_NODE_SPECIAL_MERGE_FIELDS,
|
|
73
76
|
UPG_CANONICAL_FORMAT_VERSION: () => UPG_CANONICAL_FORMAT_VERSION,
|
|
74
77
|
UPG_CONTAINMENT_FREE_TYPES: () => UPG_CONTAINMENT_FREE_TYPES,
|
|
75
78
|
UPG_COUNT_BENCHMARKS: () => UPG_COUNT_BENCHMARKS,
|
|
@@ -4085,6 +4088,39 @@ function isLegacyProductStage(stage) {
|
|
|
4085
4088
|
return typeof stage === "string" && stage.toLowerCase() in LEGACY_PRODUCT_STAGES;
|
|
4086
4089
|
}
|
|
4087
4090
|
|
|
4091
|
+
// src/shapes/base-node.ts
|
|
4092
|
+
var BASE_NODE_FIELD_PRESENCE = {
|
|
4093
|
+
id: true,
|
|
4094
|
+
type: true,
|
|
4095
|
+
title: true,
|
|
4096
|
+
slug: true,
|
|
4097
|
+
aliases: true,
|
|
4098
|
+
key: true,
|
|
4099
|
+
description: true,
|
|
4100
|
+
tags: true,
|
|
4101
|
+
status: true,
|
|
4102
|
+
archived: true,
|
|
4103
|
+
archived_at: true,
|
|
4104
|
+
source_id: true,
|
|
4105
|
+
source_type: true,
|
|
4106
|
+
mapping_confidence: true,
|
|
4107
|
+
external_tool: true,
|
|
4108
|
+
external_ref: true,
|
|
4109
|
+
external_id: true,
|
|
4110
|
+
properties: true
|
|
4111
|
+
};
|
|
4112
|
+
var UPG_BASE_NODE_FIELDS = Object.freeze(
|
|
4113
|
+
Object.keys(BASE_NODE_FIELD_PRESENCE)
|
|
4114
|
+
);
|
|
4115
|
+
var UPG_BASE_NODE_FIELD_SET = new Set(UPG_BASE_NODE_FIELDS);
|
|
4116
|
+
var UPG_BASE_NODE_SPECIAL_MERGE_FIELDS = /* @__PURE__ */ new Set([
|
|
4117
|
+
"id",
|
|
4118
|
+
"type",
|
|
4119
|
+
"slug",
|
|
4120
|
+
"aliases",
|
|
4121
|
+
"properties"
|
|
4122
|
+
]);
|
|
4123
|
+
|
|
4088
4124
|
// src/shapes/document.ts
|
|
4089
4125
|
var UPG_CROSS_ONLY_EDGE_TYPES = [
|
|
4090
4126
|
// Peer overlap: "these two products share / overlap on this thing." Symmetric,
|
|
@@ -33124,7 +33160,7 @@ function checkHeaderSealText(text) {
|
|
|
33124
33160
|
}
|
|
33125
33161
|
|
|
33126
33162
|
// src/index.ts
|
|
33127
|
-
var UPG_VERSION = "0.32.
|
|
33163
|
+
var UPG_VERSION = "0.32.2";
|
|
33128
33164
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
33129
33165
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
33130
33166
|
var UPG_TYPES = getTypes();
|
|
@@ -33229,6 +33265,9 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
|
|
|
33229
33265
|
UPG_APPROACHES_BY_ID,
|
|
33230
33266
|
UPG_AREA_TAXONOMY,
|
|
33231
33267
|
UPG_AREA_TAXONOMY_BY_COVERAGE_KEY,
|
|
33268
|
+
UPG_BASE_NODE_FIELDS,
|
|
33269
|
+
UPG_BASE_NODE_FIELD_SET,
|
|
33270
|
+
UPG_BASE_NODE_SPECIAL_MERGE_FIELDS,
|
|
33232
33271
|
UPG_CANONICAL_FORMAT_VERSION,
|
|
33233
33272
|
UPG_CONTAINMENT_FREE_TYPES,
|
|
33234
33273
|
UPG_COUNT_BENCHMARKS,
|