@unified-product-graph/core 0.7.5 → 0.8.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.cjs CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  OPERATIONS_TEAM_RITUALS_PLAYBOOK: () => OPERATIONS_TEAM_RITUALS_PLAYBOOK,
44
44
  PRODUCT_DELIVERY_PLAYBOOK: () => PRODUCT_DELIVERY_PLAYBOOK,
45
45
  PRODUCT_FEEDBACK_SYNTHESIS_PLAYBOOK: () => PRODUCT_FEEDBACK_SYNTHESIS_PLAYBOOK,
46
+ PROPERTY_SCALE_MAP: () => PROPERTY_SCALE_MAP,
46
47
  REFLECT_MODES: () => REFLECT_MODES,
47
48
  STRATEGY_OUTCOMES_PLAYBOOK: () => STRATEGY_OUTCOMES_PLAYBOOK,
48
49
  UPG_ACTIVE_TYPES: () => UPG_ACTIVE_TYPES,
@@ -143,6 +144,7 @@ __export(index_exports, {
143
144
  getMigrationMap: () => getMigrationMap,
144
145
  getPlaybookById: () => getPlaybookById,
145
146
  getPlaybooksForRegion: () => getPlaybooksForRegion,
147
+ getPropertiesForScale: () => getPropertiesForScale,
146
148
  getPropertyDefaultScale: () => getPropertyDefaultScale,
147
149
  getPropertyMigrations: () => getPropertyMigrations,
148
150
  getPropertySchema: () => getPropertySchema,
@@ -6358,20 +6360,42 @@ var PROPERTY_SCALE_MAP = {
6358
6360
  // discovery, users, feedback
6359
6361
  // ── Severity ─────────────────────────────────────────────────────────────
6360
6362
  severity: "severity_5",
6361
- // users, engineering, ai, gtm, customer-success
6363
+ // users, engineering, ai, gtm, customer-success, security, accessibility
6362
6364
  severity_of_finding: "severity_5",
6363
6365
  // validation/experiment_run
6366
+ bug_severity: "severity_5",
6367
+ // product-spec/bug (UPG-579 Option C collapse)
6368
+ risk_level: "severity_5",
6369
+ // compliance/risk (UPG-579 Option B)
6370
+ scarcity_risk: "severity_5",
6371
+ // market-intelligence (UPG-579 Option B)
6364
6372
  // ── Pain ─────────────────────────────────────────────────────────────────
6365
6373
  pain: "pain_5",
6366
6374
  // discovery
6375
+ pain_score: "pain_5",
6376
+ // user (UPG-579 Option B)
6377
+ friction_score: "pain_5",
6378
+ // growth/ux (UPG-579 Option B)
6367
6379
  // ── Impact ───────────────────────────────────────────────────────────────
6368
6380
  impact: "impact_5",
6369
6381
  // discovery, market, security, compliance
6370
6382
  projected_impact: "impact_5",
6371
6383
  // validation/experiment_plan
6384
+ revenue_impact: "impact_5",
6385
+ // sales/business-model (UPG-579 Option B)
6386
+ effectiveness: "impact_5",
6387
+ // security/marketing (UPG-579 Option B)
6388
+ opportunity_score: "impact_5",
6389
+ // discovery/opportunity (UPG-579 Option B)
6372
6390
  // ── Confidence ───────────────────────────────────────────────────────────
6373
6391
  confidence: "confidence_5",
6374
6392
  // discovery, validation, sales, product-spec
6393
+ current_confidence: "confidence_5",
6394
+ // validation/hypothesis (UPG-579 Option B)
6395
+ likelihood: "confidence_5",
6396
+ // market/risk (UPG-579 Option B)
6397
+ probability: "confidence_5",
6398
+ // sales/forecast (UPG-579 Option B)
6375
6399
  // ── Effort ───────────────────────────────────────────────────────────────
6376
6400
  effort: "effort_5",
6377
6401
  // discovery
@@ -6379,17 +6403,35 @@ var PROPERTY_SCALE_MAP = {
6379
6403
  // feedback
6380
6404
  effort_to_fix: "effort_5",
6381
6405
  // engineering
6406
+ cost_estimate: "effort_5",
6407
+ // validation/experiment_plan (UPG-579 Option B)
6382
6408
  // ── Importance ───────────────────────────────────────────────────────────
6383
6409
  importance: "importance_5",
6384
6410
  // users
6411
+ influence: "importance_5",
6412
+ // team-org/stakeholder (UPG-579 Option B)
6413
+ interest: "importance_5",
6414
+ // team-org/stakeholder (UPG-579 Option B)
6415
+ relevance: "importance_5",
6416
+ // market/content (UPG-579 Option B)
6417
+ weight: "importance_5",
6418
+ // validation/evidence (UPG-579 Option B)
6385
6419
  // ── Satisfaction ─────────────────────────────────────────────────────────
6386
- current_satisfaction: "satisfaction_5"
6420
+ current_satisfaction: "satisfaction_5",
6387
6421
  // users
6422
+ emotion_score: "satisfaction_5"
6423
+ // ux-design/customer-success journey (UPG-579 Option B)
6424
+ // Intentionally NOT mapped (resolve to the generic scale_5):
6425
+ // rarity : VRIO distinctiveness; no canonical named scale fits.
6426
+ // strength : deprecated (validation/evidence; superseded by weight).
6388
6427
  };
6389
6428
  var DEFAULT_SCALE_ID = "scale_5";
6390
6429
  function getPropertyDefaultScale(_entityType, propertyName) {
6391
6430
  return PROPERTY_SCALE_MAP[propertyName] ?? DEFAULT_SCALE_ID;
6392
6431
  }
6432
+ function getPropertiesForScale(scaleId) {
6433
+ return Object.entries(PROPERTY_SCALE_MAP).filter(([, id]) => id === scaleId).map(([property]) => property);
6434
+ }
6393
6435
 
6394
6436
  // src/grammar/enum-scales.ts
6395
6437
  var UPG_ENUM_SCALES = {
@@ -6475,6 +6517,159 @@ var UPG_ENUM_SCALES = {
6475
6517
  { value: "warning", label: "Warning", description: "Soft signal: should consider and address, but can override with justification." },
6476
6518
  { value: "guideline", label: "Guideline", description: "Recommendation: encouraged and expected in most cases, but not enforced." }
6477
6519
  ]
6520
+ },
6521
+ // ── ProxyConfidence ─────────────────────────────────────────────────
6522
+ ProxyConfidence: {
6523
+ id: "ProxyConfidence",
6524
+ label: "Proxy confidence",
6525
+ description: "How strongly a proxy metric predicts the direct measure it stands in for.",
6526
+ tone_direction: "high-is-good",
6527
+ values: [
6528
+ { value: "strong", label: "Strong", description: "Tracks the direct measure closely; a reliable stand-in." },
6529
+ { value: "moderate", label: "Moderate", description: "Correlates with the direct measure but with meaningful slippage." },
6530
+ { value: "weak", label: "Weak", description: "Loosely related; use with caution and corroborate." }
6531
+ ]
6532
+ },
6533
+ // ── CauseConfidence ─────────────────────────────────────────────────
6534
+ CauseConfidence: {
6535
+ id: "CauseConfidence",
6536
+ label: "Cause confidence",
6537
+ description: "Maturity of a root-cause determination during incident debugging: how far a proposed cause has been validated.",
6538
+ tone_direction: "high-is-good",
6539
+ values: [
6540
+ { value: "hypothesised", label: "Hypothesised", description: "A proposed cause, not yet tested against evidence." },
6541
+ { value: "likely", label: "Likely", description: "Supported by evidence but not conclusively proven." },
6542
+ { value: "confirmed", label: "Confirmed", description: "Verified as the cause; reproduced or otherwise established." }
6543
+ ]
6544
+ },
6545
+ // ── ComfortLevel ────────────────────────────────────────────────────
6546
+ ComfortLevel: {
6547
+ id: "ComfortLevel",
6548
+ label: "Comfort level",
6549
+ description: "A person's comfort with a tool, technology, or practice. Closed set so personas compare on the same axis across products.",
6550
+ tone_direction: "high-is-good",
6551
+ values: [
6552
+ { value: "low", label: "Low", description: "Little or no familiarity; needs guidance to proceed." },
6553
+ { value: "medium", label: "Medium", description: "Functional, everyday competence." },
6554
+ { value: "high", label: "High", description: "Confident, fluent use without assistance." },
6555
+ { value: "expert", label: "Expert", description: "Deep mastery; can teach others or extend the tool." },
6556
+ { value: "other", label: "Other", description: "A comfort profile not captured by the above tiers." }
6557
+ ]
6558
+ },
6559
+ // ── LogLevel ────────────────────────────────────────────────────────
6560
+ LogLevel: {
6561
+ id: "LogLevel",
6562
+ label: "Log level",
6563
+ description: "Operational verbosity of a monitor or alert signal. How loud the signal should be, not how bad an outcome is for the user (kept distinct from severity_5).",
6564
+ tone_direction: "low-is-good",
6565
+ values: [
6566
+ { value: "critical", label: "Critical", description: "Page immediately; the signal is service-affecting." },
6567
+ { value: "warning", label: "Warning", description: "Needs attention soon; not yet service-affecting." },
6568
+ { value: "info", label: "Info", description: "Informational; no action required." }
6569
+ ]
6570
+ },
6571
+ // ── IncidentSeverity ────────────────────────────────────────────────
6572
+ IncidentSeverity: {
6573
+ id: "IncidentSeverity",
6574
+ label: "Incident severity",
6575
+ description: "Paging-tier classification of an incident, driving escalation and response process. Distinct from user-impact severity_5 and from LogLevel.",
6576
+ tone_direction: "low-is-good",
6577
+ values: [
6578
+ { value: "sev1", label: "SEV1", description: "Critical outage; full response, executive-visible." },
6579
+ { value: "sev2", label: "SEV2", description: "Major degradation; urgent response." },
6580
+ { value: "sev3", label: "SEV3", description: "Minor or partial impact; handled within hours." },
6581
+ { value: "sev4", label: "SEV4", description: "Negligible impact; routine handling." }
6582
+ ]
6583
+ },
6584
+ // ── SignalSentiment ─────────────────────────────────────────────────
6585
+ SignalSentiment: {
6586
+ id: "SignalSentiment",
6587
+ label: "Signal sentiment",
6588
+ description: "Sentiment polarity of an inbound signal (feedback, support, customer).",
6589
+ tone_direction: "high-is-good",
6590
+ values: [
6591
+ { value: "positive", label: "Positive", description: "Favourable signal; satisfaction or advocacy." },
6592
+ { value: "neutral", label: "Neutral", description: "No clear positive or negative lean." },
6593
+ { value: "negative", label: "Negative", description: "Unfavourable signal; dissatisfaction or risk." },
6594
+ { value: "mixed", label: "Mixed", description: "Contains both positive and negative elements." }
6595
+ ]
6596
+ },
6597
+ // ── MaturityLevel ───────────────────────────────────────────────────
6598
+ MaturityLevel: {
6599
+ id: "MaturityLevel",
6600
+ label: "Maturity level",
6601
+ description: "Capability or process maturity on the CMMI ladder.",
6602
+ tone_direction: "high-is-good",
6603
+ values: [
6604
+ { value: "initial", label: "Initial", description: "Ad hoc and unpredictable; little process." },
6605
+ { value: "developing", label: "Developing", description: "Basic process emerging but inconsistent." },
6606
+ { value: "defined", label: "Defined", description: "Documented, standardised process in place." },
6607
+ { value: "managed", label: "Managed", description: "Measured and controlled against objectives." },
6608
+ { value: "optimizing", label: "Optimizing", description: "Continuous, data-driven improvement." }
6609
+ ]
6610
+ },
6611
+ // ── ConformanceLevel ────────────────────────────────────────────────
6612
+ ConformanceLevel: {
6613
+ id: "ConformanceLevel",
6614
+ label: "Conformance level",
6615
+ description: "WCAG accessibility conformance level.",
6616
+ tone_direction: "high-is-good",
6617
+ values: [
6618
+ { value: "A", label: "A", description: "Minimum conformance; essential barriers removed." },
6619
+ { value: "AA", label: "AA", description: "Addresses the most common barriers; the usual legal target." },
6620
+ { value: "AAA", label: "AAA", description: "Highest level; not achievable for all content." }
6621
+ ]
6622
+ },
6623
+ // ── DataSensitivity ─────────────────────────────────────────────────
6624
+ DataSensitivity: {
6625
+ id: "DataSensitivity",
6626
+ label: "Data sensitivity",
6627
+ description: "Data classification tier governing handling and access.",
6628
+ tone_direction: "neutral",
6629
+ values: [
6630
+ { value: "public", label: "Public", description: "No restriction; safe to disclose openly." },
6631
+ { value: "internal", label: "Internal", description: "For internal use; not for external release." },
6632
+ { value: "confidential", label: "Confidential", description: "Sensitive; restricted to a need-to-know basis." },
6633
+ { value: "restricted", label: "Restricted", description: "Highly sensitive; strict controls and auditing." }
6634
+ ]
6635
+ },
6636
+ // ── DifficultyLevel ─────────────────────────────────────────────────
6637
+ DifficultyLevel: {
6638
+ id: "DifficultyLevel",
6639
+ label: "Difficulty level",
6640
+ description: "Learner difficulty tier for educational content.",
6641
+ tone_direction: "neutral",
6642
+ values: [
6643
+ { value: "beginner", label: "Beginner", description: "No prior knowledge assumed." },
6644
+ { value: "intermediate", label: "Intermediate", description: "Assumes working familiarity with the basics." },
6645
+ { value: "advanced", label: "Advanced", description: "Assumes deep, expert-level background." }
6646
+ ]
6647
+ },
6648
+ // ── FrequencyRating ─────────────────────────────────────────────────
6649
+ FrequencyRating: {
6650
+ id: "FrequencyRating",
6651
+ label: "Frequency rating",
6652
+ description: "Qualitative how-often rating. Distinct from the numeric frequency_5 scale and from Cadence calendar tiers.",
6653
+ tone_direction: "neutral",
6654
+ values: [
6655
+ { value: "constant", label: "Constant", description: "Effectively always; continuous occurrence." },
6656
+ { value: "regular", label: "Regular", description: "Happens on a predictable, recurring basis." },
6657
+ { value: "occasional", label: "Occasional", description: "Happens sometimes, without a fixed pattern." },
6658
+ { value: "rare", label: "Rare", description: "Happens infrequently." },
6659
+ { value: "other", label: "Other", description: "A frequency not captured by the above tiers." }
6660
+ ]
6661
+ },
6662
+ // ── EvidenceDirection ───────────────────────────────────────────────
6663
+ EvidenceDirection: {
6664
+ id: "EvidenceDirection",
6665
+ label: "Evidence direction",
6666
+ description: "Direction of evidence relative to a claim. Distinct from confidence_impact (strengthens/weakens) per the UPG-579 polysemy verdicts.",
6667
+ tone_direction: "neutral",
6668
+ values: [
6669
+ { value: "supports", label: "Supports", description: "The evidence backs the claim." },
6670
+ { value: "refutes", label: "Refutes", description: "The evidence contradicts the claim." },
6671
+ { value: "neutral", label: "Neutral", description: "The evidence is inconclusive either way." }
6672
+ ]
6478
6673
  }
6479
6674
  };
6480
6675
  function getEnumScale(name) {
@@ -6821,6 +7016,41 @@ function getDeprecatedTypes() {
6821
7016
  return deprecated;
6822
7017
  }
6823
7018
  var UPG_PROPERTY_MIGRATIONS = {
7019
+ // ── v0.8.0: UPG-574 deprecated-property removal pass ───────────────────
7020
+ //
7021
+ // The seven properties tagged `@deprecated since v0.4.0` that survived the
7022
+ // v0.5.0 hygiene pass are removed from the spec in v0.8.0 (a breaking
7023
+ // release). Five of the seven already carry a migration:
7024
+ // - `task.task_status` / `bug.bug_status` lift to `UPGBaseNode.status`
7025
+ // (see `UPG_PROPERTY_MIGRATIONS['0.4.0']`, values identical).
7026
+ // - `learning.metric` drops in favour of the `learning_observed_on_metric`
7027
+ // edge (see `UPG_PROPERTY_MIGRATIONS['0.5.0']`).
7028
+ // The two remaining property surfaces are migrated here:
7029
+ // - `evidence.strength` (simple `strong | moderate | weak` enum) is
7030
+ // dropped in favour of `weight: UPGAssessment` (scale `weight_5pt`).
7031
+ // Authors carrying the legacy key should copy the value to `weight`
7032
+ // before applying this migration: `strong → 5`, `moderate → 3`,
7033
+ // `weak → 1`, with the old word preserved in `weight.label`.
7034
+ // - `story_task.estimate` / `.effort` / `.priority` drop. `story_task`
7035
+ // itself is deprecated (`UPG_MIGRATIONS['0.4.0']` renames it to the
7036
+ // canonical `task`); the type rename copies every property verbatim,
7037
+ // so the values survive on `task` (`TaskProperties.estimate` /
7038
+ // `.effort` / `.priority`, all live). This rule removes the residue
7039
+ // from any node still typed `story_task` at migration time.
7040
+ "0.8.0": [
7041
+ {
7042
+ kind: "drop_props",
7043
+ type: "evidence",
7044
+ drop_props: ["strength"],
7045
+ reason: "UPG-574 (v0.8.0). evidence.strength was `@deprecated since v0.4.0`; the structured `weight: UPGAssessment` (scale `weight_5pt`) replaces the `strong | moderate | weak` enum to align with the spec-wide scoring pattern. Authors should copy the value to `weight` before applying this migration (strong -> 5, moderate -> 3, weak -> 1; carry the old word in `weight.label`). The migration drops the residue."
7046
+ },
7047
+ {
7048
+ kind: "drop_props",
7049
+ type: "story_task",
7050
+ drop_props: ["estimate", "effort", "priority"],
7051
+ reason: 'UPG-574 (v0.8.0). story_task.estimate / .effort / .priority were `@deprecated since v0.4.0`; story_task itself is deprecated (UPG_MIGRATIONS["0.4.0"] renames it to canonical `task`, copying all properties verbatim), so the values survive on TaskProperties.estimate / .effort / .priority (all live). This rule removes the residue from any node still typed `story_task` at migration time.'
7052
+ }
7053
+ ],
6824
7054
  // ── v0.5.0: UPG-509 deprecation hygiene pass ───────────────────────────
6825
7055
  //
6826
7056
  // Properties tagged `@deprecated since="0.4.0" removeIn="0.5.0"` (and the
@@ -8624,7 +8854,18 @@ var UPG_PROPERTY_SCHEMA = {
8624
8854
  },
8625
8855
  // A11yIssueProperties: Accessibility issue.
8626
8856
  a11y_issue: {
8627
- severity: { type: "string", enum: ["minor", "moderate", "serious", "critical"], description: "Severity. Aligned to axe-core's 4-level impact scale (industry standard): 'minor' < 'moderate' < 'serious' < 'critical'. Migration: the previous 3-level scale ('critical' | 'major' | 'minor') maps to ('critical' | 'serious' | 'minor') respectively." },
8857
+ severity: {
8858
+ type: "assessment",
8859
+ scale_id: "severity_5",
8860
+ description: "Impact severity (UPGAssessment on the `severity_5` scale). Migrated from the inline axe-core 4-level enum (`minor|moderate|serious|critical`) (UPG-579 Option C): map `critical` -> 5, `serious` -> 4, `moderate` -> 3, `minor` -> 2; carry the old word in `label`.",
8861
+ properties: {
8862
+ value: { type: "number", description: "The numeric value, used for computation." },
8863
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
8864
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
8865
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
8866
+ },
8867
+ required: ["value", "label"]
8868
+ },
8628
8869
  wcag_criterion: { type: "string", description: 'WCAG success criterion violated (e.g. "1.1.1", "2.4.7")' },
8629
8870
  rule_id: { type: "string", description: "Identifier of the rule that flagged the issue" },
8630
8871
  help_url: { type: "string", description: "URL to documentation explaining the issue and how to fix it" },
@@ -8681,7 +8922,18 @@ var UPG_PROPERTY_SCHEMA = {
8681
8922
  affinity_cluster: {
8682
8923
  theme: { type: "string", description: "Emergent theme label" },
8683
8924
  child_observation_count: { type: "number", description: "Observations in this cluster" },
8684
- confidence: { type: "string", enum: ["high", "medium", "low"], description: "Confidence in the theme's validity" }
8925
+ confidence: {
8926
+ type: "assessment",
8927
+ scale_id: "confidence_5",
8928
+ description: "Confidence in the theme's validity (UPGAssessment on `confidence_5`).",
8929
+ properties: {
8930
+ value: { type: "number", description: "The numeric value, used for computation." },
8931
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
8932
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
8933
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
8934
+ },
8935
+ required: ["value", "label"]
8936
+ }
8685
8937
  },
8686
8938
  // AgentDefinitionProperties: Agent definition.
8687
8939
  agent_definition: {
@@ -8815,7 +9067,7 @@ var UPG_PROPERTY_SCHEMA = {
8815
9067
  // AlertRuleProperties: Alert rule.
8816
9068
  alert_rule: {
8817
9069
  condition: { type: "string", description: 'Triggering query or expression. @example "avg(rate(http_errors_total[5m])) > 0.05"' },
8818
- severity: { type: "string", enum: ["critical", "warning", "info"], description: "Routes notification and escalation. `critical` = page immediately. `warning` = notify, don't page. `info` = log only." },
9070
+ severity: { type: "string", enum: ["critical", "warning", "info"], description: "Routes notification and escalation. Uses the `LogLevel` scale (operational verbosity, distinct from user-impact `severity_5`). `critical` = page immediately. `warning` = notify, don't page. `info` = log only." },
8819
9071
  notification_channel: { type: "string", description: 'Notification destination. @example "pagerduty:sev1-rotation", "slack:#alerts-low"' },
8820
9072
  evaluation_window: { type: "string", description: 'Required duration the condition holds before firing. Prevents flapping on transient spikes. @example "5m", "15m", "1h"' },
8821
9073
  escalation_policy: { type: "string", description: 'Escalation behaviour on unacknowledged alerts. @example "Escalate to engineering lead after 10 minutes"' }
@@ -8854,16 +9106,28 @@ var UPG_PROPERTY_SCHEMA = {
8854
9106
  },
8855
9107
  // AssumptionProperties: Assumption entity.
8856
9108
  assumption: {
8857
- confidence: { type: "string", enum: ["high", "medium", "low"], description: "Confidence before testing. Independent of whether the assumption is validated (tracked in lifecycle)." },
9109
+ confidence: {
9110
+ type: "assessment",
9111
+ scale_id: "confidence_5",
9112
+ description: "Confidence before testing (UPGAssessment on `confidence_5`). Independent of whether the assumption is validated (tracked in lifecycle).",
9113
+ properties: {
9114
+ value: { type: "number", description: "The numeric value, used for computation." },
9115
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9116
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9117
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9118
+ },
9119
+ required: ["value", "label"]
9120
+ },
8858
9121
  validation_method: { type: "string", description: "Validation method, planned or used" },
8859
9122
  risk_level: {
8860
- type: "object",
9123
+ type: "assessment",
9124
+ scale_id: "severity_5",
8861
9125
  description: "Exposure if the assumption turns out wrong",
8862
9126
  properties: {
8863
9127
  value: { type: "number", description: "The numeric value, used for computation." },
8864
9128
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
8865
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
8866
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9129
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9130
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
8867
9131
  },
8868
9132
  required: ["value", "label"]
8869
9133
  },
@@ -8974,8 +9238,18 @@ var UPG_PROPERTY_SCHEMA = {
8974
9238
  },
8975
9239
  // BugProperties: Bug report.
8976
9240
  bug: {
8977
- bug_severity: { type: "string", enum: ["critical", "major", "minor", "trivial"], description: "Impact severity. Independent of priority (which governs when it gets fixed). `critical` = data loss or complete feature failure. `trivial` = cosmetic only." },
8978
- bug_status: { type: "string", enum: ["open", "in_progress", "fixed", "verified", "wont_fix"], description: "@deprecated since v0.4.0. Use top-level `UPGBaseNode.status`. Values map identically: open | in_progress | fixed | verified | wont_fix. Migration: `UPG_PROPERTY_MIGRATIONS['0.4.0']` lifts this to `status`." },
9241
+ bug_severity: {
9242
+ type: "assessment",
9243
+ scale_id: "severity_5",
9244
+ description: "Impact severity (UPGAssessment on the `severity_5` scale). Independent of priority (which governs when it gets fixed). Migrated from the inline `critical|major|minor|trivial` enum (UPG-579 Option C): map `critical` -> 5, `major` -> 4, `minor` -> 2, `trivial` -> 1; carry the old word in `label`.",
9245
+ properties: {
9246
+ value: { type: "number", description: "The numeric value, used for computation." },
9247
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9248
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9249
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9250
+ },
9251
+ required: ["value", "label"]
9252
+ },
8979
9253
  steps_to_reproduce: { type: "string", description: "Step-by-step reproduction" },
8980
9254
  environment: { type: "string", description: 'Observed environment (e.g. "prod", "staging", "iOS 17.4")' },
8981
9255
  priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Urgency relative to other work. Independent of `bug_severity` (a critical bug can have low priority if rare)." },
@@ -9005,7 +9279,7 @@ var UPG_PROPERTY_SCHEMA = {
9005
9279
  maturity_level: { type: "string", enum: ["initial", "developing", "defined", "managed", "optimizing"], description: "Current maturity" },
9006
9280
  target_maturity: { type: "string", enum: ["initial", "developing", "defined", "managed", "optimizing"], description: "Target maturity" },
9007
9281
  gap: { type: "string", description: "Gap between current and target" },
9008
- evolution_stage: { type: "string", enum: ["genesis", "custom", "product", "commodity"], description: 'Wardley evolution axis: where this capability sits on the genesis \u2192 custom \u2192 product \u2192 commodity spectrum. Used by frameworks like `wardley-map`; generally useful as a maturity-of-the-domain signal independent of `maturity_level` (which measures the team\'s internal capability practice). @example "product"' },
9282
+ evolution_stage: { type: "string", enum: ["genesis", "custom", "product", "commodity"], description: "Wardley evolution axis: where this capability sits on the genesis \u2192 custom \u2192 product \u2192 commodity spectrum. Used by frameworks like `wardley-map`; generally useful as a maturity-of-the-domain signal independent of `maturity_level` (which measures the team's internal capability practice). @example 'product'" },
9009
9283
  visibility: { type: "number", description: "Position on the visibility axis from `0.0` (deepest dependency, infra the user never sees) to `1.0` (user-visible anchor). Used by `wardley-map` for the y-axis position of each capability in the value chain. @example 0.8" }
9010
9284
  },
9011
9285
  // CapacityPlanProperties: CapacityPlan entity.
@@ -9018,7 +9292,7 @@ var UPG_PROPERTY_SCHEMA = {
9018
9292
  // CeremonyProperties: Ceremony entity.
9019
9293
  ceremony: {
9020
9294
  ceremony_type: { type: "string", enum: ["standup", "planning", "review", "retro", "sync", "demo", "other"], description: "Kind of recurring meeting" },
9021
- cadence: { type: "string", description: 'How often the ceremony occurs (e.g. "daily", "biweekly")' },
9295
+ cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "How often the ceremony occurs. Uses the shared `Cadence` scale." },
9022
9296
  duration_minutes: { type: "number", description: "Typical duration of the meeting in minutes" },
9023
9297
  participants: { type: "string", description: "People or roles who attend" }
9024
9298
  },
@@ -9047,9 +9321,9 @@ var UPG_PROPERTY_SCHEMA = {
9047
9321
  category: { type: "string", description: "High-level category of the churn reason" },
9048
9322
  frequency_count: { type: "number", description: "Exact count of times this reason has been cited in `frequency_period`" },
9049
9323
  frequency_period: { type: "string", description: "The recurrence period the count is measured over (ISO-8601 `Duration`, e.g. `'P30D'`)" },
9050
- frequency_rating: { type: "string", enum: ["rare", "occasional", "regular", "constant", "other"], description: "Qualitative frequency tier when an exact count is not known" },
9324
+ frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative frequency tier when an exact count is not known" },
9051
9325
  contributing_factors: { type: "string[]", description: "Other factors that contributed to the churn" },
9052
- signal_sentiment: { type: "string", enum: ["positive", "negative", "neutral", "mixed"], description: "Detected sentiment of the churn signal" },
9326
+ signal_sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Detected sentiment of the churn signal" },
9053
9327
  signal_channel: { type: "string", description: "Channel through which the churn signal was received" },
9054
9328
  signal_urgency: { type: "string", enum: ["low", "medium", "high", "critical"], description: "Urgency of the churn risk" }
9055
9329
  },
@@ -9163,7 +9437,7 @@ var UPG_PROPERTY_SCHEMA = {
9163
9437
  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'`." },
9164
9438
  frequency_count: { type: "number", description: "Exact count in the period. Pairs with `frequency_period`." },
9165
9439
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`, e.g. `'P7D'`)" },
9166
- frequency_rating: { type: "string", enum: ["rare", "occasional", "regular", "constant", "other"], description: "Qualitative rate tier when an exact rate is unknown" }
9440
+ frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative rate tier when an exact rate is unknown" }
9167
9441
  },
9168
9442
  // ContentPieceProperties: Content piece.
9169
9443
  content_piece: {
@@ -9178,7 +9452,7 @@ var UPG_PROPERTY_SCHEMA = {
9178
9452
  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'`." },
9179
9453
  frequency_count: { type: "number", description: "Exact count of publications in the period. Pairs with `frequency_period`." },
9180
9454
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`, e.g. `'P7D'`)" },
9181
- frequency_rating: { type: "string", enum: ["rare", "occasional", "regular", "constant", "other"], description: "Qualitative rate tier when an exact rate is unknown" }
9455
+ frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative rate tier when an exact rate is unknown" }
9182
9456
  },
9183
9457
  // ContentThemeProperties: Content theme.
9184
9458
  content_theme: {
@@ -9203,13 +9477,14 @@ var UPG_PROPERTY_SCHEMA = {
9203
9477
  clause_text: { type: "string", description: "Full text of the clause" },
9204
9478
  is_negotiable: { type: "boolean", description: "Whether this clause is open to negotiation" },
9205
9479
  risk_level: {
9206
- type: "object",
9480
+ type: "assessment",
9481
+ scale_id: "severity_5",
9207
9482
  description: "Risk level if the clause is accepted as-is (1 = negligible, 5 = severe exposure)",
9208
9483
  properties: {
9209
9484
  value: { type: "number", description: "The numeric value, used for computation." },
9210
9485
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9211
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9212
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9486
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9487
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9213
9488
  },
9214
9489
  required: ["value", "label"]
9215
9490
  }
@@ -9228,9 +9503,9 @@ var UPG_PROPERTY_SCHEMA = {
9228
9503
  // CustomerFeedbackProperties: Customer feedback.
9229
9504
  customer_feedback: {
9230
9505
  feedback_type: { type: "string", enum: ["survey", "interview", "review", "nps"], description: "How the feedback was collected" },
9231
- sentiment: { type: "string", enum: ["positive", "neutral", "negative"], description: "Overall sentiment of the feedback" },
9506
+ sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Overall sentiment of the feedback" },
9232
9507
  verbatim: { type: "string", description: "Exact words from the customer" },
9233
- signal_sentiment: { type: "string", enum: ["positive", "negative", "neutral", "mixed"], description: "Detected sentiment of the underlying signal" },
9508
+ signal_sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Detected sentiment of the underlying signal" },
9234
9509
  signal_channel: { type: "string", description: "Channel through which the signal was received" },
9235
9510
  signal_urgency: { type: "string", enum: ["low", "medium", "high", "critical"], description: "Perceived urgency of the feedback" }
9236
9511
  },
@@ -9259,7 +9534,7 @@ var UPG_PROPERTY_SCHEMA = {
9259
9534
  url: { type: "string", description: "URL to the live dashboard" },
9260
9535
  audience: { type: "string", description: "Intended audience for this dashboard" },
9261
9536
  element_count: { type: "number", description: "Number of widgets or panels on the dashboard" },
9262
- refresh_cadence: { type: "string", description: "How often the dashboard data refreshes" },
9537
+ 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." },
9263
9538
  filter_count: { type: "number", description: "Number of user-configurable filters" }
9264
9539
  },
9265
9540
  // DataClassificationProperties: Data classification.
@@ -9319,7 +9594,7 @@ var UPG_PROPERTY_SCHEMA = {
9319
9594
  },
9320
9595
  // DataProductProperties: DataProduct entity.
9321
9596
  data_product: {
9322
- data_product_type: { type: "string", description: 'Classification of the data product (e.g. "report", "dataset", "stream")' },
9597
+ data_product_type: { type: "string", enum: ["report", "dataset", "stream", "api", "ml_feature", "other"], description: "Classification of the data product (UPG-579 Option B)." },
9323
9598
  sla_freshness: { type: "string", description: 'Freshness SLA commitment (e.g. "< 1 hour")' }
9324
9599
  },
9325
9600
  // DataQualityRuleProperties: DataQualityRule entity.
@@ -9336,7 +9611,7 @@ var UPG_PROPERTY_SCHEMA = {
9336
9611
  data_source: {
9337
9612
  source_type: { type: "string", enum: ["database", "api", "event_stream", "warehouse"], description: "Kind of data source" },
9338
9613
  connection_status: { type: "string", enum: ["connected", "disconnected", "error"], description: "Current connection health" },
9339
- refresh_cadence: { type: "string", description: 'How often the data is refreshed (e.g. "hourly", "daily")' }
9614
+ refresh_cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "How often the data is refreshed. Uses the shared `Cadence` scale." }
9340
9615
  },
9341
9616
  // DatabaseSchemaProperties: Database schema.
9342
9617
  database_schema: {
@@ -9367,7 +9642,7 @@ var UPG_PROPERTY_SCHEMA = {
9367
9642
  },
9368
9643
  // DeliverableProperties: Deliverable.
9369
9644
  deliverable: {
9370
- deliverable_type: { type: "string", description: 'Kind of deliverable (e.g. "document", "prototype", "release")' },
9645
+ deliverable_type: { type: "string", enum: ["document", "prototype", "release", "design", "report", "other"], description: "Kind of deliverable (UPG-579 Option B)." },
9371
9646
  due_date: { type: "string", description: "Due date for the deliverable (ISO format)" },
9372
9647
  deliverable_status: { type: "string", enum: ["not_started", "in_progress", "in_review", "accepted", "rejected"], description: "Current progress status" },
9373
9648
  acceptance_criteria: { type: "string", description: "Criteria that must be met for the deliverable to be accepted" }
@@ -9445,7 +9720,18 @@ var UPG_PROPERTY_SCHEMA = {
9445
9720
  target_domain: { type: "string", enum: ["ux", "visual", "interaction", "content", "accessibility", "other"], description: "Target design discipline" },
9446
9721
  framing: { type: "string", enum: ["how_might_we", "what_if", "why_do", "how_do", "what_prevents", "other"], description: "Question framing template" },
9447
9722
  priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Importance against other backlog questions" },
9448
- confidence: { type: "string", enum: ["high", "medium", "low"], description: "Confidence the question is well-framed. Distinct from confidence in any answer." },
9723
+ confidence: {
9724
+ type: "assessment",
9725
+ scale_id: "confidence_5",
9726
+ description: "Confidence the question is well-framed (UPGAssessment on `confidence_5`). Distinct from confidence in any answer.",
9727
+ properties: {
9728
+ value: { type: "number", description: "The numeric value, used for computation." },
9729
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9730
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9731
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9732
+ },
9733
+ required: ["value", "label"]
9734
+ },
9449
9735
  assumptions: { type: "string[]", description: "Underlying assumptions. Surfaced explicitly so they can be challenged or validated." },
9450
9736
  validation_method: { type: "string", enum: ["interview", "survey", "usability_test", "analytics", "a_b_test", "prototype_test", "literature_review", "other"], description: "Primary validation method" }
9451
9737
  },
@@ -9472,24 +9758,26 @@ var UPG_PROPERTY_SCHEMA = {
9472
9758
  desired_outcome: {
9473
9759
  statement: { type: "string", description: "Outcome statement in the user's words" },
9474
9760
  importance: {
9475
- type: "object",
9761
+ type: "assessment",
9762
+ scale_id: "importance_5",
9476
9763
  description: "How important this outcome is to the user (1 = low, 5 = critical)",
9477
9764
  properties: {
9478
9765
  value: { type: "number", description: "The numeric value, used for computation." },
9479
9766
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9480
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9481
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9767
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9768
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9482
9769
  },
9483
9770
  required: ["value", "label"]
9484
9771
  },
9485
9772
  current_satisfaction: {
9486
- type: "object",
9773
+ type: "assessment",
9774
+ scale_id: "satisfaction_5",
9487
9775
  description: "How satisfied the user currently is with this outcome (1 = very unsatisfied, 5 = fully satisfied)",
9488
9776
  properties: {
9489
9777
  value: { type: "number", description: "The numeric value, used for computation." },
9490
9778
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9491
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9492
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9779
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9780
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9493
9781
  },
9494
9782
  required: ["value", "label"]
9495
9783
  }
@@ -9607,20 +9895,20 @@ var UPG_PROPERTY_SCHEMA = {
9607
9895
  evidence_source: { type: "string", enum: ["experiment_run", "observation", "quote", "metric_change", "market_data", "interview"], description: "Origin type. Drives renderer + filter UI; the provenance edge (`derived_from_*`) carries the actual source node reference." },
9608
9896
  direction: { type: "string", enum: ["supports", "refutes", "neutral"], description: "Direction relative to the parent hypothesis." },
9609
9897
  weight: {
9610
- type: "object",
9611
- description: "Strength (UPGAssessment, scale `weight_5pt`).",
9898
+ type: "assessment",
9899
+ scale_id: "importance_5",
9900
+ description: "Strength (UPGAssessment, scale `scale_5`).",
9612
9901
  properties: {
9613
9902
  value: { type: "number", description: "The numeric value, used for computation." },
9614
9903
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9615
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9616
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9904
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9905
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9617
9906
  },
9618
9907
  required: ["value", "label"]
9619
9908
  },
9620
9909
  summary: { type: "string", description: "Plain-English summary." },
9621
9910
  observed_at: { type: "string", description: "ISO date observed." },
9622
- source: { type: "string", description: "Free-text provenance note" },
9623
- strength: { type: "string", enum: ["strong", "moderate", "weak"], description: "@deprecated since v0.4.0. Use `weight: UPGAssessment`. Simple enum replaced by structured assessment to align with UPG scoring patterns." }
9911
+ source: { type: "string", description: "Free-text provenance note" }
9624
9912
  },
9625
9913
  // ExperimentProperties: A structured activity designed to test a hypothesis.
9626
9914
  experiment: {
@@ -9637,46 +9925,50 @@ var UPG_PROPERTY_SCHEMA = {
9637
9925
  method: { type: "string", enum: ["a_b_test", "multivariate", "qual_interview", "prototype_test", "fake_door", "wizard_of_oz", "longitudinal"], description: "Experimental method. Drives renderer and analysis tooling." },
9638
9926
  success_criteria: { type: "string", description: 'Plain-English description of "passing"' },
9639
9927
  projected_reach: {
9640
- type: "object",
9928
+ type: "assessment",
9929
+ scale_id: "reach_5",
9641
9930
  description: "Projected reach: how many people the run is expected to touch (UPGAssessment)",
9642
9931
  properties: {
9643
9932
  value: { type: "number", description: "The numeric value, used for computation." },
9644
9933
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9645
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9646
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9934
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9935
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9647
9936
  },
9648
9937
  required: ["value", "label"]
9649
9938
  },
9650
9939
  projected_impact: {
9651
- type: "object",
9940
+ type: "assessment",
9941
+ scale_id: "impact_5",
9652
9942
  description: "Projected impact on the target metric (UPGAssessment)",
9653
9943
  properties: {
9654
9944
  value: { type: "number", description: "The numeric value, used for computation." },
9655
9945
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9656
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9657
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9946
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9947
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9658
9948
  },
9659
9949
  required: ["value", "label"]
9660
9950
  },
9661
9951
  confidence: {
9662
- type: "object",
9663
- description: "Team confidence at plan-time (UPGAssessment, scale `confidence_5pt`)",
9952
+ type: "assessment",
9953
+ scale_id: "confidence_5",
9954
+ description: "Team confidence at plan-time (UPGAssessment, scale `confidence_5`)",
9664
9955
  properties: {
9665
9956
  value: { type: "number", description: "The numeric value, used for computation." },
9666
9957
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9667
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9668
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9958
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9959
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9669
9960
  },
9670
9961
  required: ["value", "label"]
9671
9962
  },
9672
9963
  cost_estimate: {
9673
- type: "object",
9964
+ type: "assessment",
9965
+ scale_id: "effort_5",
9674
9966
  description: "Cost estimate at plan-time (UPGAssessment)",
9675
9967
  properties: {
9676
9968
  value: { type: "number", description: "The numeric value, used for computation." },
9677
9969
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9678
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9679
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9970
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9971
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9680
9972
  },
9681
9973
  required: ["value", "label"]
9682
9974
  },
@@ -9690,13 +9982,14 @@ var UPG_PROPERTY_SCHEMA = {
9690
9982
  actual_reach: { type: "number", description: "Observed reach: how many people the run actually touched" },
9691
9983
  outcome_summary: { type: "string", description: "Plain-English outcome" },
9692
9984
  severity_of_finding: {
9693
- type: "object",
9985
+ type: "assessment",
9986
+ scale_id: "severity_5",
9694
9987
  description: "Severity / strength of the finding (UPGAssessment)",
9695
9988
  properties: {
9696
9989
  value: { type: "number", description: "The numeric value, used for computation." },
9697
9990
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9698
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9699
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
9991
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
9992
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9700
9993
  },
9701
9994
  required: ["value", "label"]
9702
9995
  },
@@ -9715,7 +10008,18 @@ var UPG_PROPERTY_SCHEMA = {
9715
10008
  feasibility_study: {
9716
10009
  study_type: { type: "string", enum: ["technical", "business", "market", "resource"], description: 'Type of feasibility being assessed. @example "technical" for assessing engineering viability' },
9717
10010
  conclusion: { type: "string", enum: ["feasible", "not_feasible", "conditional", "needs_more_data"], description: "Outcome conclusion of the study" },
9718
- confidence: { type: "string", enum: ["high", "medium", "low"], description: "Confidence in the conclusion" }
10011
+ confidence: {
10012
+ type: "assessment",
10013
+ scale_id: "confidence_5",
10014
+ description: "Confidence in the conclusion (UPGAssessment on `confidence_5`).",
10015
+ properties: {
10016
+ value: { type: "number", description: "The numeric value, used for computation." },
10017
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10018
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10019
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10020
+ },
10021
+ required: ["value", "label"]
10022
+ }
9719
10023
  },
9720
10024
  // FeatureProperties: A discrete, user-facing capability of the product.
9721
10025
  feature: {
@@ -9750,28 +10054,30 @@ var UPG_PROPERTY_SCHEMA = {
9750
10054
  feature_request: {
9751
10055
  request_source: { type: "string", enum: ["customer", "internal", "prospect", "support", "community"], description: "Where the request originated" },
9752
10056
  vote_count: { type: "number", description: "Number of votes or upvotes from users" },
9753
- signal_sentiment: { type: "string", enum: ["positive", "negative", "neutral", "mixed"], description: "Detected sentiment of the request" },
10057
+ signal_sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Detected sentiment of the request" },
9754
10058
  signal_channel: { type: "string", description: "Channel through which the request was received" },
9755
10059
  signal_urgency: { type: "string", enum: ["low", "medium", "high", "critical"], description: "Perceived urgency of the request" },
9756
10060
  revenue_impact: {
9757
- type: "object",
10061
+ type: "assessment",
10062
+ scale_id: "impact_5",
9758
10063
  description: "Estimated revenue impact if implemented (1-5)",
9759
10064
  properties: {
9760
10065
  value: { type: "number", description: "The numeric value, used for computation." },
9761
10066
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9762
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9763
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10067
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10068
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9764
10069
  },
9765
10070
  required: ["value", "label"]
9766
10071
  },
9767
10072
  effort_estimate: {
9768
- type: "object",
10073
+ type: "assessment",
10074
+ scale_id: "effort_5",
9769
10075
  description: "Estimated implementation effort (1-5)",
9770
10076
  properties: {
9771
10077
  value: { type: "number", description: "The numeric value, used for computation." },
9772
10078
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9773
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9774
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10079
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10080
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9775
10081
  },
9776
10082
  required: ["value", "label"]
9777
10083
  },
@@ -9788,13 +10094,14 @@ var UPG_PROPERTY_SCHEMA = {
9788
10094
  sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Overall sentiment across mentions" },
9789
10095
  actionable: { type: "boolean", description: "Whether this theme can be acted upon" },
9790
10096
  frequency: {
9791
- type: "object",
10097
+ type: "assessment",
10098
+ scale_id: "frequency_5",
9792
10099
  description: "How often the theme is mentioned (1-5)",
9793
10100
  properties: {
9794
10101
  value: { type: "number", description: "The numeric value, used for computation." },
9795
10102
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9796
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9797
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10103
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10104
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9798
10105
  },
9799
10106
  required: ["value", "label"]
9800
10107
  },
@@ -9812,7 +10119,7 @@ var UPG_PROPERTY_SCHEMA = {
9812
10119
  fix_type: { type: "string", enum: ["hotfix", "permanent", "workaround", "configuration", "process_change"], description: "Kind of fix. `hotfix` = urgent patch. `permanent` = proper structural fix. `workaround` = mitigates symptom without addressing root cause; should track a follow-up." },
9813
10120
  commit: { type: "string", description: "Git commit SHA" },
9814
10121
  files_changed: { type: "string[]", description: "Files changed" },
9815
- deployed_at: { type: "string", description: "ISO timestamp landed in the target environment. Pairs with `fix_status === 'deployed'`." },
10122
+ deployed_at: { type: "string", description: "ISO timestamp landed in the target environment." },
9816
10123
  fixed_date: { type: "string", description: "Application date (ISO date). Coarser-grained complement to `deployed_at`." },
9817
10124
  verified: { type: "boolean", description: "Verified in production" },
9818
10125
  verified_by_test: { type: "boolean", description: "Validated by an automated regression or integration test. Distinct from `verified` (human judgment)." }
@@ -9822,13 +10129,14 @@ var UPG_PROPERTY_SCHEMA = {
9822
10129
  forecast_period: { type: "string", description: 'Time period the forecast covers (e.g. "Q2 2026")' },
9823
10130
  predicted_revenue: { type: "number", description: "Predicted revenue amount" },
9824
10131
  confidence: {
9825
- type: "object",
10132
+ type: "assessment",
10133
+ scale_id: "confidence_5",
9826
10134
  description: "Confidence in the prediction (1 = speculative, 5 = high conviction)",
9827
10135
  properties: {
9828
10136
  value: { type: "number", description: "The numeric value, used for computation." },
9829
10137
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9830
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9831
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10138
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10139
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9832
10140
  },
9833
10141
  required: ["value", "label"]
9834
10142
  },
@@ -9880,13 +10188,14 @@ var UPG_PROPERTY_SCHEMA = {
9880
10188
  hallucination_report: {
9881
10189
  report_type: { type: "string", enum: ["factual", "logical", "fabrication", "inconsistency"], description: "Classification" },
9882
10190
  severity: {
9883
- type: "object",
10191
+ type: "assessment",
10192
+ scale_id: "severity_5",
9884
10193
  description: "Impact severity (1 = trivial, 5 = dangerous misinformation)",
9885
10194
  properties: {
9886
10195
  value: { type: "number", description: "The numeric value, used for computation." },
9887
10196
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9888
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9889
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10197
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10198
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9890
10199
  },
9891
10200
  required: ["value", "label"]
9892
10201
  },
@@ -9908,13 +10217,14 @@ var UPG_PROPERTY_SCHEMA = {
9908
10217
  we_know_when: { type: "string", description: "The measurable signal that confirms or refutes the claim." },
9909
10218
  risk_if_wrong: { type: "string", description: "Risk surface for prioritisation if the claim turns out wrong." },
9910
10219
  current_confidence: {
9911
- type: "object",
10220
+ type: "assessment",
10221
+ scale_id: "confidence_5",
9912
10222
  description: "Team confidence at the current point in time. Derived from the weighted sum of attached `hypothesis_evidence` rows (formula spec'd separately). Authors may set explicitly; loaders may overwrite from derivation.",
9913
10223
  properties: {
9914
10224
  value: { type: "number", description: "The numeric value, used for computation." },
9915
10225
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9916
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9917
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10226
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10227
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9918
10228
  },
9919
10229
  required: ["value", "label"]
9920
10230
  }
@@ -9924,13 +10234,14 @@ var UPG_PROPERTY_SCHEMA = {
9924
10234
  evidence_type: { type: "string", enum: ["experiment_run", "observation", "quote", "metric_change", "market_data", "interview"], description: "Kind of evidence. Drives renderer + filter UI. The provenance edge (`derived_from_*`) carries the actual source node reference per P14; this enum is typing/UI metadata." },
9925
10235
  direction: { type: "string", enum: ["supports", "refutes", "neutral"], description: "Direction relative to the parent claim. Canonical direction axis aligned to `Evidence.direction` so every direction-of-evidence property uses the same vocab. `supports` = paired with the `supports` edge. `refutes` = paired with the `refutes` edge. `neutral` = data insufficient or noisy. BREAKING in v0.4.0: legacy `'confirms'`, `'disconfirms'`, `'inconclusive'` no longer type-check. Migration: `confirms \u2192 supports`, `disconfirms \u2192 refutes`, `inconclusive \u2192 neutral`." },
9926
10236
  weight: {
9927
- type: "object",
9928
- description: "Strength of the evidence (UPGAssessment, scale `weight_5pt`).",
10237
+ type: "assessment",
10238
+ scale_id: "importance_5",
10239
+ description: "Strength of the evidence (UPGAssessment, scale `scale_5`).",
9929
10240
  properties: {
9930
10241
  value: { type: "number", description: "The numeric value, used for computation." },
9931
10242
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
9932
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
9933
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10243
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10244
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
9934
10245
  },
9935
10246
  required: ["value", "label"]
9936
10247
  },
@@ -9948,8 +10259,8 @@ var UPG_PROPERTY_SCHEMA = {
9948
10259
  // IncidentProperties: Incident.
9949
10260
  incident: {
9950
10261
  incident_type: { type: "string", enum: ["operational", "security", "data_breach", "performance", "dependency", "other"], description: 'Discriminator. Absorbs the deprecated `security_incident` type. When `incident_type === \'security\'`, this node replaces the former `security_incident`. @example "security" for a data breach, "operational" for a service outage, "performance" for degradation' },
9951
- severity_level: { type: "string", enum: ["sev1", "sev2", "sev3", "sev4"], description: 'Severity. `sev1` = critical/system down. `sev2` = major impact. `sev3` = minor impact. `sev4` = minimal impact. @example "sev1" for complete service unavailability' },
9952
- urgency: { type: "string", enum: ["high", "low"], description: "Notification urgency. Independent of severity. `high` triggers phone calls. `low` sends a message." },
10262
+ severity_level: { type: "string", enum: ["sev1", "sev2", "sev3", "sev4"], description: 'Incident severity tier (paging classification). `sev1` = critical/system down. `sev2` = major impact. `sev3` = minor impact. `sev4` = minimal. Uses the `IncidentSeverity` scale; distinct from user-impact `severity_5`. @example "sev1" for complete service unavailability' },
10263
+ urgency: { type: "string", enum: ["low", "medium", "high", "critical"], description: "Notification urgency. Independent of severity. Uses the shared `SignalUrgency` scale (`low` | `medium` | `high` | `critical`); higher tiers escalate the notification channel." },
9953
10264
  started_at: { type: "string", description: "ISO timestamp the incident started or was first detected." },
9954
10265
  acknowledged_at: { type: "string", description: "ISO timestamp first acknowledged by a responder. Used to compute time-to-acknowledge." },
9955
10266
  contained_at: { type: "string", description: "ISO timestamp contained. Blast radius limited, bleeding stopped. Containment precedes full resolution, especially for security incidents." },
@@ -9975,7 +10286,18 @@ var UPG_PROPERTY_SCHEMA = {
9975
10286
  // InsightProperties: Unified insight, synthesised from evidence and observations.
9976
10287
  insight: {
9977
10288
  insight_level: { type: "string", enum: ["pattern", "finding", "actionable", "strategic"], description: "Maturity level. `pattern` = recurring observation, not yet interpreted. `finding` = interpreted pattern with a clear meaning. `actionable` = finding with a clear next step. `strategic` = finding that affects product direction." },
9978
- confidence: { type: "string", enum: ["high", "medium", "low"], description: "Confidence. Reflects the strength and diversity of supporting evidence." },
10289
+ confidence: {
10290
+ type: "assessment",
10291
+ scale_id: "confidence_5",
10292
+ description: "Confidence (UPGAssessment on `confidence_5`). Reflects the strength and diversity of supporting evidence.",
10293
+ properties: {
10294
+ value: { type: "number", description: "The numeric value, used for computation." },
10295
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10296
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10297
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10298
+ },
10299
+ required: ["value", "label"]
10300
+ },
9979
10301
  evidence_count: { type: "number", description: "Supporting observations, quotes, or evidence items. Higher counts increase confidence." },
9980
10302
  novelty: { type: "string", enum: ["known", "surprising", "contradictory"], description: "Novelty against existing knowledge. `known` = confirms what we already believed. `surprising` = challenges or extends our understanding. `contradictory` = directly conflicts with a prior assumption." },
9981
10303
  actionability: { type: "string", enum: ["immediate", "needs_validation", "informational"], description: "Current actionability. `immediate` = clear action, no further research needed. `needs_validation` = promising but requires more evidence. `informational` = important context, no direct action." },
@@ -10013,20 +10335,21 @@ var UPG_PROPERTY_SCHEMA = {
10013
10335
  // InvestigationProperties: Active thread of inquiry: debugging, architecture exploration, RCA.
10014
10336
  investigation: {
10015
10337
  severity: {
10016
- type: "object",
10338
+ type: "assessment",
10339
+ scale_id: "severity_5",
10017
10340
  description: "Believed severity of the underlying issue. Drives prioritisation across investigations. Canonicalised in v0.4.0: the ad-hoc `'low' | 'medium' | 'high' | 'critical'` shape was replaced by `UPGAssessment` so every \"severity\" property reports on the same axis. Migration: `low \u2192 2`, `medium \u2192 3`, `high \u2192 4`, `critical \u2192 5`.",
10018
10341
  properties: {
10019
10342
  value: { type: "number", description: "The numeric value, used for computation." },
10020
10343
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10021
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10022
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10344
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10345
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10023
10346
  },
10024
10347
  required: ["value", "label"]
10025
10348
  },
10026
10349
  hypothesis: { type: "string", description: "Working hypothesis about the root cause" },
10027
10350
  findings: { type: "string", description: "Findings discovered so far" },
10028
10351
  started_at: { type: "string", description: "ISO timestamp the investigation began" },
10029
- resolved_at: { type: "string", description: "ISO timestamp the investigation was concluded. Pairs with `investigation_status === 'resolved' | 'abandoned'`." },
10352
+ resolved_at: { type: "string", description: "ISO timestamp the investigation was concluded. Pairs with `status === 'resolved' | 'abandoned'`." },
10030
10353
  lead_investigator: { type: "string", description: "Lead investigator (email or handle). Distinct from the team owning the affected service." },
10031
10354
  session_id: { type: "string", description: "Originating session" },
10032
10355
  category: { type: "string", enum: ["performance", "security", "data_quality", "reliability", "cost", "compliance", "other"], description: "Kind of issue under investigation. Distinct from `RootCauseProperties.cause_category`, which captures *why something went wrong*." }
@@ -10052,24 +10375,26 @@ var UPG_PROPERTY_SCHEMA = {
10052
10375
  statement: { type: "string", description: 'Job statement: "When I... I want to... So I can..."' },
10053
10376
  job_type: { type: "string", enum: ["functional", "emotional", "social", "supporting"], description: "Classification by motivation dimension" },
10054
10377
  importance: {
10055
- type: "object",
10378
+ type: "assessment",
10379
+ scale_id: "importance_5",
10056
10380
  description: "Importance to the user (1 = low, 5 = critical)",
10057
10381
  properties: {
10058
10382
  value: { type: "number", description: "The numeric value, used for computation." },
10059
10383
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10060
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10061
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10384
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10385
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10062
10386
  },
10063
10387
  required: ["value", "label"]
10064
10388
  },
10065
10389
  current_satisfaction: {
10066
- type: "object",
10390
+ type: "assessment",
10391
+ scale_id: "satisfaction_5",
10067
10392
  description: "Current satisfaction with how this job gets done (1 = very unsatisfied, 5 = fully satisfied)",
10068
10393
  properties: {
10069
10394
  value: { type: "number", description: "The numeric value, used for computation." },
10070
10395
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10071
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10072
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10396
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10397
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10073
10398
  },
10074
10399
  required: ["value", "label"]
10075
10400
  },
@@ -10087,24 +10412,26 @@ var UPG_PROPERTY_SCHEMA = {
10087
10412
  action_description: { type: "string", description: "Plain-language description. Primary content of the action." },
10088
10413
  channel: { type: "string", enum: ["in-app", "email", "web", "mobile", "phone", "in-person", "sms", "social", "other"], description: "Channel or surface. Keeps service-blueprint columns consistent across the journey." },
10089
10414
  pain_score: {
10090
- type: "object",
10415
+ type: "assessment",
10416
+ scale_id: "pain_5",
10091
10417
  description: "Pain (1 = effortless, 5 = very painful). Drives opportunity discovery.",
10092
10418
  properties: {
10093
10419
  value: { type: "number", description: "The numeric value, used for computation." },
10094
10420
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10095
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10096
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10421
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10422
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10097
10423
  },
10098
10424
  required: ["value", "label"]
10099
10425
  },
10100
10426
  opportunity_score: {
10101
- type: "object",
10427
+ type: "assessment",
10428
+ scale_id: "impact_5",
10102
10429
  description: "Opportunity (1 = low leverage, 5 = high leverage). Pairs with `pain_score` to rank investment.",
10103
10430
  properties: {
10104
10431
  value: { type: "number", description: "The numeric value, used for computation." },
10105
10432
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10106
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10107
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10433
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10434
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10108
10435
  },
10109
10436
  required: ["value", "label"]
10110
10437
  },
@@ -10128,24 +10455,26 @@ var UPG_PROPERTY_SCHEMA = {
10128
10455
  touchpoint: { type: "string", description: "Interaction touchpoint" },
10129
10456
  channel: { type: "string", description: 'Channel (e.g. "web", "email", "in-store")' },
10130
10457
  emotion_score: {
10131
- type: "object",
10458
+ type: "assessment",
10459
+ scale_id: "satisfaction_5",
10132
10460
  description: "User emotion (1 = very negative, 5 = very positive)",
10133
10461
  properties: {
10134
10462
  value: { type: "number", description: "The numeric value, used for computation." },
10135
10463
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10136
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10137
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10464
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10465
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10138
10466
  },
10139
10467
  required: ["value", "label"]
10140
10468
  },
10141
10469
  friction_score: {
10142
- type: "object",
10470
+ type: "assessment",
10471
+ scale_id: "pain_5",
10143
10472
  description: "Friction (1 = effortless, 5 = very painful)",
10144
10473
  properties: {
10145
10474
  value: { type: "number", description: "The numeric value, used for computation." },
10146
10475
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10147
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10148
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10476
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10477
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10149
10478
  },
10150
10479
  required: ["value", "label"]
10151
10480
  },
@@ -10158,7 +10487,7 @@ var UPG_PROPERTY_SCHEMA = {
10158
10487
  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`.' },
10159
10488
  frequency_count: { type: "number", description: "Exact count of runs in the period. Pairs with `frequency_period`." },
10160
10489
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`, e.g. `'P7D'`)" },
10161
- frequency_rating: { type: "string", enum: ["rare", "occasional", "regular", "constant", "other"], description: "Qualitative tier. Use when an exact rate is unknown." },
10490
+ frequency_rating: { type: "string", enum: ["constant", "regular", "occasional", "rare", "other"], description: "Qualitative tier. Use when an exact rate is unknown." },
10162
10491
  operational_owner: { type: "string", description: "Operationally accountable team or individual" },
10163
10492
  capacity_constraint: { type: "string", description: "Bottleneck or scaling constraint" },
10164
10493
  automation_level: { type: "string", enum: ["manual", "assisted", "automated"], description: "How much runs without human intervention" }
@@ -10169,13 +10498,14 @@ var UPG_PROPERTY_SCHEMA = {
10169
10498
  criticality: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Criticality to the business model" },
10170
10499
  owner: { type: "string", description: "Accountable person or team" },
10171
10500
  scarcity_risk: {
10172
- type: "object",
10501
+ type: "assessment",
10502
+ scale_id: "severity_5",
10173
10503
  description: "Replacement difficulty",
10174
10504
  properties: {
10175
10505
  value: { type: "number", description: "The numeric value, used for computation." },
10176
10506
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10177
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10178
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10507
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10508
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10179
10509
  },
10180
10510
  required: ["value", "label"]
10181
10511
  },
@@ -10209,7 +10539,6 @@ var UPG_PROPERTY_SCHEMA = {
10209
10539
  // LearningProperties: Result of an experiment. Evidence that updates a hypothesis.
10210
10540
  learning: {
10211
10541
  result: { type: "string", description: "Summary" },
10212
- metric: { type: "string", description: 'Observed metric. @deprecated since="0.4.0" removeIn="0.5.0". Use the canonical edge `learning_observed_on_metric` to link to the metric structurally. Free-text was the wrong shape: a metric is a queryable graph entity.' },
10213
10542
  result_value: { type: "number", description: "Measured value of the result" },
10214
10543
  result_unit: { type: "string", description: 'Unit (e.g. "%" or "ms")' },
10215
10544
  result_direction: { type: "string", enum: ["supports", "refutes", "neutral"], description: "Direction relative to the parent hypothesis. Canonical direction axis. BREAKING in v0.4.0: legacy `'positive'`, `'negative'`, `'neutral'` are replaced by `'supports'`, `'refutes'`, `'neutral'` to align with `Evidence.direction` and `HypothesisEvidence.direction`. Migration: `positive \u2192 supports`, `negative \u2192 refutes`, `neutral \u2192 neutral`." },
@@ -10265,25 +10594,27 @@ var UPG_PROPERTY_SCHEMA = {
10265
10594
  // MarketTrendProperties: Market trend.
10266
10595
  market_trend: {
10267
10596
  relevance: {
10268
- type: "object",
10597
+ type: "assessment",
10598
+ scale_id: "importance_5",
10269
10599
  description: "Relevance to our product (1 = low, 5 = critical).",
10270
10600
  properties: {
10271
10601
  value: { type: "number", description: "The numeric value, used for computation." },
10272
10602
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10273
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10274
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10603
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10604
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10275
10605
  },
10276
10606
  required: ["value", "label"]
10277
10607
  },
10278
10608
  timeframe: { type: "string", description: 'Expected peak or mainstream window. @example "12-18 months", "2027"' },
10279
10609
  impact: {
10280
- type: "object",
10610
+ type: "assessment",
10611
+ scale_id: "impact_5",
10281
10612
  description: "Expected impact on our market or category.",
10282
10613
  properties: {
10283
10614
  value: { type: "number", description: "The numeric value, used for computation." },
10284
10615
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10285
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10286
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10616
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10617
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10287
10618
  },
10288
10619
  required: ["value", "label"]
10289
10620
  },
@@ -10394,35 +10725,38 @@ var UPG_PROPERTY_SCHEMA = {
10394
10725
  valence: { type: "string", enum: ["pain", "gap", "constraint"], description: "What kind of experience: pain (friction), gap (unmet), constraint (limitation)" },
10395
10726
  maturity: { type: "string", enum: ["raw", "validated", "prioritized"], description: "How mature is this need in our understanding" },
10396
10727
  frequency: {
10397
- type: "object",
10728
+ type: "assessment",
10729
+ scale_id: "frequency_5",
10398
10730
  description: "How often the user encounters this need (1 = rarely, 5 = constantly)",
10399
10731
  properties: {
10400
10732
  value: { type: "number", description: "The numeric value, used for computation." },
10401
10733
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10402
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10403
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10734
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10735
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10404
10736
  },
10405
10737
  required: ["value", "label"]
10406
10738
  },
10407
10739
  severity: {
10408
- type: "object",
10740
+ type: "assessment",
10741
+ scale_id: "severity_5",
10409
10742
  description: "How painful or disruptive the need is when unaddressed (1 = minor, 5 = critical)",
10410
10743
  properties: {
10411
10744
  value: { type: "number", description: "The numeric value, used for computation." },
10412
10745
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10413
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10414
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10746
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10747
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10415
10748
  },
10416
10749
  required: ["value", "label"]
10417
10750
  },
10418
10751
  importance: {
10419
- type: "object",
10752
+ type: "assessment",
10753
+ scale_id: "importance_5",
10420
10754
  description: "How important resolving this need is to the user (1 = low, 5 = critical)",
10421
10755
  properties: {
10422
10756
  value: { type: "number", description: "The numeric value, used for computation." },
10423
10757
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10424
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10425
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10758
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10759
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10426
10760
  },
10427
10761
  required: ["value", "label"]
10428
10762
  },
@@ -10443,13 +10777,14 @@ var UPG_PROPERTY_SCHEMA = {
10443
10777
  statement: { type: "string", description: "The objection as stated by the source" },
10444
10778
  source_type: { type: "string", enum: ["prospect", "competitor", "internal", "market"], description: "Where this objection originated" },
10445
10779
  severity: {
10446
- type: "object",
10780
+ type: "assessment",
10781
+ scale_id: "severity_5",
10447
10782
  description: "How frequently or strongly this objection comes up (1-5)",
10448
10783
  properties: {
10449
10784
  value: { type: "number", description: "The numeric value, used for computation." },
10450
10785
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10451
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10452
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10786
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10787
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10453
10788
  },
10454
10789
  required: ["value", "label"]
10455
10790
  },
@@ -10468,7 +10803,7 @@ var UPG_PROPERTY_SCHEMA = {
10468
10803
  session_ref: { type: "string", description: "Capturing session reference. Convenience field; the canonical relationship to study/session is an edge per P14. Retained as a lightweight context anchor for AI inference." },
10469
10804
  is_highlighted: { type: "boolean", description: "Flagged as a highlight. Absorbed from the deprecated Highlight entity." },
10470
10805
  highlight_tag: { type: "string", description: 'Free-form highlight type tag. @example "pain", "delight", "behaviour", "moment of clarity"' },
10471
- sentiment: { type: "string", enum: ["positive", "negative", "neutral", "mixed"], description: "Structured sentiment. Tools like Dovetail and EnjoyHQ converge on these four values. More precise than `highlight_tag` for aggregation." }
10806
+ sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Structured sentiment. Tools like Dovetail and EnjoyHQ converge on these four values. More precise than `highlight_tag` for aggregation." }
10472
10807
  },
10473
10808
  // OnCallRotationProperties: On-call rotation.
10474
10809
  on_call_rotation: {
@@ -10480,35 +10815,38 @@ var UPG_PROPERTY_SCHEMA = {
10480
10815
  // OpportunityProperties: A problem worth solving, grounded in user need and business value
10481
10816
  opportunity: {
10482
10817
  reach: {
10483
- type: "object",
10818
+ type: "assessment",
10819
+ scale_id: "reach_5",
10484
10820
  description: "How many users experience this problem",
10485
10821
  properties: {
10486
10822
  value: { type: "number", description: "The numeric value, used for computation." },
10487
10823
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10488
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10489
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10824
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10825
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10490
10826
  },
10491
10827
  required: ["value", "label"]
10492
10828
  },
10493
10829
  frequency: {
10494
- type: "object",
10830
+ type: "assessment",
10831
+ scale_id: "frequency_5",
10495
10832
  description: "How often users experience this problem",
10496
10833
  properties: {
10497
10834
  value: { type: "number", description: "The numeric value, used for computation." },
10498
10835
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10499
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10500
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10836
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10837
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10501
10838
  },
10502
10839
  required: ["value", "label"]
10503
10840
  },
10504
10841
  pain: {
10505
- type: "object",
10842
+ type: "assessment",
10843
+ scale_id: "pain_5",
10506
10844
  description: "How painful it is when unaddressed",
10507
10845
  properties: {
10508
10846
  value: { type: "number", description: "The numeric value, used for computation." },
10509
10847
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10510
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10511
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10848
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10849
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10512
10850
  },
10513
10851
  required: ["value", "label"]
10514
10852
  },
@@ -10529,17 +10867,18 @@ var UPG_PROPERTY_SCHEMA = {
10529
10867
  current_state: { type: "string", description: "Baseline or latest read" },
10530
10868
  evidence_summary: { type: "string", description: "Evidence gathered so far (quotes, metrics, studies)" },
10531
10869
  confidence: {
10532
- type: "object",
10870
+ type: "assessment",
10871
+ scale_id: "confidence_5",
10533
10872
  description: "Confidence this is the right outcome to pursue",
10534
10873
  properties: {
10535
10874
  value: { type: "number", description: "The numeric value, used for computation." },
10536
10875
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10537
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10538
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10876
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10877
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10539
10878
  },
10540
10879
  required: ["value", "label"]
10541
10880
  },
10542
- outcome_status: { type: "string", description: "Current lifecycle phase. Free-form until an outcome lifecycle is defined in `grammar/lifecycles.ts`." }
10881
+ outcome_status: { type: "string", enum: ["identified", "measuring", "achieved", "abandoned"], description: "Current lifecycle phase, mirroring the `outcome` lifecycle in `grammar/lifecycles.ts` (UPG-579 Option B): `identified` -> `measuring` -> `achieved` | `abandoned`." }
10543
10882
  },
10544
10883
  // ParticipantProperties: Research participant.
10545
10884
  participant: {
@@ -10570,13 +10909,14 @@ var UPG_PROPERTY_SCHEMA = {
10570
10909
  value_exchange: { type: "string", description: "What each party gives and receives" },
10571
10910
  partnership_tier: { type: "string", enum: ["strategic", "preferred", "standard", "trial"], description: "Commercial significance. Drives attention and exec sponsorship." },
10572
10911
  risk_level: {
10573
- type: "object",
10912
+ type: "assessment",
10913
+ scale_id: "severity_5",
10574
10914
  description: "Exposure if the partnership fails (concentration risk, IP risk, etc.)",
10575
10915
  properties: {
10576
10916
  value: { type: "number", description: "The numeric value, used for computation." },
10577
10917
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10578
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10579
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
10918
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
10919
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10580
10920
  },
10581
10921
  required: ["value", "label"]
10582
10922
  },
@@ -10617,7 +10957,7 @@ var UPG_PROPERTY_SCHEMA = {
10617
10957
  },
10618
10958
  // PipelineSalesProperties: Sales pipeline.
10619
10959
  pipeline_sales: {
10620
- pipeline_type: { type: "string", description: 'Classification of the pipeline (e.g. "new business", "expansion")' },
10960
+ pipeline_type: { type: "string", enum: ["new_business", "expansion", "renewal", "partner", "other"], description: "Classification of the pipeline (UPG-579 Option B)." },
10621
10961
  avg_cycle_days: { type: "number", description: "Average days from opportunity creation to close" }
10622
10962
  },
10623
10963
  // PipelineStageProperties: Pipeline stage.
@@ -10659,7 +10999,7 @@ var UPG_PROPERTY_SCHEMA = {
10659
10999
  // PricingStrategyProperties: Pricing strategy.
10660
11000
  pricing_strategy: {
10661
11001
  strategy_type: { type: "string", enum: ["value_based", "cost_plus", "competitor_based", "penetration", "freemium"], description: "Pricing methodology used" },
10662
- review_cadence: { type: "string", description: "How often pricing is reviewed" },
11002
+ review_cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "How often pricing is reviewed. Uses the shared `Cadence` scale." },
10663
11003
  last_change: { type: "string", description: "Date of the last pricing change (ISO format)" }
10664
11004
  },
10665
11005
  // PricingTierProperties: PricingTier: the central pricing concept (the plan a customer buys).
@@ -10768,13 +11108,14 @@ var UPG_PROPERTY_SCHEMA = {
10768
11108
  rebuttal: {
10769
11109
  statement: { type: "string", description: "The counter-argument or response to an objection" },
10770
11110
  strength: {
10771
- type: "object",
11111
+ type: "assessment",
11112
+ scale_id: "scale_5",
10772
11113
  description: "How convincing this rebuttal is (1-5)",
10773
11114
  properties: {
10774
11115
  value: { type: "number", description: "The numeric value, used for computation." },
10775
11116
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10776
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10777
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11117
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11118
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10778
11119
  },
10779
11120
  required: ["value", "label"]
10780
11121
  },
@@ -10867,24 +11208,26 @@ var UPG_PROPERTY_SCHEMA = {
10867
11208
  risk: {
10868
11209
  risk_type: { type: "string", enum: ["technical", "business", "legal", "security", "operational"], description: "Domain the risk belongs to" },
10869
11210
  probability: {
10870
- type: "object",
11211
+ type: "assessment",
11212
+ scale_id: "confidence_5",
10871
11213
  description: "How likely this risk is to materialise (1 = unlikely, 5 = near certain)",
10872
11214
  properties: {
10873
11215
  value: { type: "number", description: "The numeric value, used for computation." },
10874
11216
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10875
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10876
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11217
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11218
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10877
11219
  },
10878
11220
  required: ["value", "label"]
10879
11221
  },
10880
11222
  impact: {
10881
- type: "object",
11223
+ type: "assessment",
11224
+ scale_id: "impact_5",
10882
11225
  description: "Severity of consequences if the risk materialises (1 = negligible, 5 = catastrophic)",
10883
11226
  properties: {
10884
11227
  value: { type: "number", description: "The numeric value, used for computation." },
10885
11228
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10886
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10887
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11229
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11230
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10888
11231
  },
10889
11232
  required: ["value", "label"]
10890
11233
  },
@@ -10905,7 +11248,18 @@ var UPG_PROPERTY_SCHEMA = {
10905
11248
  quarter: { type: "string", description: 'Planning quarter (e.g. "Q2 2026"). Pair with `start_date`/`target_date` for precise scheduling.' },
10906
11249
  priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Importance against other items" },
10907
11250
  item_status: { type: "string", enum: ["planned", "in_progress", "shipped", "deferred"], description: "Status. `deferred` = explicitly pushed to a later period." },
10908
- confidence: { type: "string", enum: ["high", "medium", "low"], description: "Delivery confidence within the planned period." },
11251
+ confidence: {
11252
+ type: "assessment",
11253
+ scale_id: "confidence_5",
11254
+ description: "Delivery confidence within the planned period (UPGAssessment on `confidence_5`).",
11255
+ properties: {
11256
+ value: { type: "number", description: "The numeric value, used for computation." },
11257
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11258
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11259
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11260
+ },
11261
+ required: ["value", "label"]
11262
+ },
10909
11263
  start_date: { type: "string", description: "ISO date work begins. More precise than `quarter` for continuous planning." },
10910
11264
  target_date: { type: "string", description: "ISO date completion is expected. For shipped items, the actual completion date." }
10911
11265
  },
@@ -10919,13 +11273,14 @@ var UPG_PROPERTY_SCHEMA = {
10919
11273
  // RootCauseProperties: Underlying architectural or systemic issue.
10920
11274
  root_cause: {
10921
11275
  severity: {
10922
- type: "object",
11276
+ type: "assessment",
11277
+ scale_id: "severity_5",
10923
11278
  description: "Severity (1 = minor, 5 = critical)",
10924
11279
  properties: {
10925
11280
  value: { type: "number", description: "The numeric value, used for computation." },
10926
11281
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10927
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10928
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11282
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11283
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10929
11284
  },
10930
11285
  required: ["value", "label"]
10931
11286
  },
@@ -10975,13 +11330,14 @@ var UPG_PROPERTY_SCHEMA = {
10975
11330
  security_control: {
10976
11331
  control_type: { type: "string", enum: ["preventive", "detective", "corrective", "compensating"], description: "Functional role. `preventive` = stops attacks (MFA, input validation). `detective` = identifies attacks in progress (intrusion detection, audit logs). `corrective` = reduces impact after an attack (incident response, backup restore). `compensating` = alternative when primary isn't feasible." },
10977
11332
  effectiveness: {
10978
- type: "object",
11333
+ type: "assessment",
11334
+ scale_id: "impact_5",
10979
11335
  description: "Mitigation effectiveness (1 = minimal, 5 = fully effective)",
10980
11336
  properties: {
10981
11337
  value: { type: "number", description: "The numeric value, used for computation." },
10982
11338
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
10983
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
10984
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11339
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11340
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
10985
11341
  },
10986
11342
  required: ["value", "label"]
10987
11343
  },
@@ -10992,7 +11348,7 @@ var UPG_PROPERTY_SCHEMA = {
10992
11348
  // SecurityPolicyProperties: Security policy.
10993
11349
  security_policy: {
10994
11350
  scope: { type: "string", description: "Systems or processes covered" },
10995
- review_cadence: { type: "string", description: 'Review cadence (e.g. "annually", "quarterly")' },
11351
+ review_cadence: { type: "string", enum: ["continuous", "hourly", "daily", "weekly", "monthly", "quarterly", "yearly", "on_demand", "other"], description: "Review cadence (e.g. `yearly`, `quarterly`). Uses the shared `Cadence` scale." },
10996
11352
  version: { type: "string", description: "Version" },
10997
11353
  effective_date: { type: "string", description: "ISO effective date" },
10998
11354
  url: { type: "string", description: "Policy document URL" },
@@ -11063,17 +11419,18 @@ var UPG_PROPERTY_SCHEMA = {
11063
11419
  },
11064
11420
  // SkillProperties: Skill entity.
11065
11421
  skill: {
11066
- skill_category: { type: "string", description: 'Category of the skill (e.g. "technical", "leadership", "design")' },
11422
+ skill_category: { type: "string", enum: ["technical", "leadership", "design", "product", "business", "operations", "other"], description: "Category of the skill (UPG-579 Option B)." },
11067
11423
  proficiency_levels: { type: "string[]", description: "Description of proficiency levels for this skill" },
11068
11424
  domain: { type: "string", description: 'Problem domain the skill applies to (e.g. "payments", "accessibility")' },
11069
11425
  rarity: {
11070
- type: "object",
11426
+ type: "assessment",
11427
+ scale_id: "scale_5",
11071
11428
  description: "How scarce this skill is in the labour market this team hires from",
11072
11429
  properties: {
11073
11430
  value: { type: "number", description: "The numeric value, used for computation." },
11074
11431
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11075
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11076
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11432
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11433
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11077
11434
  },
11078
11435
  required: ["value", "label"]
11079
11436
  },
@@ -11089,46 +11446,50 @@ var UPG_PROPERTY_SCHEMA = {
11089
11446
  solution: {
11090
11447
  timeline: { type: "string", description: "Estimated delivery or target timeline" },
11091
11448
  reach: {
11092
- type: "object",
11449
+ type: "assessment",
11450
+ scale_id: "reach_5",
11093
11451
  description: "How many users this solution reaches (1 = few, 5 = most)",
11094
11452
  properties: {
11095
11453
  value: { type: "number", description: "The numeric value, used for computation." },
11096
11454
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11097
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11098
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11455
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11456
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11099
11457
  },
11100
11458
  required: ["value", "label"]
11101
11459
  },
11102
11460
  impact: {
11103
- type: "object",
11461
+ type: "assessment",
11462
+ scale_id: "impact_5",
11104
11463
  description: "Expected impact on the target outcome (1 = minimal, 5 = transformative)",
11105
11464
  properties: {
11106
11465
  value: { type: "number", description: "The numeric value, used for computation." },
11107
11466
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11108
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11109
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11467
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11468
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11110
11469
  },
11111
11470
  required: ["value", "label"]
11112
11471
  },
11113
11472
  confidence: {
11114
- type: "object",
11473
+ type: "assessment",
11474
+ scale_id: "confidence_5",
11115
11475
  description: "How confident the team is in this solution (1 = speculative, 5 = proven)",
11116
11476
  properties: {
11117
11477
  value: { type: "number", description: "The numeric value, used for computation." },
11118
11478
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11119
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11120
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11479
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11480
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11121
11481
  },
11122
11482
  required: ["value", "label"]
11123
11483
  },
11124
11484
  effort: {
11125
- type: "object",
11485
+ type: "assessment",
11486
+ scale_id: "effort_5",
11126
11487
  description: "Level of effort required to implement (1 = trivial, 5 = very large)",
11127
11488
  properties: {
11128
11489
  value: { type: "number", description: "The numeric value, used for computation." },
11129
11490
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11130
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11131
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11491
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11492
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11132
11493
  },
11133
11494
  required: ["value", "label"]
11134
11495
  },
@@ -11138,24 +11499,26 @@ var UPG_PROPERTY_SCHEMA = {
11138
11499
  stakeholder: {
11139
11500
  stakeholder_type: { type: "string", enum: ["internal", "external", "investor", "regulator"], description: "Relationship of the stakeholder to the organisation" },
11140
11501
  influence: {
11141
- type: "object",
11502
+ type: "assessment",
11503
+ scale_id: "importance_5",
11142
11504
  description: "How much influence this stakeholder has over decisions (1 = minimal, 5 = decisive)",
11143
11505
  properties: {
11144
11506
  value: { type: "number", description: "The numeric value, used for computation." },
11145
11507
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11146
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11147
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11508
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11509
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11148
11510
  },
11149
11511
  required: ["value", "label"]
11150
11512
  },
11151
11513
  interest: {
11152
- type: "object",
11514
+ type: "assessment",
11515
+ scale_id: "importance_5",
11153
11516
  description: "How much interest this stakeholder has in the outcome (1 = passive, 5 = deeply invested)",
11154
11517
  properties: {
11155
11518
  value: { type: "number", description: "The numeric value, used for computation." },
11156
11519
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11157
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11158
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11520
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11521
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11159
11522
  },
11160
11523
  required: ["value", "label"]
11161
11524
  }
@@ -11167,19 +11530,6 @@ var UPG_PROPERTY_SCHEMA = {
11167
11530
  risks_flagged: { type: "number", description: "Number of risks flagged in this report" },
11168
11531
  blockers: { type: "string", description: "Description of current blockers" }
11169
11532
  },
11170
- // UserStoryProperties: "As X, I want Y so Z" templated promise, a user story (UCS pattern P5).
11171
- user_story: {
11172
- as_a: { type: "string", description: '"As a [persona], \u2026". Free-text persona name or slug ref.' },
11173
- i_want_to: { type: "string", description: "Capability or action the persona wants." },
11174
- so_that: { type: "string", description: "Benefit or outcome the persona expects." },
11175
- text: { type: "string", description: "Free-form story text. Used as a single-line rendered view." }
11176
- },
11177
- // StoryTaskProperties
11178
- story_task: {
11179
- estimate: { type: "string", description: "@deprecated Use TaskProperties.estimate" },
11180
- effort: { type: "number", description: "@deprecated Use TaskProperties.effort (string form)" },
11181
- priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "@deprecated Use TaskProperties.priority" }
11182
- },
11183
11533
  // StrategicPillarProperties: StrategicPillar entity. Durable multi-year direction the product commits to.
11184
11534
  strategic_pillar: {
11185
11535
  owner: { type: "string", description: "Owning person or team" },
@@ -11213,19 +11563,20 @@ var UPG_PROPERTY_SCHEMA = {
11213
11563
  support_ticket: {
11214
11564
  ticket_type: { type: "string", enum: ["bug", "question", "feature_request"], description: "Classification of the ticket" },
11215
11565
  severity: {
11216
- type: "object",
11566
+ type: "assessment",
11567
+ scale_id: "severity_5",
11217
11568
  description: "Impact severity of the issue (1 = cosmetic, 5 = service down)",
11218
11569
  properties: {
11219
11570
  value: { type: "number", description: "The numeric value, used for computation." },
11220
11571
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11221
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11222
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11572
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11573
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11223
11574
  },
11224
11575
  required: ["value", "label"]
11225
11576
  },
11226
11577
  resolution: { type: "string", description: "Description of how the ticket was resolved" },
11227
11578
  source: { type: "string", description: 'Where the ticket originated (e.g. "email", "in-app", "chat")' },
11228
- signal_sentiment: { type: "string", enum: ["positive", "negative", "neutral", "mixed"], description: "Detected sentiment of the customer's message" },
11579
+ signal_sentiment: { type: "string", enum: ["positive", "neutral", "negative", "mixed"], description: "Detected sentiment of the customer's message" },
11229
11580
  signal_channel: { type: "string", description: "Channel through which the signal was received" },
11230
11581
  signal_urgency: { type: "string", enum: ["low", "medium", "high", "critical"], description: "Perceived urgency of the customer's request" }
11231
11582
  },
@@ -11246,19 +11597,20 @@ var UPG_PROPERTY_SCHEMA = {
11246
11597
  symptom_description: { type: "string", description: "Plain-language description of observed behaviour. Primary content of the entity." },
11247
11598
  first_observed_at: { type: "string", description: "ISO timestamp first observed in the wild. Pairs with `frequency_rating` and `reproducibility` for triage." },
11248
11599
  severity: {
11249
- type: "object",
11600
+ type: "assessment",
11601
+ scale_id: "severity_5",
11250
11602
  description: "Severity for affected users. Independent of how widespread the symptom is. Canonicalised in v0.4.0: the ad-hoc `'low' | 'medium' | 'high' | 'critical'` shape was replaced by `UPGAssessment`.",
11251
11603
  properties: {
11252
11604
  value: { type: "number", description: "The numeric value, used for computation." },
11253
11605
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11254
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11255
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11606
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11607
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11256
11608
  },
11257
11609
  required: ["value", "label"]
11258
11610
  },
11259
11611
  frequency_count: { type: "number", description: "Exact observation count in the period. Pairs with `frequency_period` for a precise rate." },
11260
11612
  frequency_period: { type: "string", description: "Recurrence period (ISO-8601 `Duration`). @example 'P7D' (per week), 'P1D' (per day), 'PT1H' (per hour)" },
11261
- frequency_rating: { type: "string", enum: ["rare", "occasional", "regular", "constant", "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`." },
11613
+ 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`." },
11262
11614
  affected_users_estimate: { type: "number", description: "Approximate count of users affected. Snapshot estimate." },
11263
11615
  reproducibility: { type: "string", enum: ["always", "frequent", "intermittent", "rare", "once"], description: "Reproduction reliability" },
11264
11616
  steps_to_reproduce: { type: "string", description: "Steps to reproduce" }
@@ -11271,7 +11623,6 @@ var UPG_PROPERTY_SCHEMA = {
11271
11623
  },
11272
11624
  // TaskProperties: Task: a discrete unit of work, smaller than a story.
11273
11625
  task: {
11274
- task_status: { type: "string", enum: ["todo", "in_progress", "in_review", "done"], description: "@deprecated since v0.4.0. Use top-level `UPGBaseNode.status`. Values map identically: todo | in_progress | in_review | done. Migration: `UPG_PROPERTY_MIGRATIONS['0.4.0']` lifts this to `status`." },
11275
11626
  assignee: { type: "string", description: "Assigned person" },
11276
11627
  effort: { type: "string", description: 'Effort estimate (e.g. "2h", "1d", "3 points"). Use a consistent unit within your team.' },
11277
11628
  priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Relative importance against other tasks" },
@@ -11296,24 +11647,26 @@ var UPG_PROPERTY_SCHEMA = {
11296
11647
  technical_debt_item: {
11297
11648
  debt_type: { type: "string", enum: ["code", "architecture", "security", "test", "docs", "dependency"], description: "Type of debt. `code` = quality issues. `architecture` = structural problems. `security` = unpatched vulnerabilities. `test` = missing/flaky tests. `docs` = missing or stale documentation. `dependency` = outdated packages." },
11298
11649
  severity: {
11299
- type: "object",
11650
+ type: "assessment",
11651
+ scale_id: "severity_5",
11300
11652
  description: "Severity on system or team. Requires human evaluation.",
11301
11653
  properties: {
11302
11654
  value: { type: "number", description: "The numeric value, used for computation." },
11303
11655
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11304
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11305
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11656
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11657
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11306
11658
  },
11307
11659
  required: ["value", "label"]
11308
11660
  },
11309
11661
  effort_to_fix: {
11310
- type: "object",
11662
+ type: "assessment",
11663
+ scale_id: "effort_5",
11311
11664
  description: "Estimated effort to resolve. Requires team knowledge of the codebase.",
11312
11665
  properties: {
11313
11666
  value: { type: "number", description: "The numeric value, used for computation." },
11314
11667
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11315
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11316
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11668
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11669
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11317
11670
  },
11318
11671
  required: ["value", "label"]
11319
11672
  },
@@ -11396,24 +11749,26 @@ var UPG_PROPERTY_SCHEMA = {
11396
11749
  threat: {
11397
11750
  category: { type: "string", description: 'Attack or threat scenario. @example "injection", "misconfiguration", "social engineering", "supply chain"' },
11398
11751
  likelihood: {
11399
- type: "object",
11752
+ type: "assessment",
11753
+ scale_id: "confidence_5",
11400
11754
  description: "Likelihood (1 = theoretical, 5 = actively exploited). @example value 5 for a known, exploitable, commonly targeted pattern",
11401
11755
  properties: {
11402
11756
  value: { type: "number", description: "The numeric value, used for computation." },
11403
11757
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11404
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11405
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11758
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11759
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11406
11760
  },
11407
11761
  required: ["value", "label"]
11408
11762
  },
11409
11763
  impact: {
11410
- type: "object",
11764
+ type: "assessment",
11765
+ scale_id: "impact_5",
11411
11766
  description: "Impact (1 = minimal, 5 = catastrophic). @example value 5 for threats that expose PII or cause complete service compromise",
11412
11767
  properties: {
11413
11768
  value: { type: "number", description: "The numeric value, used for computation." },
11414
11769
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11415
- scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)" },
11416
- normalized: { type: "number", description: "Normalized 0\u20131 value for cross-tool comparison (optional)" }
11770
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11771
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11417
11772
  },
11418
11773
  required: ["value", "label"]
11419
11774
  },
@@ -11471,7 +11826,7 @@ var UPG_PROPERTY_SCHEMA = {
11471
11826
  // UserAdvisoryBoardProperties: User advisory board.
11472
11827
  user_advisory_board: {
11473
11828
  member_count: { type: "number", description: "Number of members on the board" },
11474
- meeting_cadence: { type: "string", description: 'How often the board meets (e.g. "monthly", "quarterly")' },
11829
+ 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." },
11475
11830
  board_focus: { type: "string", description: "Primary topic or area the board advises on" }
11476
11831
  },
11477
11832
  // UserFlowProperties: User flow.
@@ -11487,6 +11842,13 @@ var UPG_PROPERTY_SCHEMA = {
11487
11842
  journey_type: { type: "string", enum: ["current_state", "future_state", "day_in_the_life", "service_blueprint"], description: "Maps current or future state" },
11488
11843
  scenario: { type: "string", description: "Scenario context" }
11489
11844
  },
11845
+ // UserStoryProperties: "As X, I want Y so Z" templated promise on a user story (UCS pattern P5).
11846
+ user_story: {
11847
+ as_a: { type: "string", description: '"As a [persona], \u2026". Free-text persona name or slug ref.' },
11848
+ i_want_to: { type: "string", description: "Capability or action the persona wants." },
11849
+ so_that: { type: "string", description: "Benefit or outcome the persona expects." },
11850
+ text: { type: "string", description: "Free-form story text. Used as a single-line rendered view." }
11851
+ },
11490
11852
  // ValueObjectProperties: DDD value object.
11491
11853
  value_object: {
11492
11854
  immutable: { type: "boolean", description: "Whether immutable" },
@@ -11501,7 +11863,7 @@ var UPG_PROPERTY_SCHEMA = {
11501
11863
  },
11502
11864
  // ValueStreamProperties: ValueStream entity.
11503
11865
  value_stream: {
11504
- stream_stage: { type: "string", description: "Current stage in the value delivery pipeline" },
11866
+ stream_stage: { type: "string", enum: ["discovery", "definition", "build", "delivery", "operation", "other"], description: "Current stage in the value delivery pipeline (UPG-579 Option B)." },
11505
11867
  lead_time: { type: "string", description: 'End-to-end lead time. @example "2 weeks"' },
11506
11868
  throughput: { type: "string", description: 'Throughput measure. @example "5 features/sprint"' }
11507
11869
  },
@@ -11521,7 +11883,18 @@ var UPG_PROPERTY_SCHEMA = {
11521
11883
  vulnerability: {
11522
11884
  cve_id: { type: "string", description: 'CVE identifier from the National Vulnerability Database. @example "CVE-2024-1234"' },
11523
11885
  cvss_score: { type: "number", description: "CVSS numeric score (0.0\u201310.0). Computed from the CVSS vector. Distinct from the categorical `severity`. @example 9.8 (critical), 6.5 (medium), 3.7 (low)" },
11524
- severity: { type: "string", enum: ["critical", "high", "medium", "low", "informational"], description: 'Categorical severity derived from CVSS. `critical` = 9.0\u201310.0. `high` = 7.0\u20138.9. `medium` = 4.0\u20136.9. `low` = 0.1\u20133.9. `informational` = 0.0. Score alone is insufficient for triage; severity drives filtering and prioritisation. @example "critical" for a remotely exploitable, no-auth-required vulnerability' },
11886
+ severity: {
11887
+ type: "assessment",
11888
+ scale_id: "severity_5",
11889
+ description: "Categorical severity derived from CVSS. Impact severity (UPGAssessment on the `severity_5` scale). Score alone is insufficient for triage; severity drives filtering and prioritisation. Migrated from the inline `critical|high|medium|low|informational` enum (UPG-579 Option C): map `critical` -> 5, `high` -> 4, `medium` -> 3, `low` -> 2, `informational` -> 1; carry the old word in `label`. @example value 5, label 'Critical', scale_id 'severity_5' (a remotely exploitable, no-auth vuln)",
11890
+ properties: {
11891
+ value: { type: "number", description: "The numeric value, used for computation." },
11892
+ label: { type: "string", description: "The qualitative label (what the assessor meant)." },
11893
+ scale_id: { type: "string", description: "Which assessment scale this was rated on (optional)." },
11894
+ normalized: { type: "number", description: "Normalized 0-1 value for cross-tool comparison (optional)." }
11895
+ },
11896
+ required: ["value", "label"]
11897
+ },
11525
11898
  cvss_version: { type: "string", enum: ["v3.1", "v4.0"], description: 'CVSS scoring version. v3.1 and v4.0 differ significantly for the same vulnerability. @example "v4.0" for vulnerabilities scored after the v4.0 release in 2023' },
11526
11899
  affected_component: { type: "string", description: 'Affected component, library, or system. @example "lodash", "openssl", "login service"' },
11527
11900
  affected_package: { type: "string", description: 'Affected package with version. More precise than `affected_component`. @example "lodash@4.17.20", "openssl@1.1.1q"' },
@@ -16163,6 +16536,7 @@ var STRATEGY_OUTCOMES_PLAYBOOK = {
16163
16536
  description: "Cascade vision through themes, outcomes, objectives, key results, and the bets you are making to get there.",
16164
16537
  region: "strategy_outcomes",
16165
16538
  is_canonical: true,
16539
+ related_framework_ids: ["okr-framework", "three-horizons", "north-star-metric", "metrics-tree", "wardley-map"],
16166
16540
  target_anchor_entity: "objective",
16167
16541
  creation_sequence: [
16168
16542
  seqStep(
@@ -16217,6 +16591,7 @@ var USERS_NEEDS_PLAYBOOK = {
16217
16591
  description: "Bootstrap personas, jobs, needs, and desired outcomes: the user side of every product graph.",
16218
16592
  region: "users_needs",
16219
16593
  is_canonical: true,
16594
+ related_framework_ids: ["persona-canvas", "empathy-map", "value-proposition-canvas", "kano-model"],
16220
16595
  target_anchor_entity: "persona",
16221
16596
  creation_sequence: [
16222
16597
  seqStep(
@@ -16270,6 +16645,7 @@ var DISCOVERY_RESEARCH_VALIDATION_PLAYBOOK = {
16270
16645
  description: "Evidence-first discovery sequence: plan \u2192 recruit \u2192 observe \u2192 synthesize \u2192 insight \u2192 opportunity \u2192 hypothesis \u2192 test.",
16271
16646
  region: "discovery_research_validation",
16272
16647
  is_canonical: true,
16648
+ related_framework_ids: ["double-diamond", "opportunity-solution-tree", "build-measure-learn", "hypothesis-board"],
16273
16649
  target_anchor_entity: "opportunity",
16274
16650
  creation_sequence: [
16275
16651
  seqStep(
@@ -16346,6 +16722,7 @@ var MARKET_COMPETITIVE_PLAYBOOK = {
16346
16722
  description: "Map the competitive landscape: define the market, name the alternatives, read trends, find moves.",
16347
16723
  region: "market_competitive",
16348
16724
  is_canonical: true,
16725
+ related_framework_ids: ["porter-five-forces", "swot-analysis", "value-chain-analysis", "wardley-map", "bullseye-framework"],
16349
16726
  target_anchor_entity: "competitor",
16350
16727
  creation_sequence: [
16351
16728
  seqStep(
@@ -16393,6 +16770,7 @@ var EXPERIENCE_DESIGN_BRAND_PLAYBOOK = {
16393
16770
  description: "Journey-first design sequence: research \u2192 personas \u2192 journeys \u2192 define \u2192 ideate \u2192 prototype \u2192 test \u2192 design system.",
16394
16771
  region: "experience_design_brand",
16395
16772
  is_canonical: true,
16773
+ related_framework_ids: ["double-diamond", "atomic-design", "story-map"],
16396
16774
  target_anchor_entity: "user_journey",
16397
16775
  creation_sequence: [
16398
16776
  seqStep(
@@ -16500,6 +16878,7 @@ var PRODUCT_DELIVERY_PLAYBOOK = {
16500
16878
  description: "Shape what gets built: features, epics, user stories, releases, milestones, and the dependencies between them.",
16501
16879
  region: "product_delivery",
16502
16880
  is_canonical: true,
16881
+ related_framework_ids: ["story-map", "rice-scoring", "moscow", "now-next-later", "shape-up", "kano-model"],
16503
16882
  target_anchor_entity: "feature",
16504
16883
  creation_sequence: [
16505
16884
  seqStep(
@@ -16563,6 +16942,7 @@ var ENGINEERING_PLATFORM_PLAYBOOK = {
16563
16942
  description: "Architecture-first engineering sequence: architecture \u2192 services \u2192 data \u2192 build \u2192 test \u2192 deploy \u2192 monitor \u2192 security.",
16564
16943
  region: "engineering_platform",
16565
16944
  is_canonical: true,
16945
+ related_framework_ids: ["c4-model", "adr-log", "dora-metrics"],
16566
16946
  target_anchor_entity: "service",
16567
16947
  creation_sequence: [
16568
16948
  seqStep(
@@ -16637,6 +17017,7 @@ var BUSINESS_GTM_GROWTH_PLAYBOOK = {
16637
17017
  description: "Viability-first business sequence: value prop \u2192 customer \u2192 revenue \u2192 costs \u2192 unit economics \u2192 GTM \u2192 competitive advantage.",
16638
17018
  region: "business_gtm_growth",
16639
17019
  is_canonical: true,
17020
+ related_framework_ids: ["business-model-canvas", "pirate-metrics-aarrr", "north-star-metric", "product-led-growth-framework", "marketing-mix-4ps"],
16640
17021
  target_anchor_entity: "value_proposition",
16641
17022
  creation_sequence: [
16642
17023
  seqStep(
@@ -16856,6 +17237,7 @@ var ANALYTICS_DATA_PLAYBOOK = {
16856
17237
  description: "Bootstrap the measurement plane: sources, schemas, pipelines, metrics, dashboards, and the rules that keep them honest.",
16857
17238
  region: "analytics_data",
16858
17239
  is_canonical: true,
17240
+ related_framework_ids: ["metrics-tree", "north-star-metric", "pirate-metrics-aarrr", "dora-metrics"],
16859
17241
  target_anchor_entity: "metric",
16860
17242
  creation_sequence: [
16861
17243
  seqStep(
@@ -16903,6 +17285,7 @@ var OPERATIONS_QUALITY_PLAYBOOK = {
16903
17285
  description: "The operational backbone: pipelines, monitoring, incident response, security, quality gates, compliance, support. Specialised playbooks cover team rituals.",
16904
17286
  region: "operations_quality",
16905
17287
  is_canonical: true,
17288
+ related_framework_ids: ["raci-matrix", "retrospective", "team-health-check", "raid-log"],
16906
17289
  target_anchor_entity: "incident",
16907
17290
  creation_sequence: [
16908
17291
  seqStep(
@@ -23808,7 +24191,7 @@ function isCanonical(text) {
23808
24191
  }
23809
24192
 
23810
24193
  // src/index.ts
23811
- var UPG_VERSION = "0.7.3";
24194
+ var UPG_VERSION = "0.8.0";
23812
24195
  var UPG_FORMAT_VERSION = "0.4.0";
23813
24196
  var MARKDOWN_FORMAT_VERSION = "0.1";
23814
24197
  var UPG_TYPES = getTypes();
@@ -23896,6 +24279,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
23896
24279
  OPERATIONS_TEAM_RITUALS_PLAYBOOK,
23897
24280
  PRODUCT_DELIVERY_PLAYBOOK,
23898
24281
  PRODUCT_FEEDBACK_SYNTHESIS_PLAYBOOK,
24282
+ PROPERTY_SCALE_MAP,
23899
24283
  REFLECT_MODES,
23900
24284
  STRATEGY_OUTCOMES_PLAYBOOK,
23901
24285
  UPG_ACTIVE_TYPES,
@@ -23996,6 +24380,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
23996
24380
  getMigrationMap,
23997
24381
  getPlaybookById,
23998
24382
  getPlaybooksForRegion,
24383
+ getPropertiesForScale,
23999
24384
  getPropertyDefaultScale,
24000
24385
  getPropertyMigrations,
24001
24386
  getPropertySchema,