@unified-product-graph/core 0.35.0 → 0.36.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/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
- 324 entity types across 37 domains. 1091 typed edges. 53 canonical framework definitions, with more added as each is reviewed.
10
+ 324 entity types across 37 domains. 1092 typed edges. 53 canonical framework definitions, with more added as each is reviewed.
11
11
 
12
12
  ## Install
13
13
 
package/dist/index.cjs CHANGED
@@ -1902,6 +1902,25 @@ var UPG_EDGE_CATALOG = {
1902
1902
  // (graph traversal) treat 'semantic' as the catch-all for non-causal,
1903
1903
  // non-hierarchical relationships.
1904
1904
  journey_step_precedes_journey_step: { forward_verb: "precedes", reverse_verb: "follows", classification: "semantic", source_type: "journey_step", target_type: "journey_step" },
1905
+ // (0.36.0, UPG feedback 510c4bfa) A user_flow states which user_journey it
1906
+ // maps onto (`user_flow_maps_user_journey`) but not which of that journey's
1907
+ // steps, in what order, it actually walks — the only recovery without this
1908
+ // edge is inferring scope from shared screens, which both over-matches
1909
+ // (co-located read-only steps) and under-matches (steps rendered off-screen).
1910
+ // `journey_step` stays owned by its journey via `user_journey_contains_journey_step`;
1911
+ // this is a reference into that ownership, not a second containment.
1912
+ // `semantic`, not `cross-domain`: both `user_flow` and `journey_step` are in
1913
+ // the ux_design domain, and T1.7's guardrail treats same-domain
1914
+ // `cross-domain` edges as reclassification debt to pay down, not a pattern
1915
+ // to extend — `journey_phase_spans_journey_step` carries that debt already;
1916
+ // this edge does not repeat it. Same reasoning as `journey_step_precedes_journey_step`:
1917
+ // 'semantic' is the catch-all for a non-causal, non-hierarchical, in-domain
1918
+ // relationship. No `carries_properties`: the walked steps' own `step_order`
1919
+ // is already the source of truth for sequence, so ordering is read off the
1920
+ // target, not a second order system that could drift from the journey's. A
1921
+ // flow walking steps out of journey order is a future `carries_properties`
1922
+ // widening, not this one.
1923
+ user_flow_walks_journey_step: { forward_verb: "walks", reverse_verb: "walked_by", classification: "semantic", source_type: "user_flow", target_type: "journey_step" },
1905
1924
  user_flow_routes_through_screen: { forward_verb: "routes_through", reverse_verb: "routed_in", classification: "hierarchy", source_type: "user_flow", target_type: "screen" },
1906
1925
  screen_renders_as_screen_state: { forward_verb: "renders_as", reverse_verb: "rendered_by", classification: "hierarchy", source_type: "screen", target_type: "screen_state" },
1907
1926
  need_reframed_as_design_question: { forward_verb: "reframed_as", reverse_verb: "reframes", classification: "causal", source_type: "need", target_type: "design_question" },
@@ -15180,7 +15199,11 @@ var UPG_PROPERTY_SCHEMA = {
15180
15199
  composition_mode: { type: "string", enum: ["exclusive", "additive", "chained"], description: "How the occupants relate: one wins (`exclusive`), all coexist (`additive`), or each wraps the next (`chained`). Declaring `chained` exempts the surface from `contended-surface-without-arbitration`; leaving this unset does not." },
15181
15200
  arbitration_rule: { type: "string", description: 'Who wins when more occupants want the surface than `capacity` allows, and why. Absence is meaningful: on a contested surface it means nobody decided. @example "Highest priority wins; ties break to the most recently updated."', notes: "An empty or absent rule on a contested surface is exactly what `contended-surface-without-arbitration` detects. Do not fill it in with a placeholder to silence the check: the check exists to find the unrecorded decision, and a placeholder hides it without settling anything. The field is overloaded across composition modes, which is worth knowing before writing one. On an `exclusive` surface it records DISPLACEMENT (who is not rendered). On an `additive` surface everyone fits, so what it records is ORDER. Only the displacement reading is what the contention detector reads." },
15182
15201
  arbitration_state: { type: "string", enum: ["enforced_documented", "enforced_undocumented", "safe_by_coincidence", "none", "no_contention_by_design"], description: "Whether the arbitration answer is enforced, written down, both, neither, or not owed at all. Leaving the field unset means unassessed, and always did.", notes: 'The separations are the whole point of the field, because absence alone conflates four situations with four different remediations: "enforced in code but never transcribed" is ten minutes of typing, "never decided" is a design meeting, "safe only because nothing has collided yet" is the dangerous one, and "nothing to decide, the occupants never compete" is a chained surface, which owes no arbitration rule at all.' },
15183
- extensibility: { type: "string", enum: ["closed", "plugin_registerable", "user_configurable"], description: "Who may add occupants to the surface." },
15202
+ extensibility: { type: "string", enum: ["closed", "plugin_registerable", "user_configurable"], description: "Who may add occupants to the surface. @deprecated since 0.36.0, removeIn 1.0.0. Use `extension_mechanism` / `extension_audience` / `extension_scope` / `extension_point`: this single enum collapses four independent facts (mechanism, audience, scope, and the named API entry point) into one value, which forces false `closed` readings on surfaces that are overridable through a mechanism the enum has no room to name. STAGED, not renamed: the field is kept and still read, no stored bytes change. There is no `PROPERTY_SCALE_MAP_BY_ENTITY` entry for this one: unlike `risk.probability` \u2192 `likelihood_5`, this is a structural split with no scale to remap onto, so no machine migration ships; re-modelling a surface's real mechanism/audience/scope is a judgement call, same as promoting `objective.timeframe` to a `planning_cycle` node." },
15203
+ extension_mechanism: { type: "string", enum: ["none", "component_wrap", "component_replace", "list_resolve", "register", "config_flag", "render_callback"], description: "The mechanism by which this surface is customized: e.g. `component_wrap` for a `renderDefault`-style override, `list_resolve` for a filter/append resolver, `register` for named-collection registration. Independent of `extension_audience` and `extension_scope`. `none` means not customizable by this mechanism, not unassessed.", notes: "A surface can be `component_wrap`-able by a schema author globally and `register`-able by a plugin author per type at the same time, which is exactly the shape `extensibility` could not hold: it named only a mechanism-or-audience, never both." },
15204
+ extension_audience: { type: "string[]", enum: ["config_author", "schema_author", "plugin_author", "end_user"], description: "WHO may customize the surface through the declared `extension_mechanism`: the studio config author, the schema author, a plugin author, or the end user. Multi-valued because the same surface is often overridable by more than one audience through different entry points (e.g. globally by a config author, per-type by a schema author)." },
15205
+ extension_scope: { type: "string[]", enum: ["global", "per_type", "per_field", "per_instance"], description: "AT WHAT SCOPE the customization applies: the whole surface, one type, one field, or one instance. Multi-valued: a form field surface can be overridable globally and per type at once.", notes: 'This is the fact `extensibility: \'closed\'` got wrong most often: "has no registration list of its own" (no per-instance entry, e.g. `form.components.field` has none) does not mean "cannot be customized" (it is still overridable globally and per type via a schema-level `components` declaration).' },
15206
+ extension_point: { type: "string", description: 'The named API entry point through which the customization happens. @example "form.components.field", "document.actions", "studio.tools"', notes: "A durable, checkable link from the model to the code, in the same spirit as recording a DOM selector: it makes the customization fact verifiable against the real API rather than asserted from memory." },
15184
15207
  mutates_content: { type: "boolean", description: "Whether occupying this surface can change the underlying content, as opposed to only selecting or revealing it. The selector-versus-mutator distinction: a gutter that toggles a value is a mutator, a gutter that jumps the cursor is not." },
15185
15208
  dimensional_constraint: { type: "string", description: 'The hard spatial budget the surface imposes on its occupants, in whatever unit the design system speaks. @example "292px wide", "25px per field", "two grid columns"' }
15186
15209
  },
@@ -34124,7 +34147,7 @@ function checkHeaderSealText(text) {
34124
34147
  }
34125
34148
 
34126
34149
  // src/index.ts
34127
- var UPG_VERSION = "0.35.0";
34150
+ var UPG_VERSION = "0.36.0";
34128
34151
  var UPG_FORMAT_VERSION = "0.4.0";
34129
34152
  var MARKDOWN_FORMAT_VERSION = "0.1";
34130
34153
  var UPG_TYPES = getTypes();