@unified-product-graph/core 0.17.8 → 0.19.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,322 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.19.0] - 2026-07-04
11
+
12
+ **The MCP surface consolidates from 139 tools to 93 (+ 5 prompts): the static-spec introspection cluster folds into four faceted reads, and five procedural routers become skills.** The spec catalogue had accreted 45 near-identical `list_*` / `get_*` reads plus five routers — a surface an agent had to scan linearly before it could choose. This release collapses the reads into four facets and retires the routers, leaving the 89 write and live-graph-read verbs untouched. A parity gate (`retired-tools.json` + a byte-equality test wired as a prepublish stage) proves every retired tool's data is still reachable and identical through the facets, on both the local and cloud servers — which licenses a clean break with no deprecation window. Both servers' instructions gain a methodology preamble (the SEE → THINK → ACT → LEARN working loop) so the surface conveys *how to work*, not only *what exists*. Breaking. Local 139 → 93; cloud 100 → 54.
13
+
14
+ ### Added
15
+ - **`list_catalog({ kind })`** and **`get_catalog_entry({ kind, id })`** — the two faceted reads that subsume 40 per-catalogue `list_*` / `get_*` tools (entity types, edge types, regions, lenses, domains, anti-patterns, playbooks, frameworks, …).
16
+ - **`get_spec_version` gains `changelog` and `since`** — folds the proposed `get_changelog` / `whats_new` surface in; `changelog: true` returns this file parsed into entries, `since` filters to versions strictly newer. Default output is byte-identical to before.
17
+ - **Enriched `get_entity_schema`** — now also returns valid children, the entity's region, and the resolved edge for a source→target pair (absorbing `get_valid_children`, `get_region_for_entity_type`, `resolve_edge_for_pair`).
18
+ - **Shared `mcp-catalog` module** imported by both servers, so parity is structural rather than hand-maintained.
19
+ - **Methodology preamble** in both servers' instructions.
20
+
21
+ ### Removed
22
+ - **48 spec-introspection tools** (25 `list_*` → `list_catalog`, 15 `get_*` → `get_catalog_entry`, 3 folds into `get_entity_schema`, 5 routers → skills). Every one is reachable — byte-equal — through the faceted surface (parity-gated).
23
+
24
+ ---
25
+
26
+ ## [0.18.0] - 2026-07-03
27
+
28
+ **Cross-product edge eligibility becomes a three-state gate derived from entity tiers, replacing the hand-maintained allowlist.** 0.17.3 derived which edge *types* may cross graphs; this governs which *instances* may, per endpoint. A `portfolio_shared` flag on 26 entity-type-meta records sorts every candidate cross-product edge into three tiers: **curated** (38 — explicitly modelled, allowed), **provisional** (194 — plausible cross-graph pairs, allowed with a warning and no PR requirement), and **resident** (794 — spine containment that must co-reside, hard-rejected). Pure tier-derivation over-admits by 4–5×, so eligibility is treated as *permission, not obligation*. Canonical cross-edges are unchanged at 59.
29
+
30
+ ### Added
31
+ - **`portfolio_shared`** on `EntityTypeMeta` (26 types) — the tier signal the gate reads.
32
+ - **Tri-state `cross_product_scope`** on the read path.
33
+
34
+ ### Changed
35
+ - **Cross-product write validation → a three-state gate** — a relaxation: provisional pairs now warn-and-allow rather than block.
36
+
37
+ ---
38
+
39
+ ## [0.17.8] - 2026-07-03
40
+
41
+ **The write-merge path stops silently clobbering concurrent edits: field-level three-way merge, and delete/modify collisions surface as conflicts.** A latent defect (roughly three months old — not a regression) could drop one of two concurrent edits to the same node. The merge is rewritten to reconcile at the field level and to raise delete/modify collisions as explicit `CONFLICT`s instead of resolving them silently. The dogfood graph was verified clean. SDK-only.
42
+
43
+ ### Fixed
44
+ - Field-level three-way merge; delete/modify collisions surfaced as `CONFLICT` (zero silent resolution).
45
+
46
+ ---
47
+
48
+ ## [0.17.7] - 2026-07-02
49
+
50
+ **Property schemas rejoin the generated-artifact gate, entity descriptions are filled in, and a count-drift guard prevents doc/spec divergence.** The property-schema files re-enter `check:generated` so they cannot drift from source, missing entity descriptions are authored, and a new `check:count-drift` gate fails the build whenever a hardcoded count anywhere disagrees with the derived spec counts.
51
+
52
+ ### Added
53
+ - **`check:count-drift`** release gate.
54
+
55
+ ### Changed
56
+ - `switching_cost.magnitude` resolves onto the `severity_5` assessment scale (finalised).
57
+ - Property-schema files back under `check:generated`.
58
+
59
+ ---
60
+
61
+ ## [0.17.6] - 2026-07-02
62
+
63
+ **A shelf-clearing sweep: `reload_product` for conflict recovery, `insight_informs_opportunity` made deliberate-only, and a property-modifier doc generator.** `reload_product({ discard_local })` recovers from a write `CONFLICT` when the active `.upg` was edited out of band, without a restart. `insight_informs_opportunity` is flagged `deliberate_only`, so an insight-contains-opportunity nesting no longer auto-materialises a judgment edge. A generator keeps the property-modifier docs in sync, alongside copy and count-accuracy fixes.
64
+
65
+ ### Added
66
+ - **`reload_product`** conflict-recovery tool.
67
+
68
+ ### Changed
69
+ - `insight_informs_opportunity` → `deliberate_only`.
70
+
71
+ ---
72
+
73
+ ## [0.17.5] - 2026-07-02
74
+
75
+ **`user_research` gains provenance: a `source_url` and document containment, so an insight can point back to where it came from.** Research entities could hold findings but not cite them. This adds `source_url` to `user_research` and a document-containment path so a research artifact and the insights extracted from it carry a verifiable source.
76
+
77
+ ### Added
78
+ - `source_url` on `user_research`; document-containment provenance for research.
79
+
80
+ ---
81
+
82
+ ## [0.17.4] - 2026-07-01
83
+
84
+ **OKR-planning coverage — objective↔dependency, a `strategic_question` entity, defer edges — plus the `deliberate_only` keystone that stops auto-nest from materialising judgment edges.** From the first graph-versus-planning-doc fidelity check: `objective_depends_on_dependency` and its mirror `dependency_blocks_objective`; a new `strategic_question` entity that completes the research / design / strategy question triad; and defer edges (`objective_defers_feature` / `objective_defers_capability`) that carry a freeform `deferred_to` planning label. The keystone is a `deliberate_only` catalogue flag, derived once into `UPG_DELIBERATE_ONLY_EDGE_TYPES`, that every auto-nest write path and adapter resolver reads — so an edge that must be authored deliberately is never inferred from a containment nesting.
85
+
86
+ ### Added
87
+ - **`strategic_question`** entity (the strategy-domain sibling of `research_question` / `design_question`).
88
+ - `objective_depends_on_dependency` / `dependency_blocks_objective`.
89
+ - `objective_defers_feature` / `objective_defers_capability`, carrying a `deferred_to` edge property.
90
+ - **`deliberate_only`** catalogue flag + `isDeliberateOnlyEdge` derivation.
91
+
92
+ ---
93
+
94
+ ## [0.17.3] - 2026-07-01
95
+
96
+ **A single `cross_product_eligible` catalogue flag now derives the entire cross-edge registry — one source of truth for which edge types may cross graphs.** The cross-edge type set had been maintained by hand. This makes it a derivation: a `cross_product_eligible` flag on each edge-catalogue entry flows automatically into `UPGCrossEdgeType` and `UPG_CROSS_EDGE_TYPES`, while portfolio-native edges stay in the explicit `UPG_CROSS_ONLY_EDGE_TYPES`. It front-loads the whole strategy / OKR / measurement laddering plus the eight product→strategy alignment edges (the set moves 41 → 55). Ships with an atomic `batch_delete_cross_product_edges`, an `org` tree pattern (department → team → sub-team), and portfolio-structure reads.
97
+
98
+ ### Added
99
+ - `cross_product_eligible` flag + the derived cross-edge registry.
100
+ - `batch_delete_cross_product_edges` (atomic).
101
+ - `org` tree pattern.
102
+
103
+ ### Changed
104
+ - Cross-edge set 41 → 55.
105
+
106
+ ---
107
+
108
+ ## [0.17.2] - 2026-06-30
109
+
110
+ **Org-wide modeling: second-level team nesting, cross-product OKR/measurement edges, a `constraint_origin` sub-role, and young-graph anti-pattern tuning.** `team_contains_team` adds parent→child org nesting. Four OKR/measurement edges (`strategic_theme_contains_objective`, `objective_achieved_through_key_result`, `key_result_quantified_by_metric`, `objective_measured_by_metric`) gain cross-product registry variants (cross-edges 37 → 41). `deduplicate_nodes` gains a read-only `match: "similar"` near-duplicate suggestion, `update_product` a slug / file-rename path, and `constraint` a `constraint_origin` (internal / external) sub-role.
111
+
112
+ ### Added
113
+ - `team_contains_team`; four cross-product OKR/measurement edge variants.
114
+ - `constraint_origin` on `constraint`.
115
+ - `deduplicate_nodes match: "similar"`; `update_product` rename path.
116
+
117
+ ### Changed
118
+ - Three coverage anti-patterns stage-tuned so young graphs aren't flagged prematurely.
119
+
120
+ ---
121
+
122
+ ## [0.17.1] - 2026-06-30
123
+
124
+ **First-class `create_portfolio` with portfolio kinds, and a domain-guide note separating `product_area` from `team_org`.** `create_portfolio` becomes a first-class tool (warning on a dangling `parent_portfolio_id`), and a domain-guide note distinguishes `product_area` (a product's own decomposition) from `team_org` (who owns it). Includes post-QA repairs to workspace re-kinding and `member_kind` docs.
125
+
126
+ ### Added
127
+ - `create_portfolio` tool + portfolio kinds.
128
+
129
+ ---
130
+
131
+ ## [0.17.0] - 2026-06-29
132
+
133
+ **`operating_function` gains a `member_kind` discriminator and a required north-star metric, with cross-product org-ownership edges and three anti-patterns.** The operating-function layer (how an org runs itself) matures: a `member_kind` discriminator with table-driven validation profiles, a required north-star metric (with softened coverage warnings on thin graphs), and cross-product ownership edges linking an operating function to the org that runs it. Also completes Pattern G C1 — `owner: string` becomes `node_owned_by_*` edges.
134
+
135
+ ### Added
136
+ - `member_kind` on `operating_function` + validation profiles.
137
+ - Operating-function org-ownership cross-edges.
138
+ - Three anti-patterns: operating-function without north-star / operating-content / org-link.
139
+
140
+ ### Changed
141
+ - `operating_function` requires a north-star metric.
142
+ - Pattern G C1: `owner: string` → `node_owned_by_*` edges.
143
+
144
+ ---
145
+
146
+ ## [0.16.2] - 2026-06-18
147
+
148
+ **A first-class template system: `list_templates` / `get_template` (local + cloud parity), an SDK access layer, and the `/templates` gallery driven from the package.** Starter templates become queryable spec data rather than site content — two MCP tools with parity across both servers, an SDK template-access layer and `upg template` CLI command, CLI starter seeds sourced from the package, and the site gallery reading the same single source. Ships with a conformance drift gate.
149
+
150
+ ### Added
151
+ - `list_templates` / `get_template` (local + cloud); SDK template layer; `upg template` command.
152
+
153
+ ---
154
+
155
+ ## [0.16.1] - 2026-06-18
156
+
157
+ **Adoption-path hardening: revived CLI verify gates, SDK-reference re-verification, and a templates conformance pass.** A QA sweep of the adoption surface (SDK / CLI / MCP): the dead `--no-orphans` / `--no-broken-chains` verify gates are revived, the SDK barrel reference is re-verified against core, templates gain a conformance pass and drift gate, and skills' stale status / stage vocabulary is scrubbed to canonical. Tooling and docs only; no spec-model change.
158
+
159
+ ### Fixed
160
+ - Dead `verify --no-orphans` / `--no-broken-chains` gates; SDK barrel-reference drift; stale status / stage vocabulary in skills.
161
+
162
+ ---
163
+
164
+ ## [0.16.0] - 2026-06-17
165
+
166
+ **Pattern G — the open-standard data boundary: 12 PII / registry / vendor properties dropped, 20 infrastructure pointers tagged `@volatile`.** The boundary ADR draws the line between what the open standard models (product structure) and what it must not carry (personal data, tenancy, session, vendor pointers). Twelve such properties are removed and twenty infrastructure pointers marked `@volatile`. Breaking. The `owner: string` → edge split (C1) defers to 0.17.0.
167
+
168
+ ### Removed
169
+ - 12 PII / registry / session / vendor properties.
170
+
171
+ ### Changed
172
+ - 20 infrastructure pointers → `@volatile`.
173
+
174
+ ---
175
+
176
+ ## [0.15.0] - 2026-06-17
177
+
178
+ **Pattern D — 14 `*_status` shadow properties collapse into the entity lifecycle.** Fourteen properties that duplicated an entity's phase as a parallel `*_status` scalar are removed; the single base `status` / lifecycle becomes the one axis, and the T1.1 guardrail goes 14 → 0. `*_status` properties that are genuinely distinct axes (not subsets of a phase set) are kept. Breaking.
179
+
180
+ ### Removed
181
+ - 14 `*_status` shadow properties (lifted to base `status`).
182
+
183
+ ---
184
+
185
+ ## [0.14.1] - 2026-06-17
186
+
187
+ **Release rider: a browser-safe `crypto` import in the canonical serialiser (unblocks Sanity Studio).** The canonical serialiser imported `crypto` in a form that broke browser bundlers; it is namespaced to `node:crypto`. Fix only.
188
+
189
+ ### Fixed
190
+ - Browser-safe `crypto` import in `format/canonical.ts`.
191
+
192
+ ---
193
+
194
+ ## [0.14.0] - 2026-06-17
195
+
196
+ **Pattern E — 14 deprecated / ghost properties removed, with a hard-removal guard.** Fourteen long-deprecated or never-implemented ("ghost") properties are removed, gated by a new T1.8 guard that fails the build if a hard-removed property reappears, and recorded in `UPG_PROPERTY_MIGRATIONS['0.14.0']`. Breaking.
197
+
198
+ ### Removed
199
+ - 14 deprecated / ghost properties.
200
+
201
+ ### Added
202
+ - T1.8 hard-removal guard.
203
+
204
+ ---
205
+
206
+ ## [0.13.2] - 2026-06-17
207
+
208
+ **Runtime-state properties are tagged `@snapshot` and aggregates `@derived`, taking the T1.2 / T1.3 baselines to zero.** The additive half of Wave 2: roughly 55 runtime / live-state properties on definition entities are marked `@snapshot` and about 30 derived / computed scalars `@derived` — mark, don't delete — so the guardrail baselines reach 0 without data loss.
209
+
210
+ ### Changed
211
+ - ~85 properties tagged `@snapshot` / `@derived`.
212
+
213
+ ---
214
+
215
+ ## [0.13.1] - 2026-06-17
216
+
217
+ **A connective cross-edge layer: shared jobs and needs, feature→product surfacing, screen→competitor targeting, persona delegation, and design-system connectors.** New cross-domain edges that connect entities without containing them — `shares_job` / `shares_need`, `feature_surfaces_product`, `screen_targets_competitor`, `persona_delegates_to_persona` (agent delegation, promoted to a cross-edge), and design-system connectors. The relational tissue between domains.
218
+
219
+ ### Added
220
+ - Connective cross-edges: `shares_job` / `shares_need`, `feature_surfaces_product`, `screen_targets_competitor`, `persona_delegates_to_persona`, design-system connectors.
221
+
222
+ ---
223
+
224
+ ## [0.13.0] - 2026-06-17
225
+
226
+ **Edge hygiene: a dead revenue cross-domain edge dropped, the hypothesis lifecycle de-duplicated, and the metric↔outcome cycle broken.** Wave 1 of the structural cleanup removes a dead cross-domain revenue edge, collapses duplicate hypothesis-lifecycle edges, and breaks a metric↔outcome reference cycle that made traversal ambiguous. Adds CLI `tree --pattern` help for `north_star`.
227
+
228
+ ### Changed
229
+ - Dead revenue cross-domain edge removed; hypothesis lifecycle de-duplicated; metric↔outcome cycle broken.
230
+
231
+ ---
232
+
233
+ ## [0.12.8] - 2026-06-17
234
+
235
+ **A queryable property-modifier surface (`@derived` / `@snapshot` / `@volatile`) with the T1.2 / T1.3 guardrails.** Introduces the property-modifier vocabulary as first-class, queryable spec metadata — a property can be tagged derived (computed), snapshot (cached live-state), or volatile (infrastructure) — and the guardrails that hold the counts. This is the substrate the 0.13.2 tagging pass and the 0.16.0 boundary sweep build on.
236
+
237
+ ### Added
238
+ - Property-modifier surface + T1.2 / T1.3 guardrails.
239
+
240
+ ---
241
+
242
+ ## [0.12.7] - 2026-06-17
243
+
244
+ **A cross-product reference family for brand, design system, and marketing.** Edges that let one graph reference shared brand, design-system, and marketing entities living in another graph within a portfolio.
245
+
246
+ ### Added
247
+ - Cross-product reference edges (brand, design system, marketing).
248
+
249
+ ---
250
+
251
+ ## [0.12.6] - 2026-06-17
252
+
253
+ **`user_story` and `experiment_run` graduate to `stable`.** Two proposed entity types meet the promotion rubric and graduate.
254
+
255
+ ### Changed
256
+ - `user_story`, `experiment_run` → `stable`.
257
+
258
+ ---
259
+
260
+ ## [0.12.5] - 2026-06-17
261
+
262
+ **A `screen_markets_product` cross-edge, the `portfolio_census` read, and a single-sourced active entity-type count.** Adds the `screen_markets_product` cross-edge, a `portfolio_census` cross-product read tool, a hardened proposed-promotion rubric checker, and single-sources the active entity-type count.
263
+
264
+ ### Added
265
+ - `screen_markets_product` cross-edge; `portfolio_census` tool.
266
+
267
+ ---
268
+
269
+ ## [0.12.4] - 2026-06-16
270
+
271
+ **P14 Bucket B — actor scalars become promotable to polymorphic `node_owned_by_*` edges (additive).** The actor-ownership string fields become promotable to polymorphic `node_owned_by_*` edges via `promote_scalar_to_edge`, per the enumeration-versus-polymorphism ADR. Additive — promotion is opt-in.
272
+
273
+ ### Added
274
+ - P14 Bucket B: actor scalars → `node_owned_by_*` (promotable).
275
+
276
+ ---
277
+
278
+ ## [0.12.3] - 2026-06-16
279
+
280
+ **`switching_cost.magnitude` steered onto the `severity_5` assessment scale; the SDK resolves products in `workspace.json` subfolders.** Property-scale alignment plus a resolver fix so products nested in workspace subfolders are found.
281
+
282
+ ### Changed
283
+ - `switching_cost.magnitude` → `severity_5` assessment scale.
284
+
285
+ ### Fixed
286
+ - `findProductFileById` resolves products in `workspace.json` subfolders.
287
+
288
+ ---
289
+
290
+ ## [0.12.2] - 2026-06-16
291
+
292
+ **Canonical registry: `register_instance` resolves nodes in any workspace product.** The registry / instance-of layer's `register_instance` now resolves its target across any product in the workspace, not only the active one.
293
+
294
+ ### Changed
295
+ - `register_instance` — cross-product node resolution.
296
+
297
+ ---
298
+
299
+ ## [0.12.1] - 2026-06-16
300
+
301
+ **`operating_lifecycle` / `operating_stage` refined (properties and edges).** Property and edge refinements to the operating-lifecycle primitive introduced in the 0.11 line.
302
+
303
+ ### Changed
304
+ - `operating_lifecycle` / `operating_stage` property + edge refinements.
305
+
306
+ ---
307
+
308
+ ## [0.12.0] - 2026-06-16
309
+
310
+ **P14 — the string-reference sweep: `promote_scalar_to_edge` turns entity-reference scalars into real edges, starting with 22 orphans and the flagship `north_star_metric`.** The keystone of the P14 conformance track. A `promote_scalar_to_edge` engine converts properties that named another entity by string into first-class edges: Bucket A1 promotes 22 orphan entity-reference scalars, A2 resolves shadow references, Bucket C collapses one aggregate, and the flagship `north_star_metric` becomes an edge. This is the foundation the polymorphic-ownership work (Bucket B, 0.12.4) and the modifier waves build on.
311
+
312
+ ### Added
313
+ - `promote_scalar_to_edge` engine; `north_star_metric` edge; `list_scalar_to_edge_migrations` (cloud parity).
314
+
315
+ ### Changed
316
+ - 22 orphan scalars, shadow references, and one aggregate → edges (P14 A1 / A2 / C).
317
+
318
+ ---
319
+
320
+ ## [0.11.6] - 2026-06-16
321
+
322
+ **Version bump — regenerated site artifacts and paper-count sync.** Version-stamp and artifact regeneration; no spec-model change.
323
+
324
+ ---
325
+
10
326
  ## [0.11.5] - 2026-06-15
11
327
 
12
328
  **`get_tree` gains a `commercial` pattern: the business-model spine as a one-call tree.** The monetisation axis was the one populated, tree-shaped region with no pattern — *"show me the money model: streams, costs, tiers, and the metrics that measure them"* meant a hand-authored `query`. `commercial` roots at `business_model` and walks its revenue streams, cost structure, and unit economics; a stream into its pricing tiers, the metrics that measure it, and the pricing strategy that prices it; and metrics decompose into their components (the MRR waterfall). A pricing tier reached from both its stream and its pricing strategy renders once, then as a shared reference — the same multi-parent (G5) path `delivery` relies on. It is a curated spanning tree over the containment subset of the multi-hub `business_gtm_growth` region (the GTM/value flow stays excluded — a tree would misrepresent it); company-grain financials (CAC, LTV, runway) hang off the product, not a single stream, and remain an okr/strategy concern. Declarative child-map record, no engine work, all-optional (a stream without a metric is not a structural hole). 12 patterns now; no new tools (131). A new pattern on a young tool = a patch.
package/dist/index.cjs CHANGED
@@ -103,6 +103,7 @@ __export(index_exports, {
103
103
  UPG_PLAYBOOKS: () => UPG_PLAYBOOKS,
104
104
  UPG_POLYMORPHIC_EDGE_KEYS: () => UPG_POLYMORPHIC_EDGE_KEYS,
105
105
  UPG_PORTFOLIO_KINDS: () => UPG_PORTFOLIO_KINDS,
106
+ UPG_PORTFOLIO_SHARED_TYPES: () => UPG_PORTFOLIO_SHARED_TYPES,
106
107
  UPG_PRODUCT_STAGES: () => UPG_PRODUCT_STAGES,
107
108
  UPG_PRODUCT_STAGE_COERCION_MAP: () => UPG_PRODUCT_STAGE_COERCION_MAP,
108
109
  UPG_PROPERTY_MIGRATIONS: () => UPG_PROPERTY_MIGRATIONS,
@@ -141,6 +142,7 @@ __export(index_exports, {
141
142
  concernEvaluatedFor: () => concernEvaluatedFor,
142
143
  concernFor: () => concernFor,
143
144
  concernGatesFor: () => concernGatesFor,
145
+ crossProductScope: () => crossProductScope,
144
146
  describeTreePattern: () => describeTreePattern,
145
147
  edgeCarriesProperties: () => edgeCarriesProperties,
146
148
  evaluateAntiPatterns: () => evaluateAntiPatterns,
@@ -202,7 +204,9 @@ __export(index_exports, {
202
204
  isCanonical: () => isCanonical,
203
205
  isCanonicalProductStage: () => isCanonicalProductStage,
204
206
  isContainmentFreeType: () => isContainmentFreeType,
207
+ isCrossCapable: () => isCrossCapable,
205
208
  isCrossProductEligible: () => isCrossProductEligible,
209
+ isCuratedCrossEligible: () => isCuratedCrossEligible,
206
210
  isDeliberateOnlyEdge: () => isDeliberateOnlyEdge,
207
211
  isDeprecatedType: () => isDeprecatedType,
208
212
  isDomainGuideStep: () => isDomainGuideStep,
@@ -213,6 +217,7 @@ __export(index_exports, {
213
217
  isLifecyclePlannedType: () => isLifecyclePlannedType,
214
218
  isPolymorphicEdge: () => isPolymorphicEdge,
215
219
  isPortfolio: () => isPortfolio,
220
+ isPortfolioSharedType: () => isPortfolioSharedType,
216
221
  isRecordEntity: () => isRecordEntity,
217
222
  isRegisteredPolymorphicEdge: () => isRegisteredPolymorphicEdge,
218
223
  isRuntimeStateShapedProperty: () => isRuntimeStateShapedProperty,
@@ -766,27 +771,27 @@ function getDomainIdForType(entityType) {
766
771
  // src/registry/entity-meta.ts
767
772
  var UPG_ENTITY_META = [
768
773
  // Foundations (0.9.12): shared specifications + the primitives they define.
769
- { name: "specification", type_id: "ent_352", maturity: "proposed", since: "0.9.12" },
770
- { name: "primitive", type_id: "ent_353", maturity: "proposed", since: "0.9.12" },
771
- { name: "operating_lifecycle", type_id: "ent_355", maturity: "proposed", since: "0.11.6" },
772
- { name: "operating_stage", type_id: "ent_356", maturity: "proposed", since: "0.11.6" },
774
+ { name: "specification", type_id: "ent_352", maturity: "proposed", since: "0.9.12", portfolio_shared: true },
775
+ { name: "primitive", type_id: "ent_353", maturity: "proposed", since: "0.9.12", portfolio_shared: true },
776
+ { name: "operating_lifecycle", type_id: "ent_355", maturity: "proposed", since: "0.11.6", portfolio_shared: true },
777
+ { name: "operating_stage", type_id: "ent_356", maturity: "proposed", since: "0.11.6", portfolio_shared: true },
773
778
  // ── Strategic ──
774
779
  { name: "product", type_id: "ent_001", maturity: "stable", since: "0.1.0" },
775
- { name: "outcome", type_id: "ent_002", maturity: "stable", since: "0.1.0" },
780
+ { name: "outcome", type_id: "ent_002", maturity: "stable", since: "0.1.0", portfolio_shared: true },
776
781
  { name: "kpi", type_id: "ent_003", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "metric" },
777
- { name: "objective", type_id: "ent_004", maturity: "stable", since: "0.1.0" },
778
- { name: "key_result", type_id: "ent_005", maturity: "stable", since: "0.1.0" },
779
- { name: "metric", type_id: "ent_006", maturity: "stable", since: "0.1.0" },
782
+ { name: "objective", type_id: "ent_004", maturity: "stable", since: "0.1.0", portfolio_shared: true },
783
+ { name: "key_result", type_id: "ent_005", maturity: "stable", since: "0.1.0", portfolio_shared: true },
784
+ { name: "metric", type_id: "ent_006", maturity: "stable", since: "0.1.0", portfolio_shared: true },
780
785
  // F7 (UPG-673): graduated proposed → stable at v0.9.x — proposed since 0.2.2,
781
786
  // the metric-quality assessment artefact is settled with no open restructure.
782
787
  { name: "metric_quality_assessment", type_id: "ent_339", maturity: "stable", since: "0.2.2" },
783
- { name: "vision", type_id: "ent_007", maturity: "stable", since: "0.1.0" },
784
- { name: "mission", type_id: "ent_008", maturity: "stable", since: "0.1.0" },
785
- { name: "strategic_theme", type_id: "ent_009", maturity: "stable", since: "0.1.0" },
786
- { name: "initiative", type_id: "ent_010", maturity: "stable", since: "0.1.0" },
787
- { name: "capability", type_id: "ent_011", maturity: "stable", since: "0.1.0" },
788
+ { name: "vision", type_id: "ent_007", maturity: "stable", since: "0.1.0", portfolio_shared: true },
789
+ { name: "mission", type_id: "ent_008", maturity: "stable", since: "0.1.0", portfolio_shared: true },
790
+ { name: "strategic_theme", type_id: "ent_009", maturity: "stable", since: "0.1.0", portfolio_shared: true },
791
+ { name: "initiative", type_id: "ent_010", maturity: "stable", since: "0.1.0", portfolio_shared: true },
792
+ { name: "capability", type_id: "ent_011", maturity: "stable", since: "0.1.0", portfolio_shared: true },
788
793
  { name: "value_stream", type_id: "ent_012", maturity: "stable", since: "0.1.0" },
789
- { name: "strategic_pillar", type_id: "ent_013", maturity: "stable", since: "0.1.0" },
794
+ { name: "strategic_pillar", type_id: "ent_013", maturity: "stable", since: "0.1.0", portfolio_shared: true },
790
795
  { name: "assumption", type_id: "ent_014", maturity: "stable", since: "0.1.0" },
791
796
  { name: "decision", type_id: "ent_015", maturity: "stable", since: "0.1.0" },
792
797
  { name: "constraint", type_id: "ent_348", maturity: "stable", since: "0.4.3" },
@@ -842,18 +847,18 @@ var UPG_ENTITY_META = [
842
847
  { name: "evidence", type_id: "ent_031", maturity: "stable", since: "0.1.0" },
843
848
  { name: "research_plan", type_id: "ent_032", maturity: "stable", since: "0.1.0" },
844
849
  // ── Market Intelligence ──
845
- { name: "competitor", type_id: "ent_033", maturity: "stable", since: "0.1.0" },
846
- { name: "competitor_feature", type_id: "ent_034", maturity: "stable", since: "0.1.0" },
847
- { name: "competitor_signal", type_id: "ent_354", maturity: "proposed", since: "0.10.0" },
850
+ { name: "competitor", type_id: "ent_033", maturity: "stable", since: "0.1.0", portfolio_shared: true },
851
+ { name: "competitor_feature", type_id: "ent_034", maturity: "stable", since: "0.1.0", portfolio_shared: true },
852
+ { name: "competitor_signal", type_id: "ent_354", maturity: "proposed", since: "0.10.0", portfolio_shared: true },
848
853
  { name: "market_trend", type_id: "ent_035", maturity: "stable", since: "0.1.0" },
849
- { name: "market_segment", type_id: "ent_036", maturity: "stable", since: "0.1.0" },
854
+ { name: "market_segment", type_id: "ent_036", maturity: "stable", since: "0.1.0", portfolio_shared: true },
850
855
  { name: "competitive_analysis", type_id: "ent_037", maturity: "stable", since: "0.1.0" },
851
856
  // Classification taxonomy hosted by competitive_analysis.
852
857
  // F7 (UPG-673): graduated proposed → stable at v0.9.x — two minor releases
853
858
  // stable since 0.4.0, the taxonomy-axis/value pair backs the competitive-
854
859
  // analysis classification spine with no open rename/restructure ticket.
855
- { name: "classification_axis", type_id: "ent_346", maturity: "stable", since: "0.4.0" },
856
- { name: "classification_value", type_id: "ent_347", maturity: "stable", since: "0.4.0" },
860
+ { name: "classification_axis", type_id: "ent_346", maturity: "stable", since: "0.4.0", portfolio_shared: true },
861
+ { name: "classification_value", type_id: "ent_347", maturity: "stable", since: "0.4.0", portfolio_shared: true },
857
862
  // ── UX Research ──
858
863
  { name: "research_study", type_id: "ent_038", maturity: "stable", since: "0.1.0" },
859
864
  { name: "research_insight", type_id: "ent_039", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "insight" },
@@ -875,9 +880,9 @@ var UPG_ENTITY_META = [
875
880
  { name: "how_might_we", type_id: "ent_333", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.2.0", replacement: "design_question" },
876
881
  { name: "design_concept", type_id: "ent_054", maturity: "stable", since: "0.1.0" },
877
882
  { name: "prototype", type_id: "ent_055", maturity: "stable", since: "0.1.0" },
878
- { name: "design_component", type_id: "ent_056", maturity: "stable", since: "0.1.0" },
883
+ { name: "design_component", type_id: "ent_056", maturity: "stable", since: "0.1.0", portfolio_shared: true },
879
884
  { name: "design_token", type_id: "ent_057", maturity: "stable", since: "0.1.0" },
880
- { name: "brand_identity", type_id: "ent_058", maturity: "stable", since: "0.1.0" },
885
+ { name: "brand_identity", type_id: "ent_058", maturity: "stable", since: "0.1.0", portfolio_shared: true },
881
886
  { name: "brand_colour", type_id: "ent_059", maturity: "stable", since: "0.1.0" },
882
887
  { name: "brand_typography", type_id: "ent_060", maturity: "stable", since: "0.1.0" },
883
888
  { name: "brand_voice", type_id: "ent_061", maturity: "stable", since: "0.1.0" },
@@ -886,7 +891,7 @@ var UPG_ENTITY_META = [
886
891
  { name: "design_guideline", type_id: "ent_064", maturity: "stable", since: "0.1.0" },
887
892
  { name: "annotation", type_id: "ent_065", maturity: "stable", since: "0.1.0" },
888
893
  { name: "interaction_spec", type_id: "ent_066", maturity: "stable", since: "0.1.0" },
889
- { name: "design_system", type_id: "ent_067", maturity: "stable", since: "0.1.0" },
894
+ { name: "design_system", type_id: "ent_067", maturity: "stable", since: "0.1.0", portfolio_shared: true },
890
895
  { name: "user_flow", type_id: "ent_068", maturity: "stable", since: "0.1.0" },
891
896
  { name: "screen", type_id: "ent_069", maturity: "stable", since: "0.1.0" },
892
897
  { name: "screen_state", type_id: "ent_070", maturity: "stable", since: "0.1.0" },
@@ -1005,15 +1010,15 @@ var UPG_ENTITY_META = [
1005
1010
  { name: "rebuttal", type_id: "ent_140", maturity: "stable", since: "0.1.0" },
1006
1011
  { name: "proof_point", type_id: "ent_141", maturity: "stable", since: "0.1.0" },
1007
1012
  // ── Team & Organisation ──
1008
- { name: "team", type_id: "ent_142", maturity: "stable", since: "0.1.0" },
1013
+ { name: "team", type_id: "ent_142", maturity: "stable", since: "0.1.0", portfolio_shared: true },
1009
1014
  { name: "role", type_id: "ent_143", maturity: "stable", since: "0.1.0" },
1010
1015
  { name: "stakeholder", type_id: "ent_144", maturity: "stable", since: "0.1.0" },
1011
1016
  { name: "person", type_id: "ent_349", maturity: "stable", since: "0.5.0" },
1012
1017
  { name: "product_decision", type_id: "ent_145", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.2.0", replacement: "decision" },
1013
1018
  { name: "team_okr", type_id: "ent_146", maturity: "stable", since: "0.1.0" },
1014
1019
  { name: "retrospective", type_id: "ent_147", maturity: "stable", since: "0.1.0" },
1015
- { name: "dependency", type_id: "ent_148", maturity: "stable", since: "0.1.0" },
1016
- { name: "department", type_id: "ent_149", maturity: "stable", since: "0.1.0" },
1020
+ { name: "dependency", type_id: "ent_148", maturity: "stable", since: "0.1.0", portfolio_shared: true },
1021
+ { name: "department", type_id: "ent_149", maturity: "stable", since: "0.1.0", portfolio_shared: true },
1017
1022
  { name: "skill", type_id: "ent_150", maturity: "stable", since: "0.1.0" },
1018
1023
  { name: "ceremony", type_id: "ent_151", maturity: "stable", since: "0.1.0" },
1019
1024
  { name: "capacity_plan", type_id: "ent_152", maturity: "stable", since: "0.1.0" },
@@ -1225,6 +1230,10 @@ var UPG_ENTITY_META_BY_ID = new Map(
1225
1230
  );
1226
1231
  var UPG_ACTIVE_TYPES = UPG_ENTITY_META.filter((m) => m.maturity === "stable" || m.maturity === "proposed").map((m) => m.name);
1227
1232
  var UPG_DEPRECATED_TYPES = UPG_ENTITY_META.filter((m) => m.maturity === "deprecated").map((m) => m.name);
1233
+ var UPG_PORTFOLIO_SHARED_TYPES = UPG_ENTITY_META.filter((m) => m.portfolio_shared === true).map((m) => m.name);
1234
+ function isPortfolioSharedType(name) {
1235
+ return UPG_ENTITY_META_BY_NAME.get(name)?.portfolio_shared === true;
1236
+ }
1228
1237
  function isDeprecatedType(name) {
1229
1238
  const meta = UPG_ENTITY_META_BY_NAME.get(name);
1230
1239
  return meta?.maturity === "deprecated";
@@ -10319,6 +10328,21 @@ function rotateSlug(node, next) {
10319
10328
  return node;
10320
10329
  }
10321
10330
 
10331
+ // src/grammar/cross-scope.ts
10332
+ var CURATED_CROSS_EDGE_SET = new Set(UPG_CROSS_EDGE_TYPES);
10333
+ function isCrossCapable(sourceType, targetType) {
10334
+ return isPortfolioSharedType(sourceType) || isPortfolioSharedType(targetType);
10335
+ }
10336
+ function isCuratedCrossEligible(edgeType) {
10337
+ return CURATED_CROSS_EDGE_SET.has(edgeType);
10338
+ }
10339
+ function crossProductScope(edgeType) {
10340
+ if (CURATED_CROSS_EDGE_SET.has(edgeType)) return "curated";
10341
+ const def = UPG_EDGE_CATALOG[edgeType];
10342
+ if (def && isCrossCapable(def.source_type, def.target_type)) return "provisional";
10343
+ return "resident";
10344
+ }
10345
+
10322
10346
  // src/properties/property-schema.ts
10323
10347
  var UPG_PROPERTY_SCHEMA = {
10324
10348
  // A11yAnnotationProperties: Accessibility annotation.
@@ -29975,7 +29999,7 @@ function isCanonical(text) {
29975
29999
  }
29976
30000
 
29977
30001
  // src/index.ts
29978
- var UPG_VERSION = "0.17.8";
30002
+ var UPG_VERSION = "0.19.0";
29979
30003
  var UPG_FORMAT_VERSION = "0.4.0";
29980
30004
  var MARKDOWN_FORMAT_VERSION = "0.1";
29981
30005
  var UPG_TYPES = getTypes();
@@ -30113,6 +30137,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
30113
30137
  UPG_PLAYBOOKS,
30114
30138
  UPG_POLYMORPHIC_EDGE_KEYS,
30115
30139
  UPG_PORTFOLIO_KINDS,
30140
+ UPG_PORTFOLIO_SHARED_TYPES,
30116
30141
  UPG_PRODUCT_STAGES,
30117
30142
  UPG_PRODUCT_STAGE_COERCION_MAP,
30118
30143
  UPG_PROPERTY_MIGRATIONS,
@@ -30151,6 +30176,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
30151
30176
  concernEvaluatedFor,
30152
30177
  concernFor,
30153
30178
  concernGatesFor,
30179
+ crossProductScope,
30154
30180
  describeTreePattern,
30155
30181
  edgeCarriesProperties,
30156
30182
  evaluateAntiPatterns,
@@ -30212,7 +30238,9 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
30212
30238
  isCanonical,
30213
30239
  isCanonicalProductStage,
30214
30240
  isContainmentFreeType,
30241
+ isCrossCapable,
30215
30242
  isCrossProductEligible,
30243
+ isCuratedCrossEligible,
30216
30244
  isDeliberateOnlyEdge,
30217
30245
  isDeprecatedType,
30218
30246
  isDomainGuideStep,
@@ -30223,6 +30251,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
30223
30251
  isLifecyclePlannedType,
30224
30252
  isPolymorphicEdge,
30225
30253
  isPortfolio,
30254
+ isPortfolioSharedType,
30226
30255
  isRecordEntity,
30227
30256
  isRegisteredPolymorphicEdge,
30228
30257
  isRuntimeStateShapedProperty,