@unified-product-graph/core 0.22.2 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +41 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -22
- package/dist/index.d.ts +44 -22
- package/dist/index.js +41 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/spec/examples/cms-field-guide.upg +24 -24
package/dist/index.d.cts
CHANGED
|
@@ -1470,6 +1470,20 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
1470
1470
|
source_type: string;
|
|
1471
1471
|
target_type: string;
|
|
1472
1472
|
};
|
|
1473
|
+
epic_decomposes_into_task: {
|
|
1474
|
+
forward_verb: string;
|
|
1475
|
+
reverse_verb: string;
|
|
1476
|
+
classification: "hierarchy";
|
|
1477
|
+
source_type: string;
|
|
1478
|
+
target_type: string;
|
|
1479
|
+
};
|
|
1480
|
+
epic_affected_by_bug: {
|
|
1481
|
+
forward_verb: string;
|
|
1482
|
+
reverse_verb: string;
|
|
1483
|
+
classification: "hierarchy";
|
|
1484
|
+
source_type: string;
|
|
1485
|
+
target_type: string;
|
|
1486
|
+
};
|
|
1473
1487
|
task_has_subtask: {
|
|
1474
1488
|
forward_verb: string;
|
|
1475
1489
|
reverse_verb: string;
|
|
@@ -7583,6 +7597,14 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
7583
7597
|
target_type: string;
|
|
7584
7598
|
cross_product_eligible: true;
|
|
7585
7599
|
};
|
|
7600
|
+
dependency_resolved_by_objective: {
|
|
7601
|
+
forward_verb: string;
|
|
7602
|
+
reverse_verb: string;
|
|
7603
|
+
classification: "cross-domain";
|
|
7604
|
+
source_type: string;
|
|
7605
|
+
target_type: string;
|
|
7606
|
+
cross_product_eligible: true;
|
|
7607
|
+
};
|
|
7586
7608
|
objective_raises_strategic_question: {
|
|
7587
7609
|
forward_verb: string;
|
|
7588
7610
|
reverse_verb: string;
|
|
@@ -8188,7 +8210,7 @@ interface UPGPortfolioDocument {
|
|
|
8188
8210
|
/**
|
|
8189
8211
|
* Legacy product-stage aliases (UPG-509 Part 2).
|
|
8190
8212
|
*
|
|
8191
|
-
* Existing graphs (`entopo.upg`, `
|
|
8213
|
+
* Existing graphs (`entopo.upg`, `nimbus.upg`, `maximum-minimum.upg`,
|
|
8192
8214
|
* `notion-saturated.upg`, etc.) carry `product.stage` values that pre-date
|
|
8193
8215
|
* the canonical `UPGProductStage` enum
|
|
8194
8216
|
* (`concept | validation | build | beta | launch | growth | mature |
|
|
@@ -8631,7 +8653,7 @@ declare const UPG_DOMAINS: readonly [{
|
|
|
8631
8653
|
}, {
|
|
8632
8654
|
readonly id: "foundations";
|
|
8633
8655
|
readonly label: "Foundations";
|
|
8634
|
-
readonly description: "The shared specifications and foundational primitives a product organisation stewards or implements everywhere. Specifications are governed specs (query languages, protocols, data formats, encodings) like
|
|
8656
|
+
readonly description: "The shared specifications and foundational primitives a product organisation stewards or implements everywhere. Specifications are governed specs (query languages, protocols, data formats, encodings) like NQL or Structured Text; primitives are the compositional units those specs define (a block, a reference, a query value). Both are registry-hostable canonicals that products implement, expose, or conform to. Distinct from a product feature: a specification has no single owner, no P&L, and no buyer; it is the rulebook many products point at.";
|
|
8635
8657
|
readonly types: readonly ["specification", "primitive", "operating_lifecycle", "operating_stage"];
|
|
8636
8658
|
}];
|
|
8637
8659
|
/**
|
|
@@ -9825,7 +9847,7 @@ declare function migrateEdge<T extends {
|
|
|
9825
9847
|
* type's lifecycle exists but the graph carries pre-canonical status values
|
|
9826
9848
|
* the lifecycle never had.
|
|
9827
9849
|
*
|
|
9828
|
-
* Source: live drift in `.upg/entopo.upg`, `.upg/
|
|
9850
|
+
* Source: live drift in `.upg/entopo.upg`, `.upg/nimbus.upg`, and
|
|
9829
9851
|
* `.upg/inkling.upg` surveyed during the v0.5 launch train (UPG-527).
|
|
9830
9852
|
* Highest single drift class: 173 `service` nodes with `status: "active"`
|
|
9831
9853
|
* against the canonical `[development, staging, production, deprecated]`
|
|
@@ -11452,7 +11474,7 @@ interface CompetitorProperties {
|
|
|
11452
11474
|
/**
|
|
11453
11475
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11454
11476
|
* an analyst report, or a research note.
|
|
11455
|
-
* @example "https://
|
|
11477
|
+
* @example "https://docs.larch.example/pricing/"
|
|
11456
11478
|
*/
|
|
11457
11479
|
source?: string;
|
|
11458
11480
|
/**
|
|
@@ -11504,7 +11526,7 @@ interface CompetitorFeatureProperties {
|
|
|
11504
11526
|
/**
|
|
11505
11527
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11506
11528
|
* an analyst report, or a research note.
|
|
11507
|
-
* @example "https://
|
|
11529
|
+
* @example "https://docs.larch.example/changelog/"
|
|
11508
11530
|
*/
|
|
11509
11531
|
source?: string;
|
|
11510
11532
|
/**
|
|
@@ -11626,7 +11648,7 @@ interface CompetitiveAnalysisProperties {
|
|
|
11626
11648
|
*
|
|
11627
11649
|
* @example
|
|
11628
11650
|
* [
|
|
11629
|
-
* { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-
|
|
11651
|
+
* { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-structured-text',
|
|
11630
11652
|
* rationale_kind: 'opportunity',
|
|
11631
11653
|
* rationale_md: 'No technical reason; only adoption inertia. Watching brief.' },
|
|
11632
11654
|
* { axis_a_value_ref: 'val-composable', axis_b_value_ref: 'val-wysiwyg',
|
|
@@ -11644,7 +11666,7 @@ interface CompetitiveAnalysisProperties {
|
|
|
11644
11666
|
/**
|
|
11645
11667
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11646
11668
|
* an analyst report, or a research note.
|
|
11647
|
-
* @example "https://
|
|
11669
|
+
* @example "https://docs.larch.example/changelog/"
|
|
11648
11670
|
*/
|
|
11649
11671
|
source?: string;
|
|
11650
11672
|
/**
|
|
@@ -11723,7 +11745,7 @@ interface CompetitorSignalProperties {
|
|
|
11723
11745
|
/**
|
|
11724
11746
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11725
11747
|
* an analyst report, or a research note.
|
|
11726
|
-
* @example "https://
|
|
11748
|
+
* @example "https://docs.larch.example/changelog/"
|
|
11727
11749
|
*/
|
|
11728
11750
|
source?: string;
|
|
11729
11751
|
/**
|
|
@@ -11851,14 +11873,14 @@ interface ClassificationAxisProperties {
|
|
|
11851
11873
|
* @example
|
|
11852
11874
|
* const properties: ClassificationValueProperties = {
|
|
11853
11875
|
* rationale: 'Composable extends headless with three load-bearing commitments.',
|
|
11854
|
-
* exemplars: ['
|
|
11876
|
+
* exemplars: ['Nimbus', 'Larch', 'Prism'],
|
|
11855
11877
|
* commitments: [
|
|
11856
11878
|
* { name: 'Typed content graph', description: 'Schemas in code; references as edges.' },
|
|
11857
11879
|
* { name: 'Real-time backend', description: 'Live queries, CRDT collaboration.' },
|
|
11858
11880
|
* { name: 'Embeddable studio', description: 'Editor is a library hosted inside the team app.' },
|
|
11859
11881
|
* ],
|
|
11860
11882
|
* capabilities: [
|
|
11861
|
-
* { surface: 'delivery', bullets: ['
|
|
11883
|
+
* { surface: 'delivery', bullets: ['NQL', 'GraphQL', 'REST', 'Live Sync API'] },
|
|
11862
11884
|
* ],
|
|
11863
11885
|
* }
|
|
11864
11886
|
*/
|
|
@@ -11871,7 +11893,7 @@ interface ClassificationValueProperties {
|
|
|
11871
11893
|
/**
|
|
11872
11894
|
* Free-text examples of products occupying this value.
|
|
11873
11895
|
* For queryable occupancy, prefer `competitor` nodes with `classified_as` edges.
|
|
11874
|
-
* @example ['
|
|
11896
|
+
* @example ['Nimbus', 'Larch', 'Prism']
|
|
11875
11897
|
*/
|
|
11876
11898
|
exemplars?: string[];
|
|
11877
11899
|
/**
|
|
@@ -11898,8 +11920,8 @@ interface ClassificationValueProperties {
|
|
|
11898
11920
|
*
|
|
11899
11921
|
* @example
|
|
11900
11922
|
* [
|
|
11901
|
-
* { surface: 'delivery', bullets: ['
|
|
11902
|
-
* { surface: 'extensibility', bullets: ['Custom input components', '
|
|
11923
|
+
* { surface: 'delivery', bullets: ['NQL', 'GraphQL', 'REST', 'Live Sync API', 'Asset CDN'] },
|
|
11924
|
+
* { surface: 'extensibility', bullets: ['Custom input components', 'editor plugins'] },
|
|
11903
11925
|
* ]
|
|
11904
11926
|
*/
|
|
11905
11927
|
capabilities?: Array<ClassificationCapability>;
|
|
@@ -15405,7 +15427,7 @@ interface EventSchemaProperties {
|
|
|
15405
15427
|
*/
|
|
15406
15428
|
interface DashboardProperties {
|
|
15407
15429
|
/** Analytics tool hosting this dashboard */
|
|
15408
|
-
tool?: 'looker' | 'amplitude' | 'mixpanel' | 'posthog' | 'custom';
|
|
15430
|
+
tool?: 'looker' | 'amplitude' | 'mixpanel' | 'posthog' | 'omni' | 'custom';
|
|
15409
15431
|
/** URL to the live dashboard */
|
|
15410
15432
|
url?: string;
|
|
15411
15433
|
/** Intended audience for this dashboard */
|
|
@@ -18843,9 +18865,9 @@ interface FrameworkExerciseProperties {
|
|
|
18843
18865
|
* kind: 'language',
|
|
18844
18866
|
* language_flavor: 'query',
|
|
18845
18867
|
* governance: 'open_spec_stewarded',
|
|
18846
|
-
* steward: '
|
|
18868
|
+
* steward: 'Nimbus',
|
|
18847
18869
|
* openness: 'open',
|
|
18848
|
-
* spec_url: 'https://
|
|
18870
|
+
* spec_url: 'https://nimbus.example/docs/nql',
|
|
18849
18871
|
* current_version: '1.0',
|
|
18850
18872
|
* since: '2019',
|
|
18851
18873
|
* }
|
|
@@ -18875,13 +18897,13 @@ interface SpecificationProperties {
|
|
|
18875
18897
|
conformance?: string;
|
|
18876
18898
|
}
|
|
18877
18899
|
/** A foundational compositional unit a specification defines: the noun products
|
|
18878
|
-
* pass around and compose with (a
|
|
18900
|
+
* pass around and compose with (a Structured Text block, a typed reference, a
|
|
18879
18901
|
* Git commit, a Stripe PaymentIntent). Lifecycle-free, like `metric`.
|
|
18880
18902
|
*
|
|
18881
18903
|
* @example
|
|
18882
18904
|
* const properties: PrimitiveProperties = {
|
|
18883
18905
|
* primitive_kind: 'block',
|
|
18884
|
-
* defined_by: 'specification/
|
|
18906
|
+
* defined_by: 'specification/structured_text',
|
|
18885
18907
|
* since: '2018',
|
|
18886
18908
|
* }
|
|
18887
18909
|
*/
|
|
@@ -18894,7 +18916,7 @@ interface PrimitiveProperties {
|
|
|
18894
18916
|
since?: string;
|
|
18895
18917
|
}
|
|
18896
18918
|
/** An operating_lifecycle: a canonical, ordered (often cyclic) operating process
|
|
18897
|
-
* that many products' journey phases map onto — e.g.
|
|
18919
|
+
* that many products' journey phases map onto — e.g. Nimbus's content-operations
|
|
18898
18920
|
* lifecycle. Registry-hostable like a `specification`; the cross-product join key
|
|
18899
18921
|
* that turns per-surface journeys into one operation. Distinct from the per-entity
|
|
18900
18922
|
* status `lifecycle` grammar concept (this is an entity, not a state machine).
|
|
@@ -18902,13 +18924,13 @@ interface PrimitiveProperties {
|
|
|
18902
18924
|
* @example
|
|
18903
18925
|
* const properties: OperatingLifecycleProperties = {
|
|
18904
18926
|
* cyclic: true,
|
|
18905
|
-
* source: '
|
|
18927
|
+
* source: 'a canonical 5-stage content-ops lifecycle',
|
|
18906
18928
|
* }
|
|
18907
18929
|
*/
|
|
18908
18930
|
interface OperatingLifecycleProperties {
|
|
18909
18931
|
/** True if the process loops (e.g. Analyze → Extend → Plan). The sequence is fully expressed by the stages' `stage_order`; `cyclic` adds the wrap from the last stage back to the first. */
|
|
18910
18932
|
cyclic?: boolean;
|
|
18911
|
-
/** Origin of the canonical model (e.g. "
|
|
18933
|
+
/** Origin of the canonical model (e.g. "a published content-ops lifecycle"). Optional provenance; promote to an edge if it names a real `specification`/`document`. */
|
|
18912
18934
|
source?: string;
|
|
18913
18935
|
}
|
|
18914
18936
|
/** An operating_stage: one ordered stage of an `operating_lifecycle`. A product's
|
|
@@ -22518,7 +22540,7 @@ declare function isCanonical(text: string): boolean;
|
|
|
22518
22540
|
* it stamps the `upg_version` field of every `.upg` file written by the SDK.
|
|
22519
22541
|
* The `check:version-lockstep` gate enforces this at release time.
|
|
22520
22542
|
*/
|
|
22521
|
-
declare const UPG_VERSION: "0.
|
|
22543
|
+
declare const UPG_VERSION: "0.23.1";
|
|
22522
22544
|
/**
|
|
22523
22545
|
* The `.upg` JSON document format version. Written to the `upg_version` field.
|
|
22524
22546
|
* Evolves independently from `UPG_VERSION` (the catalogue version).
|
package/dist/index.d.ts
CHANGED
|
@@ -1470,6 +1470,20 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
1470
1470
|
source_type: string;
|
|
1471
1471
|
target_type: string;
|
|
1472
1472
|
};
|
|
1473
|
+
epic_decomposes_into_task: {
|
|
1474
|
+
forward_verb: string;
|
|
1475
|
+
reverse_verb: string;
|
|
1476
|
+
classification: "hierarchy";
|
|
1477
|
+
source_type: string;
|
|
1478
|
+
target_type: string;
|
|
1479
|
+
};
|
|
1480
|
+
epic_affected_by_bug: {
|
|
1481
|
+
forward_verb: string;
|
|
1482
|
+
reverse_verb: string;
|
|
1483
|
+
classification: "hierarchy";
|
|
1484
|
+
source_type: string;
|
|
1485
|
+
target_type: string;
|
|
1486
|
+
};
|
|
1473
1487
|
task_has_subtask: {
|
|
1474
1488
|
forward_verb: string;
|
|
1475
1489
|
reverse_verb: string;
|
|
@@ -7583,6 +7597,14 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
7583
7597
|
target_type: string;
|
|
7584
7598
|
cross_product_eligible: true;
|
|
7585
7599
|
};
|
|
7600
|
+
dependency_resolved_by_objective: {
|
|
7601
|
+
forward_verb: string;
|
|
7602
|
+
reverse_verb: string;
|
|
7603
|
+
classification: "cross-domain";
|
|
7604
|
+
source_type: string;
|
|
7605
|
+
target_type: string;
|
|
7606
|
+
cross_product_eligible: true;
|
|
7607
|
+
};
|
|
7586
7608
|
objective_raises_strategic_question: {
|
|
7587
7609
|
forward_verb: string;
|
|
7588
7610
|
reverse_verb: string;
|
|
@@ -8188,7 +8210,7 @@ interface UPGPortfolioDocument {
|
|
|
8188
8210
|
/**
|
|
8189
8211
|
* Legacy product-stage aliases (UPG-509 Part 2).
|
|
8190
8212
|
*
|
|
8191
|
-
* Existing graphs (`entopo.upg`, `
|
|
8213
|
+
* Existing graphs (`entopo.upg`, `nimbus.upg`, `maximum-minimum.upg`,
|
|
8192
8214
|
* `notion-saturated.upg`, etc.) carry `product.stage` values that pre-date
|
|
8193
8215
|
* the canonical `UPGProductStage` enum
|
|
8194
8216
|
* (`concept | validation | build | beta | launch | growth | mature |
|
|
@@ -8631,7 +8653,7 @@ declare const UPG_DOMAINS: readonly [{
|
|
|
8631
8653
|
}, {
|
|
8632
8654
|
readonly id: "foundations";
|
|
8633
8655
|
readonly label: "Foundations";
|
|
8634
|
-
readonly description: "The shared specifications and foundational primitives a product organisation stewards or implements everywhere. Specifications are governed specs (query languages, protocols, data formats, encodings) like
|
|
8656
|
+
readonly description: "The shared specifications and foundational primitives a product organisation stewards or implements everywhere. Specifications are governed specs (query languages, protocols, data formats, encodings) like NQL or Structured Text; primitives are the compositional units those specs define (a block, a reference, a query value). Both are registry-hostable canonicals that products implement, expose, or conform to. Distinct from a product feature: a specification has no single owner, no P&L, and no buyer; it is the rulebook many products point at.";
|
|
8635
8657
|
readonly types: readonly ["specification", "primitive", "operating_lifecycle", "operating_stage"];
|
|
8636
8658
|
}];
|
|
8637
8659
|
/**
|
|
@@ -9825,7 +9847,7 @@ declare function migrateEdge<T extends {
|
|
|
9825
9847
|
* type's lifecycle exists but the graph carries pre-canonical status values
|
|
9826
9848
|
* the lifecycle never had.
|
|
9827
9849
|
*
|
|
9828
|
-
* Source: live drift in `.upg/entopo.upg`, `.upg/
|
|
9850
|
+
* Source: live drift in `.upg/entopo.upg`, `.upg/nimbus.upg`, and
|
|
9829
9851
|
* `.upg/inkling.upg` surveyed during the v0.5 launch train (UPG-527).
|
|
9830
9852
|
* Highest single drift class: 173 `service` nodes with `status: "active"`
|
|
9831
9853
|
* against the canonical `[development, staging, production, deprecated]`
|
|
@@ -11452,7 +11474,7 @@ interface CompetitorProperties {
|
|
|
11452
11474
|
/**
|
|
11453
11475
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11454
11476
|
* an analyst report, or a research note.
|
|
11455
|
-
* @example "https://
|
|
11477
|
+
* @example "https://docs.larch.example/pricing/"
|
|
11456
11478
|
*/
|
|
11457
11479
|
source?: string;
|
|
11458
11480
|
/**
|
|
@@ -11504,7 +11526,7 @@ interface CompetitorFeatureProperties {
|
|
|
11504
11526
|
/**
|
|
11505
11527
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11506
11528
|
* an analyst report, or a research note.
|
|
11507
|
-
* @example "https://
|
|
11529
|
+
* @example "https://docs.larch.example/changelog/"
|
|
11508
11530
|
*/
|
|
11509
11531
|
source?: string;
|
|
11510
11532
|
/**
|
|
@@ -11626,7 +11648,7 @@ interface CompetitiveAnalysisProperties {
|
|
|
11626
11648
|
*
|
|
11627
11649
|
* @example
|
|
11628
11650
|
* [
|
|
11629
|
-
* { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-
|
|
11651
|
+
* { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-structured-text',
|
|
11630
11652
|
* rationale_kind: 'opportunity',
|
|
11631
11653
|
* rationale_md: 'No technical reason; only adoption inertia. Watching brief.' },
|
|
11632
11654
|
* { axis_a_value_ref: 'val-composable', axis_b_value_ref: 'val-wysiwyg',
|
|
@@ -11644,7 +11666,7 @@ interface CompetitiveAnalysisProperties {
|
|
|
11644
11666
|
/**
|
|
11645
11667
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11646
11668
|
* an analyst report, or a research note.
|
|
11647
|
-
* @example "https://
|
|
11669
|
+
* @example "https://docs.larch.example/changelog/"
|
|
11648
11670
|
*/
|
|
11649
11671
|
source?: string;
|
|
11650
11672
|
/**
|
|
@@ -11723,7 +11745,7 @@ interface CompetitorSignalProperties {
|
|
|
11723
11745
|
/**
|
|
11724
11746
|
* Provenance: where this was observed. A changelog, pricing, or docs URL,
|
|
11725
11747
|
* an analyst report, or a research note.
|
|
11726
|
-
* @example "https://
|
|
11748
|
+
* @example "https://docs.larch.example/changelog/"
|
|
11727
11749
|
*/
|
|
11728
11750
|
source?: string;
|
|
11729
11751
|
/**
|
|
@@ -11851,14 +11873,14 @@ interface ClassificationAxisProperties {
|
|
|
11851
11873
|
* @example
|
|
11852
11874
|
* const properties: ClassificationValueProperties = {
|
|
11853
11875
|
* rationale: 'Composable extends headless with three load-bearing commitments.',
|
|
11854
|
-
* exemplars: ['
|
|
11876
|
+
* exemplars: ['Nimbus', 'Larch', 'Prism'],
|
|
11855
11877
|
* commitments: [
|
|
11856
11878
|
* { name: 'Typed content graph', description: 'Schemas in code; references as edges.' },
|
|
11857
11879
|
* { name: 'Real-time backend', description: 'Live queries, CRDT collaboration.' },
|
|
11858
11880
|
* { name: 'Embeddable studio', description: 'Editor is a library hosted inside the team app.' },
|
|
11859
11881
|
* ],
|
|
11860
11882
|
* capabilities: [
|
|
11861
|
-
* { surface: 'delivery', bullets: ['
|
|
11883
|
+
* { surface: 'delivery', bullets: ['NQL', 'GraphQL', 'REST', 'Live Sync API'] },
|
|
11862
11884
|
* ],
|
|
11863
11885
|
* }
|
|
11864
11886
|
*/
|
|
@@ -11871,7 +11893,7 @@ interface ClassificationValueProperties {
|
|
|
11871
11893
|
/**
|
|
11872
11894
|
* Free-text examples of products occupying this value.
|
|
11873
11895
|
* For queryable occupancy, prefer `competitor` nodes with `classified_as` edges.
|
|
11874
|
-
* @example ['
|
|
11896
|
+
* @example ['Nimbus', 'Larch', 'Prism']
|
|
11875
11897
|
*/
|
|
11876
11898
|
exemplars?: string[];
|
|
11877
11899
|
/**
|
|
@@ -11898,8 +11920,8 @@ interface ClassificationValueProperties {
|
|
|
11898
11920
|
*
|
|
11899
11921
|
* @example
|
|
11900
11922
|
* [
|
|
11901
|
-
* { surface: 'delivery', bullets: ['
|
|
11902
|
-
* { surface: 'extensibility', bullets: ['Custom input components', '
|
|
11923
|
+
* { surface: 'delivery', bullets: ['NQL', 'GraphQL', 'REST', 'Live Sync API', 'Asset CDN'] },
|
|
11924
|
+
* { surface: 'extensibility', bullets: ['Custom input components', 'editor plugins'] },
|
|
11903
11925
|
* ]
|
|
11904
11926
|
*/
|
|
11905
11927
|
capabilities?: Array<ClassificationCapability>;
|
|
@@ -15405,7 +15427,7 @@ interface EventSchemaProperties {
|
|
|
15405
15427
|
*/
|
|
15406
15428
|
interface DashboardProperties {
|
|
15407
15429
|
/** Analytics tool hosting this dashboard */
|
|
15408
|
-
tool?: 'looker' | 'amplitude' | 'mixpanel' | 'posthog' | 'custom';
|
|
15430
|
+
tool?: 'looker' | 'amplitude' | 'mixpanel' | 'posthog' | 'omni' | 'custom';
|
|
15409
15431
|
/** URL to the live dashboard */
|
|
15410
15432
|
url?: string;
|
|
15411
15433
|
/** Intended audience for this dashboard */
|
|
@@ -18843,9 +18865,9 @@ interface FrameworkExerciseProperties {
|
|
|
18843
18865
|
* kind: 'language',
|
|
18844
18866
|
* language_flavor: 'query',
|
|
18845
18867
|
* governance: 'open_spec_stewarded',
|
|
18846
|
-
* steward: '
|
|
18868
|
+
* steward: 'Nimbus',
|
|
18847
18869
|
* openness: 'open',
|
|
18848
|
-
* spec_url: 'https://
|
|
18870
|
+
* spec_url: 'https://nimbus.example/docs/nql',
|
|
18849
18871
|
* current_version: '1.0',
|
|
18850
18872
|
* since: '2019',
|
|
18851
18873
|
* }
|
|
@@ -18875,13 +18897,13 @@ interface SpecificationProperties {
|
|
|
18875
18897
|
conformance?: string;
|
|
18876
18898
|
}
|
|
18877
18899
|
/** A foundational compositional unit a specification defines: the noun products
|
|
18878
|
-
* pass around and compose with (a
|
|
18900
|
+
* pass around and compose with (a Structured Text block, a typed reference, a
|
|
18879
18901
|
* Git commit, a Stripe PaymentIntent). Lifecycle-free, like `metric`.
|
|
18880
18902
|
*
|
|
18881
18903
|
* @example
|
|
18882
18904
|
* const properties: PrimitiveProperties = {
|
|
18883
18905
|
* primitive_kind: 'block',
|
|
18884
|
-
* defined_by: 'specification/
|
|
18906
|
+
* defined_by: 'specification/structured_text',
|
|
18885
18907
|
* since: '2018',
|
|
18886
18908
|
* }
|
|
18887
18909
|
*/
|
|
@@ -18894,7 +18916,7 @@ interface PrimitiveProperties {
|
|
|
18894
18916
|
since?: string;
|
|
18895
18917
|
}
|
|
18896
18918
|
/** An operating_lifecycle: a canonical, ordered (often cyclic) operating process
|
|
18897
|
-
* that many products' journey phases map onto — e.g.
|
|
18919
|
+
* that many products' journey phases map onto — e.g. Nimbus's content-operations
|
|
18898
18920
|
* lifecycle. Registry-hostable like a `specification`; the cross-product join key
|
|
18899
18921
|
* that turns per-surface journeys into one operation. Distinct from the per-entity
|
|
18900
18922
|
* status `lifecycle` grammar concept (this is an entity, not a state machine).
|
|
@@ -18902,13 +18924,13 @@ interface PrimitiveProperties {
|
|
|
18902
18924
|
* @example
|
|
18903
18925
|
* const properties: OperatingLifecycleProperties = {
|
|
18904
18926
|
* cyclic: true,
|
|
18905
|
-
* source: '
|
|
18927
|
+
* source: 'a canonical 5-stage content-ops lifecycle',
|
|
18906
18928
|
* }
|
|
18907
18929
|
*/
|
|
18908
18930
|
interface OperatingLifecycleProperties {
|
|
18909
18931
|
/** True if the process loops (e.g. Analyze → Extend → Plan). The sequence is fully expressed by the stages' `stage_order`; `cyclic` adds the wrap from the last stage back to the first. */
|
|
18910
18932
|
cyclic?: boolean;
|
|
18911
|
-
/** Origin of the canonical model (e.g. "
|
|
18933
|
+
/** Origin of the canonical model (e.g. "a published content-ops lifecycle"). Optional provenance; promote to an edge if it names a real `specification`/`document`. */
|
|
18912
18934
|
source?: string;
|
|
18913
18935
|
}
|
|
18914
18936
|
/** An operating_stage: one ordered stage of an `operating_lifecycle`. A product's
|
|
@@ -22518,7 +22540,7 @@ declare function isCanonical(text: string): boolean;
|
|
|
22518
22540
|
* it stamps the `upg_version` field of every `.upg` file written by the SDK.
|
|
22519
22541
|
* The `check:version-lockstep` gate enforces this at release time.
|
|
22520
22542
|
*/
|
|
22521
|
-
declare const UPG_VERSION: "0.
|
|
22543
|
+
declare const UPG_VERSION: "0.23.1";
|
|
22522
22544
|
/**
|
|
22523
22545
|
* The `.upg` JSON document format version. Written to the `upg_version` field.
|
|
22524
22546
|
* Evolves independently from `UPG_VERSION` (the catalogue version).
|
package/dist/index.js
CHANGED
|
@@ -495,7 +495,7 @@ var UPG_DOMAINS = [
|
|
|
495
495
|
{
|
|
496
496
|
id: "foundations",
|
|
497
497
|
label: "Foundations",
|
|
498
|
-
description: "The shared specifications and foundational primitives a product organisation stewards or implements everywhere. Specifications are governed specs (query languages, protocols, data formats, encodings) like
|
|
498
|
+
description: "The shared specifications and foundational primitives a product organisation stewards or implements everywhere. Specifications are governed specs (query languages, protocols, data formats, encodings) like NQL or Structured Text; primitives are the compositional units those specs define (a block, a reference, a query value). Both are registry-hostable canonicals that products implement, expose, or conform to. Distinct from a product feature: a specification has no single owner, no P&L, and no buyer; it is the rulebook many products point at.",
|
|
499
499
|
types: ["specification", "primitive", "operating_lifecycle", "operating_stage"]
|
|
500
500
|
}
|
|
501
501
|
];
|
|
@@ -1429,6 +1429,17 @@ var UPG_EDGE_CATALOG = {
|
|
|
1429
1429
|
bug_affects_feature: { forward_verb: "affects", reverse_verb: "affected_by", classification: "cross-domain", source_type: "bug", target_type: "feature" },
|
|
1430
1430
|
roadmap_item_references_feature: { forward_verb: "references", reverse_verb: "referenced_by", classification: "cross-domain", source_type: "roadmap_item", target_type: "feature" },
|
|
1431
1431
|
feature_decomposes_into_task: { forward_verb: "decomposes_into", reverse_verb: "implements", classification: "hierarchy", source_type: "feature", target_type: "task" },
|
|
1432
|
+
// Epic-level mirrors of the feature→task / feature→bug hierarchy (feedback
|
|
1433
|
+
// df99026a). A `feature` is the flat planning root, but an `epic` is a body of
|
|
1434
|
+
// work under it, and real imported ticket sets (Linear/Jira) carry bugs and
|
|
1435
|
+
// pure engineering tasks that belong to ONE epic, not the feature as a whole.
|
|
1436
|
+
// Without these, such tickets had to be mislabelled `user_story` (the only
|
|
1437
|
+
// epic child) to keep the epic grouping. These are additive twins of the
|
|
1438
|
+
// feature-level edges (same verbs/classification), so `pickCanonicalEdge` /
|
|
1439
|
+
// `resolveContainmentEdge('epic', 'task'|'bug')` and the adapter import path
|
|
1440
|
+
// resolve them with no further wiring.
|
|
1441
|
+
epic_decomposes_into_task: { forward_verb: "decomposes_into", reverse_verb: "implements", classification: "hierarchy", source_type: "epic", target_type: "task" },
|
|
1442
|
+
epic_affected_by_bug: { forward_verb: "affected_by", reverse_verb: "affects", classification: "hierarchy", source_type: "epic", target_type: "bug" },
|
|
1432
1443
|
task_has_subtask: { forward_verb: "has_subtask", reverse_verb: "is_subtask_of", classification: "hierarchy", source_type: "task", target_type: "task" },
|
|
1433
1444
|
// ── Planning cadence (0.20.0) ────────────────────────────────────────────────
|
|
1434
1445
|
// The cadence axis. E1 self-nests the interval (a program-increment contains
|
|
@@ -3205,6 +3216,15 @@ var UPG_EDGE_CATALOG = {
|
|
|
3205
3216
|
// by another team's graph within the portfolio (0.17.3 locked predicate).
|
|
3206
3217
|
objective_depends_on_dependency: { forward_verb: "depends_on", reverse_verb: "dependency_of", classification: "cross-domain", source_type: "objective", target_type: "dependency", cross_product_eligible: true },
|
|
3207
3218
|
dependency_blocks_objective: { forward_verb: "blocks", reverse_verb: "blocked_by", classification: "cross-domain", source_type: "dependency", target_type: "objective", cross_product_eligible: true },
|
|
3219
|
+
// The RESOLVING side, distinct from the two blocking edges above.
|
|
3220
|
+
// `dependency_blocks_objective` names an objective the dependency holds up (the
|
|
3221
|
+
// waiting side); this names the objective whose completion CLEARS the
|
|
3222
|
+
// dependency (the providing side). In a portfolio, a dependency in one
|
|
3223
|
+
// product's graph points at the objective in another product's graph that
|
|
3224
|
+
// delivers the awaited work, instead of recording it only in the free-text
|
|
3225
|
+
// `resolution` property. cross_product_eligible — the resolving objective
|
|
3226
|
+
// lives in another product's graph.
|
|
3227
|
+
dependency_resolved_by_objective: { forward_verb: "resolved_by", reverse_verb: "resolves", classification: "cross-domain", source_type: "dependency", target_type: "objective", cross_product_eligible: true },
|
|
3208
3228
|
// objective / initiative → strategic_question. A planning doc's "Risks & Open
|
|
3209
3229
|
// Questions" section names unresolved coordination questions the plan is
|
|
3210
3230
|
// exposed to (who owns a capability across teams after a reorg). The
|
|
@@ -3732,7 +3752,10 @@ var UPG_VALID_CHILDREN = {
|
|
|
3732
3752
|
// task_implements_user_story edge.
|
|
3733
3753
|
feature: ["epic", "bug", "task"],
|
|
3734
3754
|
feature_area: ["feature", "feature_area"],
|
|
3735
|
-
epic
|
|
3755
|
+
// epic owns user_story (the templated promise) and, mirroring feature, may
|
|
3756
|
+
// also directly contain bug/task — heterogeneous imported tickets that belong
|
|
3757
|
+
// to one epic rather than the feature as a whole (feedback df99026a).
|
|
3758
|
+
epic: ["user_story", "bug", "task"],
|
|
3736
3759
|
user_story: ["acceptance_criterion"],
|
|
3737
3760
|
task: ["task"],
|
|
3738
3761
|
// planning_cycle (0.20.0): the cadence axis self-nests (a program-increment
|
|
@@ -10462,9 +10485,9 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10462
10485
|
// ClassificationValueProperties: ClassificationValue: a value on a classification axis.
|
|
10463
10486
|
classification_value: {
|
|
10464
10487
|
rationale: { type: "string", description: "Short paragraph: why this value earns its own row/column. Longer narrative belongs in `summary_md` or attached `content_piece` nodes." },
|
|
10465
|
-
exemplars: { type: "string[]", description: "Free-text examples of products occupying this value. For queryable occupancy, prefer `competitor` nodes with `classified_as` edges. @example ['
|
|
10488
|
+
exemplars: { type: "string[]", description: "Free-text examples of products occupying this value. For queryable occupancy, prefer `competitor` nodes with `classified_as` edges. @example ['Nimbus', 'Larch', 'Prism']" },
|
|
10466
10489
|
commitments: { type: "object[]", description: "The N (typically 2\u20134) load-bearing commitments that define this category. Each commitment is a structural axis; removing it changes the category. Pairs with `capabilities`: commitments are the *load-bearing definition*; capabilities are the *surface offering*. @example [ { name: 'Typed content graph', description: 'Schemas in code; references as edges; content is structured data.' }, { name: 'Real-time backend', description: 'Live queries, CRDT collaboration, sub-second propagation.' }, { name: 'Embeddable studio', description: 'Editor is a library hosted inside the team app, not an external portal.' }, ]" },
|
|
10467
|
-
capabilities: { type: "object[]", description: "Structured capability bullets across the six canonical surfaces. Each surface appears at most once per `classification_value`. Pairs with `commitments`: capabilities describe what the category *offers*; commitments describe what *defines* it. @example [ { surface: 'delivery', bullets: ['
|
|
10490
|
+
capabilities: { type: "object[]", description: "Structured capability bullets across the six canonical surfaces. Each surface appears at most once per `classification_value`. Pairs with `commitments`: capabilities describe what the category *offers*; commitments describe what *defines* it. @example [ { surface: 'delivery', bullets: ['NQL', 'GraphQL', 'REST', 'Live Sync API', 'Asset CDN'] }, { surface: 'extensibility', bullets: ['Custom input components', 'editor plugins'] }, ]" }
|
|
10468
10491
|
},
|
|
10469
10492
|
// CodeRepositoryProperties: Code repository.
|
|
10470
10493
|
code_repository: {
|
|
@@ -10499,9 +10522,9 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10499
10522
|
analysis_type: { type: "string", enum: ["feature_comparison", "positioning", "swot", "pricing"], description: "Type of analysis. `feature_comparison` = side-by-side matrix. `positioning` = competitor positioning relative to each other. `swot` = strengths, weaknesses, opportunities, threats. `pricing` = pricing structure comparison." },
|
|
10500
10523
|
analysis_date: { type: "string", description: 'ISO date conducted. Competitive intelligence decays quickly; track snapshot age. @example "2026-03-15"' },
|
|
10501
10524
|
framework_id: { type: "string", description: 'Framework ID (references `UPGFramework.id`). @example "porter-five-forces", "swot-analysis", "competitive-matrix"' },
|
|
10502
|
-
empty_cells: { type: "object[]", description: "Empty cells in a 2-axis classification matrix that earn explicit commentary. Only the strategically interesting cells. Opportunity-kind cells are the most valuable; they identify unoccupied strategic space. Each entry references two `classification_value` nodes by id (one from each `classification_axis` child of this `competitive_analysis`). `validate_graph` enforces that the refs resolve to `classification_value` nodes whose parents are distinct `classification_axis` instances. See `ClassificationValueProperties.commitments` for the inverse \"occupied cell\" structural-definition shape. @example [ { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-
|
|
10525
|
+
empty_cells: { type: "object[]", description: "Empty cells in a 2-axis classification matrix that earn explicit commentary. Only the strategically interesting cells. Opportunity-kind cells are the most valuable; they identify unoccupied strategic space. Each entry references two `classification_value` nodes by id (one from each `classification_axis` child of this `competitive_analysis`). `validate_graph` enforces that the refs resolve to `classification_value` nodes whose parents are distinct `classification_axis` instances. See `ClassificationValueProperties.commitments` for the inverse \"occupied cell\" structural-definition shape. @example [ { axis_a_value_ref: 'val-git-based', axis_b_value_ref: 'val-structured-text', rationale_kind: 'opportunity', rationale_md: 'No technical reason; only adoption inertia. Watching brief.' }, { axis_a_value_ref: 'val-composable', axis_b_value_ref: 'val-wysiwyg', rationale_kind: 'structural', rationale_md: 'Composable rejects HTML blobs; WYSIWYG requires them.' }, ]" },
|
|
10503
10526
|
last_updated: { type: "string", description: 'Provenance: ISO date-time this record was last observed or refreshed. Distinct from `analysis_date` (when the analysis was conducted). @example "2026-06-13"' },
|
|
10504
|
-
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://
|
|
10527
|
+
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://docs.larch.example/changelog/"' },
|
|
10505
10528
|
confidence: {
|
|
10506
10529
|
type: "assessment",
|
|
10507
10530
|
scale_id: "confidence_5",
|
|
@@ -10529,7 +10552,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10529
10552
|
strengths: { type: "string[]", description: "Bulleted factual strengths. Each item is a short statement, not prose. @example ['Real-time multiplayer canvas', 'Generous free tier']" },
|
|
10530
10553
|
weaknesses: { type: "string[]", description: "Bulleted factual weaknesses: gaps, friction, or capabilities materially below market. @example ['Weak API query capabilities', 'No mobile companion']" },
|
|
10531
10554
|
last_updated: { type: "string", description: 'Provenance: ISO date-time this record was last observed or refreshed. Lets a stale record be told apart from a fresh one. @example "2026-06-13"' },
|
|
10532
|
-
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://
|
|
10555
|
+
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://docs.larch.example/pricing/"' },
|
|
10533
10556
|
confidence: {
|
|
10534
10557
|
type: "assessment",
|
|
10535
10558
|
scale_id: "confidence_5",
|
|
@@ -10551,7 +10574,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10551
10574
|
quality: { type: "string", enum: ["better", "same", "worse", "missing"], description: "Quality comparison. `better` = ours is meaningfully superior. `same` = roughly equivalent. `worse` = theirs is meaningfully superior. `missing` = we have no equivalent." },
|
|
10552
10575
|
parity_status: { type: "string", enum: ["ahead", "behind", "parity", "unique_to_us", "unique_to_them"], description: "Parity. More granular than `quality`; captures whether the gap is offensive or defensive. `ahead` = we lead. `behind` = they lead. `parity` = equivalent. `unique_to_us` / `unique_to_them` = only one side offers it." },
|
|
10553
10576
|
last_updated: { type: "string", description: 'ISO date this assessment was last updated. Competitor feature landscapes change quickly. @example "2026-02-15"' },
|
|
10554
|
-
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://
|
|
10577
|
+
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://docs.larch.example/changelog/"' },
|
|
10555
10578
|
confidence: {
|
|
10556
10579
|
type: "assessment",
|
|
10557
10580
|
scale_id: "confidence_5",
|
|
@@ -10577,7 +10600,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10577
10600
|
from_value: { type: "string", description: "Reclassification only. The prior `classification_value` id the competitor was classified as before this move (the superseded cell). Absent for a first-time classification (nothing was superseded)." },
|
|
10578
10601
|
to_value: { type: "string", description: "Reclassification only. The new `classification_value` id the competitor is classified as after this move (the cell the new classify edge points at)." },
|
|
10579
10602
|
last_updated: { type: "string", description: 'Provenance: ISO date-time this record was last observed or refreshed. @example "2026-06-13"' },
|
|
10580
|
-
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://
|
|
10603
|
+
source: { type: "string", description: 'Provenance: where this was observed. A changelog, pricing, or docs URL, an analyst report, or a research note. @example "https://docs.larch.example/changelog/"' },
|
|
10581
10604
|
confidence: {
|
|
10582
10605
|
type: "assessment",
|
|
10583
10606
|
scale_id: "confidence_5",
|
|
@@ -10717,7 +10740,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10717
10740
|
},
|
|
10718
10741
|
// DashboardProperties: Dashboard entity.
|
|
10719
10742
|
dashboard: {
|
|
10720
|
-
tool: { type: "string", enum: ["looker", "amplitude", "mixpanel", "posthog", "custom"], description: "Analytics tool hosting this dashboard" },
|
|
10743
|
+
tool: { type: "string", enum: ["looker", "amplitude", "mixpanel", "posthog", "omni", "custom"], description: "Analytics tool hosting this dashboard" },
|
|
10721
10744
|
url: { type: "string", description: "URL to the live dashboard", modifier: "volatile" },
|
|
10722
10745
|
audience: { type: "string", description: "Intended audience for this dashboard" },
|
|
10723
10746
|
element_count: { type: "number", description: "Number of widgets or panels on the dashboard", modifier: "derived" },
|
|
@@ -12008,7 +12031,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
12008
12031
|
// OperatingLifecycleProperties: An operating_lifecycle: a canonical, ordered (often cyclic) operating process
|
|
12009
12032
|
operating_lifecycle: {
|
|
12010
12033
|
cyclic: { type: "boolean", description: "True if the process loops (e.g. Analyze \u2192 Extend \u2192 Plan). The sequence is fully expressed by the stages' `stage_order`; `cyclic` adds the wrap from the last stage back to the first." },
|
|
12011
|
-
source: { type: "string", description: 'Origin of the canonical model (e.g. "
|
|
12034
|
+
source: { type: "string", description: 'Origin of the canonical model (e.g. "a published content-ops lifecycle"). Optional provenance; promote to an edge if it names a real `specification`/`document`.' }
|
|
12012
12035
|
},
|
|
12013
12036
|
// OperatingStageProperties: An operating_stage: one ordered stage of an `operating_lifecycle`. A product's
|
|
12014
12037
|
operating_stage: {
|
|
@@ -22876,6 +22899,12 @@ var PRODUCT_SPEC_GUIDE = {
|
|
|
22876
22899
|
entity_types: ["feature_area", "feature", "epic", "user_story", "task"],
|
|
22877
22900
|
edge_chain: ["feature_area_contains_feature", "feature_decomposed_into_epic", "epic_specified_by_user_story", "task_implements_user_story"]
|
|
22878
22901
|
},
|
|
22902
|
+
{
|
|
22903
|
+
name: "Epic Work Items",
|
|
22904
|
+
description: "A bug or a pure engineering/infra task that belongs to one specific epic (not the feature as a whole) attaches directly to that epic, mirroring how task and bug attach at the feature level. Use this when importing a real tracker (Linear/Jira) whose tickets are heterogeneous: keep genuine stories as user_story, but let bugs, spikes, and engineering tasks nest under their epic with their true type instead of being mislabelled to preserve the grouping.",
|
|
22905
|
+
entity_types: ["epic", "task", "bug"],
|
|
22906
|
+
edge_chain: ["epic_decomposes_into_task", "epic_affected_by_bug"]
|
|
22907
|
+
},
|
|
22879
22908
|
{
|
|
22880
22909
|
name: "Planning Cadence",
|
|
22881
22910
|
description: "The cadence axis. Create a planning_cycle (a sprint, iteration, quarter, or PI), nest finer cycles inside a coarse one, schedule the stories that flow through it, and scope the objectives the cycle serves. Scheduling and scoping are deliberate links, not containment: a story keeps its feature/epic parent.",
|
|
@@ -29692,7 +29721,7 @@ function isCanonical(text) {
|
|
|
29692
29721
|
}
|
|
29693
29722
|
|
|
29694
29723
|
// src/index.ts
|
|
29695
|
-
var UPG_VERSION = "0.
|
|
29724
|
+
var UPG_VERSION = "0.23.1";
|
|
29696
29725
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
29697
29726
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
29698
29727
|
var UPG_TYPES = getTypes();
|