@unified-product-graph/core 0.29.0 → 0.31.0

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,51 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.31.0] - 2026-08-19
11
+
12
+ **The eval harness gets the four spec affordances its architecture brief asked for, and the workspace canvas learns what a tool-owned key is.** Two threads converge: the eval-architecture design cycle (ratified 2026-08-16) needed benchmarks that can name what they measure and runs that can carry more than one number; and the image-artifact pilot found two namespacing conventions already coexisting in one canvas bag, with the spec silent on which was right. Additive; no breaking change; no migration of any `.upg` file.
13
+
14
+ ### Added
15
+ - **`eval_benchmark_measures_node`** (semantic, polymorphic). A benchmark names its SUBJECT by pointing at it: a tool, a document, a check, an importer, a feature. The wildcard is deliberately wider than the truth (a benchmark cannot meaningfully measure a persona); that over-width is stated on the label as an honest deferral of "what is a tool in the graph", which this release does not answer. Coexists with the typed `eval_benchmark_measures_feature` on the `constraint_constrains_feature` / `node_constrains_node` precedent.
16
+ - **`eval_benchmark_draws_cases_from_ai_dataset`** (semantic). A labeled corpus IS an `ai_dataset`; this is the one join edge that makes it so, per the recurrence discipline that tries the existing type before minting one.
17
+ - **`metric_scores` on `eval_run`** — an exported `MetricScore[]` (`metric`, `value`, `sample_size`), so a run reports precision AND recall as separate numbers instead of one aggregate `score` or a stringly-typed pair. `value` is normalized 0 through 1 (1 best) because comparing runs is the entire reason the array exists and two runs on different raw scales do not compare; non-rate measurements (wall-clock, tokens, cost) stay on their typed fields. `sample_size` is required: a sampled run reports its sample size beside its score, always, so a comparison across runs can never quietly compare different sample sizes.
18
+ - **`benchmark_type` widened** with `precision_recall`, `task_success`, `coherence`. The enum is a DIMENSION axis (what kind of number); the subject axis lives on `eval_benchmark_measures_node`. Do not add subject-shaped values here — they would encode on the dimension axis what the edge already carries, and the two would drift.
19
+ - **Namespaced keys on the workspace canvas.** The rule, now in spec: a tool-owned key is `<tool>:<key>` (colon, because an underscore key is indistinguishable from an ordinary property name — which is also why no validator can police this rule, and enforcement is documentation plus the type); every consumer preserves unknown keys byte for byte; **no consumer interprets a key it does not own** — preservation is a storage guarantee that says nothing about meaning. `WorkspaceCanvas` carries a template-literal index signature encoding the colon form at compile time.
20
+ - **`composition` type-scope sentence** (F4) clarifying which entity kinds an identity rule reaches.
21
+
22
+ ### Changed
23
+ - The driving query of a query-driven layer is declared in spec, not in a bag key — a consequence of the no-foreign-interpretation rule: a bag-held query would make every future gallery proprietary to one application. The LOCATION is ruled here; the SHAPE is held for the next minor, since the field pilot measured that the hole exists, not what fills it.
24
+ - `entopo_views` (underscore) migrates to `entopo:views` (colon) in the same window as this release, executed by the Entopo Local lane: same-day rename, one release of tolerant reading for dev-written files carrying the old form, tolerance retiring at 0.32.0. Tolerance converts an undetectable failure into a scheduled one.
25
+
26
+ ### Notes
27
+ - Truth: 323 entities · 1079 edges · 69 cross-edges · 25 anti-patterns · 98 tools. Zero new checks; the syntax rule introduces none because none could see the half that matters.
28
+ - Polymorphic edge families: 10 (21 entries), asserted as data in the spec-integrity test (a `FAMILIES` record that must partition the array exactly).
29
+ - Fixture coverage: both new edges carry saturated-graph instances; `eval_benchmark_measures_node` points at an `api_endpoint` deliberately, so the example teaches the wildcard where the typed feature edge does not belong.
30
+ - The 0.30.0 package shipped a CHANGELOG whose `[0.29.0]` heading had been lost to a release-prep edit; this release carries the corrected ladder.
31
+
32
+ ---
33
+
34
+ ## [0.30.0] - 2026-08-15
35
+
36
+ **A surface tree is often not one tree but a family of trees selected by configuration, and the graph can now say so.** A feature flag, a plan tier, a permission level or a beta programme changes which surfaces exist and what contains what; until now every surface fact was implicitly qualified by "in whatever configuration someone happened to be looking at", unrecorded. The stored graph is now the union of that family, a single configuration is a projection of it, unqualified facts are invariant, and a graph declaring no variance is semantically identical to before. Zero migration; additive; no breaking change.
37
+
38
+ ### Added
39
+ - **`configuration_axis` entity** (`proposed`, `ent_360`) — one node per semantic lever, with a closed `values` list, a `default_value`, and a `kind` (`feature_flag | plan_tier | permission_level | beta_program | other`). One axis per lever, not one per code flag: the axis names what the team pulls, the flag names how the code implements it.
40
+ - **Four edges.** `product_defines_configuration_axis` (hierarchy — the axis renders in the tree), `surface_varies_by_configuration_axis` (carries `present_under: [values]`; no edge means invariant), `feature_flag_drives_configuration_axis` (mechanism vs lever), and `surface_alternates_with_surface` ("one of these, depending" — validated against the axis declarations, direction by convention only).
41
+ - **`active_when` qualifier** on `surface_contains_surface` and `feature_occupies_surface` — and deliberately on no other edge: conditional composition is the question this release answers, and a general modality system is not. The scope is enforced: a qualifier on any other edge type is a `configuration_drift` error.
42
+ - **Projection operator** — node exclusion, then edge deactivation, then dangling removal; commutative across axes; identity on graphs declaring no variance.
43
+ - **`configuration_drift` validate scope** — ten checks covering unresolved axes, empty value lists, illegal qualifiers, contradictory alternations, and projection-stranded children. Error-severity drift gates `valid` and `structurally_valid`.
44
+ - **Per-projection anti-pattern evaluation.** Findings true everywhere report unqualified, exactly as before. Findings true in only some configurations report once, annotated (`configurations: [{axis, value}]`). Findings true only in the union are suppressed and counted (`suppressed_union_artifacts`) — they are superposition artifacts, the double-count class 0.28.0 removed. Findings true only in a projection are surfaced — a check may legitimately fire for one plan tier and no other, and the union cannot see it.
45
+ - **`configuration` parameter** on `query`, `get_tree`, and `validate_graph` — read or validate one member of the family. Every other tool rejects the argument by name rather than silently reading the union. Configuration-vs-configuration diffing rides `query`'s existing `diff_from`, which now reports edge deltas when `edge_include` is set. Tool count unchanged at 98.
46
+
47
+ ### Changed
48
+ - The one-named-configuration convention (published with 0.29.0) becomes the documented fallback for graphs that do not declare variance: the configuration you named is the projection you were implicitly describing, and nothing needs migrating when you begin declaring axes.
49
+
50
+ ### Notes
51
+ - Truth: 322 entities · 1073 edges · 69 cross-edges · 98 tools. Zero new anti-patterns — the drift checks carry the invariants, and a detector with no field evidence behind it is how a check family gets noisy.
52
+
53
+ ---
54
+
10
55
  ## [0.29.0] - 2026-08-15
11
56
 
12
57
  **The contention check learns to read `capacity`, violations learn to name their nodes, and a batch write learns to un-say a property.** All three came from the same field reporter measuring the check on a real 43-surface graph: 10 surfaces flagged, 7 correctly, 3 falsely — and every false positive had an occupant count at or below its stated capacity. A surface whose occupants all fit is partitioned, not contended. Additive; no breaking change.
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  The TypeScript core for the **Unified Product Graph (UPG)**, an open specification that gives product tools a shared vocabulary for entities, edges, and frameworks.
9
9
 
10
- 321 entity types across 37 domains. 1069 typed edges. 46 canonical framework definitions, with more added as each is reviewed.
10
+ 323 entity types across 37 domains. 1079 typed edges. 53 canonical framework definitions, with more added as each is reviewed.
11
11
 
12
12
  ## Install
13
13