@unified-product-graph/core 0.29.0 → 0.31.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.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * @see registry/entity-meta.ts for type IDs and maturity
12
12
  * @see grammar/hierarchy.ts for parent-child rules
13
13
  */
14
- type UPGEntityType = 'specification' | 'primitive' | 'operating_lifecycle' | 'operating_stage' | 'product' | 'outcome' | 'objective' | 'key_result' | 'metric' | 'metric_quality_assessment' | 'vision' | 'mission' | 'strategic_theme' | 'initiative' | 'capability' | 'value_stream' | 'strategic_pillar' | 'assumption' | 'decision' | 'constraint' | 'strategic_question' | 'persona' | 'job' | 'need' | 'desired_outcome' | 'job_step' | 'switching_cost' | 'opportunity' | 'solution' | 'feasibility_study' | 'design_sprint' | 'hypothesis' | 'hypothesis_evidence' | 'experiment' | 'experiment_plan' | 'experiment_run' | 'learning' | 'test_plan' | 'evidence' | 'research_plan' | 'competitor' | 'competitor_feature' | 'competitor_signal' | 'market_trend' | 'market_segment' | 'competitive_analysis' | 'classification_axis' | 'classification_value' | 'research_study' | 'insight' | 'participant' | 'observation' | 'quote' | 'affinity_cluster' | 'research_question' | 'interview_guide' | 'survey_response' | 'user_journey' | 'journey_step' | 'journey_phase' | 'journey_action' | 'design_question' | 'design_concept' | 'prototype' | 'wireframe' | 'user_flow' | 'screen' | 'screen_state' | 'surface' | 'annotation' | 'interaction_spec' | 'design_component' | 'design_token' | 'design_system' | 'design_pattern' | 'design_guideline' | 'brand_identity' | 'brand_colour' | 'brand_typography' | 'brand_voice' | 'brand_logo' | 'brand_imagery' | 'feature_area' | 'feature' | 'epic' | 'user_story' | 'story_statement' | 'story_task' | 'acceptance_criterion' | 'release' | 'task' | 'bug' | 'roadmap' | 'roadmap_item' | 'theme' | 'roadmap_theme' | 'changelog' | 'planning_cycle' | 'bounded_context' | 'service' | 'domain_event' | 'api_contract' | 'technical_debt_item' | 'feature_flag' | 'deployment' | 'aggregate' | 'domain_entity' | 'value_object' | 'command' | 'read_model' | 'api_endpoint' | 'database_schema' | 'queue_topic' | 'build_artifact' | 'code_repository' | 'library_dependency' | 'integration_pattern' | 'external_api' | 'data_flow' | 'investigation' | 'root_cause' | 'symptom' | 'fix' | 'funnel' | 'funnel_step' | 'acquisition_channel' | 'growth_campaign' | 'cohort' | 'behavioral_segment' | 'growth_loop' | 'variant' | 'attribution_model' | 'business_model' | 'value_proposition' | 'revenue_stream' | 'pricing_tier' | 'cost_structure' | 'unit_economics' | 'partnership' | 'key_resource' | 'key_activity' | 'customer_relationship' | 'distribution_channel' | 'gtm_strategy' | 'ideal_customer_profile' | 'positioning' | 'messaging' | 'launch' | 'content_strategy' | 'sales_motion' | 'competitive_battle_card' | 'demand_gen_program' | 'territory' | 'objection' | 'rebuttal' | 'proof_point' | 'team' | 'role' | 'stakeholder' | 'person' | 'team_okr' | 'retrospective' | 'dependency' | 'department' | 'skill' | 'ceremony' | 'capacity_plan' | 'data_source' | 'event_schema' | 'dashboard' | 'data_model' | 'data_quality_rule' | 'data_product' | 'data_pipeline' | 'data_lineage' | 'glossary_term' | 'data_domain' | 'report' | 'content_piece' | 'knowledge_base_article' | 'brand_asset' | 'prompt_template' | 'content_calendar' | 'content_theme' | 'documentation_template' | 'document' | 'legal_entity' | 'ip_asset' | 'contract' | 'contract_clause' | 'privacy_policy' | 'compliance_requirement' | 'risk' | 'data_contract' | 'audit_log_policy' | 'compliance_framework' | 'security_audit' | 'service_level_indicator' | 'service_level_objective' | 'error_budget' | 'incident' | 'postmortem' | 'runbook' | 'monitor' | 'alert_rule' | 'ci_pipeline' | 'release_strategy' | 'on_call_rotation' | 'infrastructure_component' | 'threat_model' | 'threat' | 'vulnerability' | 'security_control' | 'security_policy' | 'penetration_test' | 'security_review' | 'data_classification' | 'access_policy' | 'a11y_standard' | 'a11y_guideline' | 'a11y_audit' | 'a11y_issue' | 'a11y_annotation' | 'test_suite' | 'test_case' | 'qa_session' | 'regression_test' | 'test_coverage_report' | 'test_environment' | 'test_result' | 'feedback_program' | 'feature_request' | 'feedback_vote' | 'nps_campaign' | 'user_advisory_board' | 'beta_program' | 'feedback_theme' | 'pricing_strategy' | 'discount_strategy' | 'trial_config' | 'paywall' | 'ai_model' | 'prompt_version' | 'eval_benchmark' | 'eval_run' | 'ai_cost_tracker' | 'hallucination_report' | 'ai_guardrail' | 'model_comparison' | 'ai_experiment' | 'ai_dataset' | 'ai_trace' | 'workflow_template' | 'workflow_run' | 'agent_definition' | 'agent_session' | 'review_gate' | 'approval_record' | 'agent_skill' | 'agent_hook' | 'workflow_artifact' | 'agent_task' | 'organization' | 'portfolio' | 'product_area' | 'workspace' | 'framework_exercise' | 'account' | 'contact' | 'lead' | 'deal' | 'pipeline_sales' | 'pipeline_stage' | 'quote_document' | 'subscription' | 'invoice' | 'forecast' | 'program' | 'project' | 'milestone' | 'risk_register' | 'change_request' | 'deliverable' | 'resource_allocation' | 'status_report' | 'marketing_strategy' | 'marketing_channel' | 'marketing_campaign_plan' | 'email_sequence' | 'social_post' | 'seo_keyword' | 'ad_creative' | 'press_release' | 'event' | 'community_initiative' | 'support_ticket' | 'customer_feedback' | 'churn_reason' | 'customer_health_score' | 'playbook' | 'service_level_agreement' | 'customer_journey_stage' | 'touchpoint' | 'success_milestone' | 'service_blueprint' | 'locale' | 'translation_key' | 'translation_bundle' | 'locale_config' | 'cultural_adaptation' | 'regional_pricing' | 'education_program' | 'tutorial' | 'walkthrough' | 'webinar' | 'certification' | 'help_video' | 'learning_path' | 'partner_program' | 'partner_tier' | 'api_ecosystem' | 'marketplace_listing' | 'developer_portal' | 'integration_partner' | 'partner_revenue_share';
14
+ type UPGEntityType = 'specification' | 'primitive' | 'operating_lifecycle' | 'operating_stage' | 'product' | 'outcome' | 'objective' | 'key_result' | 'metric' | 'metric_quality_assessment' | 'vision' | 'mission' | 'strategic_theme' | 'initiative' | 'capability' | 'value_stream' | 'strategic_pillar' | 'assumption' | 'decision' | 'constraint' | 'strategic_question' | 'persona' | 'job' | 'need' | 'desired_outcome' | 'job_step' | 'switching_cost' | 'opportunity' | 'solution' | 'feasibility_study' | 'design_sprint' | 'hypothesis' | 'hypothesis_evidence' | 'experiment' | 'experiment_plan' | 'experiment_run' | 'learning' | 'test_plan' | 'evidence' | 'research_plan' | 'competitor' | 'competitor_feature' | 'competitor_signal' | 'market_trend' | 'market_segment' | 'competitive_analysis' | 'classification_axis' | 'classification_value' | 'research_study' | 'insight' | 'participant' | 'observation' | 'quote' | 'affinity_cluster' | 'research_question' | 'interview_guide' | 'survey_response' | 'user_journey' | 'journey_step' | 'journey_phase' | 'journey_action' | 'design_question' | 'design_concept' | 'prototype' | 'wireframe' | 'user_flow' | 'screen' | 'screen_state' | 'surface' | 'annotation' | 'interaction_spec' | 'design_component' | 'design_token' | 'design_system' | 'design_pattern' | 'design_guideline' | 'brand_identity' | 'brand_colour' | 'brand_typography' | 'brand_voice' | 'brand_logo' | 'brand_imagery' | 'feature_area' | 'feature' | 'epic' | 'user_story' | 'story_statement' | 'story_task' | 'acceptance_criterion' | 'release' | 'task' | 'bug' | 'roadmap' | 'roadmap_item' | 'theme' | 'roadmap_theme' | 'changelog' | 'planning_cycle' | 'configuration_axis' | 'bounded_context' | 'service' | 'domain_event' | 'api_contract' | 'technical_debt_item' | 'feature_flag' | 'deployment' | 'aggregate' | 'domain_entity' | 'value_object' | 'command' | 'read_model' | 'api_endpoint' | 'database_schema' | 'queue_topic' | 'build_artifact' | 'code_repository' | 'library_dependency' | 'integration_pattern' | 'external_api' | 'data_flow' | 'investigation' | 'root_cause' | 'symptom' | 'fix' | 'funnel' | 'funnel_step' | 'acquisition_channel' | 'growth_campaign' | 'cohort' | 'behavioral_segment' | 'growth_loop' | 'variant' | 'attribution_model' | 'business_model' | 'value_proposition' | 'revenue_stream' | 'pricing_tier' | 'cost_structure' | 'unit_economics' | 'partnership' | 'key_resource' | 'key_activity' | 'customer_relationship' | 'distribution_channel' | 'gtm_strategy' | 'ideal_customer_profile' | 'positioning' | 'messaging' | 'launch' | 'content_strategy' | 'sales_motion' | 'competitive_battle_card' | 'demand_gen_program' | 'territory' | 'objection' | 'rebuttal' | 'proof_point' | 'team' | 'role' | 'stakeholder' | 'person' | 'team_okr' | 'retrospective' | 'dependency' | 'department' | 'skill' | 'ceremony' | 'capacity_plan' | 'data_source' | 'event_schema' | 'dashboard' | 'data_model' | 'data_quality_rule' | 'data_product' | 'data_pipeline' | 'data_lineage' | 'glossary_term' | 'data_domain' | 'report' | 'content_piece' | 'knowledge_base_article' | 'brand_asset' | 'prompt_template' | 'content_calendar' | 'content_theme' | 'documentation_template' | 'document' | 'legal_entity' | 'ip_asset' | 'contract' | 'contract_clause' | 'privacy_policy' | 'compliance_requirement' | 'risk' | 'data_contract' | 'audit_log_policy' | 'compliance_framework' | 'security_audit' | 'service_level_indicator' | 'service_level_objective' | 'error_budget' | 'incident' | 'postmortem' | 'runbook' | 'monitor' | 'alert_rule' | 'ci_pipeline' | 'release_strategy' | 'on_call_rotation' | 'infrastructure_component' | 'threat_model' | 'threat' | 'vulnerability' | 'security_control' | 'security_policy' | 'penetration_test' | 'security_review' | 'data_classification' | 'access_policy' | 'a11y_standard' | 'a11y_guideline' | 'a11y_audit' | 'a11y_issue' | 'a11y_annotation' | 'test_suite' | 'test_case' | 'qa_session' | 'regression_test' | 'test_coverage_report' | 'test_environment' | 'test_result' | 'feedback_program' | 'feature_request' | 'feedback_vote' | 'nps_campaign' | 'user_advisory_board' | 'beta_program' | 'feedback_theme' | 'pricing_strategy' | 'discount_strategy' | 'trial_config' | 'paywall' | 'ai_model' | 'prompt_version' | 'eval_benchmark' | 'eval_run' | 'ai_cost_tracker' | 'hallucination_report' | 'ai_guardrail' | 'model_comparison' | 'ai_experiment' | 'ai_dataset' | 'ai_trace' | 'workflow_template' | 'workflow_run' | 'agent_definition' | 'agent_session' | 'review_gate' | 'approval_record' | 'agent_skill' | 'agent_hook' | 'workflow_artifact' | 'agent_task' | 'organization' | 'portfolio' | 'product_area' | 'workspace' | 'framework_exercise' | 'composition' | 'account' | 'contact' | 'lead' | 'deal' | 'pipeline_sales' | 'pipeline_stage' | 'quote_document' | 'subscription' | 'invoice' | 'forecast' | 'program' | 'project' | 'milestone' | 'risk_register' | 'change_request' | 'deliverable' | 'resource_allocation' | 'status_report' | 'marketing_strategy' | 'marketing_channel' | 'marketing_campaign_plan' | 'email_sequence' | 'social_post' | 'seo_keyword' | 'ad_creative' | 'press_release' | 'event' | 'community_initiative' | 'support_ticket' | 'customer_feedback' | 'churn_reason' | 'customer_health_score' | 'playbook' | 'service_level_agreement' | 'customer_journey_stage' | 'touchpoint' | 'success_milestone' | 'service_blueprint' | 'locale' | 'translation_key' | 'translation_bundle' | 'locale_config' | 'cultural_adaptation' | 'regional_pricing' | 'education_program' | 'tutorial' | 'walkthrough' | 'webinar' | 'certification' | 'help_video' | 'learning_path' | 'partner_program' | 'partner_tier' | 'api_ecosystem' | 'marketplace_listing' | 'developer_portal' | 'integration_partner' | 'partner_revenue_share';
15
15
  /**
16
16
  * No entity types are currently deprecated; this union is `never`. The
17
17
  * deprecated-name bridge, which previously widened this union to early
@@ -138,11 +138,27 @@ interface UPGBaseNode {
138
138
  * wall-clock timestamp: generation is deterministic). This file is a GATED
139
139
  * artifact — check:generated re-runs the generator and fails on any drift, so
140
140
  * edit the sources above, never this file.
141
- * Entity types with properties: 324
141
+ * Entity types with properties: 326
142
142
  */
143
143
  interface PropertyDefinition {
144
144
  type: 'string' | 'number' | 'boolean' | 'string[]' | 'object' | 'object[]' | 'assessment';
145
+ /**
146
+ * The CONTRACT: what the property means and the semantics a caller must
147
+ * not get wrong. Two or three sentences. This is what a hover card, a
148
+ * tooltip and a token-conscious agent read.
149
+ */
145
150
  description?: string;
151
+ /**
152
+ * The LONGFORM half (`@remarks` in the source JSDoc): rationale, edge
153
+ * cases, workflow recipes, design history. The reference page renders it
154
+ * behind a disclosure; hovers and schema summaries leave it out.
155
+ *
156
+ * Semantics MOVE here, they are never deleted. A field that stops being
157
+ * findable is worse than a field that is long, which is the lesson a
158
+ * reporter taught by concluding a capability did not exist when it was
159
+ * documented somewhere they did not read.
160
+ */
161
+ notes?: string;
146
162
  enum?: string[];
147
163
  /** For 'assessment'-typed fields: the canonical UPG scale this property is rated on (e.g. 'confidence_5'). */
148
164
  scale_id?: string;
@@ -283,6 +299,68 @@ declare const CLASSIFICATION_EDGE_PROPERTY_SCHEMA: PropertySchema;
283
299
  * a stated period); the writers reject any other key.
284
300
  */
285
301
  declare const DEFER_EDGE_PROPERTY_SCHEMA: PropertySchema;
302
+ /**
303
+ * Property schema carried by `surface_varies_by_configuration_axis` (0.30.0).
304
+ *
305
+ * CONDITIONAL EXISTENCE, expressed as an edge. The surface exists in the stored
306
+ * graph regardless; this edge says which members of the configuration family it
307
+ * appears in. No edge at all means invariant, which is why every graph written
308
+ * before this existed keeps meaning exactly what it meant.
309
+ */
310
+ declare const CONFIGURATION_VARIANCE_EDGE_PROPERTY_SCHEMA: PropertySchema;
311
+ /**
312
+ * Property schema carried by the two surface-composition edges
313
+ * (`surface_contains_surface` and `feature_occupies_surface`), 0.30.0.
314
+ *
315
+ * A single `active_when` key qualifies the relationship by a configuration
316
+ * axis: the edge holds only under the named values, and is absent from every
317
+ * other projection.
318
+ *
319
+ * SCOPE IS THE POINT, NOT AN OVERSIGHT. These two edges are the whole legal
320
+ * surface for the qualifier, and `validate_graph` rejects `active_when` on any
321
+ * other edge type. UPG is not adding a general modality system on one field
322
+ * report; it is answering the composition question that report actually asked.
323
+ * Any further edge earns the qualifier on field evidence, one at a time.
324
+ *
325
+ * A QUALIFIER CANNOT EXPRESS NON-EXISTENCE. If the surface itself is absent
326
+ * under a value, say so on the node with `surface_varies_by_configuration_axis`;
327
+ * the projection then drops this edge as dangling and the qualifier is
328
+ * redundant. Reach for `active_when` only when BOTH endpoints exist and the
329
+ * RELATIONSHIP is what changes: the occupant that moves to a different row, the
330
+ * feature that occupies a different place under the flag.
331
+ *
332
+ * ONE AXIS PER QUALIFIER. An edge conditional on two axes at once is a stated
333
+ * non-goal; where it is genuinely needed, the honest model is one axis whose
334
+ * values are the combinations that actually occur, which is the same discipline
335
+ * as "one axis per semantic lever".
336
+ */
337
+ declare const CONFIGURATION_QUALIFIER_EDGE_PROPERTY_SCHEMA: PropertySchema;
338
+ /**
339
+ * Property schema carried by `workspace_arranges_node`: where a node sits on a
340
+ * canvas, and how its card is presented there.
341
+ *
342
+ * A PLACEMENT IS A FACT ABOUT THE RELATIONSHIP, not about either endpoint. The
343
+ * same persona can sit at different coordinates on five different canvases, and
344
+ * none of those coordinates is a property of the persona. This is the same
345
+ * principle `framework_exercise_includes_node` applies to per-entity results.
346
+ *
347
+ * `selected` IS DELIBERATELY ABSENT. Selection is ephemeral UI state, and
348
+ * persisting it means reloading a canvas restores someone's month-old
349
+ * selection and every click dirties the file. The spec does not bless it.
350
+ *
351
+ * AT MOST ONE ARRANGEMENT PER (WORKSPACE, NODE) PAIR: a card appears once on a
352
+ * canvas. The write amplification is real and named rather than hidden:
353
+ * dragging a card rewrites edge properties and so changes the body checksum,
354
+ * which is diff noise on a shared graph. It is bounded by the tool writing only
355
+ * the canvases a user explicitly keeps, and by viewport panning touching the
356
+ * opaque `canvas` bag rather than any edge.
357
+ *
358
+ * `x` and `y` are expected on every instance. Requiredness here is convention
359
+ * rather than enforcement: `PropertyDefinition.required` names required keys
360
+ * WITHIN a nested object, and the edge-property validator has no top-level
361
+ * required-key concept, so the contract is stated in each description.
362
+ */
363
+ declare const WORKSPACE_ARRANGEMENT_EDGE_PROPERTY_SCHEMA: PropertySchema;
286
364
  declare const UPG_EDGE_CATALOG: {
287
365
  product_targets_persona: {
288
366
  forward_verb: string;
@@ -1769,6 +1847,8 @@ declare const UPG_EDGE_CATALOG: {
1769
1847
  classification: "hierarchy";
1770
1848
  source_type: string;
1771
1849
  target_type: string;
1850
+ carries_properties: true;
1851
+ property_schema: PropertySchema;
1772
1852
  };
1773
1853
  surface_serves_job: {
1774
1854
  forward_verb: string;
@@ -1815,12 +1895,44 @@ declare const UPG_EDGE_CATALOG: {
1815
1895
  source_type: string;
1816
1896
  target_type: string;
1817
1897
  };
1898
+ product_defines_configuration_axis: {
1899
+ forward_verb: string;
1900
+ reverse_verb: string;
1901
+ classification: "hierarchy";
1902
+ source_type: string;
1903
+ target_type: string;
1904
+ };
1905
+ feature_flag_drives_configuration_axis: {
1906
+ forward_verb: string;
1907
+ reverse_verb: string;
1908
+ classification: "cross-domain";
1909
+ source_type: string;
1910
+ target_type: string;
1911
+ };
1912
+ surface_varies_by_configuration_axis: {
1913
+ forward_verb: string;
1914
+ reverse_verb: string;
1915
+ classification: "cross-domain";
1916
+ source_type: string;
1917
+ target_type: string;
1918
+ carries_properties: true;
1919
+ property_schema: PropertySchema;
1920
+ };
1921
+ surface_alternates_with_surface: {
1922
+ forward_verb: string;
1923
+ reverse_verb: string;
1924
+ classification: "semantic";
1925
+ source_type: string;
1926
+ target_type: string;
1927
+ };
1818
1928
  feature_occupies_surface: {
1819
1929
  forward_verb: string;
1820
1930
  reverse_verb: string;
1821
1931
  classification: "cross-domain";
1822
1932
  source_type: string;
1823
1933
  target_type: string;
1934
+ carries_properties: true;
1935
+ property_schema: PropertySchema;
1824
1936
  };
1825
1937
  screen_renders_surface: {
1826
1938
  forward_verb: string;
@@ -3215,6 +3327,20 @@ declare const UPG_EDGE_CATALOG: {
3215
3327
  source_type: string;
3216
3328
  target_type: string;
3217
3329
  };
3330
+ eval_benchmark_measures_node: {
3331
+ forward_verb: string;
3332
+ reverse_verb: string;
3333
+ classification: "semantic";
3334
+ source_type: string;
3335
+ target_type: string;
3336
+ };
3337
+ eval_benchmark_draws_cases_from_ai_dataset: {
3338
+ forward_verb: string;
3339
+ reverse_verb: string;
3340
+ classification: "semantic";
3341
+ source_type: string;
3342
+ target_type: string;
3343
+ };
3218
3344
  ai_guardrail_enforces_security_policy: {
3219
3345
  forward_verb: string;
3220
3346
  reverse_verb: string;
@@ -3425,6 +3551,13 @@ declare const UPG_EDGE_CATALOG: {
3425
3551
  source_type: string;
3426
3552
  target_type: string;
3427
3553
  };
3554
+ agent_task_executes_task: {
3555
+ forward_verb: string;
3556
+ reverse_verb: string;
3557
+ classification: "cross-domain";
3558
+ source_type: string;
3559
+ target_type: string;
3560
+ };
3428
3561
  product_measures_funnel: {
3429
3562
  forward_verb: string;
3430
3563
  reverse_verb: string;
@@ -5231,6 +5364,13 @@ declare const UPG_EDGE_CATALOG: {
5231
5364
  source_type: string;
5232
5365
  target_type: string;
5233
5366
  };
5367
+ product_targets_milestone: {
5368
+ forward_verb: string;
5369
+ reverse_verb: string;
5370
+ classification: "hierarchy";
5371
+ source_type: string;
5372
+ target_type: string;
5373
+ };
5234
5374
  project_produces_deliverable: {
5235
5375
  forward_verb: string;
5236
5376
  reverse_verb: string;
@@ -5917,6 +6057,22 @@ declare const UPG_EDGE_CATALOG: {
5917
6057
  source_type: string;
5918
6058
  target_type: string;
5919
6059
  };
6060
+ workspace_arranges_node: {
6061
+ forward_verb: string;
6062
+ reverse_verb: string;
6063
+ classification: "cross-domain";
6064
+ source_type: string;
6065
+ target_type: string;
6066
+ carries_properties: true;
6067
+ property_schema: PropertySchema;
6068
+ };
6069
+ composition_focuses_node: {
6070
+ forward_verb: string;
6071
+ reverse_verb: string;
6072
+ classification: "cross-domain";
6073
+ source_type: string;
6074
+ target_type: string;
6075
+ };
5920
6076
  feature_addresses_job: {
5921
6077
  forward_verb: string;
5922
6078
  reverse_verb: string;
@@ -7904,7 +8060,9 @@ declare function isDeliberateOnlyEdge(type: string): boolean;
7904
8060
  /**
7905
8061
  * Canonical allow-list of edges that use the `'node'` wildcard endpoint.
7906
8062
  *
7907
- * Eight semantic families are sanctioned:
8063
+ * Ten semantic families are sanctioned. The count and the partition are
8064
+ * asserted in `spec-integrity.test.ts`, so this list cannot silently fall out
8065
+ * of step with the array below the way it did between 0.28.0 and 0.31.0:
7908
8066
  *
7909
8067
  * 1. **Universal semantic verbs**: any node can inform / constrain / inspire
7910
8068
  * any other node. The meaning is deliberately abstract; consumers render
@@ -7928,6 +8086,17 @@ declare function isDeliberateOnlyEdge(type: string): boolean;
7928
8086
  * produce any entity type arranged in it (decision, feature, persona, ...).
7929
8087
  * Widened from the single-target `workspace_produced_decision`; see
7930
8088
  * `UPG_EDGE_MIGRATIONS` for the rename rule.
8089
+ * 9. **Canvas arrangement and published-view focus**: any entity can be dragged
8090
+ * onto a canvas or shown in a published view, and neither placement carries
8091
+ * a structural role, so both collapse polymorphic rather than enumerating
8092
+ * the type universe twice. Both are `cross-domain`, so neither enters
8093
+ * `UPG_VALID_CHILDREN` and neither can be walked as containment.
8094
+ * 10. **Benchmark subject** (0.31.0): an eval measures a tool, a document, a
8095
+ * check, an importer, a feature. Registered as OVER-WIDE by admission,
8096
+ * because a benchmark measures a measurable thing rather than literally any
8097
+ * node; the width is what it costs to avoid answering "what is a tool in the
8098
+ * graph" as a side effect of building an eval harness. Reach for the typed
8099
+ * `eval_benchmark_measures_feature` when the subject IS a feature.
7931
8100
  *
7932
8101
  * Adding a new polymorphic edge requires extending this array AND the
7933
8102
  * spec-integrity regression test, which forces a conscious decision and
@@ -8715,7 +8884,7 @@ declare const UPG_DOMAINS: readonly [{
8715
8884
  readonly id: "product_spec";
8716
8885
  readonly label: "Product Specification";
8717
8886
  readonly description: "What you are building and shipping. Feature areas group related capabilities. Features, epics, and user stories break work down. Acceptance criteria define done. Tasks and bugs track execution. Releases and changelogs mark what shipped. Roadmaps and roadmap items plan what comes next. Roadmap themes group roadmap work around the customer problem it solves, one level down from the strategic themes in Strategy. Planning cycles are the cadence axis: the named, dated, self-nesting intervals (sprint, iteration, quarter, program increment, cooldown) that work is scheduled through. Translates Strategy into Engineering and tracks delivery through Program Management.";
8718
- readonly types: readonly ["feature", "feature_area", "epic", "user_story", "acceptance_criterion", "release", "task", "bug", "roadmap", "roadmap_item", "roadmap_theme", "changelog", "planning_cycle"];
8887
+ readonly types: readonly ["feature", "feature_area", "epic", "user_story", "acceptance_criterion", "release", "task", "bug", "roadmap", "roadmap_item", "roadmap_theme", "changelog", "planning_cycle", "configuration_axis"];
8719
8888
  }, {
8720
8889
  readonly id: "engineering";
8721
8890
  readonly label: "Engineering";
@@ -8809,7 +8978,7 @@ declare const UPG_DOMAINS: readonly [{
8809
8978
  }, {
8810
8979
  readonly id: "program_mgmt";
8811
8980
  readonly label: "Program Management";
8812
- readonly description: "Coordinating delivery across teams and timelines. Programs are the highest container. Projects break programs down. Milestones mark key dates. Risk registers track threats to delivery. Change requests manage scope changes. Deliverables define what ships. Resource allocations assign effort. Status reports communicate progress. Connects Product Specification (what to deliver) to Team & Organisation (who delivers).";
8981
+ readonly description: "Coordinating delivery across teams and timelines. Programs are the highest container. Projects break programs down. Milestones mark key dates, and hang from either a project or, where a product owns the date outright with no program above it, from the product itself. Risk registers track threats to delivery. Change requests manage scope changes. Deliverables define what ships. Resource allocations assign effort. Status reports communicate progress. Connects Product Specification (what to deliver) to Team & Organisation (who delivers).";
8813
8982
  readonly types: readonly ["program", "project", "milestone", "risk_register", "change_request", "deliverable", "resource_allocation", "status_report"];
8814
8983
  }, {
8815
8984
  readonly id: "marketing";
@@ -8844,8 +9013,8 @@ declare const UPG_DOMAINS: readonly [{
8844
9013
  }, {
8845
9014
  readonly id: "workspace";
8846
9015
  readonly label: "Workspace";
8847
- readonly description: "Spatial thinking spaces for arranging entities, debating decisions, and committing to the graph. Workspaces are transient canvases that sit alongside all other domains, letting you compose and explore relationships before they become permanent graph structure. A framework exercise is a structured workspace: one run of a framework (MoSCoW, RICE, Kano, …) applied to a chosen set of entities, with each entity's result recorded on the exercise-to-entity edge rather than the entity itself.";
8848
- readonly types: readonly ["workspace", "framework_exercise"];
9016
+ readonly description: "Spatial thinking spaces for arranging entities, debating decisions, and committing to the graph. Workspaces are transient canvases that sit alongside all other domains, letting you compose and explore relationships before they become permanent graph structure. A framework exercise is a structured workspace: one run of a framework (MoSCoW, RICE, Kano, …) applied to a chosen set of entities, with each entity's result recorded on the exercise-to-entity edge rather than the entity itself. A composition is the durable other half: a named, published view assembled from a canvas, with a stable slug people link to and a revision history, whose frozen arrangement holds pointers rather than copied content.";
9017
+ readonly types: readonly ["workspace", "framework_exercise", "composition"];
8849
9018
  }, {
8850
9019
  readonly id: "foundations";
8851
9020
  readonly label: "Foundations";
@@ -9011,6 +9180,203 @@ declare const UPG_CONTAINMENT_FREE_TYPES: ReadonlySet<string>;
9011
9180
  */
9012
9181
  declare function isContainmentFreeType(entityType: string): boolean;
9013
9182
 
9183
+ /**
9184
+ * UPG Configuration Projection (0.30.0).
9185
+ *
9186
+ * The stored graph is the UNION of a configuration family. A single
9187
+ * configuration is a PROJECTION of it, and this is the operator that takes one.
9188
+ *
9189
+ * π(G, C) drops what a named configuration does not contain and leaves
9190
+ * everything else exactly as it was. Facts that carry no configuration
9191
+ * qualification are invariant: they belong to every member of the family, which
9192
+ * is why a graph written before this existed projects to itself under every C
9193
+ * and needs no migration.
9194
+ *
9195
+ * PURE, AND DELIBERATELY STORE-FREE. It takes node and edge arrays and returns
9196
+ * node and edge arrays, so the local file store, the cloud SQL store and a
9197
+ * synthetic store built for validation preview all reuse one definition of what
9198
+ * a projection IS. A projection implemented twice is two projections.
9199
+ *
9200
+ * READ-ONLY. Nothing writes a projected graph back. The union is the file.
9201
+ *
9202
+ * https://unifiedproductgraph.org/spec | MIT
9203
+ */
9204
+ /** The minimum a node must expose to be projected. */
9205
+ interface ProjectableNode {
9206
+ id: string;
9207
+ type?: string;
9208
+ properties?: Record<string, unknown> | undefined;
9209
+ }
9210
+ /** The minimum an edge must expose to be projected. */
9211
+ interface ProjectableEdge {
9212
+ id?: string;
9213
+ source: string;
9214
+ target: string;
9215
+ type?: string;
9216
+ properties?: Record<string, unknown> | undefined;
9217
+ }
9218
+ /**
9219
+ * A configuration: axis node id to the single value that holds on it.
9220
+ *
9221
+ * PARTIAL BY DESIGN. An axis absent from the map is not applied, so every fact
9222
+ * qualified on it is retained. Projecting on nothing returns the union, which
9223
+ * makes a configuration a strictly narrowing filter an agent can apply
9224
+ * incrementally rather than an all-or-nothing mode.
9225
+ */
9226
+ type Configuration = Readonly<Record<string, string>>;
9227
+ /** The edge that declares conditional existence. */
9228
+ declare const VARIES_BY_EDGE = "surface_varies_by_configuration_axis";
9229
+ /** The property carried by that edge. */
9230
+ declare const PRESENT_UNDER_PROPERTY = "present_under";
9231
+ /** The qualifier property carried by the two composition edges. */
9232
+ declare const ACTIVE_WHEN_PROPERTY = "active_when";
9233
+ /**
9234
+ * The only edge types on which `active_when` is legal (D3).
9235
+ *
9236
+ * Scope is enforced, not merely documented: `validate_graph`'s
9237
+ * `configuration_drift` scope reports the qualifier on any other edge type as
9238
+ * an error. The projection operator itself is deliberately permissive here (it
9239
+ * honours a qualifier wherever it finds one) so that a graph carrying an
9240
+ * illegal qualifier still projects predictably while the validator names the
9241
+ * problem. Silently ignoring it would make the drift invisible in the one view
9242
+ * where its effect shows.
9243
+ */
9244
+ declare const QUALIFIABLE_EDGE_TYPES: readonly string[];
9245
+ /** Result of a projection: the surviving nodes and edges, plus what it dropped. */
9246
+ interface ProjectionResult<N extends ProjectableNode = ProjectableNode, E extends ProjectableEdge = ProjectableEdge> {
9247
+ nodes: N[];
9248
+ edges: E[];
9249
+ /** Node ids dropped because the configuration excluded them. */
9250
+ excluded_node_ids: string[];
9251
+ /** Count of edges dropped because their own qualifier excluded them. */
9252
+ deactivated_edge_count: number;
9253
+ /** Count of edges dropped because an endpoint was excluded. */
9254
+ dangling_edge_count: number;
9255
+ }
9256
+ /**
9257
+ * Read a string array property defensively; anything else reads as absent.
9258
+ *
9259
+ * Exported so the drift checker and the read-tool view share one reading of
9260
+ * what a list-valued configuration property is. Three copies of this drifting
9261
+ * apart is how a value the validator accepts becomes a value the projection
9262
+ * ignores.
9263
+ */
9264
+ declare function readStringArray(properties: Record<string, unknown> | undefined, key: string): string[] | undefined;
9265
+ /**
9266
+ * Read an `active_when` qualifier, or undefined when the edge carries none or
9267
+ * carries something malformed.
9268
+ *
9269
+ * A malformed qualifier reads as ABSENT rather than as "excludes everything".
9270
+ * Absence means the relationship is invariant, so a broken qualifier leaves the
9271
+ * edge in every projection: the graph shows too much rather than too little,
9272
+ * and `configuration_drift` reports the malformation by name. The alternative
9273
+ * would let one bad property silently delete structure from every view.
9274
+ */
9275
+ declare function readActiveWhen(edge: ProjectableEdge): {
9276
+ axis: string;
9277
+ values: string[];
9278
+ } | undefined;
9279
+ /**
9280
+ * Project a graph onto one configuration.
9281
+ *
9282
+ * Applied in order, ONCE. The operator is a filter, not a solver:
9283
+ *
9284
+ * 1. NODE EXCLUSION. A node is dropped when it declares variance on an axis
9285
+ * named in `configuration` and the chosen value is not in its
9286
+ * `present_under`. A node that says nothing about a named axis is retained,
9287
+ * because silence means invariant.
9288
+ * 2. EDGE DEACTIVATION. An edge is dropped when its own `active_when` names an
9289
+ * axis in `configuration` and the chosen value is not among its values.
9290
+ * 3. DANGLING REMOVAL. Any surviving edge with an endpoint dropped in step 1
9291
+ * goes too.
9292
+ *
9293
+ * NO CASCADE, AND THIS IS THE SUBTLE PART. A child surface is NOT dropped
9294
+ * because its parent was. The motivating field case is precisely a surface
9295
+ * whose PARENT changes under the flag (a navigation row splits in two and an
9296
+ * occupant moves into the new row), so cascading would delete a surface that is
9297
+ * genuinely present. A surface that survives with no containment parent in that
9298
+ * projection is a modelling gap for the validator to report, not a deletion for
9299
+ * the operator to guess at.
9300
+ *
9301
+ * COMMUTATIVE ACROSS AXES. Each axis's predicate reads only that axis, so
9302
+ * projecting on two axes in either order, or both at once, gives the same
9303
+ * result. Multi-axis projection therefore needs no ordering rule.
9304
+ *
9305
+ * @example
9306
+ * // A graph where the inspector exists only under the split-nav flag.
9307
+ * projectGraph(nodes, edges, { axis_nav: 'legacy_nav' }).nodes
9308
+ * // → every node except the split-nav-only surfaces
9309
+ */
9310
+ declare function projectGraph<N extends ProjectableNode = ProjectableNode, E extends ProjectableEdge = ProjectableEdge>(nodes: N[], edges: E[], configuration: Configuration): ProjectionResult<N, E>;
9311
+ /**
9312
+ * Every configuration this graph can be projected onto, one axis at a time.
9313
+ *
9314
+ * PER-AXIS, NOT CARTESIAN. The list is the union (an empty configuration) plus
9315
+ * one entry per declared value of each axis: `1 + Σ|values|`, linear in the
9316
+ * declarations. The cartesian product across axes is combinatorial and buys
9317
+ * nothing here, because every v1 qualifier reads a single axis and every check
9318
+ * that consumes a projection is surface-local. Cross-axis interaction is a
9319
+ * stated non-goal; when a detector needs it, this is the function that grows.
9320
+ */
9321
+ declare function enumerateProjections(nodes: ProjectableNode[]): Array<{
9322
+ axis?: string;
9323
+ value?: string;
9324
+ configuration: Configuration;
9325
+ }>;
9326
+
9327
+ /**
9328
+ * UPG Configuration Drift (0.30.0).
9329
+ *
9330
+ * Structural checking of the configuration declarations themselves: that an
9331
+ * axis is well formed, that every value named anywhere is a value the axis
9332
+ * actually declares, that the qualifier appears only where it is legal, and
9333
+ * that a declared alternation is consistent with what the declarations imply.
9334
+ *
9335
+ * DRIFT, NOT AN ANTI-PATTERN. These are contradictions inside the model, the
9336
+ * same family as an unknown entity type or a status outside its lifecycle: a
9337
+ * graph carrying one is saying something it cannot mean. Anti-patterns are the
9338
+ * other thing, judgements about a graph that is internally consistent, and
9339
+ * 0.30.0 deliberately mints none of those (a detector with no field evidence
9340
+ * behind it is how a check family gets noisy).
9341
+ *
9342
+ * Runs on the UNION. The declarations are facts about the whole family, so they
9343
+ * are checked once, not once per projection. The single exception is
9344
+ * `orphaned_under_projection`, which by definition can only be seen by taking
9345
+ * one.
9346
+ *
9347
+ * https://unifiedproductgraph.org/spec | MIT
9348
+ */
9349
+
9350
+ /** The kinds of configuration drift the validator reports. */
9351
+ type ConfigurationDriftKind = 'axis_values_empty' | 'axis_default_not_a_value' | 'present_under_empty' | 'present_under_unknown_value' | 'qualifier_axis_unresolved' | 'qualifier_values_empty' | 'qualifier_unknown_value' | 'qualifier_on_illegal_edge' | 'alternation_axis_mismatch' | 'alternation_overlap' | 'orphaned_under_projection';
9352
+ /** One configuration-drift finding. */
9353
+ interface ConfigurationDriftFinding {
9354
+ kind: ConfigurationDriftKind;
9355
+ /**
9356
+ * `error` means the graph contradicts itself and a projection of it cannot be
9357
+ * trusted. `warning` means the graph is coherent but a projection of it has a
9358
+ * gap worth looking at.
9359
+ */
9360
+ severity: 'error' | 'warning';
9361
+ /** The node this finding is about, when it is about a node. */
9362
+ node_id?: string;
9363
+ /** The edge this finding is about, when it is about an edge. */
9364
+ edge_id?: string;
9365
+ /** The axis involved, where one is identifiable. */
9366
+ axis_id?: string;
9367
+ /** Human-readable statement of what is wrong. */
9368
+ message: string;
9369
+ }
9370
+ /**
9371
+ * Check every configuration declaration in a graph.
9372
+ *
9373
+ * @param nodes All nodes in the union.
9374
+ * @param edges All edges in the union.
9375
+ * @returns Findings, in a stable order: axis checks, then variance, then
9376
+ * qualifiers, then alternation, then the per-projection orphan warning.
9377
+ */
9378
+ declare function checkConfigurationDrift(nodes: ProjectableNode[], edges: ProjectableEdge[]): ConfigurationDriftFinding[];
9379
+
9014
9380
  /**
9015
9381
  * UPG Lifecycles. Phase-and-state journeys for entity types with meaningful status.
9016
9382
  *
@@ -9297,9 +9663,29 @@ declare function getLifecycleRenderShape(entityType: string): LifecycleRenderSha
9297
9663
  * encoding (value) so UIs can display labels and formulas can compute
9298
9664
  * scores. */
9299
9665
  interface UPGAssessment {
9300
- /** The numeric value, used for computation. */
9666
+ /** The numeric value, used for computation. Must fall within the referenced
9667
+ * scale's `min`..`max`. This is the ONLY field that carries cross-tool meaning. */
9301
9668
  value: number;
9302
- /** The qualitative label: what the assessor actually meant. */
9669
+ /** The qualitative label: what the assessor actually meant.
9670
+ *
9671
+ * FREE TEXT BY CONTRACT (docket wave 2 item 7; clarification STAGED, release
9672
+ * number assigned at release prep). This is the
9673
+ * assessor's own word and is NOT required to equal the `UPGScalePoint.label` of
9674
+ * the matching point. The two are different vocabularies serving different jobs:
9675
+ * `UPGScalePoint.label` is the scale's display name for a point (what a picker
9676
+ * offers); `UPGAssessment.label` is the judgment as it was actually authored
9677
+ * (what a human wrote). `{ value: 5, label: 'critical' }` on a `severity_5`
9678
+ * property is CONFORMANT even though point 5 displays as "Blocker" — indeed
9679
+ * several property descriptions instruct writers to "carry the old word in
9680
+ * `label`" when migrating a legacy enum.
9681
+ *
9682
+ * Consequently: never reconcile stored labels against scale point labels, and
9683
+ * never widen a scale's `points` to admit authored words. Compare on `value`.
9684
+ *
9685
+ * The one exception is `friendly_aliases`. An alias (`low`/`medium`/`high`) is a
9686
+ * writer-side shorthand, not a judgment — expanding it MUST yield both the
9687
+ * canonical `value` and the canonical point label, so an unexpanded alias left
9688
+ * sitting in `label` is a writer bug. */
9303
9689
  label: string;
9304
9690
  /** Which assessment scale this was rated on.
9305
9691
  * References a scale definition in the spec or in the document's
@@ -10805,19 +11191,22 @@ interface ProductProperties {
10805
11191
  launched_at?: ISODateTime;
10806
11192
  /**
10807
11193
  * The product configuration this graph describes, named in plain language.
11194
+ * A label for readers: nothing reads it to gate, filter, or alter how a tool
11195
+ * interprets the graph.
11196
+ *
11197
+ * @example "Enterprise plan, split-navigation flag on"
10808
11198
  *
11199
+ * @remarks
10809
11200
  * A product's composition often differs by feature flag, plan tier,
10810
11201
  * permission level or beta programme: surfaces appear, disappear, or are
10811
11202
  * replaced by different surfaces with different occupants. A graph that
10812
- * models one of those without saying which is qualified by a condition
10813
- * nobody wrote down, and every fact in it inherits that silence.
10814
- *
10815
- * NAMING, NOT CONFIGURING. This is a label for readers. Nothing reads it to
10816
- * gate, filter, or alter how a tool interprets the graph, and it makes no
10817
- * claim about which configuration most customers are on.
11203
+ * models one of those without saying which is qualified by a condition nobody
11204
+ * wrote down, and every fact in it inherits that silence.
10818
11205
  *
10819
- * @example "Enterprise plan, split-navigation flag on"
10820
- * @example "Default: free tier, all flags off"
11206
+ * It makes no claim about which configuration most customers are on. Where a
11207
+ * product genuinely ships several and the differences matter, declare a
11208
+ * `configuration_axis` instead and let each fact say which values it holds
11209
+ * under.
10821
11210
  */
10822
11211
  described_configuration?: string;
10823
11212
  }
@@ -11181,23 +11570,32 @@ interface PersonaProperties {
11181
11570
  * @example "10+ years SaaS experience", "New to healthcare IT" */
11182
11571
  domain_expertise?: string;
11183
11572
  /**
11184
- * Role in the buying / adoption decision (the decision-making-unit split):
11185
- * who signs (buyer) vs who uses (user) vs who advocates internally (champion)
11186
- * vs who shapes the choice (influencer) vs who delivers / implements
11187
- * (partner). A portfolio must separate the economic buyer from the
11188
- * practitioner user; they are distinct personas with distinct jobs. Closed
11189
- * set so roles compare across products.
11573
+ * Role in the buying or adoption decision: who signs (`buyer`), who uses
11574
+ * (`user`), who advocates internally (`champion`), who shapes the choice
11575
+ * (`influencer`), and who delivers it (`partner`). A closed set, so roles
11576
+ * compare across products.
11577
+ *
11190
11578
  * @example "buyer"
11579
+ *
11580
+ * @remarks
11581
+ * A portfolio must separate the economic buyer from the practitioner user:
11582
+ * they are distinct personas with distinct jobs, and collapsing them is how a
11583
+ * product ends up built for whoever was easiest to interview.
11191
11584
  */
11192
11585
  audience_role?: 'buyer' | 'user' | 'champion' | 'influencer' | 'partner';
11193
11586
  /**
11194
- * Who performs the work: a human archetype (default), an autonomous AI agent
11195
- * (e.g. Content Agent), or a non-agentic platform service. Absent = `human`, so
11196
- * existing personas need no migration. An `agent` persona is a first-class actor
11197
- * that participates in journeys via the same persona machinery and that humans
11198
- * delegate to via `persona_delegates_to_persona`. Human-coverage / segmentation
11199
- * metrics count `human` only; agent/system are opt-in.
11587
+ * Who performs the work: a human archetype, an autonomous AI agent, or a
11588
+ * non-agentic platform service. Absent means `human`, so existing personas
11589
+ * need no migration.
11590
+ *
11200
11591
  * @example "agent"
11592
+ *
11593
+ * @remarks
11594
+ * An `agent` persona is a first-class actor: it participates in journeys
11595
+ * through the same persona machinery, and humans delegate to it via
11596
+ * `persona_delegates_to_persona`. Human-coverage and segmentation metrics
11597
+ * count `human` only, so agent and system personas are opt-in rather than
11598
+ * silently inflating a coverage number.
11201
11599
  */
11202
11600
  actor_kind?: 'human' | 'agent' | 'system';
11203
11601
  }
@@ -11444,15 +11842,17 @@ interface HypothesisEvidenceProperties {
11444
11842
  */
11445
11843
  evidence_type?: 'experiment_run' | 'observation' | 'quote' | 'metric_change' | 'market_data' | 'interview';
11446
11844
  /**
11447
- * Direction relative to the parent claim. Canonical direction axis aligned to
11448
- * `Evidence.direction` so every direction-of-evidence property uses the same vocab.
11449
- * `supports` = paired with the `supports` edge.
11450
- * `refutes` = paired with the `refutes` edge.
11451
- * `neutral` = data insufficient or noisy.
11845
+ * Direction relative to the parent claim: `supports` and `refutes` pair with
11846
+ * the edges of the same name, `neutral` means the data is insufficient or
11847
+ * noisy.
11848
+ *
11849
+ * BREAKING in v0.4.0: `confirms`, `disconfirms` and `inconclusive` no longer
11850
+ * type-check. Migration is one-to-one: confirms to supports, disconfirms to
11851
+ * refutes, inconclusive to neutral.
11452
11852
  *
11453
- * BREAKING in v0.4.0: legacy `'confirms'`, `'disconfirms'`, `'inconclusive'` no
11454
- * longer type-check. Migration: `confirms → supports`, `disconfirms → refutes`,
11455
- * `inconclusive → neutral`.
11853
+ * @remarks
11854
+ * Aligned to `Evidence.direction` so every direction-of-evidence property in
11855
+ * the spec shares one vocabulary.
11456
11856
  */
11457
11857
  direction?: EvidenceDirection;
11458
11858
  /** Strength of the evidence (UPGAssessment, scale `scale_5`). */
@@ -11561,6 +11961,20 @@ interface ExperimentPlanProperties {
11561
11961
  * }
11562
11962
  */
11563
11963
  interface ExperimentRunProperties {
11964
+ /**
11965
+ * What sort of experiment this run is: `ab_test` is a controlled split
11966
+ * between variants, `growth` an acquisition or activation experiment,
11967
+ * `pricing` a packaging or willingness-to-pay one. Distinct from
11968
+ * `disposition`, which is the outcome axis.
11969
+ *
11970
+ * @remarks
11971
+ * Three retired types (`ab_test`, `growth_experiment`, `pricing_experiment`)
11972
+ * collapsed into `experiment_run` precisely along this axis, and the
11973
+ * migration defaults stamp it so the distinction survives consolidation.
11974
+ *
11975
+ * Extensible: further kinds may be added in a minor release.
11976
+ */
11977
+ experiment_type?: 'ab_test' | 'growth' | 'pricing';
11564
11978
  /** ISO actual start date (may differ from the plan's `planned_start_date`) */
11565
11979
  actual_start_date?: ISODate;
11566
11980
  /** ISO actual end date */
@@ -11875,19 +12289,21 @@ interface CompetitiveAnalysisProperties {
11875
12289
  */
11876
12290
  framework_id?: string;
11877
12291
  /**
11878
- * Empty cells in a 2-axis classification matrix that earn explicit commentary.
11879
- * Only the strategically interesting cells. Opportunity-kind cells are the most
11880
- * valuable; they identify unoccupied strategic space.
12292
+ * Empty cells in a two-axis classification matrix that earn explicit
12293
+ * commentary, and only the strategically interesting ones. Opportunity-kind
12294
+ * cells are the most valuable: they identify unoccupied strategic space.
11881
12295
  *
11882
- * Each entry references two `classification_value` nodes by id (one from each
11883
- * `classification_axis` child of this `competitive_analysis`). `validate_graph`
11884
- * enforces that the refs resolve to `classification_value` nodes whose parents
11885
- * are distinct `classification_axis` instances.
12296
+ * @remarks
12297
+ * Each entry references two `classification_value` nodes by id, one from each
12298
+ * `classification_axis` child of this `competitive_analysis`.
12299
+ * `validate_graph` enforces that the refs resolve to `classification_value`
12300
+ * nodes whose parents are distinct `classification_axis` instances, so a cell
12301
+ * cannot name two values from the same axis.
11886
12302
  *
11887
12303
  * See `ClassificationValueProperties.commitments` for the inverse
11888
12304
  * "occupied cell" structural-definition shape.
11889
12305
  *
11890
- * @example
12306
+ * A worked pair, one of each rationale kind:
11891
12307
  * [
11892
12308
  * { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-structured-text',
11893
12309
  * rationale_kind: 'opportunity',
@@ -11943,11 +12359,14 @@ interface CompetitorSignalProperties {
11943
12359
  */
11944
12360
  observed_at?: ISODateTime;
11945
12361
  /**
11946
- * Kind of move. `feature_launch` = shipped a feature. `pricing_change` = a plan
11947
- * or tier change. `acquisition` / `partnership` / `market_entry` = strategic moves.
11948
- * `reclassification` = the competitor moved between classification cells on an
11949
- * axis (e.g. ai_integrated to ai_agentic); auto-emitted at the classify-write
11950
- * chokepoint and carries `axis` / `from_value` / `to_value` / `competitor`.
12362
+ * Kind of move: a shipped `feature_launch`, a `pricing_change`, the strategic
12363
+ * `acquisition` / `partnership` / `market_entry`, or a `reclassification`
12364
+ * when the competitor moves between classification cells on an axis.
12365
+ *
12366
+ * @remarks
12367
+ * `reclassification` is auto-emitted at the classify-write chokepoint rather
12368
+ * than authored, and carries `axis`, `from_value`, `to_value` and
12369
+ * `competitor` so the move is reconstructable without diffing two snapshots.
11951
12370
  */
11952
12371
  signal_type?: 'feature_launch' | 'pricing_change' | 'acquisition' | 'partnership' | 'market_entry' | 'reclassification';
11953
12372
  /** One-line factual summary of the move (what shipped, not marketing copy). */
@@ -12106,14 +12525,19 @@ interface ClassificationAxisProperties {
12106
12525
  */
12107
12526
  axis_kind?: 'categorical' | 'ordinal' | 'continuous';
12108
12527
  /**
12109
- * How many values a subject may hold on this axis at once (UPG 0.11.3).
12110
- * `single` (default) = a subject sits at exactly one value; a re-classification
12111
- * to a new value SUPERSEDES the prior one (the classify writer retires the old
12112
- * same-axis edge and records the move in the reclassification history).
12113
- * `multi` = a subject may legitimately hold several values at once (e.g. an
12114
- * axis like "supported frameworks"); re-classifying ADDS a value and does not
12115
- * supersede. A separate axis from `axis_kind`: an axis can be `categorical`
12116
- * (unordered) yet `single`-select, or `categorical` yet `multi`-select.
12528
+ * How many values a subject may hold on this axis at once. `single` (the
12529
+ * default) means re-classifying SUPERSEDES the prior value; `multi` means it
12530
+ * ADDS one.
12531
+ *
12532
+ * @remarks
12533
+ * Under `single` the classify writer retires the old same-axis edge and
12534
+ * records the move in the reclassification history, so the change is
12535
+ * traceable rather than silent. `multi` suits an axis like "supported
12536
+ * frameworks", where holding several values at once is the truth.
12537
+ *
12538
+ * A separate axis from `axis_kind`: an axis can be `categorical` (unordered)
12539
+ * yet single-select, or `categorical` yet multi-select. The two answer
12540
+ * different questions and neither implies the other.
12117
12541
  */
12118
12542
  cardinality?: 'single' | 'multi';
12119
12543
  }
@@ -12150,13 +12574,16 @@ interface ClassificationValueProperties {
12150
12574
  */
12151
12575
  exemplars?: string[];
12152
12576
  /**
12153
- * The N (typically 2–4) load-bearing commitments that define this category.
12154
- * Each commitment is a structural axis; removing it changes the category.
12577
+ * The load-bearing commitments that define this category, typically two to
12578
+ * four. Each is a structural axis: removing it changes the category.
12155
12579
  *
12156
- * Pairs with `capabilities`: commitments are the *load-bearing definition*;
12157
- * capabilities are the *surface offering*.
12580
+ * @remarks
12581
+ * Pairs with `capabilities`, and the distinction matters when deciding where
12582
+ * a bullet belongs: commitments are the load-bearing DEFINITION, capabilities
12583
+ * are the surface OFFERING. A capability can be dropped without the category
12584
+ * changing; a commitment cannot.
12158
12585
  *
12159
- * @example
12586
+ * A worked set:
12160
12587
  * [
12161
12588
  * { name: 'Typed content graph', description: 'Schemas in code; references as edges; content is structured data.' },
12162
12589
  * { name: 'Real-time backend', description: 'Live queries, CRDT collaboration, sub-second propagation.' },
@@ -12165,11 +12592,14 @@ interface ClassificationValueProperties {
12165
12592
  */
12166
12593
  commitments?: Array<ClassificationCommitment>;
12167
12594
  /**
12168
- * Structured capability bullets across the six canonical surfaces.
12169
- * Each surface appears at most once per `classification_value`.
12595
+ * Structured capability bullets across the six canonical surfaces. Each
12596
+ * surface appears at most once per `classification_value`.
12170
12597
  *
12171
- * Pairs with `commitments`: capabilities describe what the category *offers*;
12172
- * commitments describe what *defines* it.
12598
+ * @remarks
12599
+ * Pairs with `commitments`, and the distinction decides where a bullet
12600
+ * belongs: capabilities describe what the category OFFERS, commitments
12601
+ * describe what DEFINES it. Dropping a capability leaves the category intact;
12602
+ * dropping a commitment does not.
12173
12603
  *
12174
12604
  * @example
12175
12605
  * [
@@ -12331,6 +12761,19 @@ interface InsightProperties {
12331
12761
  * @example "usability_study", "interview_series", "survey"
12332
12762
  */
12333
12763
  source_method?: string;
12764
+ /**
12765
+ * Which discipline the insight came out of. The second provenance axis,
12766
+ * symmetrical with `source_method`: that one is HOW the insight was produced,
12767
+ * this one is WHICH PRACTICE produced it, and neither substitutes for the
12768
+ * other.
12769
+ *
12770
+ * @example "ux", "support", "sales", "data_science"
12771
+ *
12772
+ * @remarks
12773
+ * Declared in v0.26.0 so the retired `ux_insight` type's migration default
12774
+ * (`source_domain: 'ux'`) lands in a typed field rather than being lost.
12775
+ */
12776
+ source_domain?: string;
12334
12777
  /**
12335
12778
  * Insight statement in plain language. Write as an active, present-tense assertion.
12336
12779
  * @example "Users consistently skip the tutorial because they trust their ability to explore independently."
@@ -12692,6 +13135,20 @@ interface WireframeProperties {
12692
13135
  * }
12693
13136
  */
12694
13137
  interface UserFlowProperties {
13138
+ /**
13139
+ * What sort of flow this is. Free-form rather than a closed enum, because
13140
+ * flow kinds are product-specific and the spec has no complete vocabulary
13141
+ * for them.
13142
+ *
13143
+ * @example "onboarding", "checkout", "recovery", "upgrade"
13144
+ *
13145
+ * @remarks
13146
+ * `user_flow` otherwise carries only structure (`trigger`, `steps`,
13147
+ * `success_state`, `failure_state`) and no classification. The retired
13148
+ * `onboarding_flow` type collapsed into `user_flow` along this axis, and its
13149
+ * migration default stamps the value so the distinction survives.
13150
+ */
13151
+ flow_type?: string;
12695
13152
  /**
12696
13153
  * Display order of this flow among sibling flows (0-indexed). The scalar
12697
13154
  * ordering convention shared with `journey_step.step_order` and
@@ -12857,14 +13314,36 @@ type SurfaceCompositionMode = 'exclusive' | 'additive' | 'chained';
12857
13314
  * mutually exclusive conditions). The most dangerous state, because it looks
12858
13315
  * settled from the outside and breaks the first time an occupant is added.
12859
13316
  * - `none` — nobody ever decided. Remediation is a design meeting.
13317
+ * - `no_contention_by_design` — there is no arbitration question to answer,
13318
+ * because the occupants never compete. The exact opposite of
13319
+ * `safe_by_coincidence`: designed absence of the question rather than
13320
+ * accidental absence of a collision.
12860
13321
  *
12861
13322
  * THIS IS NOT AN ESCAPE HATCH. Declaring `enforced_documented` does not by
12862
13323
  * itself silence `contended-surface-without-arbitration`: the detector still
12863
13324
  * requires a non-empty `arbitration_rule`, so claiming the rule is documented
12864
13325
  * without documenting it changes nothing. `safe_by_coincidence` and `none`
12865
13326
  * make the check fire whatever else is recorded, because both are admissions.
12866
- */
12867
- type SurfaceArbitrationState = 'enforced_documented' | 'enforced_undocumented' | 'safe_by_coincidence' | 'none';
13327
+ * `no_contention_by_design` silences nothing that is not already silent: the
13328
+ * contention branch is a separate check that exempts only on
13329
+ * `composition_mode: 'chained'`, so a surface that claims this state while
13330
+ * genuinely over capacity, ruleless and not chained is still caught there.
13331
+ *
13332
+ * WHY ABSENCE COULD NOT CARRY THIS. An unset `arbitration_state` already means
13333
+ * "unassessed", and a surface whose occupants wrap rather than compete was
13334
+ * previously forced to use that same emptiness to say something quite
13335
+ * different. Certainty and ignorance became indistinguishable in one field.
13336
+ * `no_contention_by_design` makes a positive design claim, which is what makes
13337
+ * it declare-to-earn rather than an "I don't know". A generic `not_applicable`
13338
+ * was considered and rejected for exactly this reason: it reads as
13339
+ * "unassessed", collapses back into absence, and buys nothing.
13340
+ *
13341
+ * LEGALITY IS CONVENTION, NOT ENFORCEMENT. This value belongs on surfaces
13342
+ * whose `composition_mode` is `chained`, and nothing checks that pairing. UPG
13343
+ * has no cross-property conditional-enum mechanism, and a check must never
13344
+ * fire on legal modelling. Enforce only if field drift appears.
13345
+ */
13346
+ type SurfaceArbitrationState = 'enforced_documented' | 'enforced_undocumented' | 'safe_by_coincidence' | 'none' | 'no_contention_by_design';
12868
13347
  /** A place in the UI, its occupants, and the rule that arbitrates between them.
12869
13348
  *
12870
13349
  * `screen` answers *which route is this?*; `feature_area` answers *who owns
@@ -12918,37 +13397,35 @@ interface SurfaceProperties {
12918
13397
  visibility_condition?: string;
12919
13398
  /**
12920
13399
  * How many occupants ONE INSTANCE of the surface holds at once, as a
12921
- * non-negative count. Count the instances themselves with `cardinality`.
13400
+ * non-negative count. Absent means unbounded, `0` means a reserved place
13401
+ * nothing may occupy. Always the cap the design INTENDS, never what was
13402
+ * observed rendering. Count the instances themselves with `cardinality`.
12922
13403
  *
12923
- * CAPACITY IS ALWAYS INTENT, NEVER OBSERVED BEHAVIOUR. It records the cap the
12924
- * design asserts, so a banner region declared `capacity: 1` keeps saying 1
12925
- * even after someone finds it rendering four. Reality that has drifted from
12926
- * the declared intent is recorded as a trackable, assignable debt item on
12927
- * `surface_deviates_via_technical_debt_item`, not by quietly editing this
12928
- * number up to match the bug. Editing it to match would destroy the only
12929
- * record that a gap exists.
13404
+ * @remarks
13405
+ * Intent, not observation: a banner region declared `capacity: 1` keeps
13406
+ * saying 1 even after someone finds it rendering four. Reality that has
13407
+ * drifted from the declared intent belongs on
13408
+ * `surface_deviates_via_technical_debt_item` as a trackable, assignable debt
13409
+ * item. Editing this number up to match the bug would destroy the only record
13410
+ * that a gap exists.
12930
13411
  *
12931
- * ABSENT MEANS UNBOUNDED. UPG has no union-typed property primitive
12932
- * (`PropertyDefinition.type` is a single scalar kind), so the proposed
12933
- * `integer | unbounded` shape is expressed as an optional number whose
12934
- * absence carries the "no cap" reading, rather than a magic sentinel value
12935
- * that every consumer would have to special-case. `0` is a real cap meaning
12936
- * "nothing may occupy this surface" (a reserved place), not "unbounded".
13412
+ * Why absence rather than a sentinel: UPG has no union-typed property
13413
+ * primitive, so `integer | unbounded` is expressed as an optional number
13414
+ * whose absence carries the "no cap" reading, instead of a magic value every
13415
+ * consumer would have to special-case.
12937
13416
  *
12938
- * THREE STATES, AND THEY ARE ALL DIFFERENT. Absent = unbounded, no cap
12939
- * stated. `0` = a reserved place nothing may occupy. `null` = neither of
12940
- * those, and nothing this field defines; it is what you get by writing an
12941
- * explicit null rather than removing the key, and no consumer reads it as a
12942
- * cap. To return this property to ABSENT, remove the key with
12943
- * `update_node`'s or `batch_update_nodes`' `unset_properties`, since a
12944
- * property merge preserves anything you omit.
13417
+ * Three states, all different. ABSENT is unbounded, no cap stated. `0` is a
13418
+ * reserved place. `null` is neither, and nothing this field defines: it is
13419
+ * what an explicit null write leaves behind, and no consumer reads it as a
13420
+ * cap. To return the property to absent, remove the key with `update_node`'s
13421
+ * or `batch_update_nodes`' `unset_properties`, since a property merge
13422
+ * preserves anything omitted.
12945
13423
  *
12946
- * UNBOUNDED IS NOT AN EXEMPTION FROM SCRUTINY. The contention detector reads
12947
- * an absent capacity as a threshold of 1, on the reasoning that a surface
12948
- * which states no limit has stated no answer either, so several occupants is
12949
- * exactly the unrecorded decision worth naming. Declaring a real capacity is
12950
- * therefore the way to quiet the check honestly, and the only way that also
12951
- * records something true.
13424
+ * Unbounded is not an exemption from scrutiny. The contention detector reads
13425
+ * an absent capacity as a threshold of 1, because a surface that states no
13426
+ * limit has stated no answer either, so several occupants is exactly the
13427
+ * unrecorded decision worth naming. Declaring a real capacity is the way to
13428
+ * quiet the check honestly, and the only way that also records something true.
12952
13429
  */
12953
13430
  capacity?: number;
12954
13431
  /**
@@ -12971,20 +13448,34 @@ interface SurfaceProperties {
12971
13448
  composition_mode?: SurfaceCompositionMode;
12972
13449
  /**
12973
13450
  * Who wins when more occupants want the surface than `capacity` allows, and
12974
- * why.
13451
+ * why. Absence is meaningful: on a contested surface it means nobody decided.
12975
13452
  *
12976
- * ABSENCE IS MEANINGFUL: a null or empty `arbitration_rule` on a contested
12977
- * surface means nobody decided, which is exactly what the
12978
- * `contended-surface-without-arbitration` anti-pattern detects. Do not fill
12979
- * this in with a placeholder to silence the check.
12980
13453
  * @example "Highest priority wins; ties break to the most recently updated."
13454
+ *
13455
+ * @remarks
13456
+ * An empty or absent rule on a contested surface is exactly what
13457
+ * `contended-surface-without-arbitration` detects. Do not fill it in with a
13458
+ * placeholder to silence the check: the check exists to find the unrecorded
13459
+ * decision, and a placeholder hides it without settling anything.
13460
+ *
13461
+ * The field is overloaded across composition modes, which is worth knowing
13462
+ * before writing one. On an `exclusive` surface it records DISPLACEMENT (who
13463
+ * is not rendered). On an `additive` surface everyone fits, so what it
13464
+ * records is ORDER. Only the displacement reading is what the contention
13465
+ * detector reads.
12981
13466
  */
12982
13467
  arbitration_rule?: string;
12983
13468
  /**
12984
- * Whether the arbitration answer is enforced, written down, both, or neither.
12985
- * Separates "enforced in code but never transcribed" (ten minutes of typing)
12986
- * from "never decided" (a design meeting) from "safe only because nothing has
12987
- * collided yet" (the dangerous one).
13469
+ * Whether the arbitration answer is enforced, written down, both, neither, or
13470
+ * not owed at all. Leaving the field unset means unassessed, and always did.
13471
+ *
13472
+ * @remarks
13473
+ * The separations are the whole point of the field, because absence alone
13474
+ * conflates four situations with four different remediations: "enforced in
13475
+ * code but never transcribed" is ten minutes of typing, "never decided" is a
13476
+ * design meeting, "safe only because nothing has collided yet" is the
13477
+ * dangerous one, and "nothing to decide, the occupants never compete" is a
13478
+ * chained surface, which owes no arbitration rule at all.
12988
13479
  */
12989
13480
  arbitration_state?: SurfaceArbitrationState;
12990
13481
  /** Who may add occupants to the surface. */
@@ -13551,13 +14042,23 @@ interface FeatureProperties {
13551
14042
  *
13552
14043
  * @example
13553
14044
  * const properties: EpicProperties = {
13554
- * estimate: '3 person-weeks',
14045
+ * effort: '3 person-weeks',
13555
14046
  * priority: 'high',
13556
14047
  * owner: 'sam.patel@arkheiev.com',
13557
14048
  * }
13558
14049
  */
13559
14050
  interface EpicProperties {
13560
- /** Rough size estimate (e.g. "3 sprints", "L", "13 points") */
14051
+ /** Effort estimate (e.g. "2h", "1d", "3 points"). Use a consistent unit within your team. Canonical name for the work-item size family (`epic`, `user_story`, `task`). */
14052
+ effort?: string;
14053
+ /**
14054
+ * Rough size estimate (e.g. "3 sprints", "L", "13 points").
14055
+ * @deprecated STAGED, release number assigned at release prep (docket Track "Docket wave 2").
14056
+ * Use `effort`, the family-uniform name already carried by
14057
+ * `user_story` and `task`. `estimate` was epic's lone divergent spelling of the same
14058
+ * concept and it caused real misreads (the app read `estimate` on `user_story`, where
14059
+ * only `effort` is declared). Kept (not removed) for back-compat; removal is a later
14060
+ * major. Writers: emit `effort`. Readers: prefer `effort`, fall back to `estimate`.
14061
+ */
13561
14062
  estimate?: string;
13562
14063
  /** Task-level priority */
13563
14064
  priority?: Priority;
@@ -13636,8 +14137,23 @@ interface AcceptanceCriterionProperties {
13636
14137
  condition: string;
13637
14138
  /** Test mode */
13638
14139
  test_type?: 'manual' | 'automated';
13639
- /** Current pass/fail */
13640
- pass_status?: 'untested' | 'pass' | 'fail';
14140
+ /**
14141
+ * Current verification state of this criterion. `untested` means never
14142
+ * attempted; `blocked` means attempted but not verifiable for an
14143
+ * environmental reason; `regressed` means previously passing, now failing.
14144
+ *
14145
+ * @remarks
14146
+ * `blocked` is a distinct state from `untested` (a missing credential or an
14147
+ * unreachable dependency is not the same as nobody having tried), which the
14148
+ * earlier three-value enum conflated into a silent gap.
14149
+ *
14150
+ * `regressed` is a criterion-level state and is NOT derivable here, because
14151
+ * `acceptance_criterion` stores current state only and keeps no result
14152
+ * history. The history lives on the `test_case` to `test_result` series,
14153
+ * where a single execution's outcome is `TestResultProperties.result_status`
14154
+ * and can never itself be "regressed".
14155
+ */
14156
+ pass_status?: 'untested' | 'pass' | 'fail' | 'regressed' | 'blocked';
13641
14157
  }
13642
14158
  /** A shipped version or milestone of the product.
13643
14159
  *
@@ -13822,6 +14338,95 @@ interface PlanningCycleProperties {
13822
14338
  /** Shape Up appetite: the fixed time budget a cycle is willing to spend on a bet (e.g. "6 weeks", "2 weeks"). */
13823
14339
  appetite?: string;
13824
14340
  }
14341
+ /** What kind of lever this axis is. Names the mechanism family so a reader
14342
+ * knows what changing the value would mean operationally.
14343
+ *
14344
+ * - `feature_flag` — a runtime toggle owned by the product team.
14345
+ * - `plan_tier` — what the customer bought.
14346
+ * - `permission_level` — what this user is allowed to see.
14347
+ * - `beta_program` — enrolment in an early-access cohort.
14348
+ * - `other` — a lever that is none of these and is described in the node's
14349
+ * description rather than forced into a category that fits badly.
14350
+ */
14351
+ type ConfigurationAxisKind = 'feature_flag' | 'plan_tier' | 'permission_level' | 'beta_program' | 'other';
14352
+ /** A named dimension along which the product's composition differs.
14353
+ *
14354
+ * The stored graph is the UNION of a configuration family; an axis names one
14355
+ * dimension of that family, and a projection picks one value on it. A graph
14356
+ * that declares no axis describes a product with one configuration, which is
14357
+ * what every graph written before this entity existed already meant. That is
14358
+ * the zero-migration guarantee: silence still means "true everywhere".
14359
+ *
14360
+ * ONE AXIS PER SEMANTIC LEVER, NOT PER CODE FLAG. The unit is the decision a
14361
+ * reader makes ("are we on the new navigation or the old one?"), not the
14362
+ * boolean a deploy system stores. Two flags that cannot be set independently
14363
+ * — one forcing the other on — are ONE axis with two values, and modelling
14364
+ * them as two axes would assert a four-configuration family, three members of
14365
+ * which do not exist. Link each driving flag with
14366
+ * `feature_flag_drives_configuration_axis`: the mechanism lives in
14367
+ * engineering, the lever lives here.
14368
+ *
14369
+ * VALUES ARE CLOSED. Every `present_under` and every `active_when.values`
14370
+ * entry must name a member of this list, and `validate_graph`'s
14371
+ * `configuration_drift` scope says so. An axis whose values are open cannot
14372
+ * support a projection, because nothing bounds the family being projected
14373
+ * from.
14374
+ *
14375
+ * NOT `classification_axis`. That instrument sorts SUBJECTS into cells: a
14376
+ * subject may sit in several at once, each placement carries evidence and
14377
+ * confidence, and the axis describes a landscape. This one selects WHICH
14378
+ * GRAPH YOU ARE READING: exactly one value holds at a time, placements carry
14379
+ * no evidence, and changing the value changes what exists. The shapes rhyme;
14380
+ * the questions do not.
14381
+ *
14382
+ * Per UPG principle P14, structural relationships are edges:
14383
+ * the product that defines it: `product_defines_configuration_axis` (inbound)
14384
+ * the driving mechanism: `feature_flag_drives_configuration_axis` (inbound)
14385
+ * what varies along it: `surface_varies_by_configuration_axis` (inbound)
14386
+ *
14387
+ * @example
14388
+ * const properties: ConfigurationAxisProperties = {
14389
+ * values: ['legacy_nav', 'split_nav'],
14390
+ * default_value: 'legacy_nav',
14391
+ * kind: 'feature_flag',
14392
+ * }
14393
+ */
14394
+ interface ConfigurationAxisProperties {
14395
+ /**
14396
+ * The closed set of values this axis can take. Required: an axis with no
14397
+ * values selects nothing and cannot be projected along. Every `present_under`
14398
+ * and `active_when.values` entry must name one of them.
14399
+ *
14400
+ * @remarks
14401
+ * Two values is the common case and three is not unusual (a plan ladder).
14402
+ * Order is not significant: the axis is categorical, not ordinal. Where the
14403
+ * ordering does matter (an entitlement ladder in which each tier includes the
14404
+ * one below), that is a classification question, and `classification_axis`
14405
+ * with `axis_kind: 'ordinal'` is the instrument for it.
14406
+ */
14407
+ values: string[];
14408
+ /**
14409
+ * The value this axis is understood to sit at when nobody says otherwise.
14410
+ * Must be a member of `values`. NOTHING APPLIES IT AUTOMATICALLY: an
14411
+ * unqualified read returns the union, not this projection.
14412
+ *
14413
+ * @remarks
14414
+ * The union is the honest answer to an unqualified question, because it is
14415
+ * every configuration at once; silently substituting one of them would hide
14416
+ * the others from a reader who did not know to ask. What the field does carry
14417
+ * is the declaration convention for `surface_alternates_with_surface`
14418
+ * (declare the edge from the surface present under the default) and a
14419
+ * documented anchor for tools that later want to offer a starting
14420
+ * configuration.
14421
+ *
14422
+ * It is a claim about the model, not about deployment: it says which value
14423
+ * most of the graph was written against, not which configuration most
14424
+ * customers are on.
14425
+ */
14426
+ default_value?: string;
14427
+ /** What kind of lever this is. Names the mechanism family. */
14428
+ kind?: ConfigurationAxisKind;
14429
+ }
13825
14430
 
13826
14431
  /**
13827
14432
  * UPG Property Schemas: Metrics. Unified measurement across the product.
@@ -13928,15 +14533,16 @@ interface MetricProperties {
13928
14533
  /** Person or team responsible for tracking this metric. Promote to a `node_owned_by_person` edge if ownership must be queryable. */
13929
14534
  owner?: string;
13930
14535
  /**
13931
- * Universal health rollup. Orthogonal to lifecycle and `guardrail_status`.
13932
- * Applies to every metric regardless of `designation`.
13933
- * `healthy` = trending well against target / inside safe range.
13934
- * `at_risk` = drifting, approaching breach or target shortfall.
13935
- * `unhealthy` = missed target or breached; action needed.
13936
- * `unknown` = no current reading or not yet measured.
14536
+ * Universal health rollup, applying to every metric regardless of
14537
+ * `designation`: `healthy` is inside range, `at_risk` is drifting toward a
14538
+ * breach or shortfall, `unhealthy` has missed or breached, `unknown` has no
14539
+ * current reading.
13937
14540
  *
13938
- * For guardrails specifically, `guardrail_status` remains the
13939
- * breach-specific signal (`safe`/`warning`/`breached`).
14541
+ * @remarks
14542
+ * Orthogonal to lifecycle and to `guardrail_status`. For guardrails
14543
+ * specifically, `guardrail_status` remains the breach-specific signal
14544
+ * (`safe` / `warning` / `breached`), so a guardrail carries both: one says
14545
+ * how it is trending, the other says whether it has been crossed.
13940
14546
  */
13941
14547
  metric_health?: MetricHealth;
13942
14548
  /** Lower bound for guardrail safety (below this = breach) */
@@ -14970,10 +15576,14 @@ interface CiPipelineProperties {
14970
15576
  interface ReleaseStrategyProperties {
14971
15577
  /**
14972
15578
  * How a new version reaches production.
14973
- * `blue_green` = instant switch between two identical environments.
14974
- * `canary` = gradual percentage rollout. `rolling` = replace instances incrementally.
14975
- * `recreate` = take down old, bring up new. `feature_flag` = code ships, features gated.
15579
+ *
14976
15580
  * @example "canary" for gradual rollout, "blue_green" for instant switch with instant rollback
15581
+ *
15582
+ * @remarks
15583
+ * `blue_green` switches instantly between two identical environments.
15584
+ * `canary` rolls out by percentage. `rolling` replaces instances
15585
+ * incrementally. `recreate` takes the old down before bringing the new up.
15586
+ * `feature_flag` ships the code with the features gated.
14977
15587
  */
14978
15588
  strategy_type?: 'blue_green' | 'canary' | 'rolling' | 'recreate' | 'feature_flag';
14979
15589
  /**
@@ -15118,8 +15728,18 @@ interface TestPlanProperties {
15118
15728
  * }
15119
15729
  */
15120
15730
  interface TestSuiteProperties {
15121
- /** Category of test suite */
15122
- suite_type?: 'unit' | 'integration' | 'e2e' | 'performance' | 'security' | 'accessibility';
15731
+ /**
15732
+ * Category of test suite. The single canonical verification-method vocabulary
15733
+ * in the spec: do not mint a second one at criterion level.
15734
+ *
15735
+ * @remarks
15736
+ * `visual` covers visual-regression and screenshot-diff suites, whose
15737
+ * evidence is a rendered-output comparison rather than an assertion over
15738
+ * behaviour. Before it existed, producers mapped visual suites onto
15739
+ * `integration` as the least-wrong stock value, which made them
15740
+ * indistinguishable from genuine integration coverage.
15741
+ */
15742
+ suite_type?: 'unit' | 'integration' | 'e2e' | 'performance' | 'security' | 'accessibility' | 'visual';
15123
15743
  /** Number of tests in the suite */
15124
15744
  test_count?: number;
15125
15745
  /** Percentage of tests passing (0-100) */
@@ -15193,6 +15813,21 @@ interface QaSessionProperties {
15193
15813
  duration_minutes?: number;
15194
15814
  /** Number of bugs found during the session */
15195
15815
  bugs_found?: number;
15816
+ /**
15817
+ * Environment the session was run against. Single-valued, unlike
15818
+ * `TestPlanProperties.environments` (a plan spans several); the enum is the
15819
+ * same one, mirroring `TestEnvironmentProperties.env_type`.
15820
+ */
15821
+ environment?: 'local' | 'ci' | 'staging' | 'sandbox' | 'production_mirror';
15822
+ /**
15823
+ * Plain-English outcome of the session: what it established, not how many
15824
+ * bugs it counted (`bugs_found`). Named `outcome_summary`, matching
15825
+ * `ExperimentRunProperties.outcome_summary`, because a bare `outcome` would
15826
+ * collide with the `outcome` entity type.
15827
+ */
15828
+ outcome_summary?: string;
15829
+ /** ISO timestamp of when the session was run. Mirrors `TestResultProperties.executed_at`. */
15830
+ executed_at?: ISODateTime;
15196
15831
  }
15197
15832
  /** Regression test.
15198
15833
  *
@@ -15309,14 +15944,17 @@ interface TestResultProperties {
15309
15944
  */
15310
15945
  interface ThreatModelProperties {
15311
15946
  /**
15312
- * Methodology.
15313
- * `stride` = Spoofing, Tampering, Repudiation, Information Disclosure, DoS,
15314
- * Elevation of Privilege (OWASP standard).
15315
- * `dread` = Damage, Reproducibility, Exploitability, Affected users,
15316
- * Discoverability (numeric scoring).
15317
- * `pasta` = Process for Attack Simulation and Threat Analysis (7-stage).
15318
- * `attack_tree` = hierarchical tree of attack paths.
15947
+ * Threat-modelling methodology: `stride`, `dread`, `pasta`, or `attack_tree`.
15948
+ *
15319
15949
  * @example "stride" is the most widely used methodology for web applications
15950
+ *
15951
+ * @remarks
15952
+ * `stride` is the OWASP standard (Spoofing, Tampering, Repudiation,
15953
+ * Information Disclosure, Denial of Service, Elevation of Privilege).
15954
+ * `dread` is numeric scoring (Damage, Reproducibility, Exploitability,
15955
+ * Affected users, Discoverability). `pasta` is the seven-stage Process for
15956
+ * Attack Simulation and Threat Analysis. `attack_tree` is a hierarchical tree
15957
+ * of attack paths.
15320
15958
  */
15321
15959
  methodology?: 'stride' | 'dread' | 'pasta' | 'attack_tree' | 'other';
15322
15960
  /**
@@ -15409,13 +16047,17 @@ interface VulnerabilityProperties {
15409
16047
  */
15410
16048
  cvss_score?: number;
15411
16049
  /**
15412
- * Categorical severity derived from CVSS.
15413
- * Impact severity (UPGAssessment on the `severity_5` scale). Score alone is
15414
- * insufficient for triage; severity drives filtering and prioritisation.
15415
- * Migrated from the inline `critical|high|medium|low|informational` enum
15416
- * (UPG-579 Option C): map `critical` -> 5, `high` -> 4, `medium` -> 3,
15417
- * `low` -> 2, `informational` -> 1; carry the old word in `label`.
16050
+ * Categorical severity derived from CVSS, as a UPGAssessment on the
16051
+ * `severity_5` scale. Score alone is insufficient for triage: severity is
16052
+ * what drives filtering and prioritisation.
16053
+ *
15418
16054
  * @example value 5, label 'Critical', scale_id 'severity_5' (a remotely exploitable, no-auth vuln)
16055
+ *
16056
+ * @remarks
16057
+ * Migrated from the inline `critical|high|medium|low|informational` enum
16058
+ * (UPG-579 Option C): map `critical` to 5, `high` to 4, `medium` to 3, `low`
16059
+ * to 2, `informational` to 1, carrying the old word in `label` so the
16060
+ * original vocabulary survives the move.
15419
16061
  */
15420
16062
  severity?: UPGAssessment;
15421
16063
  /**
@@ -15507,6 +16149,8 @@ interface SecurityPolicyProperties {
15507
16149
  policy_status?: 'draft' | 'active' | 'under_review' | 'retired';
15508
16150
  /** Imperative force */
15509
16151
  rule_strength?: RuleStrength;
16152
+ /** Owning person or team accountable for the policy. Promote to a `node_owned_by_team` edge if ownership must be queryable. */
16153
+ owner?: string;
15510
16154
  }
15511
16155
  /** Penetration test.
15512
16156
  *
@@ -16006,6 +16650,8 @@ interface DataProductProperties {
16006
16650
  data_product_type?: 'report' | 'dataset' | 'stream' | 'api' | 'ml_feature' | 'other';
16007
16651
  /** Freshness SLA commitment (e.g. "< 1 hour") */
16008
16652
  sla_freshness?: string;
16653
+ /** Owning person or team. Sibling of `data_domain.steward`: use `owner` for the accountable party of a single data product, `steward` for a whole domain. Promote to a `node_owned_by_team` edge if ownership must be queryable. */
16654
+ owner?: string;
16009
16655
  }
16010
16656
  /** DataPipeline entity.
16011
16657
  *
@@ -16057,6 +16703,8 @@ interface GlossaryTermProperties {
16057
16703
  term_definition?: string;
16058
16704
  /** Alternative names or abbreviations for this term */
16059
16705
  synonyms?: string[];
16706
+ /** Person or team accountable for keeping the definition current. Promote to a `node_owned_by_person` edge if ownership must be queryable. */
16707
+ owner?: string;
16060
16708
  }
16061
16709
  /** DataDomain. A coarse-grained grouping of related data assets (sources,
16062
16710
  * pipelines, products, glossary terms) under a single stewardship boundary.
@@ -16155,6 +16803,14 @@ interface BrandAssetProperties {
16155
16803
  usage_rights?: string;
16156
16804
  }
16157
16805
  /** Internal document.
16806
+ *
16807
+ * @deprecated since 0.2.0. Use `DocumentProperties` (`document` with an internal
16808
+ * audience). `internal_doc` is absent from the entity-catalog union, so no
16809
+ * conformant graph can hold a node of this type — these properties are
16810
+ * unreachable in practice. Migration is lossless: `doc_type` → `document_type`
16811
+ * (its enum already contains rfc/runbook/guide/spec/onboarding), `url` →
16812
+ * `source_url`. Retained only because this interface is part of the published
16813
+ * type surface; RETIREMENT SCHEDULED for the next MAJOR (docket wave 2, item 3).
16158
16814
  *
16159
16815
  * @example
16160
16816
  * const properties: InternalDocProperties = {
@@ -16163,9 +16819,9 @@ interface BrandAssetProperties {
16163
16819
  * }
16164
16820
  */
16165
16821
  interface InternalDocProperties {
16166
- /** Classification of the document */
16822
+ /** Classification of the document. @deprecated use `document.document_type` */
16167
16823
  doc_type?: 'rfc' | 'runbook' | 'guide' | 'spec' | 'onboarding' | 'other';
16168
- /** URL or path to the document */
16824
+ /** URL or path to the document. @deprecated use `document.source_url` */
16169
16825
  url?: string;
16170
16826
  }
16171
16827
  /** Document. Provenance container linking to source files.
@@ -16410,6 +17066,8 @@ interface ComplianceRequirementProperties {
16410
17066
  regulation?: 'gdpr' | 'ccpa' | 'hipaa' | 'soc2' | 'iso27001' | 'pci_dss' | 'other';
16411
17067
  /** Current compliance posture */
16412
17068
  compliance_status?: 'compliant' | 'non_compliant' | 'in_progress' | 'not_applicable';
17069
+ /** Accountable person or team. Promote to a `node_owned_by_person` edge if ownership must be queryable. */
17070
+ owner?: string;
16413
17071
  }
16414
17072
  /** Risk.
16415
17073
  *
@@ -16421,8 +17079,15 @@ interface ComplianceRequirementProperties {
16421
17079
  * }
16422
17080
  */
16423
17081
  interface RiskProperties {
16424
- /** Domain the risk belongs to */
16425
- risk_type?: 'technical' | 'business' | 'legal' | 'security' | 'operational';
17082
+ /**
17083
+ * Domain the risk belongs to. The single kind axis for `risk`: there is no
17084
+ * second classification vocabulary.
17085
+ *
17086
+ * `program` added in v0.26.0 so the retired `risk_item` (Program Management)
17087
+ * type has a home on the canonical `risk` after consolidation, rather than a
17088
+ * parallel `risk_domain` field free to drift from this one.
17089
+ */
17090
+ risk_type?: 'technical' | 'business' | 'legal' | 'security' | 'operational' | 'program';
16426
17091
  /** How likely this risk is to materialise (1 = unlikely, 5 = near certain) */
16427
17092
  probability?: UPGAssessment;
16428
17093
  /** Severity of consequences if the risk materialises (1 = negligible, 5 = catastrophic) */
@@ -16446,6 +17111,8 @@ interface DataContractProperties {
16446
17111
  deletion_policy?: string;
16447
17112
  /** Whether data is shared with third parties */
16448
17113
  third_party_sharing?: boolean;
17114
+ /** Owning person or team accountable for the contract. Promote to a `node_owned_by_team` edge if ownership must be queryable. */
17115
+ owner?: string;
16449
17116
  }
16450
17117
  /** Audit log policy.
16451
17118
  *
@@ -16775,10 +17442,17 @@ interface ProjectProperties {
16775
17442
  */
16776
17443
  interface MilestoneProperties {
16777
17444
  /**
16778
- * Display order of this milestone within its parent project (0-indexed). The
16779
- * scalar ordering convention shared with `journey_step.step_order` and
17445
+ * Display order of this milestone within its parent (0-indexed). The scalar
17446
+ * ordering convention shared with `journey_step.step_order` and
16780
17447
  * `journey_action.action_order` (UPG-663 / UPG-674). Orders the delivery
16781
- * milestones a project moves through, independent of `due_date`.
17448
+ * milestones a parent moves through, independent of `due_date`.
17449
+ *
17450
+ * @remarks
17451
+ * The parent is whichever of the two milestone parents the graph actually
17452
+ * uses: a `project` via `project_targets_milestone`, or a `product` directly
17453
+ * via `product_targets_milestone` (Portfolio Phase 2, for milestones a
17454
+ * product owns outright with no program or project above them). The order is
17455
+ * scoped to that one parent, never global.
16782
17456
  */
16783
17457
  milestone_order?: number;
16784
17458
  /** Target due date (ISO format) */
@@ -16972,8 +17646,34 @@ interface PromptVersionProperties {
16972
17646
  * }
16973
17647
  */
16974
17648
  interface EvalBenchmarkProperties {
16975
- /** Measured dimension */
16976
- benchmark_type?: 'accuracy' | 'latency' | 'cost' | 'safety' | 'custom';
17649
+ /**
17650
+ * Measured dimension.
17651
+ *
17652
+ * @remarks
17653
+ * Widened in 0.31.0 with the three dimensions an eval suite actually reports
17654
+ * and this set could not express: `precision_recall` (two numbers, not one
17655
+ * accuracy figure, and the pair is the point, because a detector that fires on
17656
+ * everything scores perfectly on recall alone), `task_success` (did the agent
17657
+ * achieve the goal), and `coherence` (rubric-graded, for multi-step runs).
17658
+ *
17659
+ * THIS ENUM IS A DIMENSION AXIS, AND IT SHOULD STAY ONE. An eval suite's
17660
+ * families are a SUBJECT axis (what is under test), and a dimension cannot
17661
+ * separate subjects, which is why several families legitimately share
17662
+ * `task_success`.
17663
+ *
17664
+ * The subject is expressed on the EDGE, not here: `eval_benchmark_measures_node`
17665
+ * names what a benchmark measures by pointing at it. So "which benchmarks cover
17666
+ * the importer" is a traversal, and this property stays a clean answer to a
17667
+ * different question, "what dimension does this benchmark report". The
17668
+ * commissioning brief hoped the enum would carry both; splitting them across the
17669
+ * enum and the edge is the better answer, and it needs no third mechanism.
17670
+ *
17671
+ * Corollary worth stating, since it is load-bearing: do NOT add subject-shaped
17672
+ * values here. `tool_use` or `documentation` would encode on this axis what the
17673
+ * edge already carries, and the two would drift the first time a benchmark
17674
+ * measured something its enum value did not admit.
17675
+ */
17676
+ benchmark_type?: 'accuracy' | 'latency' | 'cost' | 'safety' | 'precision_recall' | 'task_success' | 'coherence' | 'custom';
16977
17677
  /** Test cases in the suite */
16978
17678
  test_case_count?: number;
16979
17679
  /** Minimum passing score */
@@ -16981,6 +17681,47 @@ interface EvalBenchmarkProperties {
16981
17681
  /** ISO date of the most recent run */
16982
17682
  last_run?: ISODate;
16983
17683
  }
17684
+ /** One metric's score inside `EvalRunProperties.metric_scores`.
17685
+ *
17686
+ * Every field is required, including `sample_size`. A score without its
17687
+ * denominator is not a smaller measurement, it is not a measurement, and an
17688
+ * optional denominator is how a run quietly stops reporting one.
17689
+ *
17690
+ * @example
17691
+ * const scores: MetricScore[] = [
17692
+ * { metric: 'precision', value: 0.94, sample_size: 250 },
17693
+ * { metric: 'recall', value: 0.71, sample_size: 250 },
17694
+ * ]
17695
+ */
17696
+ interface MetricScore {
17697
+ /** What was measured, named as the metric names itself: `precision`, `recall`, `faithfulness`. */
17698
+ metric: string;
17699
+ /**
17700
+ * The score, normalized to 0 through 1, where 1 is the best result.
17701
+ *
17702
+ * @remarks
17703
+ * Normalization is the contract rather than a suggestion, because comparing
17704
+ * runs is the whole reason this array exists and two runs on different raw
17705
+ * scales do not compare. A rating collected on 1 through 5 is divided before
17706
+ * it lands here, and the raw scale belongs in the metric name if a reader
17707
+ * needs it (`faithfulness_of_5`).
17708
+ *
17709
+ * Measurements that are not rates do not belong here at all. Wall-clock time,
17710
+ * token counts, and cost already have typed fields on `eval_run`, so a metric
17711
+ * that cannot be expressed as a rate is a sign the value wanted one of those.
17712
+ */
17713
+ value: number;
17714
+ /**
17715
+ * How many cases the score was computed over.
17716
+ *
17717
+ * @remarks
17718
+ * Required so a comparison across runs can never quietly compare different
17719
+ * sample sizes. It is the one field an author is most tempted to omit and the
17720
+ * one whose absence is least visible afterwards: a precision of 0.94 reads the
17721
+ * same whether it was measured over 250 cases or 4.
17722
+ */
17723
+ sample_size: number;
17724
+ }
16984
17725
  /** Evaluation run.
16985
17726
  *
16986
17727
  * @example
@@ -17011,6 +17752,32 @@ interface EvalRunProperties {
17011
17752
  error_rate?: number;
17012
17753
  /** Feedback score summary (human or automated) */
17013
17754
  feedback_scores?: string;
17755
+ /**
17756
+ * Per-metric scores, one entry per measured metric.
17757
+ *
17758
+ * @remarks
17759
+ * Added in 0.31.0 because `score` is a single aggregate and the forcing case
17760
+ * needs two numbers: precision and recall, reported separately. An aggregate
17761
+ * hides the only interesting failure mode, which is a detector that catches
17762
+ * everything by firing on everything.
17763
+ *
17764
+ * `sample_size` is not optional decoration, and as of 0.31.0 the type says so:
17765
+ * it is a REQUIRED member of `MetricScore`. A sampled run reports its sample
17766
+ * size beside its score, always, so a comparison across runs can never quietly
17767
+ * compare different sample sizes. A number without its denominator is not a
17768
+ * smaller measurement, it is not a measurement, and a remark saying `always`
17769
+ * over a field typed optional is a contract only the careful reader honours.
17770
+ *
17771
+ * The entry shape is the exported `MetricScore` interface rather than an
17772
+ * anonymous literal, so a consumer can name the thing it is building. This is
17773
+ * one of two `object[]` properties in the spec; the other, `composition.members`,
17774
+ * already exports `CompositionMember`.
17775
+ *
17776
+ * The rejected alternative was two runs per benchmark, which needs no spec
17777
+ * change and makes every question about a benchmark's quality a join, encoding
17778
+ * a measurement artifact as graph structure.
17779
+ */
17780
+ metric_scores?: MetricScore[];
17014
17781
  }
17015
17782
  /** AI cost tracker.
17016
17783
  *
@@ -18321,12 +19088,18 @@ interface ContactProperties {
18321
19088
  /** Whether this person has purchasing authority */
18322
19089
  is_decision_maker?: boolean;
18323
19090
  /**
18324
- * Role this contact plays in the buying committee (the decision-making unit).
19091
+ * Role this contact plays in the buying committee, the decision-making unit.
19092
+ *
19093
+ * @example 'economic_buyer'
19094
+ *
19095
+ * @remarks
18325
19096
  * The substrate of enterprise multi-threading and of qualification frameworks
18326
- * (MEDDICC/SPICED): a deal with no `champion` and no `economic_buyer` mapped is
18327
- * single-threaded and at risk. `is_decision_maker` becomes largely derivable
19097
+ * such as MEDDICC and SPICED: a deal with no `champion` and no
19098
+ * `economic_buyer` mapped is single-threaded and at risk, which is a fact the
19099
+ * graph can answer rather than a judgement someone has to make.
19100
+ *
19101
+ * `is_decision_maker` becomes largely derivable from this
18328
19102
  * (`buying_role = economic_buyer`) but is kept for back-compat.
18329
- * @example 'economic_buyer'
18330
19103
  */
18331
19104
  buying_role?: 'champion' | 'economic_buyer' | 'technical_evaluator' | 'end_user' | 'detractor' | 'influencer' | 'procurement' | 'legal' | 'security';
18332
19105
  }
@@ -18365,13 +19138,16 @@ interface DealProperties {
18365
19138
  /** Likelihood of closing (0-100%) */
18366
19139
  probability?: number;
18367
19140
  /**
18368
- * Terminal result of the deal. An Event-axis outcome (the verdict on a
18369
- * one-time event), NOT a lifecycle phase, so it is `deal_outcome` and not
18370
- * `deal_status` per the status-convention Rule 3. Lifecycle (open/won/lost as
18371
- * phases) belongs on the base `status` slot; this records the win/loss verdict
18372
- * a closed deal carries and gives `deal_lost_to_competitor` / win-loss study
18373
- * derivations their anchor.
19141
+ * Terminal result of the deal: the win or loss verdict a closed deal carries.
19142
+ *
18374
19143
  * @example 'won'
19144
+ *
19145
+ * @remarks
19146
+ * An Event-axis outcome (the verdict on a one-time event) and NOT a lifecycle
19147
+ * phase, so it is `deal_outcome` rather than `deal_status`, per
19148
+ * status-convention Rule 3. Lifecycle (open, won and lost as phases) belongs
19149
+ * on the base `status` slot. This field is what gives
19150
+ * `deal_lost_to_competitor` and win-loss study derivations their anchor.
18375
19151
  */
18376
19152
  deal_outcome?: 'won' | 'lost' | 'no_decision';
18377
19153
  /**
@@ -18403,6 +19179,8 @@ interface DealProperties {
18403
19179
  * `qualification_framework`).
18404
19180
  */
18405
19181
  qualification_score?: UPGAssessment;
19182
+ /** Accountable person or team carrying the deal. Promote to a `node_owned_by_person` edge if ownership must be queryable. */
19183
+ owner?: string;
18406
19184
  }
18407
19185
  /** Sales pipeline.
18408
19186
  *
@@ -19345,7 +20123,16 @@ interface PartnerRevenueShareProperties {
19345
20123
  * members: `team_works_in_workspace` / `persona_collaborates_in_workspace`
19346
20124
  * (the `member_count` and `owner` properties are display-time aggregates;
19347
20125
  * canonical membership is the edge set)
19348
- * contained entities: spatial placement is recorded on edge metadata
20126
+ * contained entities: `workspace_arranges_node`, whose edge `properties`
20127
+ * carry the spatial placement (`x`, `y`, `expanded`, `frame_id`)
20128
+ *
20129
+ * Two meanings of "workspace" travel together in shipped tools and are
20130
+ * unrelated. THIS is the CANVAS workspace: a thinking space, an entity in the
20131
+ * graph. The FILE workspace is a folder of `.upg` products, addressed by the
20132
+ * CLI and MCP surfaces (`init_workspace`, `switch_product`, `workspace.json`).
20133
+ * A third, `UPGSource.workspace_id`, is the source tool's own project id.
20134
+ * Neither is renamed: all three are entrenched, and the ambiguity is smaller
20135
+ * than the rename would be.
19349
20136
  *
19350
20137
  * @example
19351
20138
  * const properties: WorkspaceProperties = {
@@ -19365,14 +20152,15 @@ interface WorkspaceProperties {
19365
20152
  /** Free-text description. Pairs with the closed-enum `workspace_purpose`. */
19366
20153
  purpose?: string;
19367
20154
  /**
19368
- * Closed-enum classifier. Drives template suggestions and surfaces in workspace browsers.
19369
- * `discovery` = persona/job/opportunity exploration.
19370
- * `planning` = roadmap and decision sessions.
19371
- * `retrospective` = reflection on shipped work.
19372
- * `design` = experience or UI exploration.
19373
- * `research` = organising study data and synthesis.
19374
- * `strategy` = high-level direction setting.
19375
- * `general` = catch-all.
20155
+ * What the workspace is for. Drives template suggestions and surfaces in
20156
+ * workspace browsers.
20157
+ *
20158
+ * @remarks
20159
+ * `discovery` is persona, job and opportunity exploration. `planning` covers
20160
+ * roadmap and decision sessions. `retrospective` is reflection on shipped
20161
+ * work. `design` is experience or UI exploration. `research` organises study
20162
+ * data and synthesis. `strategy` is high-level direction setting. `general`
20163
+ * is the catch-all.
19376
20164
  */
19377
20165
  workspace_purpose?: 'discovery' | 'planning' | 'retrospective' | 'design' | 'research' | 'strategy' | 'general';
19378
20166
  /** Workspace owner (handle or email). Display label; canonical owner is `team_owns_workspace` or `persona_owns_workspace`. */
@@ -19385,6 +20173,256 @@ interface WorkspaceProperties {
19385
20173
  archived_at?: ISODateTime;
19386
20174
  /** Display icon (emoji or icon name) */
19387
20175
  icon?: string;
20176
+ /**
20177
+ * Retention intent. Absent means `transient`.
20178
+ *
20179
+ * @remarks
20180
+ * A workspace is a free-form thinking space and is transient by default, so
20181
+ * the spec makes both intents EXPRESSIBLE and takes no position on which
20182
+ * reaches the file. Whether to write a transient canvas at all is a tool
20183
+ * decision, and the recommended posture is not to: a scratch canvas nobody
20184
+ * named has no business in a shared, git-tracked graph, where it lands in
20185
+ * everyone's diff. Writing only `durable` workspaces is what keeps a
20186
+ * canonical graph entity comfortable with a transient-by-default object.
20187
+ */
20188
+ retention?: 'transient' | 'durable';
20189
+ /**
20190
+ * Opaque canvas furniture: the parts of a canvas with no graph referent.
20191
+ * Preserved verbatim on round-trip and never interpreted. Tool extension keys
20192
+ * are namespaced `<tool>:<key>` with a colon, and no consumer interprets a key
20193
+ * it does not own.
20194
+ *
20195
+ * @remarks
20196
+ * The cut here is UPG principle P14 applied literally. Anything that is a
20197
+ * REFERENCE TO A GRAPH NODE is an edge, which is why placed entities ride
20198
+ * `workspace_arranges_node` and not this bag: a node id held as a scalar
20199
+ * inside a blob is a foreign key in disguise, and a deleted node would leave
20200
+ * a stale reference nothing can detect. Anything that is pure UI chrome with
20201
+ * no graph referent stays here, because minting `annotation` and `frame`
20202
+ * entity types would add catalog surface that is meaningless to every
20203
+ * consumer outside the tool that drew it.
20204
+ *
20205
+ * WHY THE COLON, and why the rule is in the summary rather than buried here.
20206
+ * An underscore key is indistinguishable from an ordinary property name, so a
20207
+ * migration that targets namespaced keys cannot match it and no validator can
20208
+ * detect one that should have been namespaced. That undetectability is why
20209
+ * enforcement lives in the type and the documentation instead of in a check:
20210
+ * a check would report clean on a bag full of underscore keys, which is worse
20211
+ * than no check. Two conventions were already coexisting when this was ruled
20212
+ * (`entopo_views` in a live writer, `entopo:view_blocks` in the contract test
20213
+ * certifying preservation), which is how a cheap rule becomes a migration.
20214
+ *
20215
+ * PRESERVATION IS NOT PERMISSION TO RENDER. Preserving every byte says nothing
20216
+ * about meaning: a field-measured canvas carried `excluded: true` tombstones,
20217
+ * and a consumer that preserved them faithfully while rendering every entry
20218
+ * showed the user images they had deleted.
20219
+ */
20220
+ canvas?: WorkspaceCanvas;
20221
+ }
20222
+ /** The opaque half of a canvas: furniture with no graph referent.
20223
+ *
20224
+ * Carried on `WorkspaceProperties.canvas`. A consumer MUST preserve this object
20225
+ * verbatim and MUST NOT act on it. That preservation is already guaranteed by
20226
+ * the canonical serialiser, which passes `properties` through as an open bag,
20227
+ * so honouring the rule costs nothing; it just needs saying.
20228
+ *
20229
+ * @example
20230
+ * const canvas: WorkspaceCanvas = {
20231
+ * canvas_version: 1,
20232
+ * viewport: { x: 0, y: 0, zoom: 1 },
20233
+ * }
20234
+ */
20235
+ interface WorkspaceCanvas {
20236
+ /** Schema version of this bag, versioned by the tool that writes it and independent of the spec version. */
20237
+ canvas_version: number;
20238
+ /** Free-text note cards placed on the canvas. */
20239
+ annotations?: Array<{
20240
+ id: string;
20241
+ text: string;
20242
+ color?: string;
20243
+ x: number;
20244
+ y: number;
20245
+ }>;
20246
+ /** Visual grouping containers. `children` holds the ids of arranged nodes inside the frame. */
20247
+ frames?: Array<{
20248
+ id: string;
20249
+ label: string;
20250
+ x: number;
20251
+ y: number;
20252
+ width: number;
20253
+ height: number;
20254
+ children?: string[];
20255
+ }>;
20256
+ /**
20257
+ * Lightweight visual associations drawn between two cards.
20258
+ *
20259
+ * @remarks
20260
+ * Called RIDGES, not edges, and the rename is the point. Inside a `.upg` file
20261
+ * the word "edge" already means a graph edge, and a ridge is emphatically not
20262
+ * one: `promoted` exists precisely to mark the moment a ridge has BECOME a
20263
+ * real edge. Two different things under one word in the file format would be
20264
+ * a genuine ambiguity, and removing it costs nothing.
20265
+ */
20266
+ ridges?: Array<{
20267
+ id: string;
20268
+ source: string;
20269
+ target: string;
20270
+ label?: string;
20271
+ promoted?: boolean;
20272
+ }>;
20273
+ /** Last camera position on the canvas. */
20274
+ viewport?: {
20275
+ x: number;
20276
+ y: number;
20277
+ zoom: number;
20278
+ };
20279
+ /**
20280
+ * Canvas cards that are not yet entities in the graph.
20281
+ *
20282
+ * @remarks
20283
+ * A draft stays here rather than being materialised as a `status: 'draft'`
20284
+ * node because a draft is BY DEFINITION not in the graph yet. That is what
20285
+ * committing means, and `workspace_produced_node` exists to record the moment
20286
+ * it enters. Auto-materialising would empty that edge of meaning and litter
20287
+ * graphs with abandoned drafts.
20288
+ */
20289
+ drafts?: Array<{
20290
+ id: string;
20291
+ type: string;
20292
+ title: string;
20293
+ description?: string;
20294
+ x: number;
20295
+ y: number;
20296
+ }>;
20297
+ /** Seed provenance, when the canvas was opened from a gap prompt rather than blank. */
20298
+ gap_context?: {
20299
+ scope_label: string;
20300
+ region_slug?: string;
20301
+ note?: string;
20302
+ gaps: Array<{
20303
+ type: string;
20304
+ label: string;
20305
+ count?: number;
20306
+ detail?: string;
20307
+ }>;
20308
+ };
20309
+ /**
20310
+ * Tool-namespaced extension keys, written by a tool and preserved by everyone.
20311
+ *
20312
+ * The doc above has always promised an open bag; until 0.31.0 this interface
20313
+ * closed, so every doc-honouring consumer widened locally (`graph-service`
20314
+ * shipped `WorkspaceCanvas & Record<string, unknown>` as its boundary type). A
20315
+ * type that forces every conforming consumer to work around it is describing
20316
+ * the wrong thing, so the type now says what the doc always did.
20317
+ *
20318
+ * THE RULE FOR THESE KEYS (0.31.0):
20319
+ * - Syntax is `<tool>:<key>`, with a COLON. An underscore key is indistinguishable
20320
+ * from an ordinary property name, so it cannot be reliably matched, which is
20321
+ * exactly what makes a future migration miss half of what it targets.
20322
+ * - Every consumer PRESERVES unknown keys byte for byte.
20323
+ * - No consumer INTERPRETS a key it does not own. Preservation is a storage
20324
+ * guarantee that says nothing about meaning: a field-measured canvas carried
20325
+ * `excluded: true` tombstones, and a consumer that preserved every byte while
20326
+ * rendering every entry showed the user images they had deleted.
20327
+ * - The prefix is the owner. No registry at present scale.
20328
+ *
20329
+ * The declared members above keep their exact types, so the enumeration guard
20330
+ * is unaffected: adding a known layer still breaks exhaustive call sites at
20331
+ * compile time.
20332
+ *
20333
+ * THE COLON IS IN THE TYPE, and this is the only place the syntax rule is
20334
+ * enforceable at all. No runtime check can catch a key that should have been
20335
+ * namespaced and was not, because an underscore key is indistinguishable from
20336
+ * an ordinary property by construction, and a write-time rejection would
20337
+ * contradict the preservation guarantee the bag is built on. A bare
20338
+ * `[key: string]: unknown` would have accepted every form the rule forbids, so
20339
+ * the pattern index signature is what makes the rule cost anything.
20340
+ *
20341
+ * The declared members are exempt because none of them matches the pattern,
20342
+ * which is the mechanism working rather than a hole in it: they are the keys
20343
+ * the spec owns, and the pattern governs the keys it does not.
20344
+ *
20345
+ * The cost paid for the openness is narrower than the old closure but real: a
20346
+ * misspelled namespaced key resolves to `unknown` and surfaces at first use
20347
+ * rather than at the typo. A misspelled DECLARED member (`canvas.anotations`)
20348
+ * is still a compile error, because it does not match the pattern either.
20349
+ */
20350
+ [namespacedKey: `${string}:${string}`]: unknown;
20351
+ }
20352
+ /** Composition: a named, published view assembled from a canvas.
20353
+ *
20354
+ * The durable counterpart to `workspace`. Where a workspace is a free-form
20355
+ * thinking space with an audience of one, a composition is a stable artifact
20356
+ * with a slug people link to, a publisher, and a revision history. Its node
20357
+ * `id` IS the slug: `.upg` ids are slugs by convention, and minting a separate
20358
+ * `slug` property would give one thing two identities.
20359
+ *
20360
+ * SCOPE OF THAT RULE, stated because assuming it generalised produced a
20361
+ * `not_found` refusal in the field (the invariant working, the documentation
20362
+ * failing): id-is-slug holds for `composition` and `workspace`. It does NOT hold
20363
+ * for `product`, which carries a uuid id and a separate slug. A rule whose scope
20364
+ * is undocumented gets over-generalised by the next reader.
20365
+ *
20366
+ * THE ARRANGEMENT IS FROZEN, THE CONTENT IS NOT. `members` captures layout and
20367
+ * pointers at publish time and never resolved data. Each member's `href` is
20368
+ * still a QUERY, re-resolved against current graph data at render, which is
20369
+ * what makes a composition a live UPG surface rather than a stale screenshot.
20370
+ * A consumer must not treat `members` as cached content.
20371
+ *
20372
+ * Provenance reuses `workspace_produced_node`: which canvas a composition was
20373
+ * published from is already expressible, so nothing new is minted for it. What
20374
+ * a composition SHOWS is `composition_focuses_node`, which is what makes
20375
+ * "which published views show this persona?" answerable to a tool that cannot
20376
+ * parse the publishing tool's URLs.
20377
+ *
20378
+ * @example
20379
+ * const properties: CompositionProperties = {
20380
+ * members: [
20381
+ * { id: 'blk_1', href: '/view/personas?segment=smb', title: 'SMB personas', x: 0, y: 0, width: 6, height: 4 },
20382
+ * ],
20383
+ * rev: 3,
20384
+ * published_at: '2026-08-17T09:00:00Z',
20385
+ * published_by: 'sam.patel@arkheiev.com',
20386
+ * }
20387
+ */
20388
+ interface CompositionMember {
20389
+ /** Stable id of the block within this composition. */
20390
+ id: string;
20391
+ /** Tool-namespaced view reference, opaque to every other tool and preserved verbatim. */
20392
+ href: string;
20393
+ /** Display title captured at publish, used as a fallback while the target resolves. */
20394
+ title: string;
20395
+ /** Horizontal position of the block in the frozen arrangement. */
20396
+ x: number;
20397
+ /** Vertical position of the block in the frozen arrangement. */
20398
+ y: number;
20399
+ /** Width of the block in the frozen arrangement. */
20400
+ width: number;
20401
+ /** Height of the block in the frozen arrangement. */
20402
+ height: number;
20403
+ /** Whether the block is drawn collapsed. */
20404
+ collapsed?: boolean;
20405
+ }
20406
+ interface CompositionProperties {
20407
+ /**
20408
+ * The frozen member arrangement, captured at publish. Layout and pointers
20409
+ * only, never resolved content.
20410
+ */
20411
+ members: CompositionMember[];
20412
+ /**
20413
+ * Monotonic revision, bumped on each republish of the same slug.
20414
+ *
20415
+ * @remarks
20416
+ * A published revision is a fact about the composition, user-visible as a new
20417
+ * print from the same plate, so it is serialised. Worth distinguishing from a
20418
+ * store's concurrency token, which shares the name in some backends but is a
20419
+ * fact about the table rather than about the thing, and is not spec data.
20420
+ */
20421
+ rev: number;
20422
+ /** ISO timestamp of the most recent publish or republish. */
20423
+ published_at: ISODateTime;
20424
+ /** Publisher handle or email. Display scalar, same posture as `WorkspaceProperties.owner`. */
20425
+ published_by?: string;
19388
20426
  }
19389
20427
  /** Framework exercise: one run of a framework over a set of entities.
19390
20428
  *
@@ -19415,6 +20453,29 @@ interface FrameworkExerciseProperties {
19415
20453
  * later evolves (inputs added, removed, or rescaled).
19416
20454
  */
19417
20455
  inputs_snapshot?: Record<string, unknown>;
20456
+ /**
20457
+ * Relative multiplier per framework input for this run, keyed by input id.
20458
+ *
20459
+ * @remarks
20460
+ * A weight belongs to the RUN, not to any entity it scores: one weight per
20461
+ * input, shared by every scored entity, which is why it sits here and not on
20462
+ * the `framework_exercise_includes_node` edge alongside the per-entity result.
20463
+ *
20464
+ * Named `input_weights` rather than a bare `weight` deliberately, and the
20465
+ * collision is live rather than hypothetical: `getPropertyDefaultScale` keys
20466
+ * on property NAME alone and ignores entity type, and `PROPERTY_SCALE_MAP`
20467
+ * already maps `weight` to the `importance_5` ordinal. A bare `weight` here
20468
+ * would silently resolve to a 1-5 assessment scale, which is the wrong type,
20469
+ * range and meaning for a multiplier. The plural also matches the spec's own
20470
+ * vocabulary: a framework declares *inputs*, not dimensions.
20471
+ *
20472
+ * @example
20473
+ * const properties: FrameworkExerciseProperties = {
20474
+ * framework_id: 'rice-scoring',
20475
+ * input_weights: { reach: 1, impact: 2, confidence: 1, effort: 1.5 },
20476
+ * }
20477
+ */
20478
+ input_weights?: Record<string, number>;
19418
20479
  }
19419
20480
 
19420
20481
  /**
@@ -19718,6 +20779,7 @@ interface UPGPropertyMap {
19718
20779
  changelog: ChangelogProperties;
19719
20780
  /** A named, dated, self-nesting planning interval (sprint / iteration / quarter / PI / cooldown) work is scheduled through: the cadence axis */
19720
20781
  planning_cycle: PlanningCycleProperties;
20782
+ configuration_axis: ConfigurationAxisProperties;
19721
20783
  /** A governed specification (query language, protocol, format) products implement, expose, or conform to */
19722
20784
  specification: SpecificationProperties;
19723
20785
  /** A foundational compositional unit a specification defines (a block, a reference, a query value) */
@@ -20064,6 +21126,8 @@ interface UPGPropertyMap {
20064
21126
  workspace: WorkspaceProperties;
20065
21127
  /** A framework exercise: one run of a framework over a set of entities */
20066
21128
  framework_exercise: FrameworkExerciseProperties;
21129
+ /** A composition: a named, published view assembled from a canvas */
21130
+ composition: CompositionProperties;
20067
21131
  /** An account: a company or organisation in the CRM */
20068
21132
  account: AccountProperties;
20069
21133
  /** A contact: an individual person at an account */
@@ -20637,6 +21701,18 @@ interface EntityCheck {
20637
21701
  * field nobody filled in, e.g. a `surface` with no `arbitration_rule`.
20638
21702
  * A value-keyed filter cannot express absence, because the collector only
20639
21703
  * indexes values that exist.
21704
+ *
21705
+ * NON-EMPTY VALUE HERE MEANS NON-EMPTY *STRING*. The aggregate indexes
21706
+ * backing this form record string values only, so a numeric `0` or a
21707
+ * boolean `false` counts as ABSENT to this filter. That is a known wart,
21708
+ * documented rather than fixed in 0.29.0: broadening it would change which
21709
+ * graphs existing detectors fire on, which is not a change to make in a
21710
+ * release already carrying correctness fixes. It costs nothing today (no
21711
+ * catalog filter uses this form since the contention branch moved to
21712
+ * `EdgeCountVsPropertyCheck`), and the broadening question is banked as
21713
+ * a tracked follow-up. A detector that needs to see a declared
21714
+ * zero should use `EdgeCountVsPropertyCheck.node_filter`, whose presence
21715
+ * test is deliberately broader.
20640
21716
  * 2. `{ property, value }` (0.17.0) — count entities whose `property` equals
20641
21717
  * `value`, e.g. `metric` where `designation === 'north_star'`.
20642
21718
  * 3. `{ status }` — count entities in a given lifecycle status.
@@ -20796,12 +21872,25 @@ interface EdgeCountVsPropertyCheck {
20796
21872
  */
20797
21873
  node_comparison: 'gt' | 'gte' | 'lt' | 'lte' | 'eq';
20798
21874
  /**
20799
- * Optional additional per-node requirement, stated in the vocabulary of
20800
- * `EntityCheck.filter`'s presence form: the node must carry
20801
- * (`present: true`) or must not carry (`present: false`) a non-empty value
20802
- * for `property`.
21875
+ * Optional additional per-node requirement: the node must carry
21876
+ * (`present: true`) or must not carry (`present: false`) a value for
21877
+ * `property`.
20803
21878
  *
20804
- * THIS IS WHY THE FORM IS PER-NODE RATHER THAN TWO ANDED AGGREGATES.
21879
+ * PRESENT MEANS ANY VALUE, NOT ANY NON-EMPTY STRING. Only `undefined`,
21880
+ * `null` and the empty string read as absent here. `capacity: 0` is a real
21881
+ * cap (a reserved place nothing may occupy) and `mutates_content: false` is a
21882
+ * real answer, so treating either as an omission would be wrong: this check
21883
+ * form exists to read NUMERIC intents, and a form that could not see a
21884
+ * declared zero would misread the surfaces it was built for.
21885
+ *
21886
+ * THIS DELIBERATELY DIFFERS FROM `EntityCheck.filter`'s presence form, which
21887
+ * is string-only because the aggregate indexes behind it only hold strings.
21888
+ * The asymmetry is a real difference in what the two can see, not a style
21889
+ * choice, so this field does not borrow that vocabulary. Collectors express
21890
+ * the split as two named predicates (`isPropertyPresent` here,
21891
+ * `isStringPropertyPresent` there) rather than one helper with a comment.
21892
+ *
21893
+ * THIS IS ALSO WHY THE FORM IS PER-NODE RATHER THAN TWO ANDED AGGREGATES.
20805
21894
  * "Some surface is over capacity" AND "some surface has no arbitration rule"
20806
21895
  * are both true of a graph where those are DIFFERENT surfaces, so composing
20807
21896
  * two aggregate checks would keep firing on exactly the graphs this release
@@ -22045,10 +23134,17 @@ interface UPGEntityFilterSpec {
22045
23134
  * Every `entity_count` filter the catalog declares (0.29.0), so collectors can
22046
23135
  * record which nodes matched each one without indexing the whole graph.
22047
23136
  *
22048
- * The catalog declares five filters in total, which is what makes per-node
22049
- * attribution affordable here: a handful of predicate evaluations per node,
22050
- * rather than an id list for every (type, property, value) triple that happens
22051
- * to exist in the data.
23137
+ * The catalog declares FOUR filters in total (one status form, three value
23138
+ * forms), which is what makes per-node attribution affordable here: a handful
23139
+ * of predicate evaluations per node, rather than an id list for every (type,
23140
+ * property, value) triple that happens to exist in the data.
23141
+ *
23142
+ * Note there is no `present` form among them since 0.29.0, when the contention
23143
+ * branch moved to `EdgeCountVsPropertyCheck`. The only `present: false` left in
23144
+ * the catalog is that check's `node_filter`, which this walk correctly does not
23145
+ * collect: it is a per-node clause on a different check type, tallied through
23146
+ * `UPG_EDGE_COUNT_SPECS` instead. The count is asserted in the tests rather
23147
+ * than trusted to this comment.
22052
23148
  */
22053
23149
  declare const UPG_ENTITY_FILTER_SPECS: readonly UPGEntityFilterSpec[];
22054
23150
  /**
@@ -22291,7 +23387,7 @@ interface AntiPatternInputs {
22291
23387
  * collector that omits it loses attribution and changes no verdict.
22292
23388
  *
22293
23389
  * Bounded by declaration, like every other spec-driven input here: the whole
22294
- * catalog declares five filters, so this is a handful of predicate
23390
+ * catalog declares four filters, so this is a handful of predicate
22295
23391
  * evaluations per node rather than an index over every property.
22296
23392
  */
22297
23393
  nodesByEntityFilter?: Record<string, string[]>;
@@ -22588,6 +23684,74 @@ declare const UPG_STRUCTURE_PATTERNS: readonly StructurePattern[];
22588
23684
  * https://unifiedproductgraph.org/spec | MIT
22589
23685
  */
22590
23686
 
23687
+ /**
23688
+ * One declared, deterministic test over a single property. Atoms combine into a
23689
+ * slot's membership rule; an atom is never a membership rule by itself.
23690
+ *
23691
+ * `scope` says whose property is read, reusing the discriminator that already
23692
+ * exists on `PropertyRequirementLike` rather than inventing a parallel axis:
23693
+ * `'entity'` reads a property of the entity itself (an assumption's
23694
+ * `risk_level`), `'framework'` reads a measured property held on the exercise
23695
+ * edge (Kano's `functional_response`).
23696
+ *
23697
+ * Semantics a consumer must honour — each exists because its violation is a way
23698
+ * a grid could silently lie:
23699
+ *
23700
+ * - **Pure and total.** A function of the entity's and the exercise edge's
23701
+ * properties, and nothing else. No clock, no random, no ambient read.
23702
+ * - **Mutually exclusive.** No entity may satisfy two sibling predicates.
23703
+ * Overlapping predicates make a framework invalid; that is an authoring bug to
23704
+ * reject, never a tie for the renderer to break by declaration order.
23705
+ * - **Not exhaustive.** The complement of the union is the legitimate, expected
23706
+ * set of unplaced entities. Do not add a catch-all.
23707
+ * - **Absence is not a value.** A missing property, a null, or an assessment
23708
+ * without a value fails every predicate. It never compares as zero and never
23709
+ * sorts into a corner cell.
23710
+ * - **Thresholds are declared, never inferred.** Every boundary is a literal
23711
+ * here; the renderer contributes no default of its own.
23712
+ *
23713
+ * Ruling and rationale (including Amendment 1, which set the arity):
23714
+ * the zone-predicate hook ruling (internal decision record, 2026-08-07)
23715
+ */
23716
+ type FrameworkSlotPredicateAtom = {
23717
+ /** Whose property is being read: the entity's own, or the framework exercise's */
23718
+ scope: 'entity' | 'framework';
23719
+ /** The property name being tested */
23720
+ property: string;
23721
+ } & ({
23722
+ op: 'eq';
23723
+ value: string | number | boolean;
23724
+ } | {
23725
+ op: 'in';
23726
+ value: ReadonlyArray<string | number>;
23727
+ } | {
23728
+ op: 'gte';
23729
+ value: number;
23730
+ } | {
23731
+ op: 'lt';
23732
+ value: number;
23733
+ }
23734
+ /** Half-open interval `[min, max)` — min inclusive, max exclusive */
23735
+ | {
23736
+ op: 'band';
23737
+ value: readonly [number, number];
23738
+ });
23739
+ /**
23740
+ * A slot's membership rule: a conjunction. An entity belongs iff EVERY atom
23741
+ * holds; absence of any atom's property fails the whole conjunction.
23742
+ *
23743
+ * A list rather than a single atom because every real quadrant framework
23744
+ * partitions on two properties at once — an assumption map on risk AND
23745
+ * confidence, Kano on functional AND dysfunctional response. A one-atom rule
23746
+ * cannot tell "test first" from "monitor", and declaring both as "risk is high"
23747
+ * would make them overlap, which is invalid.
23748
+ *
23749
+ * Always a list, even for one atom, so consumers never branch on arity.
23750
+ * Conjunction only: express a disjunction as two slots, which gives each
23751
+ * disjunct its own visible cell. Empty is invalid — it would match everything,
23752
+ * which is a catch-all cell in disguise.
23753
+ */
23754
+ type FrameworkSlotPredicate = readonly FrameworkSlotPredicateAtom[];
22591
23755
  /** A named position within a framework's visual structure, populated by an entity type */
22592
23756
  interface FrameworkSlot {
22593
23757
  /** Display label for this slot (e.g. "Key Partners", "Problem", "Reach") */
@@ -22611,6 +23775,18 @@ interface FrameworkSlot {
22611
23775
  * off `scope: 'framework'` properties, not roles.
22612
23776
  */
22613
23777
  role?: string;
23778
+ /**
23779
+ * The membership rule for this slot, when membership is decided by a property
23780
+ * value rather than by entity type or framework role.
23781
+ *
23782
+ * Carrying it here — beside `role` — is what keeps the zone class computable
23783
+ * from the spec record alone: a slot with a `predicate` is a PREDICATE-zone.
23784
+ * The two are not alternatives. On a predicate zone, `role` stops being the
23785
+ * membership channel and becomes the manual-override channel.
23786
+ *
23787
+ * Additive and optional. A slot without one is unaffected.
23788
+ */
23789
+ predicate?: FrameworkSlotPredicate;
22614
23790
  /** Explanation of what this slot represents in the framework */
22615
23791
  description?: string;
22616
23792
  }
@@ -22969,6 +24145,165 @@ interface FrameworkPresentationSpec {
22969
24145
  /** Custom colour map: keys are values of the colour_by dimension, values are CSS colours */
22970
24146
  colour_map?: Record<string, string>;
22971
24147
  }
24148
+ /**
24149
+ * One traversal step along a declared edge path.
24150
+ *
24151
+ * `direction` is EXPLICIT and never inferred. Inferring it from endpoint types
24152
+ * fails on self-edges — the experiment family has one
24153
+ * (`experiment_run_tested_via_experiment_run`), where source and target are the
24154
+ * same type and the endpoint types cannot disambiguate the reading.
24155
+ *
24156
+ * `forward` walks source → target as the catalog declares it; `reverse` walks
24157
+ * target → source.
24158
+ */
24159
+ interface RelationalEdgeStep {
24160
+ /** Canonical edge type id from the UPG edge catalog */
24161
+ edge: string;
24162
+ /** Which way this step traverses the edge. Never inferred. */
24163
+ direction: 'forward' | 'reverse';
24164
+ }
24165
+ /**
24166
+ * A column rendering a property of the ROW entity itself.
24167
+ *
24168
+ * A field column declares NO entity type, deliberately. Its entity is the spine
24169
+ * by definition, and asking what type it "contains" is a category error. This is
24170
+ * the difference that dissolves the Status trap: under `slots`, a column showing
24171
+ * a property of the row had to name an `entityTypeId`, which made it look like a
24172
+ * second zone holding the same type as the first — something a partition forbids.
24173
+ * A field column has no such artefact to explain away.
24174
+ */
24175
+ interface RelationalFieldColumn {
24176
+ kind: 'field';
24177
+ /** Stable machine-readable column id (snake_case), unique within the surface */
24178
+ id: string;
24179
+ /** Display header */
24180
+ label: string;
24181
+ /** Property key on the spine entity */
24182
+ property: string;
24183
+ /** Whether the column can be sorted */
24184
+ sortable?: boolean;
24185
+ }
24186
+ /**
24187
+ * A column rendering a declared expression over the ROW entity's own properties.
24188
+ *
24189
+ * Every operand must be a property the spine entity actually declares. An
24190
+ * expression reaching a property held by another entity on a path is INVALID —
24191
+ * it would evaluate to nothing for every row forever, which is a column that is
24192
+ * 100% honest gap, i.e. a lie about what the framework measures.
24193
+ */
24194
+ interface RelationalComputedColumn {
24195
+ kind: 'computed';
24196
+ /** Stable machine-readable column id (snake_case), unique within the surface */
24197
+ id: string;
24198
+ /** Display header */
24199
+ label: string;
24200
+ /** Arithmetic expression over spine properties */
24201
+ expression: string;
24202
+ /** How to render the computed value */
24203
+ format?: 'number' | 'percentage' | 'currency' | 'duration';
24204
+ /** Whether the column can be sorted */
24205
+ sortable?: boolean;
24206
+ }
24207
+ /**
24208
+ * A column rendering the entities reached from the row along a declared edge path.
24209
+ *
24210
+ * A PROJECTION IS NOT A PARTITION, and the distinction is load-bearing rather
24211
+ * than stylistic. A partition claims exclusive membership and is a function of
24212
+ * the entity alone; a projection reports a relationship and is a function of the
24213
+ * (row, path) pair. The same entity legitimately appears in several columns, and
24214
+ * in the same column of several rows — that is the edge structure being reported
24215
+ * accurately, not the "rendering illusion" that property-partitioned frameworks
24216
+ * suffer from. Nothing lands in a projection cell by index, by order, or by
24217
+ * count: the edge exists in the graph or it does not.
24218
+ *
24219
+ * Consequently, and this is a rule rather than an observation: **sibling columns
24220
+ * are NOT required to be mutually exclusive, and must not be validated as if
24221
+ * they were.** Mutual exclusivity is a predicate-zone rule. Enforcing it on a
24222
+ * join would forbid the join.
24223
+ *
24224
+ * EVERY PROJECTION IS MANY-VALUED. The edge catalog declares no cardinality on
24225
+ * any edge, so a projection resolves to a set of size 0..n and must be rendered
24226
+ * as one. Taking the first member because "a run has one hypothesis" asserts a
24227
+ * cardinality the spec does not declare, and selecting from an unordered set by
24228
+ * position is the offset-windowing defect at a different arity.
24229
+ *
24230
+ * ABSENCE IS NOT A VALUE. An empty projection renders as a typed, labelled gap,
24231
+ * never as a blank cell — three states must stay distinguishable: no edge along
24232
+ * the path, an edge to an entity whose rendered field is empty, and not yet
24233
+ * loaded. A blank cell collapses all three into one shrug.
24234
+ */
24235
+ interface RelationalProjectionColumn {
24236
+ kind: 'projection';
24237
+ /** Stable machine-readable column id (snake_case), unique within the surface */
24238
+ id: string;
24239
+ /** Display header */
24240
+ label: string;
24241
+ /**
24242
+ * The traversal from the spine to the projected entities. A LIST, not a single
24243
+ * edge.
24244
+ *
24245
+ * Multi-hop is required, not a generality. Reaching a `hypothesis` from an
24246
+ * `experiment_run` is a two-hop reverse traversal, and the spec has twice
24247
+ * REFUSED to mint the shortcut edge that would flatten it, because doing so
24248
+ * would dissolve the plan/run split made in ENTP-322/323. A single-hop-only
24249
+ * declaration would leave authors needing that column with no legal way to
24250
+ * declare it — and the illegal way is the edge the spec already rejected.
24251
+ */
24252
+ path: RelationalEdgeStep[];
24253
+ /** Property keys to render for each projected entity */
24254
+ fields: string[];
24255
+ /**
24256
+ * Maximum entities to RENDER in a cell. A declared literal; the renderer
24257
+ * contributes no default. Truncates rendering only, never membership, and a
24258
+ * truncated cell must report the full count.
24259
+ */
24260
+ limit?: number;
24261
+ /** Whether the column can be sorted */
24262
+ sortable?: boolean;
24263
+ }
24264
+ /** Any column on a relational surface */
24265
+ type RelationalColumn = RelationalFieldColumn | RelationalComputedColumn | RelationalProjectionColumn;
24266
+ /**
24267
+ * A relational / join surface: rows are the instances of one declared spine
24268
+ * type, columns are fields of the row or projections along declared edge paths.
24269
+ *
24270
+ * Additive and optional. A framework without this block is unaffected; a
24271
+ * consumer that does not understand it ignores it. It exists because the zoned
24272
+ * grid partitions ONE set into cells and cannot express a surface that JOINS
24273
+ * several sets along the relationships between them — the shape of the `table`
24274
+ * pattern, the second-largest structural family in this spec.
24275
+ *
24276
+ * Rules a consumer must honour, stated here because they are contract, not
24277
+ * rendering preference:
24278
+ *
24279
+ * 1. **The spine is the population.** Row count is the number of spine entities
24280
+ * in scope. No column may filter the row set; a column that removes rows is a
24281
+ * partition wearing a projection's clothes.
24282
+ * 2. **Counts are entity-distinct per column** — the number of DISTINCT entities
24283
+ * appearing anywhere in the column, never the sum of cell sizes. Where the two
24284
+ * differ, both may be shown only if labelled ("7 learnings across 9 rows").
24285
+ * Reporting the sum as a population is this surface's characteristic lie.
24286
+ * 3. **Unreferenced entities must be reported.** An entity of a type appearing in
24287
+ * any declared path — endpoint OR intermediate — that no row reaches is
24288
+ * invisible by construction. It must be surfaced, always, with a count and its
24289
+ * type, even at zero. Otherwise the surface silently under-reports the graph.
24290
+ * 4. **Determinism.** A projection is a function of the graph's edges and the
24291
+ * projected entities' properties, and nothing else. No clock, no random, no
24292
+ * ambient read. Same graph, same table, every machine.
24293
+ */
24294
+ interface RelationalSurfaceSpec {
24295
+ /** The UPG entity type whose instances are the rows */
24296
+ spine: string;
24297
+ /** Ordered columns; at least one */
24298
+ columns: RelationalColumn[];
24299
+ /** Declared row order. Never inferred; the renderer contributes no default. */
24300
+ sort: {
24301
+ /** `id` of a column in `columns` */
24302
+ column: string;
24303
+ /** Sort direction */
24304
+ direction: 'asc' | 'desc';
24305
+ };
24306
+ }
22972
24307
  /** One step in a guided walkthrough of how to use a framework */
22973
24308
  interface FrameworkStep {
22974
24309
  /** Step order (1-based) */
@@ -23072,6 +24407,18 @@ interface UPGFramework {
23072
24407
  structure: FrameworkStructureSpec;
23073
24408
  /** How the framework should be rendered */
23074
24409
  presentation: FrameworkPresentationSpec;
24410
+ /**
24411
+ * A relational / join surface, for frameworks whose columns are projections
24412
+ * along edges rather than a partition of one set.
24413
+ *
24414
+ * Additive and optional. When present it is the authoritative column
24415
+ * declaration and `presentation.layout` describes only chrome — the two must
24416
+ * not be read as competing rosters. `slots` should be omitted on a framework
24417
+ * that declares this block: a slot cannot express an edge path, and forcing a
24418
+ * table into slots is what produced the duplicate-`entityTypeId` artefact this
24419
+ * block removes.
24420
+ */
24421
+ relational?: RelationalSurfaceSpec;
23075
24422
  /** Educational context and guided walkthrough */
23076
24423
  education: FrameworkEducation;
23077
24424
  /** IDs of other frameworks this one can be composed with */
@@ -23317,6 +24664,7 @@ declare const UPG_REGION_COUNT: number;
23317
24664
  /**
23318
24665
  * Framework validation: validates UPGFramework objects against the spec.
23319
24666
  */
24667
+
23320
24668
  /** Result of validating a UPGFramework object */
23321
24669
  interface FrameworkValidationResult {
23322
24670
  /** Whether the framework passed all required checks */
@@ -23359,6 +24707,24 @@ interface FrameworkValidationResult {
23359
24707
  * // result.errors === []
23360
24708
  */
23361
24709
  declare function validateUPGFramework(framework: unknown): FrameworkValidationResult;
24710
+ /**
24711
+ * Whether two sibling predicates are PROVABLY disjoint — the test that decides
24712
+ * whether a framework's zones are mutually exclusive.
24713
+ *
24714
+ * Two conjunctions cannot both hold if they share a `(scope, property)` on
24715
+ * which their atoms cannot both hold: one such property is enough, because an
24716
+ * entity would have to satisfy both atoms on it simultaneously.
24717
+ *
24718
+ * Note the direction: this returns `true` only when disjointness is PROVED.
24719
+ * An unprovable pair is rejected by the validator, not accepted. Over-rejection
24720
+ * costs the author a loud error they fix by adding a discriminating atom;
24721
+ * accepted overlap costs a silent misclassification at render time. See
24722
+ * Amendment 1 §B of the zone-predicate-hook decision.
24723
+ *
24724
+ * Exported so the renderer resolves membership with the same rule the validator
24725
+ * enforced, rather than a second implementation that can drift from it.
24726
+ */
24727
+ declare function predicatesProvablyDisjoint(a: FrameworkSlotPredicate, b: FrameworkSlotPredicate): boolean;
23362
24728
 
23363
24729
  /**
23364
24730
  * Canonical Framework Library: v1 public surface.
@@ -23381,6 +24747,66 @@ declare const UPG_FRAMEWORKS_BY_ID: Record<string, UPGFramework>;
23381
24747
  /** Frameworks grouped by category */
23382
24748
  declare const UPG_FRAMEWORKS_BY_CATEGORY: Record<string, UPGFramework[]>;
23383
24749
 
24750
+ /**
24751
+ * Relational path resolution: the shared type-composition logic for the
24752
+ * `relational` block's edge paths.
24753
+ *
24754
+ * One implementation, two consumers — the framework validator (which reports
24755
+ * malformed paths as authoring errors) and the shape audit (which checks that
24756
+ * every type a path reaches is declared in `data.entity_types`). They must agree
24757
+ * on what a path means, so they resolve it with the same function rather than
24758
+ * two that drift.
24759
+ *
24760
+ * https://unifiedproductgraph.org/spec | MIT
24761
+ */
24762
+
24763
+ type EdgeCatalog = Record<string, {
24764
+ source_type: string;
24765
+ target_type: string;
24766
+ }>;
24767
+ /** One resolved hop: where the traversal was, and where the step lands it. */
24768
+ interface ResolvedStep {
24769
+ /** Entity type the traversal is at BEFORE this step */
24770
+ from: string;
24771
+ /** Entity type the traversal is at AFTER this step */
24772
+ to: string;
24773
+ }
24774
+ /** Why a path failed to resolve. `null` `reason` means it resolved cleanly. */
24775
+ interface PathResolution {
24776
+ /** The type each step lands on, in order */
24777
+ steps: ResolvedStep[];
24778
+ /** Entity type the whole path lands on, or `null` if it did not resolve */
24779
+ endpoint: string | null;
24780
+ /** Human-readable failure, or `null` on success */
24781
+ reason: string | null;
24782
+ /** Index of the step that failed, or `-1` */
24783
+ failedAt: number;
24784
+ }
24785
+ /**
24786
+ * Walk a declared path from a starting entity type.
24787
+ *
24788
+ * `direction` is read, never inferred: `forward` goes source → target as the
24789
+ * catalog declares the edge, `reverse` goes target → source. A step whose
24790
+ * starting type does not match the end it claims to enter is a TYPE-COMPOSITION
24791
+ * failure and is reported with both types named, because "invalid path" without
24792
+ * the mismatch is not actionable.
24793
+ */
24794
+ declare function resolveRelationalPath(spine: string, path: RelationalEdgeStep[], catalog?: EdgeCatalog): PathResolution;
24795
+ /**
24796
+ * Every entity type a framework's relational block touches: the spine, plus each
24797
+ * type any path passes through or lands on.
24798
+ *
24799
+ * INTERMEDIATES COUNT. A type that a path merely passes through is still a type
24800
+ * the framework depends on, and an instance of it that no row reaches is exactly
24801
+ * as invisible as an unreferenced endpoint — an experiment plan with no runs is
24802
+ * the motivating case. Excluding intermediates would let a framework depend on a
24803
+ * type it never declares.
24804
+ *
24805
+ * Unresolvable paths contribute the types they reached before failing; the
24806
+ * validator reports the failure itself.
24807
+ */
24808
+ declare function relationalCoveredEntityTypes(fw: UPGFramework): Set<string>;
24809
+
23384
24810
  /**
23385
24811
  * Canonical `.upg` serialisation, the `upg fmt` reference implementation.
23386
24812
  *
@@ -23605,7 +25031,7 @@ declare function checkHeaderSealText(text: string): UPGHeaderSealReport;
23605
25031
  * it stamps the `upg_version` field of every `.upg` file written by the SDK.
23606
25032
  * The `check:version-lockstep` gate enforces this at release time.
23607
25033
  */
23608
- declare const UPG_VERSION: "0.29.0";
25034
+ declare const UPG_VERSION: "0.31.0";
23609
25035
  /**
23610
25036
  * The `.upg` JSON document format version. Written to the `upg_version` field.
23611
25037
  * Evolves independently from `UPG_VERSION` (the catalogue version).
@@ -23730,4 +25156,4 @@ declare const UPG_EDGE_COUNT: number;
23730
25156
  */
23731
25157
  declare const UPG_META_COUNT: number;
23732
25158
 
23733
- export { type A11yAnnotationProperties, type A11yAuditProperties, type A11yGuidelineProperties, type A11yIssueProperties, type A11yStandardProperties, ANALYTICS_DATA_PLAYBOOK, type AcceptanceCriterionProperties, type AccessPolicyProperties, type AccountProperties, type AcquisitionChannelProperties, type AdCreativeProperties, type AffinityClusterProperties, type AgentDefinitionProperties, type AgentHookProperties, type AgentSessionProperties, type AgentSkillProperties, type AgentTaskProperties, type AggregateProperties, type AiCostTrackerProperties, type AiDatasetProperties, type AiExperimentProperties, type AiGuardrailProperties, type AiModelProperties, type AiTraceProperties, type AlertRuleProperties, type AnnotationProperties, type AntiPatternInputs, type AntiPatternViolation, type AnyUPGEntityType, type ApiContractProperties, type ApiEcosystemProperties, type ApiEndpointProperties, type ApproachBinding, type ApproachFilter, type ApproachRun, type ApproachRuntime, type ApprovalRecordProperties, type AssumptionProperties, type AttributionModelProperties, type AuditLogPolicyProperties, BUSINESS_GROWTH_METRIC_DRIVEN_PLAYBOOK, BUSINESS_GTM_GROWTH_PLAYBOOK, BUSINESS_MARKETING_AUDIENCE_FIRST_PLAYBOOK, type BehavioralSegmentProperties, type BenchmarkCheck, type BetaProgramProperties, type BoundedContextProperties, type BrandAssetProperties, type BrandColourProperties, type BrandIdentityProperties, type BrandImageryProperties, type BrandLogoProperties, type BrandTypographyProperties, type BrandVoiceProperties, type BugProperties, type BuildArtifactProperties, type BusinessModelProperties, CLASSIFICATION_EDGE_PROPERTY_SCHEMA, CONTENT_DEPTH_WARNING_RULES, COVERAGE_ANTI_PATTERNS, type Cadence, type CapabilityProperties, type CapacityPlanProperties, type CauseConfidence, type CeremonyProperties, type CertificationProperties, type ChangeRequestProperties, type ChangelogProperties, type ChurnReasonProperties, type CiPipelineProperties, type ClassificationAxisProperties, type ClassificationCapability, type ClassificationCapabilitySurface, type ClassificationCommitment, type ClassificationValueProperties, type CodeRepositoryProperties, type CohortProperties, type ComfortLevel, type CommandProperties, type CommunityInitiativeProperties, type CompetitiveAnalysisProperties, type CompetitiveBattleCardProperties, type CompetitorFeatureProperties, type CompetitorProperties, type CompetitorSignalProperties, type ComplianceFrameworkProperties, type ComplianceRequirementProperties, type Confidence, type ConformanceLevel, type ConstraintKind, type ConstraintOrigin, type ConstraintProperties, type ConstraintStatus, type ContactProperties, type ContentCalendarProperties, type ContentPieceProperties, type ContentStrategyProperties, type ContentThemeProperties, type ContractClauseProperties, type ContractProperties, type CostStructureProperties, type CountBenchmark, type Cron, type CrossProductEligibleEdgeType, type CrossProductScope, type CulturalAdaptationProperties, type CustomerFeedbackProperties, type CustomerHealthScoreProperties, type CustomerJourneyStageProperties, type CustomerRelationshipProperties, DEFAULT_ENTITY_EMOJI, DEFERRED_PROPOSED_BY_CONTRACT, DEFER_EDGE_PROPERTY_SCHEMA, DISCOVERY_RESEARCH_VALIDATION_PLAYBOOK, type DashboardProperties, type DataClassificationProperties, type DataContractProperties, type DataDomainProperties, type DataFlowProperties, type DataLineageProperties, type DataModelProperties, type DataPipelineProperties, type DataProductProperties, type DataQualityRuleProperties, type DataSensitivity, type DataSourceProperties, type DatabaseSchemaProperties, type DealProperties, type DecisionProperties, type DeliberateOnlyEdgeType, type DeliverableProperties, type DemandGenProgramProperties, type DepartmentProperties, type DependencyProperties, type DeploymentProperties, type DeprecatedUPGEntityType, type DesignComponentProperties, type DesignConceptProperties, type DesignGuidelineProperties, type DesignPatternProperties, type DesignQuestionProperties, type DesignSprintProperties, type DesignSystemProperties, type DesignTokenProperties, type DesiredOutcomeProperties, type DeveloperPortalProperties, type DifficultyLevel, type DiscountStrategyProperties, type DistributionChannelProperties, type DocumentProperties, type DocumentationTemplateProperties, type DomainActivation, type DomainCountCheck, type DomainEntityProperties, type DomainEventProperties, type DomainGuideStep, type DomainPopulationCheck, type Duration, ENGINEERING_PLATFORM_PLAYBOOK, ENTITY_EMOJI, EXPERIENCE_DESIGN_BRAND_PLAYBOOK, type EdgeCountVsPropertyCheck, type EducationProgramProperties, type EmailSequenceProperties, type EmptyCell, type EmptyCellRationaleKind, type EntityCheck, type EntitySequenceStep, type EntityTypeMeta, type EntityTypeResolution, type EntryMode, type EpicProperties, type ErrorBudgetProperties, type EvalBenchmarkProperties, type EvalRunProperties, type EvaluateAntiPatternsOptions, type EventProperties, type EventSchemaProperties, type EvidenceDirection, type EvidenceProperties, type ExperimentPlanProperties, type ExperimentProperties, type ExperimentRunProperties, type ExternalApiProperties, FOUNDATIONS_PLAYBOOK, type FeasibilityStudyProperties, type FeatureAreaProperties, type FeatureFlagProperties, type FeatureProperties, type FeatureRequestProperties, type FeedbackProgramProperties, type FeedbackThemeProperties, type FeedbackVoteProperties, type FixProperties, type ForecastProperties, type FrameworkCategory, type FrameworkComputedProperty, type FrameworkConstant, type FrameworkDataSpec, type FrameworkEducation, type FrameworkEntityTypeSpec, type FrameworkExerciseProperties, type FrameworkInvocationStep, type FrameworkLayout, type FrameworkLevel, type FrameworkOrigin, type FrameworkPresentationSpec, type FrameworkPropertyRequirement, type FrameworkScoringMethod, type FrameworkSlot, type FrameworkStep, type FrameworkStructureSpec, type FrameworkValidationResult, type FrequencyRating, type FunnelProperties, type FunnelStage, type FunnelStepProperties, type GlossaryTermProperties, type GrowthCampaignProperties, type GrowthLoopProperties, type GtmStrategyProperties, type GuardrailStatus, type HallucinationReportProperties, type HealthStatus, type HelpVideoProperties, type HypothesisEvidenceProperties, type HypothesisProperties, type ISO4217, type ISODate, type ISODateTime, type IdealCustomerProfileProperties, type IncidentProperties, type IncidentSeverity, type InfrastructureComponentProperties, type InitiativeProperties, type InsightProperties, type IntegrationPartnerProperties, type IntegrationPatternProperties, type IntelligenceCondition, type InteractionSpecProperties, type InternalDocProperties, type InterviewGuideProperties, type InvestigationProperties, type InvoiceProperties, type IpAssetProperties, type JobProperties, type JobStepProperties, type JourneyActionProperties, type JourneyPhaseProperties, type JourneyStepProperties, type JourneyType, type KeyActivityProperties, type KeyResourceProperties, type KeyResultProperties, type KnowledgeBaseArticleProperties, LEGACY_PRODUCT_STAGES, type LaunchProperties, type LeadProperties, type LearningPathProperties, type LearningProperties, type LegalEntityProperties, type LibraryDependencyProperties, type LifecyclePhase, type LifecycleRenderShape, type LifecycleRenderState, type LifecycleRenderTransition, type LifecycleState, type LocaleConfigProperties, type LocaleProperties, type LogLevel, type LowMedHigh, MARKDOWN_FORMAT_VERSION, MARKET_COMPETITIVE_PLAYBOOK, type MarketSegmentProperties, type MarketTrendProperties, type MarketingCampaignPlanProperties, type MarketingChannelProperties, type MarketingPlatform, type MarketingStrategyProperties, type MarketplaceListingProperties, type MatrixSlot, type MaturityLevel, type MessagingProperties, type MetricCategory, type MetricDataPoint, type MetricDesignation, type MetricHealth, type MetricImpactLevel, type MetricIndicatorDirection, type MetricProperties, type MetricQualityAssessmentProperties, type MetricSegmentType, type MetricStatisticalFunction, type MilestoneProperties, type MissionProperties, type ModelComparisonProperties, type ModifiedProperty, type MonitorProperties, type NamedGroup, type NeedMaturity, type NeedProperties, type NeedValence, type NpsCampaignProperties, OPERATIONS_QUALITY_PLAYBOOK, type ObjectionProperties, type ObjectiveProperties, type ObservationProperties, type OnCallRotationProperties, type OperatingLifecycleProperties, type OperatingStageProperties, type OpportunityProperties, type OrganizationProperties, type OrphanCheck, type OutcomeProperties, PRODUCT_DELIVERY_PLAYBOOK, PROPERTY_MODIFIERS, PROPERTY_MODIFIER_SEMANTICS, PROPERTY_SCALE_MAP, type ParticipantProperties, type PartnerProgramProperties, type PartnerRevenueShareProperties, type PartnerTierProperties, type PartnershipProperties, type PaywallProperties, type PenetrationTestProperties, type PersonProperties, type PersonaProperties, type PipelineSalesProperties, type PipelineStageProperties, type PlanningCycleProperties, type PlaybookBinding, type PlaybookFilter, type PlaybookProperties, type PlaybookRun, type PlaybookRuntime, type PortfolioProperties, type PositioningProperties, type PostmortemProperties, type PressReleaseProperties, type PricingStrategyProperties, type PricingTierProperties, type PrimitiveProperties, type Priority, type PrivacyPolicyProperties, type ProductAreaProperties, type ProductProperties, type ProductStageCoercion, type ProgramProperties, type ProjectProperties, type PromptTemplateProperties, type PromptVersionProperties, type ProofPointProperties, type PropertyDefinition, type PropertyModifier, type PropertySchema, type Protocol, type PrototypeProperties, type ProxyConfidence, type ProxyReason, type QaSessionProperties, type QueueTopicProperties, type QuoteDocumentProperties, type QuoteProperties, RECORD_ENTITY_TYPES, REFLECT_MODES, REGISTRY_PRODUCT_ID, type RatioBenchmark, type ReadModelProperties, type RebuttalProperties, type ReflectMode, type RegionalPricingProperties, type RegressionTestProperties, type RelationshipBenchmark, type RelationshipCheck, type ReleaseProperties, type ReleaseStrategyProperties, type ReportProperties, type ResearchPlanProperties, type ResearchQuestionProperties, type ResearchStudyProperties, type ResourceAllocationProperties, type RetrospectiveProperties, type RevenueStreamProperties, type ReviewGateProperties, type RiskProperties, type RiskRegisterProperties, type RoadmapItemProperties, type RoadmapProperties, type RoadmapThemeProperties, type RoleProperties, type RootCauseProperties, type RuleStrength, type RunContext, type RunbookProperties, STRATEGY_OUTCOMES_PLAYBOOK, type SalesMotionProperties, type ScreenProperties, type ScreenStateProperties, type SecurityAuditProperties, type SecurityControlProperties, type SecurityPolicyProperties, type SecurityReviewProperties, type Semver, type SeoKeywordProperties, type SerializeOptions, type ServiceBlueprintProperties, type ServiceLevelAgreementProperties, type ServiceLevelIndicatorProperties, type ServiceLevelObjectiveProperties, type ServiceProperties, type SignalChannel, type SignalSentiment, type SignalUrgency, type SkillProperties, type SocialPostProperties, type SolutionProperties, type SpecificationProperties, type StageRange, type StakeholderProperties, type StatusCategory, type StatusReportProperties, type Step, type StepKind, type StepOutput, type StepOutputKind, type StoryTaskProperties, type StrategicPillarProperties, type StrategicQuestionProperties, type StrategicThemeProperties, type StructurePattern, type SubSequenceStep, type SubscriptionProperties, type SuccessMilestoneProperties, type SupportTicketProperties, type SurfaceArbitrationState, type SurfaceCardinality, type SurfaceCompositionMode, type SurfaceExtensibility, type SurfaceId, type SurfaceInstanceScope, type SurfaceKind, type SurfacePersistence, type SurfaceProperties, type SurveyResponseProperties, type SwitchingCostProperties, type SymptomProperties, THIN_GRAPH_THRESHOLD, type TableColumn, type TargetCustomerSegmentProperties, type TaskProperties, type TeamOkrProperties, type TeamProperties, type TechnicalDebtItemProperties, type TerritoryProperties, type TestCaseProperties, type TestCoverageReportProperties, type TestEnvironmentProperties, type TestPlanProperties, type TestResultProperties, type TestSuiteProperties, type ThreatModelProperties, type ThreatProperties, type Timeframe, type TotalEntityCountCheck, type TouchpointProperties, type TranslationBundleProperties, type TranslationKeyProperties, type TrialConfigProperties, type TutorialProperties, type UPGAnchorEntity, type UPGAntiPattern, type UPGAntiPatternConcern, type UPGAntiPatternSeverity, type UPGApproach, type UPGApproachEnvelope, type UPGApproachId, type UPGAreaTaxonomyEntry, type UPGAssessment, type UPGBaseNode, type UPGBenchmarkSource, type UPGBoundaryDirection, type UPGBoundaryEdge, type UPGCrossEdge, type UPGCrossEdgeType, type UPGCrossOnlyEdgeType, type UPGCuratedAntiPattern, type UPGDocument, type UPGDomain, type UPGDomainBridge, type UPGDomainId, type UPGDomainPattern, type UPGDomainRing, type UPGDomainUsageGuide, type UPGEdge, type UPGEdgeCountSpec, type UPGEdgeDefinition, type UPGEdgeMigration, type UPGEdgeMigrationEndpoints, type UPGEdgePickHint, type UPGEdgeType, type UPGEntityFilterSpec, type UPGEntityType, type UPGEntityTypeMaturity, type UPGEnumScaleDefinition, type UPGEnumScaleValue, type UPGFramework, type UPGFrameworkMeta, type UPGHeader, type UPGHeaderCountsMismatch, type UPGHeaderIntegrity, type UPGHeaderIntegrityMismatch, type UPGHeaderProvenance, type UPGHeaderSealReport, type UPGIntegrity, type UPGLens, type UPGLensIntelligencePrompt, type UPGLifecycle, type UPGMappingConfidence, type UPGMemberKindKey, type UPGNode, type UPGOrganization, type UPGPlaybook, type UPGPortfolio, type UPGPortfolioDocument, type UPGPortfolioKind, type UPGPresenceExceptSpec, type UPGProduct, type UPGProductArea, type UPGProductStage, type UPGPropertyMap, type UPGPropertyMigration, type UPGPropertyMigrationChange, type UPGRegion, type UPGRegionEntityMembership, type UPGRegionEntityRole, type UPGRegionId, type UPGRegionShape, type UPGRegistry, type UPGScalarToEdgeMigration, type UPGScaleDefinition, type UPGScalePoint, type UPGSource, type UPGSplitEdge, type UPGSplitMigration, type UPGSplitRoute, type UPGSplitRouteTarget, type UPGSplitTarget, type UPGTreeChild, type UPGTreeGapPolicy, type UPGTreePattern, type UPGTreePatternDetail, type UPGTreePatternEdge, type UPGTreePatternSummary, type UPGTypeLabel, type UPGTypeMigration, type UPGValidationError, type UPGValidationProfile, type UPGValidationResult, type UPGValidationWarning, type UPGWildcardEndpoint, UPG_ACTIVE_TYPES, UPG_ANTI_PATTERNS, UPG_ANTI_PATTERN_CONCERNS, UPG_APPROACHES, UPG_APPROACHES_BY_ID, UPG_AREA_TAXONOMY, UPG_AREA_TAXONOMY_BY_COVERAGE_KEY, UPG_CANONICAL_FORMAT_VERSION, UPG_CONTAINMENT_FREE_TYPES, UPG_COUNT_BENCHMARKS, UPG_CROSS_EDGE_TYPES, UPG_CROSS_ELIGIBLE_CATALOG_EDGE_TYPES, UPG_CROSS_ONLY_EDGE_TYPES, UPG_DELIBERATE_ONLY_EDGE_TYPES, UPG_DEPRECATED_TYPES, UPG_DOMAINS, UPG_DOMAIN_ACTIVATION, UPG_DOMAIN_COUNT, UPG_DOMAIN_GUIDES, UPG_DOMAIN_RINGS, UPG_EDGE_CATALOG, UPG_EDGE_COUNT, UPG_EDGE_COUNT_SPECS, UPG_EDGE_MIGRATIONS, UPG_EDGE_PAIR_MAP, UPG_EDGE_TYPES, UPG_ENTITY_COUNT, UPG_ENTITY_FILTER_SPECS, UPG_ENTITY_META, UPG_ENTITY_META_BY_ID, UPG_ENTITY_META_BY_NAME, UPG_ENTITY_TO_DOMAIN, UPG_ENUM_SCALES, UPG_FORMAT_VERSION, UPG_FRAMEWORKS, UPG_FRAMEWORKS_BY_CATEGORY, UPG_FRAMEWORKS_BY_ID, UPG_FRAMEWORK_CATEGORIES, UPG_LENSES, UPG_LIFECYCLES, UPG_LIFECYCLE_FREE_TYPES, UPG_LIFECYCLE_PLANNED_TYPES, UPG_META_COUNT, UPG_MIGRATIONS, UPG_PLAYBOOKS, UPG_POLYMORPHIC_EDGE_KEYS, UPG_PORTFOLIO_KINDS, UPG_PORTFOLIO_SHARED_TYPES, UPG_PRESENCE_EXCEPT_SPECS, UPG_PRODUCT_STAGES, UPG_PRODUCT_STAGE_COERCION_MAP, UPG_PROPERTY_MIGRATIONS, UPG_PROPERTY_SCHEMA, UPG_RATIO_BENCHMARKS, UPG_REGIONS, UPG_REGION_COUNT, UPG_REGION_MAP, UPG_RELATIONSHIP_BENCHMARKS, UPG_SCALAR_TO_EDGE_MIGRATIONS, UPG_SCALES, UPG_SPLIT_MIGRATIONS, UPG_STATUS_MIGRATIONS, UPG_STRUCTURE_PATTERNS, UPG_TREE_PATTERNS, UPG_TREE_PATTERNS_BY_ID, UPG_TYPES, UPG_TYPES_SET, UPG_TYPE_ALIASES, UPG_TYPE_LABELS, UPG_TYPE_LABELS_MAP, UPG_TYPE_NAMES, UPG_VALIDATION_PROFILES, UPG_VALID_CHILDREN, UPG_VERSION, UPG_WILDCARD_ENDPOINT, USERS_NEEDS_PLAYBOOK, type UnitEconomicsProperties, UnknownEntityTypeError, type UserAdvisoryBoardProperties, type UserFlowProperties, type UserJourneyProperties, type UserStoryProperties, type ValueObjectProperties, type ValuePropositionProperties, type ValueStreamProperties, type VariantProperties, type VisionProperties, type VulnerabilityProperties, type WalkMigrationChainResult, type WalkthroughProperties, type WebinarProperties, type WireframeProperties, type WorkflowArtifactProperties, type WorkflowRunProperties, type WorkflowTemplateProperties, type WorkspaceProperties, backfillSlug, buildTypeAliases, canBeChildOf, checkHeaderSeal, checkHeaderSealText, checkToEdgeCountSpec, classifyEntityFilter, coerceProductStage, collectSlugsForType, collectTargetEntities, compareVersions, computeBodyChecksum, concernEvaluatedFor, concernFor, concernGatesFor, crossProductScope, deriveCounts, derivePortfolioCounts, deriveSingleCounts, describeTreePattern, edgeCarriesProperties, edgeCountSpecKey, entityFilterKey, evaluateAntiPatterns, findInvalidStatusMigrationTargets, formatUpgText, friendlyToAssessment, generateSlug, getAnchorEntity, getAntiPatternById, getAntiPatterns, getAntiPatternsBySeverity, getAntiPatternsForStage, getAreaTaxonomyEntry, getBenchmark, getBenchmarksByDomain, getBusinessAreasForRegion, getCanonicalPlaybookForRegion, getCoverageKeysForRegion, getDefaultLens, getDeprecatedTypes, getDomainForType, getDomainIdForType, getDomainsInRing, getEdgePropertySchema, getEntityModifierSummary, getEnumScale, getEnumValueMeta, getGuideForDomain, getLens, getLensIds, getLensPlaybook, getLensesForDomain, getLifecycleForType, getLifecycleRenderShape, getMigrationMap, getPlaybookById, getPlaybooksForRegion, getPropertiesForScale, getPropertyDefaultScale, getPropertyMigrations, getPropertyModifier, getPropertySchema, getRegion, getRegionForEntityType, getReplacementType, getRingForDomain, getScalarToEdgeMigrations, getScale, getSplitMigrations, getTreePattern, getTypeId, getTypeName, getTypes, getUPGEdgeMigrations, getValidChildren, getVisibleTypes, hasStatusMigration, isAggregateShapedProperty, isCanonical, isCanonicalProductStage, isContainmentFreeType, isCrossCapable, isCrossProductEligible, isCuratedCrossEligible, isDeliberateOnlyEdge, isDeprecatedType, isDomainGuideStep, isEntitySequenceStep, isFrameworkInvocationStep, isLegacyProductStage, isLifecycleFreeType, isLifecyclePlannedType, isPolymorphicEdge, isPortfolio, isPortfolioSharedType, isRecordEntity, isRegisteredPolymorphicEdge, isRuntimeStateShapedProperty, isSubSequenceStep, isThinCoverageAdvisory, isUPGDocument, listPropertiesByModifier, listStatusMigrations, listTreePatternSummaries, migrateEdge, migrateNode, migrateNodeProperties, migrateProductStage, migrateStatusValue, normalizeDocument, parseUpg, pickCanonicalEdge, presenceExceptKey, resolveAllEdges, resolveContainmentEdge, resolveEntityType, resolveLabel, resolveSlugCollision, resolveTreePatternEdges, ringOrderedDomainIds, rotateSlug, serializeCanonical, validateEdgeProperties, validateProductStageStrict, validateUPGDocument, validateUPGFramework, validationProfileFor, walkMigrationChainToCanonical };
25159
+ export { type A11yAnnotationProperties, type A11yAuditProperties, type A11yGuidelineProperties, type A11yIssueProperties, type A11yStandardProperties, ACTIVE_WHEN_PROPERTY, ANALYTICS_DATA_PLAYBOOK, type AcceptanceCriterionProperties, type AccessPolicyProperties, type AccountProperties, type AcquisitionChannelProperties, type AdCreativeProperties, type AffinityClusterProperties, type AgentDefinitionProperties, type AgentHookProperties, type AgentSessionProperties, type AgentSkillProperties, type AgentTaskProperties, type AggregateProperties, type AiCostTrackerProperties, type AiDatasetProperties, type AiExperimentProperties, type AiGuardrailProperties, type AiModelProperties, type AiTraceProperties, type AlertRuleProperties, type AnnotationProperties, type AntiPatternInputs, type AntiPatternViolation, type AnyUPGEntityType, type ApiContractProperties, type ApiEcosystemProperties, type ApiEndpointProperties, type ApproachBinding, type ApproachFilter, type ApproachRun, type ApproachRuntime, type ApprovalRecordProperties, type AssumptionProperties, type AttributionModelProperties, type AuditLogPolicyProperties, BUSINESS_GROWTH_METRIC_DRIVEN_PLAYBOOK, BUSINESS_GTM_GROWTH_PLAYBOOK, BUSINESS_MARKETING_AUDIENCE_FIRST_PLAYBOOK, type BehavioralSegmentProperties, type BenchmarkCheck, type BetaProgramProperties, type BoundedContextProperties, type BrandAssetProperties, type BrandColourProperties, type BrandIdentityProperties, type BrandImageryProperties, type BrandLogoProperties, type BrandTypographyProperties, type BrandVoiceProperties, type BugProperties, type BuildArtifactProperties, type BusinessModelProperties, CLASSIFICATION_EDGE_PROPERTY_SCHEMA, CONFIGURATION_QUALIFIER_EDGE_PROPERTY_SCHEMA, CONFIGURATION_VARIANCE_EDGE_PROPERTY_SCHEMA, CONTENT_DEPTH_WARNING_RULES, COVERAGE_ANTI_PATTERNS, type Cadence, type CapabilityProperties, type CapacityPlanProperties, type CauseConfidence, type CeremonyProperties, type CertificationProperties, type ChangeRequestProperties, type ChangelogProperties, type ChurnReasonProperties, type CiPipelineProperties, type ClassificationAxisProperties, type ClassificationCapability, type ClassificationCapabilitySurface, type ClassificationCommitment, type ClassificationValueProperties, type CodeRepositoryProperties, type CohortProperties, type ComfortLevel, type CommandProperties, type CommunityInitiativeProperties, type CompetitiveAnalysisProperties, type CompetitiveBattleCardProperties, type CompetitorFeatureProperties, type CompetitorProperties, type CompetitorSignalProperties, type ComplianceFrameworkProperties, type ComplianceRequirementProperties, type CompositionMember, type CompositionProperties, type Confidence, type Configuration, type ConfigurationAxisKind, type ConfigurationAxisProperties, type ConfigurationDriftFinding, type ConfigurationDriftKind, type ConformanceLevel, type ConstraintKind, type ConstraintOrigin, type ConstraintProperties, type ConstraintStatus, type ContactProperties, type ContentCalendarProperties, type ContentPieceProperties, type ContentStrategyProperties, type ContentThemeProperties, type ContractClauseProperties, type ContractProperties, type CostStructureProperties, type CountBenchmark, type Cron, type CrossProductEligibleEdgeType, type CrossProductScope, type CulturalAdaptationProperties, type CustomerFeedbackProperties, type CustomerHealthScoreProperties, type CustomerJourneyStageProperties, type CustomerRelationshipProperties, DEFAULT_ENTITY_EMOJI, DEFERRED_PROPOSED_BY_CONTRACT, DEFER_EDGE_PROPERTY_SCHEMA, DISCOVERY_RESEARCH_VALIDATION_PLAYBOOK, type DashboardProperties, type DataClassificationProperties, type DataContractProperties, type DataDomainProperties, type DataFlowProperties, type DataLineageProperties, type DataModelProperties, type DataPipelineProperties, type DataProductProperties, type DataQualityRuleProperties, type DataSensitivity, type DataSourceProperties, type DatabaseSchemaProperties, type DealProperties, type DecisionProperties, type DeliberateOnlyEdgeType, type DeliverableProperties, type DemandGenProgramProperties, type DepartmentProperties, type DependencyProperties, type DeploymentProperties, type DeprecatedUPGEntityType, type DesignComponentProperties, type DesignConceptProperties, type DesignGuidelineProperties, type DesignPatternProperties, type DesignQuestionProperties, type DesignSprintProperties, type DesignSystemProperties, type DesignTokenProperties, type DesiredOutcomeProperties, type DeveloperPortalProperties, type DifficultyLevel, type DiscountStrategyProperties, type DistributionChannelProperties, type DocumentProperties, type DocumentationTemplateProperties, type DomainActivation, type DomainCountCheck, type DomainEntityProperties, type DomainEventProperties, type DomainGuideStep, type DomainPopulationCheck, type Duration, ENGINEERING_PLATFORM_PLAYBOOK, ENTITY_EMOJI, EXPERIENCE_DESIGN_BRAND_PLAYBOOK, type EdgeCountVsPropertyCheck, type EducationProgramProperties, type EmailSequenceProperties, type EmptyCell, type EmptyCellRationaleKind, type EntityCheck, type EntitySequenceStep, type EntityTypeMeta, type EntityTypeResolution, type EntryMode, type EpicProperties, type ErrorBudgetProperties, type EvalBenchmarkProperties, type EvalRunProperties, type EvaluateAntiPatternsOptions, type EventProperties, type EventSchemaProperties, type EvidenceDirection, type EvidenceProperties, type ExperimentPlanProperties, type ExperimentProperties, type ExperimentRunProperties, type ExternalApiProperties, FOUNDATIONS_PLAYBOOK, type FeasibilityStudyProperties, type FeatureAreaProperties, type FeatureFlagProperties, type FeatureProperties, type FeatureRequestProperties, type FeedbackProgramProperties, type FeedbackThemeProperties, type FeedbackVoteProperties, type FixProperties, type ForecastProperties, type FrameworkCategory, type FrameworkComputedProperty, type FrameworkConstant, type FrameworkDataSpec, type FrameworkEducation, type FrameworkEntityTypeSpec, type FrameworkExerciseProperties, type FrameworkInvocationStep, type FrameworkLayout, type FrameworkLevel, type FrameworkOrigin, type FrameworkPresentationSpec, type FrameworkPropertyRequirement, type FrameworkScoringMethod, type FrameworkSlot, type FrameworkSlotPredicate, type FrameworkSlotPredicateAtom, type FrameworkStep, type FrameworkStructureSpec, type FrameworkValidationResult, type FrequencyRating, type FunnelProperties, type FunnelStage, type FunnelStepProperties, type GlossaryTermProperties, type GrowthCampaignProperties, type GrowthLoopProperties, type GtmStrategyProperties, type GuardrailStatus, type HallucinationReportProperties, type HealthStatus, type HelpVideoProperties, type HypothesisEvidenceProperties, type HypothesisProperties, type ISO4217, type ISODate, type ISODateTime, type IdealCustomerProfileProperties, type IncidentProperties, type IncidentSeverity, type InfrastructureComponentProperties, type InitiativeProperties, type InsightProperties, type IntegrationPartnerProperties, type IntegrationPatternProperties, type IntelligenceCondition, type InteractionSpecProperties, type InternalDocProperties, type InterviewGuideProperties, type InvestigationProperties, type InvoiceProperties, type IpAssetProperties, type JobProperties, type JobStepProperties, type JourneyActionProperties, type JourneyPhaseProperties, type JourneyStepProperties, type JourneyType, type KeyActivityProperties, type KeyResourceProperties, type KeyResultProperties, type KnowledgeBaseArticleProperties, LEGACY_PRODUCT_STAGES, type LaunchProperties, type LeadProperties, type LearningPathProperties, type LearningProperties, type LegalEntityProperties, type LibraryDependencyProperties, type LifecyclePhase, type LifecycleRenderShape, type LifecycleRenderState, type LifecycleRenderTransition, type LifecycleState, type LocaleConfigProperties, type LocaleProperties, type LogLevel, type LowMedHigh, MARKDOWN_FORMAT_VERSION, MARKET_COMPETITIVE_PLAYBOOK, type MarketSegmentProperties, type MarketTrendProperties, type MarketingCampaignPlanProperties, type MarketingChannelProperties, type MarketingPlatform, type MarketingStrategyProperties, type MarketplaceListingProperties, type MatrixSlot, type MaturityLevel, type MessagingProperties, type MetricCategory, type MetricDataPoint, type MetricDesignation, type MetricHealth, type MetricImpactLevel, type MetricIndicatorDirection, type MetricProperties, type MetricQualityAssessmentProperties, type MetricScore, type MetricSegmentType, type MetricStatisticalFunction, type MilestoneProperties, type MissionProperties, type ModelComparisonProperties, type ModifiedProperty, type MonitorProperties, type NamedGroup, type NeedMaturity, type NeedProperties, type NeedValence, type NpsCampaignProperties, OPERATIONS_QUALITY_PLAYBOOK, type ObjectionProperties, type ObjectiveProperties, type ObservationProperties, type OnCallRotationProperties, type OperatingLifecycleProperties, type OperatingStageProperties, type OpportunityProperties, type OrganizationProperties, type OrphanCheck, type OutcomeProperties, PRESENT_UNDER_PROPERTY, PRODUCT_DELIVERY_PLAYBOOK, PROPERTY_MODIFIERS, PROPERTY_MODIFIER_SEMANTICS, PROPERTY_SCALE_MAP, type ParticipantProperties, type PartnerProgramProperties, type PartnerRevenueShareProperties, type PartnerTierProperties, type PartnershipProperties, type PathResolution, type PaywallProperties, type PenetrationTestProperties, type PersonProperties, type PersonaProperties, type PipelineSalesProperties, type PipelineStageProperties, type PlanningCycleProperties, type PlaybookBinding, type PlaybookFilter, type PlaybookProperties, type PlaybookRun, type PlaybookRuntime, type PortfolioProperties, type PositioningProperties, type PostmortemProperties, type PressReleaseProperties, type PricingStrategyProperties, type PricingTierProperties, type PrimitiveProperties, type Priority, type PrivacyPolicyProperties, type ProductAreaProperties, type ProductProperties, type ProductStageCoercion, type ProgramProperties, type ProjectProperties, type ProjectableEdge, type ProjectableNode, type ProjectionResult, type PromptTemplateProperties, type PromptVersionProperties, type ProofPointProperties, type PropertyDefinition, type PropertyModifier, type PropertySchema, type Protocol, type PrototypeProperties, type ProxyConfidence, type ProxyReason, QUALIFIABLE_EDGE_TYPES, type QaSessionProperties, type QueueTopicProperties, type QuoteDocumentProperties, type QuoteProperties, RECORD_ENTITY_TYPES, REFLECT_MODES, REGISTRY_PRODUCT_ID, type RatioBenchmark, type ReadModelProperties, type RebuttalProperties, type ReflectMode, type RegionalPricingProperties, type RegressionTestProperties, type RelationalColumn, type RelationalComputedColumn, type RelationalEdgeStep, type RelationalFieldColumn, type RelationalProjectionColumn, type RelationalSurfaceSpec, type RelationshipBenchmark, type RelationshipCheck, type ReleaseProperties, type ReleaseStrategyProperties, type ReportProperties, type ResearchPlanProperties, type ResearchQuestionProperties, type ResearchStudyProperties, type ResolvedStep, type ResourceAllocationProperties, type RetrospectiveProperties, type RevenueStreamProperties, type ReviewGateProperties, type RiskProperties, type RiskRegisterProperties, type RoadmapItemProperties, type RoadmapProperties, type RoadmapThemeProperties, type RoleProperties, type RootCauseProperties, type RuleStrength, type RunContext, type RunbookProperties, STRATEGY_OUTCOMES_PLAYBOOK, type SalesMotionProperties, type ScreenProperties, type ScreenStateProperties, type SecurityAuditProperties, type SecurityControlProperties, type SecurityPolicyProperties, type SecurityReviewProperties, type Semver, type SeoKeywordProperties, type SerializeOptions, type ServiceBlueprintProperties, type ServiceLevelAgreementProperties, type ServiceLevelIndicatorProperties, type ServiceLevelObjectiveProperties, type ServiceProperties, type SignalChannel, type SignalSentiment, type SignalUrgency, type SkillProperties, type SocialPostProperties, type SolutionProperties, type SpecificationProperties, type StageRange, type StakeholderProperties, type StatusCategory, type StatusReportProperties, type Step, type StepKind, type StepOutput, type StepOutputKind, type StoryTaskProperties, type StrategicPillarProperties, type StrategicQuestionProperties, type StrategicThemeProperties, type StructurePattern, type SubSequenceStep, type SubscriptionProperties, type SuccessMilestoneProperties, type SupportTicketProperties, type SurfaceArbitrationState, type SurfaceCardinality, type SurfaceCompositionMode, type SurfaceExtensibility, type SurfaceId, type SurfaceInstanceScope, type SurfaceKind, type SurfacePersistence, type SurfaceProperties, type SurveyResponseProperties, type SwitchingCostProperties, type SymptomProperties, THIN_GRAPH_THRESHOLD, type TableColumn, type TargetCustomerSegmentProperties, type TaskProperties, type TeamOkrProperties, type TeamProperties, type TechnicalDebtItemProperties, type TerritoryProperties, type TestCaseProperties, type TestCoverageReportProperties, type TestEnvironmentProperties, type TestPlanProperties, type TestResultProperties, type TestSuiteProperties, type ThreatModelProperties, type ThreatProperties, type Timeframe, type TotalEntityCountCheck, type TouchpointProperties, type TranslationBundleProperties, type TranslationKeyProperties, type TrialConfigProperties, type TutorialProperties, type UPGAnchorEntity, type UPGAntiPattern, type UPGAntiPatternConcern, type UPGAntiPatternSeverity, type UPGApproach, type UPGApproachEnvelope, type UPGApproachId, type UPGAreaTaxonomyEntry, type UPGAssessment, type UPGBaseNode, type UPGBenchmarkSource, type UPGBoundaryDirection, type UPGBoundaryEdge, type UPGCrossEdge, type UPGCrossEdgeType, type UPGCrossOnlyEdgeType, type UPGCuratedAntiPattern, type UPGDocument, type UPGDomain, type UPGDomainBridge, type UPGDomainId, type UPGDomainPattern, type UPGDomainRing, type UPGDomainUsageGuide, type UPGEdge, type UPGEdgeCountSpec, type UPGEdgeDefinition, type UPGEdgeMigration, type UPGEdgeMigrationEndpoints, type UPGEdgePickHint, type UPGEdgeType, type UPGEntityFilterSpec, type UPGEntityType, type UPGEntityTypeMaturity, type UPGEnumScaleDefinition, type UPGEnumScaleValue, type UPGFramework, type UPGFrameworkMeta, type UPGHeader, type UPGHeaderCountsMismatch, type UPGHeaderIntegrity, type UPGHeaderIntegrityMismatch, type UPGHeaderProvenance, type UPGHeaderSealReport, type UPGIntegrity, type UPGLens, type UPGLensIntelligencePrompt, type UPGLifecycle, type UPGMappingConfidence, type UPGMemberKindKey, type UPGNode, type UPGOrganization, type UPGPlaybook, type UPGPortfolio, type UPGPortfolioDocument, type UPGPortfolioKind, type UPGPresenceExceptSpec, type UPGProduct, type UPGProductArea, type UPGProductStage, type UPGPropertyMap, type UPGPropertyMigration, type UPGPropertyMigrationChange, type UPGRegion, type UPGRegionEntityMembership, type UPGRegionEntityRole, type UPGRegionId, type UPGRegionShape, type UPGRegistry, type UPGScalarToEdgeMigration, type UPGScaleDefinition, type UPGScalePoint, type UPGSource, type UPGSplitEdge, type UPGSplitMigration, type UPGSplitRoute, type UPGSplitRouteTarget, type UPGSplitTarget, type UPGTreeChild, type UPGTreeGapPolicy, type UPGTreePattern, type UPGTreePatternDetail, type UPGTreePatternEdge, type UPGTreePatternSummary, type UPGTypeLabel, type UPGTypeMigration, type UPGValidationError, type UPGValidationProfile, type UPGValidationResult, type UPGValidationWarning, type UPGWildcardEndpoint, UPG_ACTIVE_TYPES, UPG_ANTI_PATTERNS, UPG_ANTI_PATTERN_CONCERNS, UPG_APPROACHES, UPG_APPROACHES_BY_ID, UPG_AREA_TAXONOMY, UPG_AREA_TAXONOMY_BY_COVERAGE_KEY, UPG_CANONICAL_FORMAT_VERSION, UPG_CONTAINMENT_FREE_TYPES, UPG_COUNT_BENCHMARKS, UPG_CROSS_EDGE_TYPES, UPG_CROSS_ELIGIBLE_CATALOG_EDGE_TYPES, UPG_CROSS_ONLY_EDGE_TYPES, UPG_DELIBERATE_ONLY_EDGE_TYPES, UPG_DEPRECATED_TYPES, UPG_DOMAINS, UPG_DOMAIN_ACTIVATION, UPG_DOMAIN_COUNT, UPG_DOMAIN_GUIDES, UPG_DOMAIN_RINGS, UPG_EDGE_CATALOG, UPG_EDGE_COUNT, UPG_EDGE_COUNT_SPECS, UPG_EDGE_MIGRATIONS, UPG_EDGE_PAIR_MAP, UPG_EDGE_TYPES, UPG_ENTITY_COUNT, UPG_ENTITY_FILTER_SPECS, UPG_ENTITY_META, UPG_ENTITY_META_BY_ID, UPG_ENTITY_META_BY_NAME, UPG_ENTITY_TO_DOMAIN, UPG_ENUM_SCALES, UPG_FORMAT_VERSION, UPG_FRAMEWORKS, UPG_FRAMEWORKS_BY_CATEGORY, UPG_FRAMEWORKS_BY_ID, UPG_FRAMEWORK_CATEGORIES, UPG_LENSES, UPG_LIFECYCLES, UPG_LIFECYCLE_FREE_TYPES, UPG_LIFECYCLE_PLANNED_TYPES, UPG_META_COUNT, UPG_MIGRATIONS, UPG_PLAYBOOKS, UPG_POLYMORPHIC_EDGE_KEYS, UPG_PORTFOLIO_KINDS, UPG_PORTFOLIO_SHARED_TYPES, UPG_PRESENCE_EXCEPT_SPECS, UPG_PRODUCT_STAGES, UPG_PRODUCT_STAGE_COERCION_MAP, UPG_PROPERTY_MIGRATIONS, UPG_PROPERTY_SCHEMA, UPG_RATIO_BENCHMARKS, UPG_REGIONS, UPG_REGION_COUNT, UPG_REGION_MAP, UPG_RELATIONSHIP_BENCHMARKS, UPG_SCALAR_TO_EDGE_MIGRATIONS, UPG_SCALES, UPG_SPLIT_MIGRATIONS, UPG_STATUS_MIGRATIONS, UPG_STRUCTURE_PATTERNS, UPG_TREE_PATTERNS, UPG_TREE_PATTERNS_BY_ID, UPG_TYPES, UPG_TYPES_SET, UPG_TYPE_ALIASES, UPG_TYPE_LABELS, UPG_TYPE_LABELS_MAP, UPG_TYPE_NAMES, UPG_VALIDATION_PROFILES, UPG_VALID_CHILDREN, UPG_VERSION, UPG_WILDCARD_ENDPOINT, USERS_NEEDS_PLAYBOOK, type UnitEconomicsProperties, UnknownEntityTypeError, type UserAdvisoryBoardProperties, type UserFlowProperties, type UserJourneyProperties, type UserStoryProperties, VARIES_BY_EDGE, type ValueObjectProperties, type ValuePropositionProperties, type ValueStreamProperties, type VariantProperties, type VisionProperties, type VulnerabilityProperties, WORKSPACE_ARRANGEMENT_EDGE_PROPERTY_SCHEMA, type WalkMigrationChainResult, type WalkthroughProperties, type WebinarProperties, type WireframeProperties, type WorkflowArtifactProperties, type WorkflowRunProperties, type WorkflowTemplateProperties, type WorkspaceCanvas, type WorkspaceProperties, backfillSlug, buildTypeAliases, canBeChildOf, checkConfigurationDrift, checkHeaderSeal, checkHeaderSealText, checkToEdgeCountSpec, classifyEntityFilter, coerceProductStage, collectSlugsForType, collectTargetEntities, compareVersions, computeBodyChecksum, concernEvaluatedFor, concernFor, concernGatesFor, crossProductScope, deriveCounts, derivePortfolioCounts, deriveSingleCounts, describeTreePattern, edgeCarriesProperties, edgeCountSpecKey, entityFilterKey, enumerateProjections, evaluateAntiPatterns, findInvalidStatusMigrationTargets, formatUpgText, friendlyToAssessment, generateSlug, getAnchorEntity, getAntiPatternById, getAntiPatterns, getAntiPatternsBySeverity, getAntiPatternsForStage, getAreaTaxonomyEntry, getBenchmark, getBenchmarksByDomain, getBusinessAreasForRegion, getCanonicalPlaybookForRegion, getCoverageKeysForRegion, getDefaultLens, getDeprecatedTypes, getDomainForType, getDomainIdForType, getDomainsInRing, getEdgePropertySchema, getEntityModifierSummary, getEnumScale, getEnumValueMeta, getGuideForDomain, getLens, getLensIds, getLensPlaybook, getLensesForDomain, getLifecycleForType, getLifecycleRenderShape, getMigrationMap, getPlaybookById, getPlaybooksForRegion, getPropertiesForScale, getPropertyDefaultScale, getPropertyMigrations, getPropertyModifier, getPropertySchema, getRegion, getRegionForEntityType, getReplacementType, getRingForDomain, getScalarToEdgeMigrations, getScale, getSplitMigrations, getTreePattern, getTypeId, getTypeName, getTypes, getUPGEdgeMigrations, getValidChildren, getVisibleTypes, hasStatusMigration, isAggregateShapedProperty, isCanonical, isCanonicalProductStage, isContainmentFreeType, isCrossCapable, isCrossProductEligible, isCuratedCrossEligible, isDeliberateOnlyEdge, isDeprecatedType, isDomainGuideStep, isEntitySequenceStep, isFrameworkInvocationStep, isLegacyProductStage, isLifecycleFreeType, isLifecyclePlannedType, isPolymorphicEdge, isPortfolio, isPortfolioSharedType, isRecordEntity, isRegisteredPolymorphicEdge, isRuntimeStateShapedProperty, isSubSequenceStep, isThinCoverageAdvisory, isUPGDocument, listPropertiesByModifier, listStatusMigrations, listTreePatternSummaries, migrateEdge, migrateNode, migrateNodeProperties, migrateProductStage, migrateStatusValue, normalizeDocument, parseUpg, pickCanonicalEdge, predicatesProvablyDisjoint, presenceExceptKey, projectGraph, readActiveWhen, readStringArray, relationalCoveredEntityTypes, resolveAllEdges, resolveContainmentEdge, resolveEntityType, resolveLabel, resolveRelationalPath, resolveSlugCollision, resolveTreePatternEdges, ringOrderedDomainIds, rotateSlug, serializeCanonical, validateEdgeProperties, validateProductStageStrict, validateUPGDocument, validateUPGFramework, validationProfileFor, walkMigrationChainToCanonical };