@unified-product-graph/core 0.13.1 → 0.14.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/dist/index.js CHANGED
@@ -7381,6 +7381,53 @@ function getDeprecatedTypes() {
7381
7381
  return deprecated;
7382
7382
  }
7383
7383
  var UPG_PROPERTY_MIGRATIONS = {
7384
+ // ── v0.14.0: Pattern E — remove deprecated/ghost properties (UPG-574) ────────
7385
+ //
7386
+ // Properties marked deprecated (some "Removed in 0.9.1") that were never
7387
+ // actually removed, plus superseded soft-aliases. The RICE / opportunity-sizing
7388
+ // scoring inputs were framework-scoped from 0.9.0: their value lives on the
7389
+ // `framework_exercise` includes-edge of the rice-scoring / opportunity-sizing
7390
+ // framework, not on the entity. The remaining four are superseded by a sibling
7391
+ // (cause_category, rule_strength, size_estimate, effort). Loaders drop the
7392
+ // stranded keys; the values were never canonical on the entity.
7393
+ "0.14.0": [
7394
+ {
7395
+ kind: "drop_props",
7396
+ type: "opportunity",
7397
+ drop_props: ["reach", "frequency", "pain", "opportunity_score"],
7398
+ reason: "UPG-574: opportunity scoring (reach/frequency/pain/opportunity_score) was framework-scoped from 0.9.0 (opportunity-sizing). Apply the framework and read the value off the framework_exercise edge; the entity props are removed in 0.14.0."
7399
+ },
7400
+ {
7401
+ kind: "drop_props",
7402
+ type: "solution",
7403
+ drop_props: ["reach", "impact", "confidence", "effort", "rice_score"],
7404
+ reason: "UPG-574: RICE inputs (reach/impact/confidence/effort) and the computed rice_score were framework-scoped from 0.9.0 (rice-scoring). Apply the framework and read the score off the framework_exercise edge; the entity props are removed in 0.14.0."
7405
+ },
7406
+ {
7407
+ kind: "drop_props",
7408
+ type: "root_cause",
7409
+ drop_props: ["category", "verified"],
7410
+ reason: "UPG-574: root_cause.category was a legacy free-form field superseded by the closed-enum cause_category; verified duplicated cause_confidence === confirmed. Both removed in 0.14.0."
7411
+ },
7412
+ {
7413
+ kind: "drop_props",
7414
+ type: "design_guideline",
7415
+ drop_props: ["strictness"],
7416
+ reason: "UPG-574: design_guideline.strictness was superseded by rule_strength (a richer imperative-force enum). Removed in 0.14.0."
7417
+ },
7418
+ {
7419
+ kind: "drop_props",
7420
+ type: "behavioral_segment",
7421
+ drop_props: ["size"],
7422
+ reason: "UPG-574: behavioral_segment.size was a v0.2 alias for size_estimate. Removed in 0.14.0; use size_estimate."
7423
+ },
7424
+ {
7425
+ kind: "drop_props",
7426
+ type: "task",
7427
+ drop_props: ["estimate"],
7428
+ reason: "UPG-574: task.estimate was a story_task-collapse relic that duplicated effort. Removed in 0.14.0; use effort."
7429
+ }
7430
+ ],
7384
7431
  // ── v0.12.0: P14 Bucket C — drop the one non-derived denormalized aggregate ──
7385
7432
  //
7386
7433
  // The count caches (feature_count, evidence_count, workflow step_count /
@@ -9749,9 +9796,9 @@ var UPG_PROPERTY_SCHEMA = {
9749
9796
  method: { type: "string", enum: ["automated", "manual", "assistive_tech", "expert"], description: "How the audit was conducted" },
9750
9797
  scope: { type: "string", description: 'What was audited (e.g. "homepage", "checkout flow")' },
9751
9798
  conformance_result: { type: "string", enum: ["pass", "partial", "fail"], description: "Overall conformance result" },
9752
- violations_count: { type: "number", description: "Number of accessibility violations found" },
9753
- passes_count: { type: "number", description: "Number of checks that passed" },
9754
- incomplete_count: { type: "number", description: "Number of checks that could not be completed" },
9799
+ violations_count: { type: "number", description: "Number of accessibility violations found", modifier: "derived" },
9800
+ passes_count: { type: "number", description: "Number of checks that passed", modifier: "derived" },
9801
+ incomplete_count: { type: "number", description: "Number of checks that could not be completed", modifier: "derived" },
9755
9802
  score: { type: "number", description: "Aggregate accessibility score (0-100)" },
9756
9803
  tool: { type: "string", enum: ["axe-core", "lighthouse", "wave", "manual", "other"], description: "Tool used to perform the audit" },
9757
9804
  tool_version: { type: "string", description: "Version of the audit tool" },
@@ -9811,14 +9858,14 @@ var UPG_PROPERTY_SCHEMA = {
9811
9858
  account: {
9812
9859
  account_type: { type: "string", enum: ["prospect", "customer", "partner", "churned"], description: "Relationship status of this account" },
9813
9860
  industry: { type: "string", description: "Industry vertical the account operates in" },
9814
- employee_count: { type: "number", description: "Number of employees at the account" },
9861
+ employee_count: { type: "number", description: "Number of employees at the account", modifier: "snapshot" },
9815
9862
  annual_revenue: { type: "number", description: "Annual revenue of the account" }
9816
9863
  },
9817
9864
  // AcquisitionChannelProperties: AcquisitionChannel entity.
9818
9865
  acquisition_channel: {
9819
9866
  channel_type: { type: "string", enum: ["seo", "paid", "social", "referral", "direct", "content"], description: "Category of the acquisition channel" },
9820
9867
  customer_acquisition_cost: { type: "number", description: "Customer acquisition cost for this channel" },
9821
- monthly_volume: { type: "number", description: "Monthly volume of new users from this channel" }
9868
+ monthly_volume: { type: "number", description: "Monthly volume of new users from this channel", modifier: "snapshot" }
9822
9869
  },
9823
9870
  // AdCreativeProperties: Ad creative.
9824
9871
  ad_creative: {
@@ -9833,7 +9880,7 @@ var UPG_PROPERTY_SCHEMA = {
9833
9880
  // AffinityClusterProperties: Affinity cluster grouping observations.
9834
9881
  affinity_cluster: {
9835
9882
  theme: { type: "string", description: "Emergent theme label" },
9836
- child_observation_count: { type: "number", description: "Observations in this cluster" },
9883
+ child_observation_count: { type: "number", description: "Observations in this cluster", modifier: "derived" },
9837
9884
  confidence: {
9838
9885
  type: "assessment",
9839
9886
  scale_id: "confidence_5",
@@ -9867,7 +9914,7 @@ var UPG_PROPERTY_SCHEMA = {
9867
9914
  hook_event: { type: "string", description: "Event that triggers this hook" },
9868
9915
  hook_action: { type: "string", description: "Action performed when the hook fires" },
9869
9916
  hook_status: { type: "string", enum: ["active", "disabled", "error"], description: "Operational status of the hook" },
9870
- execution_count: { type: "number", description: "Number of times this hook has fired" }
9917
+ execution_count: { type: "number", description: "Number of times this hook has fired", modifier: "snapshot" }
9871
9918
  },
9872
9919
  // AgentSessionProperties: Agent session.
9873
9920
  agent_session: {
@@ -9884,7 +9931,7 @@ var UPG_PROPERTY_SCHEMA = {
9884
9931
  agent_skill: {
9885
9932
  skill_trigger: { type: "string", description: "Event or command that activates this skill" },
9886
9933
  skill_description: { type: "string", description: "Human-readable description of what the skill does" },
9887
- invocation_count: { type: "number", description: "Number of times this skill has been invoked" }
9934
+ invocation_count: { type: "number", description: "Number of times this skill has been invoked", modifier: "snapshot" }
9888
9935
  },
9889
9936
  // AgentTaskProperties: Agent task. A discrete task assigned to an agent.
9890
9937
  agent_task: {
@@ -9916,7 +9963,7 @@ var UPG_PROPERTY_SCHEMA = {
9916
9963
  ai_dataset: {
9917
9964
  dataset_type: { type: "string", enum: ["training", "evaluation", "fine_tuning", "rlhf", "synthetic"], description: "Purpose" },
9918
9965
  version: { type: "string", description: "Version" },
9919
- record_count: { type: "number", description: "Records" },
9966
+ record_count: { type: "number", description: "Records", modifier: "snapshot" },
9920
9967
  format: { type: "string", description: 'Format (e.g. "jsonl", "csv", "parquet")' },
9921
9968
  storage_uri: { type: "string", description: "Storage URI" },
9922
9969
  checksum: { type: "string", description: "Integrity hash" },
@@ -9941,7 +9988,7 @@ var UPG_PROPERTY_SCHEMA = {
9941
9988
  ai_guardrail: {
9942
9989
  guardrail_type: { type: "string", enum: ["content_filter", "rate_limit", "token_limit", "safety", "custom"], description: "Protection category" },
9943
9990
  enforcement: { type: "string", enum: ["block", "warn", "log"], description: "Action when triggered" },
9944
- trigger_count: { type: "number", description: "Times triggered" }
9991
+ trigger_count: { type: "number", description: "Times triggered", modifier: "snapshot" }
9945
9992
  },
9946
9993
  // AiModelProperties: AI model.
9947
9994
  ai_model: {
@@ -9949,10 +9996,10 @@ var UPG_PROPERTY_SCHEMA = {
9949
9996
  model_id: { type: "string", description: 'Unique model identifier (e.g. "claude-sonnet-4-20250514")' },
9950
9997
  model_version: { type: "string", description: "Specific version" },
9951
9998
  model_purpose: { type: "string", description: "Intended use case" },
9952
- cost_per_1k_tokens: { type: "number", description: "Cost per 1,000 tokens" },
9999
+ cost_per_1k_tokens: { type: "number", description: "Cost per 1,000 tokens", modifier: "snapshot" },
9953
10000
  context_window: { type: "number", description: "Maximum context window (tokens)" },
9954
- latency_p50_ms: { type: "number", description: "Median latency (p50, ms)" },
9955
- latency_p99_ms: { type: "number", description: "Tail latency (p99, ms)" },
10001
+ latency_p50_ms: { type: "number", description: "Median latency (p50, ms)", modifier: "snapshot" },
10002
+ latency_p99_ms: { type: "number", description: "Tail latency (p99, ms)", modifier: "snapshot" },
9956
10003
  input_schema: { type: "string", description: "Expected input format or schema" },
9957
10004
  output_schema: { type: "string", description: "Expected output format or schema" },
9958
10005
  aliases: { type: "string[]", description: "Alternative names" },
@@ -9996,8 +10043,8 @@ var UPG_PROPERTY_SCHEMA = {
9996
10043
  // ApiEcosystemProperties: API ecosystem.
9997
10044
  api_ecosystem: {
9998
10045
  api_style: { type: "string", enum: ["rest", "graphql", "grpc", "webhook", "mixed"], description: "Primary API architecture style" },
9999
- developer_count: { type: "number", description: "Number of registered developers" },
10000
- app_count: { type: "number", description: "Number of apps built on the API" }
10046
+ developer_count: { type: "number", description: "Number of registered developers", modifier: "snapshot" },
10047
+ app_count: { type: "number", description: "Number of apps built on the API", modifier: "derived" }
10001
10048
  },
10002
10049
  // ApiEndpointProperties: API endpoint.
10003
10050
  api_endpoint: {
@@ -10060,15 +10107,14 @@ var UPG_PROPERTY_SCHEMA = {
10060
10107
  source: { type: "string", enum: ["clickstream", "survey", "interview", "mixed", "inferred", "imported"], description: "Membership data source. Drives confidence weighting and refresh policy." },
10061
10108
  included_behaviors: { type: "string[]", description: "Qualifying behaviours (positive criteria, free-text labels)" },
10062
10109
  excluded_behaviors: { type: "string[]", description: "Excluding behaviours (negative criteria, free-text labels)" },
10063
- size_estimate: { type: "number", description: "Estimated current size. Snapshot value." },
10064
- size: { type: "number", description: "Size. Alias retained for the v0.2 baseline." },
10110
+ size_estimate: { type: "number", description: "Estimated current size. Snapshot value. (`size`, the v0.2 alias, removed in 0.14.0, UPG-574.)" },
10065
10111
  validity_period_start: { type: "string", description: "ISO start of the validity window. Behavioural definitions decay; outside the window the snapshot should be re-computed." },
10066
10112
  validity_period_end: { type: "string", description: "End of the window over which the segment definition is considered valid (ISO format)" }
10067
10113
  },
10068
10114
  // BetaProgramProperties: Beta program.
10069
10115
  beta_program: {
10070
10116
  beta_type: { type: "string", enum: ["closed", "open", "invite_only"], description: "Access model for the beta" },
10071
- participant_count: { type: "number", description: "Number of users participating in the beta" }
10117
+ participant_count: { type: "number", description: "Number of users participating in the beta", modifier: "snapshot" }
10072
10118
  },
10073
10119
  // BoundedContextProperties: DDD bounded context.
10074
10120
  bounded_context: {
@@ -10226,7 +10272,7 @@ var UPG_PROPERTY_SCHEMA = {
10226
10272
  // ChurnReasonProperties: Churn reason.
10227
10273
  churn_reason: {
10228
10274
  category: { type: "string", description: "High-level category of the churn reason" },
10229
- frequency_count: { type: "number", description: "Exact count of times this reason has been cited in `frequency_period`" },
10275
+ frequency_count: { type: "number", description: "Exact count of times this reason has been cited in `frequency_period`", modifier: "snapshot" },
10230
10276
  frequency_period: { type: "string", description: "The recurrence period the count is measured over (ISO-8601 `Duration`, e.g. `'P30D'`)" },
10231
10277
  frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative frequency tier when an exact count is not known" },
10232
10278
  contributing_factors: { type: "string[]", description: "Other factors that contributed to the churn" },
@@ -10241,8 +10287,8 @@ var UPG_PROPERTY_SCHEMA = {
10241
10287
  avg_duration: { type: "string", description: 'Average run duration across recent executions. @example "4m 30s", "12 minutes"' },
10242
10288
  last_run_status: { type: "string", enum: ["success", "failure", "cancelled", "skipped", "in_progress"], description: "Result of the most recent run. Current health indicator." },
10243
10289
  target_branch: { type: "string", description: 'Primary branch. The branch that triggers production deployments. @example "main", "release/*"' },
10244
- run_count: { type: "number", description: "Total runs since creation. Indicates activity level. @example 1452" },
10245
- success_rate: { type: "number", description: "Reliability metric for the pipeline itself: % of runs that succeed. @example 94.3" }
10290
+ run_count: { type: "number", description: "Total runs since creation. Indicates activity level. @example 1452", modifier: "snapshot" },
10291
+ success_rate: { type: "number", description: "Reliability metric for the pipeline itself: % of runs that succeed. @example 94.3", modifier: "snapshot" }
10246
10292
  },
10247
10293
  // ClassificationAxisProperties: ClassificationAxis: a dimension along which subjects are classified.
10248
10294
  classification_axis: {
@@ -10281,8 +10327,8 @@ var UPG_PROPERTY_SCHEMA = {
10281
10327
  // CommunityInitiativeProperties: Community initiative.
10282
10328
  community_initiative: {
10283
10329
  initiative_type: { type: "string", enum: ["forum", "discord", "slack", "meetup", "ambassador", "other"], description: "Platform or format for the community" },
10284
- member_count: { type: "number", description: "Current number of community members" },
10285
- engagement_rate: { type: "number", description: "Percentage of members actively participating" }
10330
+ member_count: { type: "number", description: "Current number of community members", modifier: "snapshot" },
10331
+ engagement_rate: { type: "number", description: "Percentage of members actively participating", modifier: "snapshot" }
10286
10332
  },
10287
10333
  // CompetitiveAnalysisProperties: Competitive analysis exercise or snapshot.
10288
10334
  competitive_analysis: {
@@ -10308,7 +10354,7 @@ var UPG_PROPERTY_SCHEMA = {
10308
10354
  },
10309
10355
  // CompetitiveBattleCardProperties: CompetitiveBattleCard entity.
10310
10356
  competitive_battle_card: {
10311
- win_rate: { type: "number", description: "Historical win rate against this competitor (0-100%)" },
10357
+ win_rate: { type: "number", description: "Historical win rate against this competitor (0-100%)", modifier: "snapshot" },
10312
10358
  key_differentiators: { type: "string", description: "Summary of key differentiators versus this competitor" }
10313
10359
  },
10314
10360
  // CompetitorProperties: A product or approach competing for the same user need.
@@ -10412,7 +10458,7 @@ var UPG_PROPERTY_SCHEMA = {
10412
10458
  content_calendar: {
10413
10459
  calendar_period: { type: "string", description: 'Covered period (e.g. "Q2 2026")' },
10414
10460
  publish_cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "Publishing cadence (canonical `Cadence` since v0.4.0). Retyped from the legacy free-form `publish_cadence: string`. For exact rates (\"3 per week\"), set `frequency_count` + `frequency_period`. BREAKING in v0.4.0: previous string values like `\"3x/week\"` no longer type-check. Map to `'weekly'` + `frequency_count: 3` + `frequency_period: 'P7D'`." },
10415
- frequency_count: { type: "number", description: "Exact count in the period. Pairs with `frequency_period`." },
10461
+ frequency_count: { type: "number", description: "Exact count in the period. Pairs with `frequency_period`.", modifier: "snapshot" },
10416
10462
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`, e.g. `'P7D'`)" },
10417
10463
  frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative rate tier when an exact rate is unknown" }
10418
10464
  },
@@ -10427,7 +10473,7 @@ var UPG_PROPERTY_SCHEMA = {
10427
10473
  content_types: { type: "string[]", description: "Types of content to produce" },
10428
10474
  distribution_channels: { type: "string[]", description: "Channels where content will be distributed" },
10429
10475
  cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "Publishing cadence (canonical `Cadence` since v0.4.0). Retyped from the legacy free-form `cadence: string` (e.g. \"2x/week\"). For exact rates, set `frequency_count` + `frequency_period`. BREAKING in v0.4.0: previous string values like `\"2x/week\"` no longer type-check. Map to `'weekly'` + `frequency_count: 2` + `frequency_period: 'P7D'`." },
10430
- frequency_count: { type: "number", description: "Exact count of publications in the period. Pairs with `frequency_period`." },
10476
+ frequency_count: { type: "number", description: "Exact count of publications in the period. Pairs with `frequency_period`.", modifier: "snapshot" },
10431
10477
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`, e.g. `'P7D'`)" },
10432
10478
  frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative rate tier when an exact rate is unknown" }
10433
10479
  },
@@ -10498,7 +10544,7 @@ var UPG_PROPERTY_SCHEMA = {
10498
10544
  stage_type: { type: "string", enum: ["awareness", "acquisition", "activation", "retention", "revenue", "referral"], description: "Which pirate metric (AAARRR) this stage maps to" },
10499
10545
  stage_order: { type: "number", description: "Display order along the lifecycle timeline (0-indexed). The `*_order` convention shared with `journey_phase.phase_order` and `journey_step.step_order` (UPG-675 / CS-8), so two same-`stage_type` stages are orderable." },
10500
10546
  avg_duration: { type: "string", description: "Average time a customer spends in this stage" },
10501
- conversion_rate: { type: "number", description: "Percentage of customers who advance to the next stage" }
10547
+ conversion_rate: { type: "number", description: "Percentage of customers who advance to the next stage", modifier: "snapshot" }
10502
10548
  },
10503
10549
  // CustomerRelationshipProperties: CustomerRelationship.
10504
10550
  customer_relationship: {
@@ -10511,9 +10557,9 @@ var UPG_PROPERTY_SCHEMA = {
10511
10557
  tool: { type: "string", enum: ["looker", "amplitude", "mixpanel", "posthog", "custom"], description: "Analytics tool hosting this dashboard" },
10512
10558
  url: { type: "string", description: "URL to the live dashboard" },
10513
10559
  audience: { type: "string", description: "Intended audience for this dashboard" },
10514
- element_count: { type: "number", description: "Number of widgets or panels on the dashboard" },
10560
+ element_count: { type: "number", description: "Number of widgets or panels on the dashboard", modifier: "derived" },
10515
10561
  refresh_cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "How often the dashboard data refreshes. Uses the shared `Cadence` scale." },
10516
- filter_count: { type: "number", description: "Number of user-configurable filters" }
10562
+ filter_count: { type: "number", description: "Number of user-configurable filters", modifier: "derived" }
10517
10563
  },
10518
10564
  // DataClassificationProperties: Data classification.
10519
10565
  data_classification: {
@@ -10551,9 +10597,9 @@ var UPG_PROPERTY_SCHEMA = {
10551
10597
  data_model: {
10552
10598
  schema_name: { type: "string", description: "Name of the schema this model belongs to" },
10553
10599
  database_name: { type: "string", description: "Name of the database containing this model" },
10554
- table_count: { type: "number", description: "Number of tables in the model" },
10555
- column_count: { type: "number", description: "Total number of columns across all tables" },
10556
- test_count: { type: "number", description: "Number of data tests defined for this model" },
10600
+ table_count: { type: "number", description: "Number of tables in the model", modifier: "derived" },
10601
+ column_count: { type: "number", description: "Total number of columns across all tables", modifier: "derived" },
10602
+ test_count: { type: "number", description: "Number of data tests defined for this model", modifier: "derived" },
10557
10603
  model_type: { type: "string", enum: ["relational", "document", "graph", "time_series"], description: "Database paradigm used" },
10558
10604
  materialization: { type: "string", enum: ["view", "table", "incremental", "ephemeral", "materialized_view"], description: "How the model is materialised in the warehouse" },
10559
10605
  meta: { type: "object", description: "Arbitrary metadata key-value pairs" },
@@ -10565,7 +10611,7 @@ var UPG_PROPERTY_SCHEMA = {
10565
10611
  schedule: { type: "string", description: "Cron or scheduling expression" },
10566
10612
  avg_runtime: { type: "string", description: "Average wall-clock runtime per execution" },
10567
10613
  orchestrator: { type: "string", description: 'Orchestration tool (e.g. "Airflow", "Dagster", "dbt Cloud")' },
10568
- retry_count: { type: "number", description: "Number of automatic retries on failure" },
10614
+ retry_count: { type: "number", description: "Number of automatic retries on failure", modifier: "snapshot" },
10569
10615
  retry_delay_seconds: { type: "number", description: "Delay between retries in seconds" },
10570
10616
  timeout_seconds: { type: "number", description: "Maximum allowed runtime in seconds before timeout" },
10571
10617
  trigger_rule: { type: "string", description: "Rule that determines when this pipeline triggers" },
@@ -10598,7 +10644,7 @@ var UPG_PROPERTY_SCHEMA = {
10598
10644
  schema_version: { type: "string", description: "Current schema version" },
10599
10645
  migration_status: { type: "string", enum: ["current", "pending", "failed"], description: "Pending-migration status" },
10600
10646
  owner: { type: "string", description: "Owning person or team responsible for design and migrations. Promote to a `node_owned_by_team` edge if ownership must be queryable." },
10601
- table_count: { type: "number", description: "Tables or collections in this schema. Useful for migration scope estimation." }
10647
+ table_count: { type: "number", description: "Tables or collections in this schema. Useful for migration scope estimation.", modifier: "derived" }
10602
10648
  },
10603
10649
  // DealProperties: Deal.
10604
10650
  deal: {
@@ -10633,7 +10679,7 @@ var UPG_PROPERTY_SCHEMA = {
10633
10679
  },
10634
10680
  // DepartmentProperties: Department entity.
10635
10681
  department: {
10636
- headcount: { type: "number", description: "Total number of people in the department" },
10682
+ headcount: { type: "number", description: "Total number of people in the department", modifier: "snapshot" },
10637
10683
  budget: { type: "number", description: "Annual budget allocated to the department" },
10638
10684
  department_mission: { type: "string", description: "Charter / purpose statement for the department" },
10639
10685
  leader: { type: "string", description: "Department leader (person or role reference). Promote to a `node_owned_by_person` edge if ownership must be queryable." },
@@ -10678,8 +10724,7 @@ var UPG_PROPERTY_SCHEMA = {
10678
10724
  guideline_category: { type: "string", enum: ["spacing", "color", "typography", "layout", "interaction", "content"], description: "Category covered" },
10679
10725
  applies_to: { type: "string", description: "Applicable elements or contexts" },
10680
10726
  rationale: { type: "string", description: "Reasoning. Why this rule exists." },
10681
- rule_strength: { type: "string", enum: ["must", "must_not", "exception", "warning", "guideline"], description: "Imperative force. Supersedes `strictness`." },
10682
- strictness: { type: "string", enum: ["must", "should", "may"], description: "RFC-2119-flavoured binding strength" },
10727
+ rule_strength: { type: "string", enum: ["must", "must_not", "exception", "warning", "guideline"], description: "Imperative force. (Superseded the removed `strictness` field in 0.14.0, UPG-574.)" },
10683
10728
  exception_policy: { type: "string", description: "Exception request or documentation process" }
10684
10729
  },
10685
10730
  // DesignPatternProperties: Reusable design pattern.
@@ -10763,7 +10808,7 @@ var UPG_PROPERTY_SCHEMA = {
10763
10808
  // DeveloperPortalProperties: Developer portal.
10764
10809
  developer_portal: {
10765
10810
  portal_url: { type: "string", description: "URL of the developer portal" },
10766
- doc_count: { type: "number", description: "Number of documentation pages" },
10811
+ doc_count: { type: "number", description: "Number of documentation pages", modifier: "derived" },
10767
10812
  sandbox_available: { type: "boolean", description: "Whether a sandbox environment is available" }
10768
10813
  },
10769
10814
  // DiscountStrategyProperties: Discount strategy.
@@ -10771,7 +10816,7 @@ var UPG_PROPERTY_SCHEMA = {
10771
10816
  discount_type: { type: "string", enum: ["percentage", "fixed", "tiered", "bundle"], description: "How the discount is applied" },
10772
10817
  discount_percentage: { type: "number", description: "Discount amount as a percentage (0-100)" },
10773
10818
  valid_until: { type: "string", description: "Expiration date of the discount (ISO format)" },
10774
- redemption_count: { type: "number", description: "Number of times this discount has been redeemed" }
10819
+ redemption_count: { type: "number", description: "Number of times this discount has been redeemed", modifier: "snapshot" }
10775
10820
  },
10776
10821
  // DistributionChannelProperties: DistributionChannel.
10777
10822
  distribution_channel: {
@@ -10787,7 +10832,7 @@ var UPG_PROPERTY_SCHEMA = {
10787
10832
  document_type: { type: "string", enum: ["vision", "plan", "decision", "research", "spec", "audit", "session", "feedback", "case-study", "narrative", "bug-report", "archive-collection", "rfc", "runbook", "guide", "onboarding", "brief", "report", "reference"], description: "Purpose classification" },
10788
10833
  author: { type: "string", description: "Author (free-form: name, email, or handle). Promote to a `node_owned_by_person` edge if ownership must be queryable." },
10789
10834
  last_updated: { type: "string", description: "ISO 8601 last-meaningful-update" },
10790
- word_count: { type: "number", description: "Approximate word count. Useful for planning, indexing, summarisation." },
10835
+ word_count: { type: "number", description: "Approximate word count. Useful for planning, indexing, summarisation.", modifier: "snapshot" },
10791
10836
  content_summary: { type: "string", description: "1\u20133 sentence summary. Drives previews, search snippets, embedding context." },
10792
10837
  language: { type: "string", description: 'Primary language (BCP 47 tag, e.g. "en", "en-GB", "fr")' }
10793
10838
  },
@@ -10815,9 +10860,9 @@ var UPG_PROPERTY_SCHEMA = {
10815
10860
  // EmailSequenceProperties: Email sequence.
10816
10861
  email_sequence: {
10817
10862
  sequence_type: { type: "string", enum: ["onboarding", "nurture", "re_engagement", "sales", "other"], description: "Purpose of the email sequence" },
10818
- email_count: { type: "number", description: "Number of emails in the sequence" },
10819
- open_rate: { type: "number", description: "Average open rate across the sequence (0-1)" },
10820
- click_rate: { type: "number", description: "Average click-through rate across the sequence (0-1)" }
10863
+ email_count: { type: "number", description: "Number of emails in the sequence", modifier: "derived" },
10864
+ open_rate: { type: "number", description: "Average open rate across the sequence (0-1)", modifier: "snapshot" },
10865
+ click_rate: { type: "number", description: "Average click-through rate across the sequence (0-1)", modifier: "snapshot" }
10821
10866
  },
10822
10867
  // EpicProperties: A collection of related user stories that delivers a feature or capability.
10823
10868
  epic: {
@@ -10829,15 +10874,15 @@ var UPG_PROPERTY_SCHEMA = {
10829
10874
  },
10830
10875
  // ErrorBudgetProperties: Error budget.
10831
10876
  error_budget: {
10832
- budget_remaining: { type: "number", description: "Remaining budget percentage (0\u2013100). @example 45.2 (45.2% remaining, 54.8% used)" },
10833
- burn_rate: { type: "number", description: "Consumption rate as a multiplier against sustainable burn. 1.0 = on track. 2.5 = consuming 2.5x faster than sustainable." },
10877
+ budget_remaining: { type: "number", description: "Remaining budget percentage (0\u2013100). @example 45.2 (45.2% remaining, 54.8% used)", modifier: "snapshot" },
10878
+ burn_rate: { type: "number", description: "Consumption rate as a multiplier against sustainable burn. 1.0 = on track. 2.5 = consuming 2.5x faster than sustainable.", modifier: "snapshot" },
10834
10879
  policy: { type: "string", description: 'Policy when the budget hits 0%. @example "Freeze all non-reliability deploys", "Page engineering lead immediately"' },
10835
10880
  budget_window: { type: "string", description: 'Budget window. Defines reset cadence. @example "30 days", "rolling 28 days"' }
10836
10881
  },
10837
10882
  // EvalBenchmarkProperties: Evaluation benchmark.
10838
10883
  eval_benchmark: {
10839
10884
  benchmark_type: { type: "string", enum: ["accuracy", "latency", "cost", "safety", "custom"], description: "Measured dimension" },
10840
- test_case_count: { type: "number", description: "Test cases in the suite" },
10885
+ test_case_count: { type: "number", description: "Test cases in the suite", modifier: "derived" },
10841
10886
  passing_threshold: { type: "number", description: "Minimum passing score" },
10842
10887
  last_run: { type: "string", description: "ISO date of the most recent run" }
10843
10888
  },
@@ -10859,7 +10904,7 @@ var UPG_PROPERTY_SCHEMA = {
10859
10904
  event_type: { type: "string", enum: ["conference", "webinar", "meetup", "workshop", "trade_show", "other"], description: "Format of the event" },
10860
10905
  event_date: { type: "string", description: "Date of the event (ISO format)" },
10861
10906
  location: { type: "string", description: "Venue or virtual platform" },
10862
- attendee_count: { type: "number", description: "Number of attendees" }
10907
+ attendee_count: { type: "number", description: "Number of attendees", modifier: "snapshot" }
10863
10908
  },
10864
10909
  // EventSchemaProperties: EventSchema entity.
10865
10910
  event_schema: {
@@ -11022,7 +11067,7 @@ var UPG_PROPERTY_SCHEMA = {
11022
11067
  feature_flag: {
11023
11068
  key: { type: "string", description: 'Required. Stable flag key used in code (e.g. "new-checkout-flow").' },
11024
11069
  flag_status: { type: "string", enum: ["on", "off", "rollout"], description: "Activation state. `on` = enabled for all. `off` = disabled for all. `rollout` = partial via targeting_rules." },
11025
- rollout_pct: { type: "number", description: "Percentage enabled (0\u2013100). Meaningful when `flag_status === 'rollout'`." },
11070
+ rollout_pct: { type: "number", description: "Percentage enabled (0\u2013100). Meaningful when `flag_status === 'rollout'`.", modifier: "snapshot" },
11026
11071
  targeting_rules: { type: "string", description: "Human-readable targeting rules. Full rule evaluation happens in the flag service." },
11027
11072
  owner: { type: "string", description: "Owning person or team responsible for the flag's lifecycle. Promote to a `node_owned_by_person` edge if ownership must be queryable." },
11028
11073
  flag_type: { type: "string", enum: ["temporary", "permanent", "experiment"], description: "Lifecycle classification. `temporary` = should be removed after rollout (kill switch, gradual rollout). `permanent` = long-lived feature gate (entitlement flag). `experiment` = A/B test with a defined end condition." },
@@ -11032,7 +11077,7 @@ var UPG_PROPERTY_SCHEMA = {
11032
11077
  // FeatureRequestProperties: Feature request raised by customer, prospect, or internal stakeholder.
11033
11078
  feature_request: {
11034
11079
  request_source: { type: "string", enum: ["customer", "internal", "prospect", "support", "community"], description: "Where the request originated" },
11035
- vote_count: { type: "number", description: "Number of votes or upvotes from users" },
11080
+ vote_count: { type: "number", description: "Number of votes or upvotes from users", modifier: "snapshot" },
11036
11081
  signal_sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Detected sentiment of the request" },
11037
11082
  signal_channel: { type: "string", description: "Channel through which the request was received" },
11038
11083
  signal_urgency: { type: "string", enum: ["low", "medium", "high", "critical"], description: "Perceived urgency of the request" },
@@ -11090,7 +11135,7 @@ var UPG_PROPERTY_SCHEMA = {
11090
11135
  },
11091
11136
  // FeedbackVoteProperties: Feedback vote.
11092
11137
  feedback_vote: {
11093
- vote_count: { type: "number", description: "Total number of votes cast" },
11138
+ vote_count: { type: "number", description: "Total number of votes cast", modifier: "snapshot" },
11094
11139
  mrr_impact: { type: "number", description: "Combined MRR of voting accounts" }
11095
11140
  },
11096
11141
  // FixProperties: Specific change that resolved an issue.
@@ -11130,13 +11175,13 @@ var UPG_PROPERTY_SCHEMA = {
11130
11175
  funnel: {
11131
11176
  funnel_type: { type: "string", enum: ["acquisition", "activation", "retention", "revenue", "referral", "custom"], description: "Which stage of the customer lifecycle this funnel measures" },
11132
11177
  step_count: { type: "number", description: "Number of steps in the funnel", modifier: "derived" },
11133
- overall_conversion_rate: { type: "number", description: "End-to-end conversion rate through the funnel (0-1)" }
11178
+ overall_conversion_rate: { type: "number", description: "End-to-end conversion rate through the funnel (0-1)", modifier: "snapshot" }
11134
11179
  },
11135
11180
  // FunnelStepProperties: FunnelStep entity.
11136
11181
  funnel_step: {
11137
11182
  step_index: { type: "number", description: "Position of this step in the funnel (0-indexed)" },
11138
- conversion_rate: { type: "number", description: "Percentage of users who advance from this step" },
11139
- drop_off_rate: { type: "number", description: "Percentage of users who leave at this step" }
11183
+ conversion_rate: { type: "number", description: "Percentage of users who advance from this step", modifier: "snapshot" },
11184
+ drop_off_rate: { type: "number", description: "Percentage of users who leave at this step", modifier: "snapshot" }
11140
11185
  },
11141
11186
  // GlossaryTermProperties: GlossaryTerm entity.
11142
11187
  glossary_term: {
@@ -11311,7 +11356,7 @@ var UPG_PROPERTY_SCHEMA = {
11311
11356
  // InterviewGuideProperties: Interview guide document.
11312
11357
  interview_guide: {
11313
11358
  guide_type: { type: "string", enum: ["structured", "semi_structured", "unstructured"], description: "Format structure" },
11314
- question_count: { type: "number", description: "Total questions" },
11359
+ question_count: { type: "number", description: "Total questions", modifier: "derived" },
11315
11360
  duration_minutes: { type: "number", description: "Expected length (minutes)" }
11316
11361
  },
11317
11362
  // InvestigationProperties: Active thread of inquiry: debugging, architecture exploration, RCA.
@@ -11468,7 +11513,7 @@ var UPG_PROPERTY_SCHEMA = {
11468
11513
  key_activity: {
11469
11514
  activity_type: { type: "string", enum: ["production", "problem_solving", "platform", "network"], description: "Activity nature" },
11470
11515
  cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: 'Canonical `Cadence`. Replaces the legacy free-form `frequency: string` in v0.4.0. For exact rates (e.g. "3 times per week") set `frequency_count` + `frequency_period`. For qualitative tiers ("rare" \u2192 "constant") use `frequency_rating`.' },
11471
- frequency_count: { type: "number", description: "Exact count of runs in the period. Pairs with `frequency_period`." },
11516
+ frequency_count: { type: "number", description: "Exact count of runs in the period. Pairs with `frequency_period`.", modifier: "snapshot" },
11472
11517
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`, e.g. `'P7D'`)" },
11473
11518
  frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative tier. Use when an exact rate is unknown." },
11474
11519
  operational_owner: { type: "string", description: "Operationally accountable team or individual. Promote to a `node_owned_by_team` edge if ownership must be queryable." },
@@ -11496,7 +11541,7 @@ var UPG_PROPERTY_SCHEMA = {
11496
11541
  },
11497
11542
  // KeyResultProperties: A measurable result under an objective. The KR in OKR.
11498
11543
  key_result: {
11499
- current_value: { type: "number", description: "Most recent observed value" },
11544
+ current_value: { type: "number", description: "Most recent observed value", modifier: "snapshot" },
11500
11545
  target_value: { type: "number", description: "Value for full achievement" },
11501
11546
  unit: { type: "string", description: 'Display unit (e.g. "%", "users", "\xA3")' }
11502
11547
  },
@@ -11529,9 +11574,9 @@ var UPG_PROPERTY_SCHEMA = {
11529
11574
  learning_path: {
11530
11575
  path_order: { type: "number", description: "Display order of this path within a curriculum or program (0-indexed). The scalar ordering convention shared with `journey_step.step_order` and `journey_action.action_order` (UPG-663 / UPG-674). Makes a learning_path a deterministically orderable sequence among sibling paths rather than a star." },
11531
11576
  path_difficulty: { type: "string", enum: ["beginner", "intermediate", "advanced"], description: "Overall difficulty level of the learning path" },
11532
- item_count: { type: "number", description: "Number of items (tutorials, videos, etc.) in the path" },
11577
+ item_count: { type: "number", description: "Number of items (tutorials, videos, etc.) in the path", modifier: "derived" },
11533
11578
  estimated_hours: { type: "number", description: "Estimated total hours to complete the path" },
11534
- completion_rate: { type: "number", description: "Percentage of users who complete the full path" }
11579
+ completion_rate: { type: "number", description: "Percentage of users who complete the full path", modifier: "snapshot" }
11535
11580
  },
11536
11581
  // LegalEntityProperties: Legal entity.
11537
11582
  legal_entity: {
@@ -11549,7 +11594,7 @@ var UPG_PROPERTY_SCHEMA = {
11549
11594
  dep_type: { type: "string", enum: ["runtime", "dev", "peer", "optional"], description: "Dependency classification" },
11550
11595
  license: { type: "string", description: "SPDX license identifier" },
11551
11596
  is_outdated: { type: "boolean", description: "Whether a newer version is available" },
11552
- vulnerability_count: { type: "number", description: "Known vulnerabilities in the installed version. Populated from npm audit, Snyk, etc." }
11597
+ vulnerability_count: { type: "number", description: "Known vulnerabilities in the installed version. Populated from npm audit, Snyk, etc.", modifier: "snapshot" }
11553
11598
  },
11554
11599
  // LocaleProperties: Locale.
11555
11600
  locale: {
@@ -11569,7 +11614,7 @@ var UPG_PROPERTY_SCHEMA = {
11569
11614
  // MarketSegmentProperties: MarketSegment entity.
11570
11615
  market_segment: {
11571
11616
  segment_size: { type: "number", description: "Potential customers in this segment" },
11572
- growth_rate: { type: "number", description: "YoY growth rate as a decimal. @example 0.15 represents 15%" },
11617
+ growth_rate: { type: "number", description: "YoY growth rate as a decimal. @example 0.15 represents 15%", modifier: "snapshot" },
11573
11618
  tam: { type: "number", description: "Total Addressable Market (currency units)" },
11574
11619
  sam: { type: "number", description: "Serviceable Addressable Market (currency units)" }
11575
11620
  },
@@ -11627,7 +11672,7 @@ var UPG_PROPERTY_SCHEMA = {
11627
11672
  // MarketingChannelProperties: Marketing channel.
11628
11673
  marketing_channel: {
11629
11674
  channel_type: { type: "string", enum: ["social", "email", "seo", "sem", "content", "events", "other"], description: "Category of marketing channel" },
11630
- monthly_budget: { type: "number", description: "Monthly spend allocated to this channel" },
11675
+ monthly_budget: { type: "number", description: "Monthly spend allocated to this channel", modifier: "snapshot" },
11631
11676
  roi: { type: "number", description: "Return on investment ratio" },
11632
11677
  channel_status: { type: "string", enum: ["active", "paused", "deprecated"], description: "Operational status of the channel" }
11633
11678
  },
@@ -11662,7 +11707,7 @@ var UPG_PROPERTY_SCHEMA = {
11662
11707
  impact_level: { type: "string", enum: ["impact", "outcome", "output"], description: "Where this metric sits in the impact hierarchy" },
11663
11708
  indicator_direction: { type: "string", enum: ["leading", "lagging"], description: "Whether this metric leads or lags the behaviour it measures" },
11664
11709
  metric_category: { type: "string", enum: ["acquisition", "activation", "retention", "referral", "revenue", "engagement", "happiness", "task_success", "adoption", "other"], description: "AARRR or HEART category this metric belongs to" },
11665
- current_value: { type: "number", description: "Most recent observed value" },
11710
+ current_value: { type: "number", description: "Most recent observed value", modifier: "snapshot" },
11666
11711
  target_value: { type: "number", description: "Value we are aiming to reach" },
11667
11712
  unit: { type: "string", description: 'Display unit for the metric value (e.g. "%", "ms", "\xA3")' },
11668
11713
  range_min: { type: "number", description: "Minimum expected or baseline value" },
@@ -11760,11 +11805,11 @@ var UPG_PROPERTY_SCHEMA = {
11760
11805
  nps_campaign: {
11761
11806
  campaign_type: { type: "string", enum: ["relationship", "transactional", "feature"], description: "What triggers the NPS survey" },
11762
11807
  send_date: { type: "string", description: "Date the survey was sent (ISO format)" },
11763
- response_count: { type: "number", description: "Number of responses received" },
11764
- response_rate: { type: "number", description: "Percentage of recipients who responded" },
11808
+ response_count: { type: "number", description: "Number of responses received", modifier: "snapshot" },
11809
+ response_rate: { type: "number", description: "Percentage of recipients who responded", modifier: "snapshot" },
11765
11810
  score: { type: "number", description: "Net Promoter Score (-100 to 100)" },
11766
- promoters_pct: { type: "number", description: "Percentage of respondents who are promoters (9-10)" },
11767
- detractors_pct: { type: "number", description: "Percentage of respondents who are detractors (0-6)" }
11811
+ promoters_pct: { type: "number", description: "Percentage of respondents who are promoters (9-10)", modifier: "snapshot" },
11812
+ detractors_pct: { type: "number", description: "Percentage of respondents who are detractors (0-6)", modifier: "snapshot" }
11768
11813
  },
11769
11814
  // ObjectionProperties: Objection entity.
11770
11815
  objection: {
@@ -11806,46 +11851,11 @@ var UPG_PROPERTY_SCHEMA = {
11806
11851
  rotation_cadence: { type: "string", enum: ["daily", "weekly", "biweekly", "custom"], description: "Cycle cadence. `weekly` for standard team rotations. `daily` for high-incident-volume teams." },
11807
11852
  handoff_time: { type: "string", description: 'Shift handoff time. Affects team coordination and sleep. @example "09:00 UTC", "17:00 local"' }
11808
11853
  },
11809
- // OpportunityProperties: A problem worth solving, grounded in user need and business value
11810
- opportunity: {
11811
- reach: {
11812
- type: "assessment",
11813
- scale_id: "reach_5",
11814
- description: "How many users experience this problem. @deprecated 0.9.0:a framework-scoped scoring input, not an intrinsic property. Apply the `opportunity-sizing` framework; the value lives on the framework_exercise includes-edge. Removed in 0.9.1.",
11815
- properties: {
11816
- value: { type: "number", description: "The numeric value, used for computation." },
11817
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11818
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11819
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11820
- },
11821
- required: ["value", "label"]
11822
- },
11823
- frequency: {
11824
- type: "assessment",
11825
- scale_id: "frequency_5",
11826
- description: "How often users experience this problem. @deprecated 0.9.0:framework-scoped (opportunity-sizing). Removed in 0.9.1.",
11827
- properties: {
11828
- value: { type: "number", description: "The numeric value, used for computation." },
11829
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11830
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11831
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11832
- },
11833
- required: ["value", "label"]
11834
- },
11835
- pain: {
11836
- type: "assessment",
11837
- scale_id: "pain_5",
11838
- description: "How painful it is when unaddressed. @deprecated 0.9.0:framework-scoped (opportunity-sizing). Removed in 0.9.1.",
11839
- properties: {
11840
- value: { type: "number", description: "The numeric value, used for computation." },
11841
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11842
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11843
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11844
- },
11845
- required: ["value", "label"]
11846
- },
11847
- opportunity_score: { type: "number", description: "Computed: normalized_reach x normalized_frequency x normalized_pain (0-1). @deprecated 0.9.0:computed by the `opportunity-sizing` framework on its application edge, not stored on the entity. Removed in 0.9.1." }
11848
- },
11854
+ // OpportunityProperties: A problem worth solving, grounded in user need and business value.
11855
+ // No intrinsic scalar properties — defined by edges + framework-scoped scoring
11856
+ // (reach/frequency/pain/opportunity_score live on the `opportunity-sizing`
11857
+ // framework_exercise edge). Former props removed in 0.14.0 (UPG-574).
11858
+ opportunity: {},
11849
11859
  // OrganizationProperties: Organization entity.
11850
11860
  organization: {
11851
11861
  logo_url: { type: "string", description: "URL of the organisation's logo" },
@@ -11921,14 +11931,14 @@ var UPG_PROPERTY_SCHEMA = {
11921
11931
  paywall: {
11922
11932
  paywall_type: { type: "string", enum: ["hard", "soft", "metered", "freemium_gate"], description: "How restrictive the paywall is" },
11923
11933
  trigger: { type: "string", description: "User action or threshold that triggers the paywall" },
11924
- conversion_rate: { type: "number", description: "Percentage of users who convert at this paywall" }
11934
+ conversion_rate: { type: "number", description: "Percentage of users who convert at this paywall", modifier: "snapshot" }
11925
11935
  },
11926
11936
  // PenetrationTestProperties: Penetration test.
11927
11937
  penetration_test: {
11928
11938
  category: { type: "string", enum: ["external", "internal", "web_app", "api", "mobile"], description: "Test type" },
11929
11939
  scope: { type: "string", description: "Systems or features in scope" },
11930
- findings_count: { type: "number", description: "Total findings" },
11931
- critical_count: { type: "number", description: "Critical-severity findings" },
11940
+ findings_count: { type: "number", description: "Total findings", modifier: "derived" },
11941
+ critical_count: { type: "number", description: "Critical-severity findings", modifier: "derived" },
11932
11942
  start_date: { type: "string", description: "ISO start date" },
11933
11943
  end_date: { type: "string", description: "ISO end date" },
11934
11944
  report_url: { type: "string", description: "Full report URL" },
@@ -11959,7 +11969,7 @@ var UPG_PROPERTY_SCHEMA = {
11959
11969
  // PipelineStageProperties: Pipeline stage.
11960
11970
  pipeline_stage: {
11961
11971
  stage_order: { type: "number", description: "Position of this stage in the pipeline sequence" },
11962
- conversion_rate: { type: "number", description: "Percentage of deals that advance from this stage" },
11972
+ conversion_rate: { type: "number", description: "Percentage of deals that advance from this stage", modifier: "snapshot" },
11963
11973
  avg_days_in_stage: { type: "number", description: "Average number of days deals spend in this stage" }
11964
11974
  },
11965
11975
  // PlaybookProperties: Customer success playbook.
@@ -12184,7 +12194,7 @@ var UPG_PROPERTY_SCHEMA = {
12184
12194
  // ResearchStudyProperties: Structured user research activity.
12185
12195
  research_study: {
12186
12196
  method: { type: "string", enum: ["interview", "usability", "survey", "diary", "analytics"], description: "Research method used to conduct the study" },
12187
- participant_count: { type: "number", description: "Number of participants recruited or observed" },
12197
+ participant_count: { type: "number", description: "Number of participants recruited or observed", modifier: "snapshot" },
12188
12198
  start_date: { type: "string", description: "ISO date when the study starts" },
12189
12199
  end_date: { type: "string", description: "ISO date when the study ends" }
12190
12200
  },
@@ -12208,7 +12218,7 @@ var UPG_PROPERTY_SCHEMA = {
12208
12218
  recurring_revenue: { type: "number", description: "Monthly or annual recurring revenue from this stream" },
12209
12219
  billing_model: { type: "string", enum: ["subscription", "usage", "one_time", "tiered", "freemium", "other"], description: "Billing mechanics. May differ from `stream_type`." },
12210
12220
  recognition_basis: { type: "string", enum: ["accrual", "cash", "deferred"], description: "Accounting basis for revenue recognition" },
12211
- arr_contribution_pct: { type: "number", description: "Share of total ARR contributed (0\u2013100)" },
12221
+ arr_contribution_pct: { type: "number", description: "Share of total ARR contributed (0\u2013100)", modifier: "snapshot" },
12212
12222
  forecast: { type: "string", description: "Free-text forecast or projection" }
12213
12223
  },
12214
12224
  // ReviewGateProperties: Review gate.
@@ -12305,9 +12315,8 @@ var UPG_PROPERTY_SCHEMA = {
12305
12315
  cause_category: { type: "string", enum: ["code", "config", "process", "dependency", "data", "infrastructure", "human_error", "other"], description: "Closed-enum cause category for RCA reporting and dashboards. Distinct from the legacy free-form `category`." },
12306
12316
  cause_confidence: { type: "string", enum: ["hypothesised", "likely", "confirmed"], description: "Team certainty about this cause. `hypothesised` = educated guess. `likely` = evidence points here. `confirmed` = reproduced. Renamed from `confidence` in v0.4.0 to disambiguate from the entity-wide `UPGAssessment`-typed epistemic confidence used elsewhere. The 3-tier shape stays as a discrete RCA-lifecycle marker." },
12307
12317
  evidence_summary: { type: "string", description: "One-paragraph evidence summary. Log lines, traces, repro steps. Detailed artefacts go on linked `evidence` nodes." },
12308
- category: { type: "string", enum: ["architecture", "design", "data", "infrastructure", "process", "dependency", "other"], description: "Legacy free-form category. Retained for v0.2 baseline; new graphs prefer `cause_category`." },
12309
- affected_area: { type: "string", description: "Affected area of the system" },
12310
- verified: { type: "boolean", description: "Verified through investigation" }
12318
+ affected_area: { type: "string", description: "Affected area of the system" }
12319
+ // `category` (legacy, -> `cause_category`) and `verified` (= `cause_confidence === 'confirmed'`) removed in 0.14.0 (UPG-574).
12311
12320
  },
12312
12321
  // RunbookProperties: Runbook.
12313
12322
  runbook: {
@@ -12342,7 +12351,7 @@ var UPG_PROPERTY_SCHEMA = {
12342
12351
  security_audit: {
12343
12352
  audit_scope: { type: "string", description: "Systems or processes covered by the audit" },
12344
12353
  audit_status: { type: "string", enum: ["scheduled", "in_progress", "completed"], description: "Current progress of the audit" },
12345
- findings_count: { type: "number", description: "Total number of findings" },
12354
+ findings_count: { type: "number", description: "Total number of findings", modifier: "derived" },
12346
12355
  critical_findings: { type: "number", description: "Number of critical-severity findings" }
12347
12356
  },
12348
12357
  // SecurityControlProperties: Security control.
@@ -12387,7 +12396,7 @@ var UPG_PROPERTY_SCHEMA = {
12387
12396
  search_volume: { type: "number", description: "Estimated monthly search volume" },
12388
12397
  difficulty: { type: "number", description: "Keyword difficulty score (0-100)" },
12389
12398
  intent: { type: "string", enum: ["informational", "navigational", "commercial", "transactional"], description: "Search intent behind the keyword" },
12390
- current_rank: { type: "number", description: "Current SERP ranking position" },
12399
+ current_rank: { type: "number", description: "Current SERP ranking position", modifier: "snapshot" },
12391
12400
  target_rank: { type: "number", description: "Desired ranking position" }
12392
12401
  },
12393
12402
  // ServiceProperties: Service or microservice.
@@ -12431,7 +12440,7 @@ var UPG_PROPERTY_SCHEMA = {
12431
12440
  service_level_objective: {
12432
12441
  target_percentage: { type: "number", description: "Target percentage. The reliability commitment. @example 99.9 (three nines), 99.95, 99.99 (four nines)" },
12433
12442
  window: { type: "string", description: 'Evaluation window. @example "30 days", "rolling 28 days", "calendar quarter"' },
12434
- current_percentage: { type: "number", description: "Current achieved percentage. Compared against `target_percentage` for health. @example 99.92 (above a 99.9 target)" },
12443
+ current_percentage: { type: "number", description: "Current achieved percentage. Compared against `target_percentage` for health. @example 99.92 (above a 99.9 target)", modifier: "snapshot" },
12435
12444
  slo_type: { type: "string", enum: ["metric", "monitor", "time_slice"], description: "Measurement mechanism. `metric` = ratio (good/total). `monitor` = monitor-based. `time_slice` = uptime windows." },
12436
12445
  warning_threshold: { type: "number", description: "Soft alert threshold before the target breaches. Gives teams time to act. @example 99.95 (warn at 99.95% when target is 99.9%)" }
12437
12446
  },
@@ -12460,58 +12469,12 @@ var UPG_PROPERTY_SCHEMA = {
12460
12469
  post_type: { type: "string", enum: ["text", "image", "video", "carousel", "story"], description: "Format of the post" },
12461
12470
  scheduled_date: { type: "string", description: "Date the post is scheduled to publish (ISO format)" }
12462
12471
  },
12463
- // SolutionProperties: A proposed response to an opportunity
12472
+ // SolutionProperties: A proposed response to an opportunity.
12473
+ // RICE scoring inputs (reach/impact/confidence/effort) + computed rice_score
12474
+ // were framework-scoped from 0.9.0 and removed in 0.14.0 (UPG-574): they live
12475
+ // on the `rice-scoring` framework_exercise edge, not the entity.
12464
12476
  solution: {
12465
- timeline: { type: "string", description: "Estimated delivery or target timeline" },
12466
- reach: {
12467
- type: "assessment",
12468
- scale_id: "reach_5",
12469
- description: "How many users this solution reaches (1 = few, 5 = most). @deprecated 0.9.0:a framework-scoped scoring input, not an intrinsic property. Apply the `rice-scoring` framework; the value lives on the framework_exercise includes-edge. Removed in 0.9.1.",
12470
- properties: {
12471
- value: { type: "number", description: "The numeric value, used for computation." },
12472
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
12473
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
12474
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
12475
- },
12476
- required: ["value", "label"]
12477
- },
12478
- impact: {
12479
- type: "assessment",
12480
- scale_id: "impact_5",
12481
- description: "Expected impact on the target outcome (1 = minimal, 5 = transformative). @deprecated 0.9.0:framework-scoped (rice-scoring). Removed in 0.9.1.",
12482
- properties: {
12483
- value: { type: "number", description: "The numeric value, used for computation." },
12484
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
12485
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
12486
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
12487
- },
12488
- required: ["value", "label"]
12489
- },
12490
- confidence: {
12491
- type: "assessment",
12492
- scale_id: "confidence_5",
12493
- description: "How confident the team is in this solution (1 = speculative, 5 = proven). @deprecated 0.9.0:framework-scoped (rice-scoring). Removed in 0.9.1.",
12494
- properties: {
12495
- value: { type: "number", description: "The numeric value, used for computation." },
12496
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
12497
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
12498
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
12499
- },
12500
- required: ["value", "label"]
12501
- },
12502
- effort: {
12503
- type: "assessment",
12504
- scale_id: "effort_5",
12505
- description: "Level of effort required to implement (1 = trivial, 5 = very large). @deprecated 0.9.0:effort is a framework-scoped scoring input (it varies by assessor and method), not an intrinsic property. Removed in 0.9.1.",
12506
- properties: {
12507
- value: { type: "number", description: "The numeric value, used for computation." },
12508
- label: { type: "string", description: "The qualitative label (what the assessor meant)." },
12509
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
12510
- normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
12511
- },
12512
- required: ["value", "label"]
12513
- },
12514
- rice_score: { type: "number", description: "Computed: (reach \xD7 impact \xD7 confidence) / effort. @deprecated 0.9.0:computed by the `rice-scoring` framework on its application edge, not stored on the entity. Removed in 0.9.1." }
12477
+ timeline: { type: "string", description: "Estimated delivery or target timeline" }
12515
12478
  },
12516
12479
  // SpecificationProperties: A governed specification: a query language, protocol, data format, encoding,
12517
12480
  specification: {
@@ -12579,7 +12542,7 @@ var UPG_PROPERTY_SCHEMA = {
12579
12542
  },
12580
12543
  // SubscriptionProperties: Subscription.
12581
12544
  subscription: {
12582
- monthly_recurring_revenue: { type: "number", description: "Monthly recurring revenue from this subscription" },
12545
+ monthly_recurring_revenue: { type: "number", description: "Monthly recurring revenue from this subscription", modifier: "snapshot" },
12583
12546
  start_date: { type: "string", description: "Subscription start date (ISO format)" },
12584
12547
  renewal_date: { type: "string", description: "Next renewal date (ISO format)" },
12585
12548
  subscription_status: { type: "string", enum: ["active", "trialing", "past_due", "cancelled", "paused"], description: "Current status of the subscription" }
@@ -12613,8 +12576,8 @@ var UPG_PROPERTY_SCHEMA = {
12613
12576
  },
12614
12577
  // SurveyResponseProperties: Aggregated survey response data.
12615
12578
  survey_response: {
12616
- response_count: { type: "number", description: "Total responses" },
12617
- completion_rate: { type: "number", description: "Completion (0\u20131)" },
12579
+ response_count: { type: "number", description: "Total responses", modifier: "snapshot" },
12580
+ completion_rate: { type: "number", description: "Completion (0\u20131)", modifier: "snapshot" },
12618
12581
  method: { type: "string", enum: ["email", "in_app", "phone", "other"], description: "Distribution method" }
12619
12582
  },
12620
12583
  // SwitchingCostProperties: SwitchingCost entity.
@@ -12650,7 +12613,7 @@ var UPG_PROPERTY_SCHEMA = {
12650
12613
  },
12651
12614
  required: ["value", "label"]
12652
12615
  },
12653
- frequency_count: { type: "number", description: "Exact observation count in the period. Pairs with `frequency_period` for a precise rate." },
12616
+ frequency_count: { type: "number", description: "Exact observation count in the period. Pairs with `frequency_period` for a precise rate.", modifier: "snapshot" },
12654
12617
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`). @example 'P7D' (per week), 'P1D' (per day), 'PT1H' (per hour)" },
12655
12618
  frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative frequency tier. Canonical replacement for the legacy `'once' | 'sporadic' | 'frequent' | 'constant' | string` shape. Use when an exact rate is unknown. Migration: `once \u2192 rare`, `sporadic \u2192 occasional`, `frequent \u2192 regular`, `constant \u2192 constant`." },
12656
12619
  affected_users_estimate: { type: "number", description: "Approximate count of users affected. Snapshot estimate." },
@@ -12669,8 +12632,8 @@ var UPG_PROPERTY_SCHEMA = {
12669
12632
  effort: { type: "string", description: 'Effort estimate (e.g. "2h", "1d", "3 points"). Use a consistent unit within your team.' },
12670
12633
  priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Relative importance against other tasks" },
12671
12634
  due_date: { type: "string", description: "ISO date due. Typically bounded by the containing story's due date." },
12672
- labels: { type: "string[]", description: "Free-form classification tags. Applied uniformly across work item types." },
12673
- estimate: { type: "string", description: 'Story-point or sizing estimate. String to support fibonacci, t-shirt sizes, or custom scales (e.g. "5", "M", "3 pts"). Absorbed from `StoryTaskProperties` when `story_task` collapsed into `task` (v0.4.0).' }
12635
+ labels: { type: "string[]", description: "Free-form classification tags. Applied uniformly across work item types." }
12636
+ // `estimate` (story_task collapse relic, duplicated `effort`) removed in 0.14.0 (UPG-574).
12674
12637
  },
12675
12638
  // TeamProperties: Team entity.
12676
12639
  team: {
@@ -12774,13 +12737,13 @@ var UPG_PROPERTY_SCHEMA = {
12774
12737
  // TestSuiteProperties: Test suite.
12775
12738
  test_suite: {
12776
12739
  suite_type: { type: "string", enum: ["unit", "integration", "e2e", "performance", "security", "accessibility"], description: "Category of test suite" },
12777
- test_count: { type: "number", description: "Number of tests in the suite" },
12778
- pass_rate: { type: "number", description: "Percentage of tests passing (0-100)" },
12740
+ test_count: { type: "number", description: "Number of tests in the suite", modifier: "derived" },
12741
+ pass_rate: { type: "number", description: "Percentage of tests passing (0-100)", modifier: "snapshot" },
12779
12742
  last_run: { type: "string", description: "ISO date of last execution" },
12780
12743
  total_duration_ms: { type: "number", description: "Total execution time for the last run, in milliseconds" },
12781
- failed_count: { type: "number", description: "Number of tests that failed in the last run" },
12782
- skipped_count: { type: "number", description: "Number of tests that were skipped in the last run" },
12783
- flaky_count: { type: "number", description: "Number of tests that passed only on retry (flaky) in the last run" }
12744
+ failed_count: { type: "number", description: "Number of tests that failed in the last run", modifier: "snapshot" },
12745
+ skipped_count: { type: "number", description: "Number of tests that were skipped in the last run", modifier: "snapshot" },
12746
+ flaky_count: { type: "number", description: "Number of tests that passed only on retry (flaky) in the last run", modifier: "snapshot" }
12784
12747
  },
12785
12748
  // ThreatProperties: Threat.
12786
12749
  threat: {
@@ -12820,7 +12783,7 @@ var UPG_PROPERTY_SCHEMA = {
12820
12783
  scope: { type: "string", description: 'What system, feature, or data flow is being analysed. @example "user authentication", "payment processing", "admin API"' },
12821
12784
  last_reviewed: { type: "string", description: 'ISO date last reviewed. Models become stale as systems evolve. @example "2026-03-01"' },
12822
12785
  participants: { type: "string", description: 'Participants in the exercise. @example "Alice Chen (security lead), Bob Park (backend engineer), Carol Liu (architect)". Promote individuals to `node_owned_by_person` edges if participation must be queryable.' },
12823
- threat_count: { type: "number", description: "Threats identified. Key metric for scope and completeness. @example 12" }
12786
+ threat_count: { type: "number", description: "Threats identified. Key metric for scope and completeness. @example 12", modifier: "derived" }
12824
12787
  },
12825
12788
  // TouchpointProperties: Customer touchpoint.
12826
12789
  touchpoint: {
@@ -12844,14 +12807,14 @@ var UPG_PROPERTY_SCHEMA = {
12844
12807
  trial_config: {
12845
12808
  trial_type: { type: "string", enum: ["time_limited", "feature_limited", "usage_limited", "reverse"], description: "How the trial is limited" },
12846
12809
  duration_days: { type: "number", description: "Length of the trial period in days" },
12847
- conversion_rate: { type: "number", description: "Percentage of trial users who convert to paid" }
12810
+ conversion_rate: { type: "number", description: "Percentage of trial users who convert to paid", modifier: "snapshot" }
12848
12811
  },
12849
12812
  // TutorialProperties: Tutorial.
12850
12813
  tutorial: {
12851
12814
  tutorial_format: { type: "string", enum: ["written", "video", "interactive", "code_along"], description: "Delivery format of the tutorial" },
12852
12815
  difficulty: { type: "string", enum: ["beginner", "intermediate", "advanced"], description: "Skill level required to follow the tutorial" },
12853
12816
  duration_minutes: { type: "number", description: "Estimated time to complete in minutes" },
12854
- completion_rate: { type: "number", description: "Percentage of users who complete the tutorial" }
12817
+ completion_rate: { type: "number", description: "Percentage of users who complete the tutorial", modifier: "snapshot" }
12855
12818
  },
12856
12819
  // UnitEconomicsProperties: UnitEconomics.
12857
12820
  unit_economics: {
@@ -12862,7 +12825,7 @@ var UPG_PROPERTY_SCHEMA = {
12862
12825
  },
12863
12826
  // UserAdvisoryBoardProperties: User advisory board.
12864
12827
  user_advisory_board: {
12865
- member_count: { type: "number", description: "Number of members on the board" },
12828
+ member_count: { type: "number", description: "Number of members on the board", modifier: "snapshot" },
12866
12829
  meeting_cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "How often the board meets. Uses the shared `Cadence` scale." },
12867
12830
  board_focus: { type: "string", description: "Primary topic or area the board advises on" }
12868
12831
  },
@@ -12944,9 +12907,9 @@ var UPG_PROPERTY_SCHEMA = {
12944
12907
  // WalkthroughProperties: Product walkthrough.
12945
12908
  walkthrough: {
12946
12909
  walkthrough_type: { type: "string", enum: ["product_tour", "feature_intro", "tooltip_sequence", "checklist"], description: "Format of the in-product walkthrough" },
12947
- step_count: { type: "number", description: "Number of steps in the walkthrough" },
12910
+ step_count: { type: "number", description: "Number of steps in the walkthrough", modifier: "derived" },
12948
12911
  trigger: { type: "string", description: "User action or event that starts the walkthrough" },
12949
- completion_rate: { type: "number", description: "Percentage of users who complete the walkthrough" }
12912
+ completion_rate: { type: "number", description: "Percentage of users who complete the walkthrough", modifier: "snapshot" }
12950
12913
  },
12951
12914
  // WebinarProperties: Webinar.
12952
12915
  webinar: {
@@ -12999,7 +12962,7 @@ var UPG_PROPERTY_SCHEMA = {
12999
12962
  purpose: { type: "string", description: "Free-text description. Pairs with the closed-enum `workspace_purpose`." },
13000
12963
  workspace_purpose: { type: "string", enum: ["discovery", "planning", "retrospective", "design", "research", "strategy", "general"], description: "Closed-enum classifier. Drives template suggestions and surfaces in workspace browsers. `discovery` = persona/job/opportunity exploration. `planning` = roadmap and decision sessions. `retrospective` = reflection on shipped work. `design` = experience or UI exploration. `research` = organising study data and synthesis. `strategy` = high-level direction setting. `general` = catch-all." },
13001
12964
  owner: { type: "string", description: "Workspace owner (handle or email). Display label; canonical owner is `team_owns_workspace` or `persona_owns_workspace`." },
13002
- member_count: { type: "number", description: "Snapshot count. `team_works_in_workspace` edges are the source of truth." },
12965
+ member_count: { type: "number", description: "Snapshot count. `team_works_in_workspace` edges are the source of truth.", modifier: "derived" },
13003
12966
  archived: { type: "boolean", description: "Archived. Archived workspaces remain queryable but hidden from default views." },
13004
12967
  archived_at: { type: "string", description: "ISO timestamp archived. Pairs with `archived === true`." },
13005
12968
  icon: { type: "string", description: "Display icon (emoji or icon name)" }
@@ -29320,7 +29283,7 @@ function isCanonical(text) {
29320
29283
  }
29321
29284
 
29322
29285
  // src/index.ts
29323
- var UPG_VERSION = "0.13.1";
29286
+ var UPG_VERSION = "0.14.0";
29324
29287
  var UPG_FORMAT_VERSION = "0.4.0";
29325
29288
  var MARKDOWN_FORMAT_VERSION = "0.1";
29326
29289
  var UPG_TYPES = getTypes();