@unified-product-graph/core 0.31.0 → 0.32.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 +37 -1
- package/README.md +1 -1
- package/dist/index.cjs +235 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11094 -10645
- package/dist/index.d.ts +11094 -10645
- package/dist/index.js +235 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,42 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.32.0] - 2026-08-21
|
|
11
|
+
|
|
12
|
+
**A graph can now hold a real issue tracker's corpus without losing anything, and a query-driven view can say what it is a view OF.** Nine items in one design cycle: the two shapes the D-track held for "the next minor" (F1's query declaration, Q4b's artifact record) plus the six asks from a measured 1,032-issue Linear-parity audit. Additive throughout; three migrations registered, every one with a live population of zero.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- **`capture`** (ent_362, `proposed`, lifecycle-free, containment-free) + **`capture_renders_node`** (cross-domain, polymorphic). A dated, hashed rendition of something already in the graph: a screenshot, an export, a PDF. The subject stays a graph node; the capture says what it looked like at a moment and how to tell whether it still does. Deliberately NOT named `artifact` — that word already means `workflow_artifact` here and an inline-content document store in at least one consumer, and a third meaning is how a vocabulary stops being one. Extending `document` fails the dual-shape gate three ways (it has the PUBLISHING lifecycle, no hash, no captured-at, and a typed subject-matter edge family that is not a rendition relation); extending `workflow_artifact` would force a phantom `workflow_run` per file, since that is its only structural parent.
|
|
16
|
+
- **`UPGBaseNode.key`** — the stable, human-citable handle (`LTN-311`), unique within the product ACROSS types, immutable once assigned, never reused. Not `slug`: a slug is unique within `(product_id, type)` and auto-derives from `title`, so two types could legally hold one key and a retitle would break every citation. Not `external_id`: that records where a node CAME from and is structurally incapable of minting the next one. Paired with **`product.key_prefix`**; no counter is serialised, because the next number is `max + 1` from the graph and a counter is a fact about a store rather than about the product.
|
|
17
|
+
- **`UPGBaseNode.archived` / `archived_at`** — archive as an axis ORTHOGONAL to `status`. Generalised from `WorkspaceProperties`, which shipped the same pair for one type. Field data says it is general: a tracker held 559 archived-completed items beside 18 live-completed ones, and every existing `archived` LIFECYCLE PHASE is `status_category: 'completed'`, so in the six-bucket read the two were indistinguishable. Default-read convention (archived excluded from default views, always queryable) is documented, not enforced.
|
|
18
|
+
- **`node_assigned_to_person`** (cross-domain, polymorphic). Assignment is not ownership, and this REVERSES the 0.12.0 rule that routed `task`/`bug` `assignee` into `node_owned_by_person`. Assignment carries an interval and an exclusivity ownership does not, and a real board ran 85% unassigned while every item was owned — a state one edge cannot express. Existing `node_owned_by_person` edges are deliberately NOT rewritten: on a task, one is indistinguishable from genuine ownership by inspection, so a blanket rename would reclassify real facts. `user_story` gains the promotion rule it never had.
|
|
19
|
+
- **`product_dimensioned_by_classification_axis`** (hierarchy). One level of label grouping needs NO new label surface: `classification_axis` + `classification_value` + `node_classified_as_classification_value` have been `stable` since 0.4.0 and are strictly better than a `tag` entity (edge-level rationale, declared cardinality, cross-product eligible). The only thing missing was a home — the axis's sole parent was `competitive_analysis`. The line between the two mechanisms: **if the group has a name a person would filter by, it is an axis; otherwise it is a tag.**
|
|
20
|
+
- **`UPGViewQuery` / `UPGViewPresentation` / `UPGViewPredicate`**, with `member_query` and `presentation` on `composition` and `derived` on its members (F1's shape). The location was ruled at 0.31.0; this is the shape, and it extends `composition` rather than minting a view entity, because a composition is already named, slugged, published, revisioned and shared. Selection is portable and travels; presentation is advisory and a consumer may ignore all of it. `derived` discharges the field finding that auto-admitted members were being counted as authored content — membership arrives by query, position is authored, and a signature meant to answer "did a person change this" must exclude the former.
|
|
21
|
+
- **`backlog` on the WORK_ITEM lifecycle.** The template reached four of the six `StatusCategory` buckets, and the cost was arithmetic rather than theoretical: a source "Backlog" normalised to a phase this template does not have, importers omit what they cannot map, and roughly 195 of a measured 1,032-issue corpus arrived carrying no status at all. NO `triage` phase — that bucket is reachable through INCIDENT and DISCOVERY, where triage is actually practised, and a task nobody has accepted is a task in `backlog`. `initial_phase` deliberately stays `todo`: moving it would change what every existing graph's next node means.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **`planning_cycle_schedules_user_story` → `planning_cycle_schedules_work_item`**, widened to the polymorphic work-item endpoint by the same construction `work_item_blocks_work_item` used in the same 0.20.0 batch. The story-only endpoint could not hold a tracker import, because importers default an unrecognised issue to `task` — the one type a cadence could not reach. Registered rename; no flip. The `planning-cycle-without-scheduled-work` anti-pattern is retargeted with it, or a cycle full of tasks would have reported as empty.
|
|
25
|
+
- **`workflow_state_category` narrowed from `string` to `StatusCategory`** on all five carriers (`feature`, `epic`, `user_story`, `task`, `bug`). The field exists to carry exactly that vocabulary; an open string meant nothing enforced the one thing it was for. A side effect worth having: the generated runtime schema now emits the six bucket values as `enum` for the first time.
|
|
26
|
+
- **`RelationshipCheck.target_type` admits the wildcard**, and the presence collector records polymorphic edges under BOTH the concrete and the wildcard key. Half of this is a type widening; the other half is a latent false-positive class — the index is keyed by concrete endpoint types, so a check declaring `'node'` would have matched nothing, and for a `not_exists` comparison matching nothing means firing on every correct graph.
|
|
27
|
+
- The one-release read tolerance for the pre-0.31.0 underscore canvas key **retires as scheduled**. Preservation is unaffected: the key is no longer read, and still carried byte for byte.
|
|
28
|
+
|
|
29
|
+
### Deprecated
|
|
30
|
+
- **`WorkspaceProperties.archived` / `archived_at`** → the base-node pair, lifted by `UPG_PROPERTY_MIGRATIONS['0.32.0']`.
|
|
31
|
+
- **`TaskProperties.labels` / `BugProperties.labels`** → dropped. A duplicate of base-node `tags` with no consumers anywhere; three parallel label surfaces were two too many.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- `WorkspaceProperties` documented its parent edge as `product_contains_workspace`, which has never existed. The real edge is `product_thinks_in_workspace`, with `organization_` and `product_area_` siblings per altitude.
|
|
35
|
+
- The 0.31.0 CHANGELOG named the migrated canvas key `entopo:views`; the writer and its own contract test both use `entopo:view_blocks`. A shipped CHANGELOG cannot be recalled from npm, so the correction rides here.
|
|
36
|
+
|
|
37
|
+
### Notes
|
|
38
|
+
- Truth: **324 entities · 1082 edges · 69 cross-edges · 25 anti-patterns · 98 tools · 334 phases**. Zero new tools. Zero new checks — three invariants (`key` uniqueness, one active cycle per parent, archived-excluded-by-default) are DEFINED and unenforced, each with a stated pull-forward condition, because a check without a graded corpus is one nobody can defend.
|
|
39
|
+
- Edge arithmetic, as the cheapest check that design and build agree: +1 hierarchy, +2 cross-domain, semantic unchanged because the cadence edge was renamed rather than added. 452→453h, 421→423x.
|
|
40
|
+
- Polymorphic edge families: **13 (24 entries)**. Assignment is registered as its OWN family rather than folded into universal ownership, so a future author who merges them does it visibly.
|
|
41
|
+
- One new `(source, target, classification)` collision, and it IS the design: `node → person / cross-domain` now carries both `owned_by` and `assigned_to`. Verified as the only one; the other three new edges collide with nothing.
|
|
42
|
+
- The retargeted anti-pattern ships a labeled fixture set including the near-miss it was most likely to misjudge — a coarse `period` cycle that schedules nothing directly and only nests finer cycles.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
10
46
|
## [0.31.0] - 2026-08-19
|
|
11
47
|
|
|
12
48
|
**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.
|
|
@@ -21,7 +57,7 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
21
57
|
|
|
22
58
|
### Changed
|
|
23
59
|
- 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:
|
|
60
|
+
- `entopo_views` (underscore) migrates to `entopo:view_blocks` (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
61
|
|
|
26
62
|
### Notes
|
|
27
63
|
- 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.
|
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
|
-
|
|
10
|
+
324 entity types across 37 domains. 1082 typed edges. 53 canonical framework definitions, with more added as each is reviewed.
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|