@unified-product-graph/core 0.25.1 → 0.26.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/dist/index.cjs CHANGED
@@ -135,6 +135,8 @@ __export(index_exports, {
135
135
  backfillSlug: () => backfillSlug,
136
136
  buildTypeAliases: () => buildTypeAliases,
137
137
  canBeChildOf: () => canBeChildOf,
138
+ checkHeaderSeal: () => checkHeaderSeal,
139
+ checkHeaderSealText: () => checkHeaderSealText,
138
140
  coerceProductStage: () => coerceProductStage,
139
141
  collectSlugsForType: () => collectSlugsForType,
140
142
  compareVersions: () => compareVersions,
@@ -143,6 +145,9 @@ __export(index_exports, {
143
145
  concernFor: () => concernFor,
144
146
  concernGatesFor: () => concernGatesFor,
145
147
  crossProductScope: () => crossProductScope,
148
+ deriveCounts: () => deriveCounts,
149
+ derivePortfolioCounts: () => derivePortfolioCounts,
150
+ deriveSingleCounts: () => deriveSingleCounts,
146
151
  describeTreePattern: () => describeTreePattern,
147
152
  edgeCarriesProperties: () => edgeCarriesProperties,
148
153
  evaluateAntiPatterns: () => evaluateAntiPatterns,
@@ -1164,7 +1169,12 @@ var UPG_ENTITY_META = [
1164
1169
  // ── Program Management ──
1165
1170
  { name: "program", type_id: "ent_262", maturity: "stable", since: "0.1.0" },
1166
1171
  { name: "project", type_id: "ent_263", maturity: "stable", since: "0.1.0" },
1167
- { name: "milestone", type_id: "ent_264", maturity: "stable", since: "0.1.0" },
1172
+ // `portfolio_shared` (0.25.1 feedback): a milestone is often a cross-team gate,
1173
+ // not one project's checkpoint — an org-wide "Open Beta" that several products'
1174
+ // projects must all satisfy. Shared tier lets `project_targets_milestone` (and
1175
+ // the other milestone edges) pass the cross-scope gate as `provisional`, same
1176
+ // as `project_implements_initiative`. Precedent: `planning_cycle` (0.20.0).
1177
+ { name: "milestone", type_id: "ent_264", maturity: "stable", since: "0.1.0", portfolio_shared: true },
1168
1178
  { name: "risk_register", type_id: "ent_265", maturity: "stable", since: "0.1.0" },
1169
1179
  { name: "risk_item", type_id: "ent_266", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "risk" },
1170
1180
  { name: "change_request", type_id: "ent_267", maturity: "stable", since: "0.1.0" },
@@ -4457,54 +4467,63 @@ var PRODUCT_LIFECYCLE = {
4457
4467
  phases: [
4458
4468
  {
4459
4469
  id: "concept",
4470
+ status_category: "triage",
4460
4471
  label: "Concept",
4461
4472
  description: "Napkin idea. Problem shape and solution sketch, pre-validation.",
4462
4473
  transitions_to: ["validation", "build", "beta", "launch", "growth", "mature", "sunset"]
4463
4474
  },
4464
4475
  {
4465
4476
  id: "validation",
4477
+ status_category: "started",
4466
4478
  label: "Validation",
4467
4479
  description: "Testing demand. User conversations and experiments pressure-test assumptions before build commits.",
4468
4480
  transitions_to: ["build", "beta", "launch", "growth", "mature", "sunset"]
4469
4481
  },
4470
4482
  {
4471
4483
  id: "build",
4484
+ status_category: "started",
4472
4485
  label: "Build",
4473
4486
  description: "Actively developing v1. Core functionality is being authored, pre-user.",
4474
4487
  transitions_to: ["beta", "launch", "growth", "mature", "sunset"]
4475
4488
  },
4476
4489
  {
4477
4490
  id: "beta",
4491
+ status_category: "started",
4478
4492
  label: "Beta",
4479
4493
  description: "Early users, iterating. Feature-complete enough to learn from, still changing weekly.",
4480
4494
  transitions_to: ["launch", "growth", "mature", "maintenance", "sunset"]
4481
4495
  },
4482
4496
  {
4483
4497
  id: "launch",
4498
+ status_category: "started",
4484
4499
  label: "Launch",
4485
4500
  description: "Generally available. Announced to the target audience, open past beta access.",
4486
4501
  transitions_to: ["growth", "mature", "maintenance", "sunset"]
4487
4502
  },
4488
4503
  {
4489
4504
  id: "growth",
4505
+ status_category: "started",
4490
4506
  label: "Growth",
4491
4507
  description: "Scaling users and revenue. Product fit validated; focus is acquisition, retention, expansion.",
4492
4508
  transitions_to: ["mature", "maintenance", "sunset"]
4493
4509
  },
4494
4510
  {
4495
4511
  id: "mature",
4512
+ status_category: "started",
4496
4513
  label: "Mature",
4497
4514
  description: "Stable. Growth levelled; investment weights toward optimisation, efficiency, and durability.",
4498
4515
  transitions_to: ["maintenance", "sunset"]
4499
4516
  },
4500
4517
  {
4501
4518
  id: "maintenance",
4519
+ status_category: "started",
4502
4520
  label: "Maintenance",
4503
4521
  description: "Sustaining. Minimal investment keeps the product running for existing users. Can transition back to `mature` on a strategic revival.",
4504
4522
  transitions_to: ["mature", "sunset"]
4505
4523
  },
4506
4524
  {
4507
4525
  id: "sunset",
4526
+ status_category: "completed",
4508
4527
  label: "Sunset",
4509
4528
  description: "Winding down or retired. Existing users are being migrated or offboarded.",
4510
4529
  transitions_to: []
@@ -4518,18 +4537,21 @@ var NEED_LIFECYCLE = {
4518
4537
  phases: [
4519
4538
  {
4520
4539
  id: "raw",
4540
+ status_category: "triage",
4521
4541
  label: "Raw",
4522
4542
  description: "Captured from an interview, observation, or support ticket. Articulation may be rough; may duplicate an existing need.",
4523
4543
  transitions_to: ["validated"]
4524
4544
  },
4525
4545
  {
4526
4546
  id: "validated",
4547
+ status_category: "started",
4527
4548
  label: "Validated",
4528
4549
  description: "Corroborated by multiple data points or targeted research. The team agrees it is a real, recurring need.",
4529
4550
  transitions_to: ["prioritized"]
4530
4551
  },
4531
4552
  {
4532
4553
  id: "prioritized",
4554
+ status_category: "completed",
4533
4555
  label: "Prioritized",
4534
4556
  description: "Ranked against other needs. Ready to inform opportunity definition and solution exploration.",
4535
4557
  transitions_to: []
@@ -4543,18 +4565,21 @@ var OPPORTUNITY_LIFECYCLE = {
4543
4565
  phases: [
4544
4566
  {
4545
4567
  id: "identified",
4568
+ status_category: "triage",
4546
4569
  label: "Identified",
4547
4570
  description: "A problem worth solving has been named. Sources include needs, insights, market trends, or competitive signals. Sizing and validation come next.",
4548
4571
  transitions_to: ["validated", "deferred"]
4549
4572
  },
4550
4573
  {
4551
4574
  id: "validated",
4575
+ status_category: "started",
4552
4576
  label: "Validated",
4553
4577
  description: "Research and evidence support pursuit. The problem is real, frequent, and painful enough to justify investment.",
4554
4578
  transitions_to: ["deferred"]
4555
4579
  },
4556
4580
  {
4557
4581
  id: "deferred",
4582
+ status_category: "backlog",
4558
4583
  label: "Deferred",
4559
4584
  description: "Acknowledged but parked. Capacity, priority, or strategic timing reasons. Can be reopened.",
4560
4585
  transitions_to: ["identified"]
@@ -4568,24 +4593,28 @@ var SOLUTION_LIFECYCLE = {
4568
4593
  phases: [
4569
4594
  {
4570
4595
  id: "proposed",
4596
+ status_category: "triage",
4571
4597
  label: "Proposed",
4572
4598
  description: "Identified as a possible response to an opportunity. Pre-commitment, pre-feasibility.",
4573
4599
  transitions_to: ["in_progress", "deferred"]
4574
4600
  },
4575
4601
  {
4576
4602
  id: "in_progress",
4603
+ status_category: "started",
4577
4604
  label: "In Progress",
4578
4605
  description: "A team is actively building, testing, or refining the solution.",
4579
4606
  transitions_to: ["shipped", "deferred"]
4580
4607
  },
4581
4608
  {
4582
4609
  id: "shipped",
4610
+ status_category: "completed",
4583
4611
  label: "Shipped",
4584
4612
  description: "Delivered to users. Live in the product.",
4585
4613
  transitions_to: ["deferred"]
4586
4614
  },
4587
4615
  {
4588
4616
  id: "deferred",
4617
+ status_category: "backlog",
4589
4618
  label: "Deferred",
4590
4619
  description: "Acknowledged but parked. Capacity, priority, or a change in direction. Can be reopened.",
4591
4620
  transitions_to: ["proposed"]
@@ -4599,24 +4628,28 @@ var EXPERIMENT_PLAN_LIFECYCLE = {
4599
4628
  phases: [
4600
4629
  {
4601
4630
  id: "drafted",
4631
+ status_category: "unstarted",
4602
4632
  label: "Drafted",
4603
4633
  description: "The plan is being written. Method, success criteria, target metric, projected reach/impact, ownership, and planned dates are being defined. Not yet approved.",
4604
4634
  transitions_to: ["scheduled", "cancelled"]
4605
4635
  },
4606
4636
  {
4607
4637
  id: "scheduled",
4638
+ status_category: "unstarted",
4608
4639
  label: "Scheduled",
4609
4640
  description: "The plan is approved and slotted for execution. Resources committed; awaiting start date.",
4610
4641
  transitions_to: ["approved", "cancelled"]
4611
4642
  },
4612
4643
  {
4613
4644
  id: "approved",
4645
+ status_category: "completed",
4614
4646
  label: "Approved",
4615
4647
  description: "Past scheduling: at least one run has started or completed against this plan. The plan is now a stable design artefact; future updates create a new plan.",
4616
4648
  transitions_to: []
4617
4649
  },
4618
4650
  {
4619
4651
  id: "cancelled",
4652
+ status_category: "cancelled",
4620
4653
  label: "Cancelled",
4621
4654
  description: "The plan was abandoned before any run started. Reason should be documented in description or via an attached decision.",
4622
4655
  transitions_to: []
@@ -4630,24 +4663,28 @@ var RESEARCH_PLAN_LIFECYCLE = {
4630
4663
  phases: [
4631
4664
  {
4632
4665
  id: "draft",
4666
+ status_category: "started",
4633
4667
  label: "Draft",
4634
4668
  description: "The plan is being written. Research question, suggested methods, and evidence threshold are being defined. Not yet approved for execution.",
4635
4669
  transitions_to: ["active"]
4636
4670
  },
4637
4671
  {
4638
4672
  id: "active",
4673
+ status_category: "started",
4639
4674
  label: "Active",
4640
4675
  description: "The plan has been approved and is being executed. Research sessions are underway or scheduled.",
4641
4676
  transitions_to: ["completed", "abandoned"]
4642
4677
  },
4643
4678
  {
4644
4679
  id: "completed",
4680
+ status_category: "completed",
4645
4681
  label: "Completed",
4646
4682
  description: "The planned research has been carried out and learnings have been captured. The plan is a historical record.",
4647
4683
  transitions_to: []
4648
4684
  },
4649
4685
  {
4650
4686
  id: "abandoned",
4687
+ status_category: "cancelled",
4651
4688
  label: "Abandoned",
4652
4689
  description: "Not executed: changing priorities, a decision no longer needing validation, or resource constraints.",
4653
4690
  transitions_to: []
@@ -4661,24 +4698,28 @@ var FEEDBACK_PROGRAM_LIFECYCLE = {
4661
4698
  phases: [
4662
4699
  {
4663
4700
  id: "planning",
4701
+ status_category: "unstarted",
4664
4702
  label: "Planning",
4665
4703
  description: "The program is being designed. Goals, audience, collection method, and cadence are being defined. No feedback is being collected yet.",
4666
4704
  transitions_to: ["active"]
4667
4705
  },
4668
4706
  {
4669
4707
  id: "active",
4708
+ status_category: "started",
4670
4709
  label: "Active",
4671
4710
  description: "The program is running. Feedback is being collected and processed on the defined cadence.",
4672
4711
  transitions_to: ["paused", "retired"]
4673
4712
  },
4674
4713
  {
4675
4714
  id: "paused",
4715
+ status_category: "backlog",
4676
4716
  label: "Paused",
4677
4717
  description: "Collection has been temporarily suspended. The program will resume.",
4678
4718
  transitions_to: ["active", "retired"]
4679
4719
  },
4680
4720
  {
4681
4721
  id: "retired",
4722
+ status_category: "completed",
4682
4723
  label: "Retired",
4683
4724
  description: "The program has ended. It is no longer collecting feedback. Historical data is preserved.",
4684
4725
  transitions_to: []
@@ -4692,36 +4733,42 @@ var FEATURE_REQUEST_LIFECYCLE = {
4692
4733
  phases: [
4693
4734
  {
4694
4735
  id: "new",
4736
+ status_category: "triage",
4695
4737
  label: "New",
4696
4738
  description: "The request has been submitted. It has not yet been reviewed by the product team.",
4697
4739
  transitions_to: ["under_review"]
4698
4740
  },
4699
4741
  {
4700
4742
  id: "under_review",
4743
+ status_category: "triage",
4701
4744
  label: "Under Review",
4702
4745
  description: "The request is being triaged. The product team is assessing feasibility, demand, and strategic fit.",
4703
4746
  transitions_to: ["planned", "wont_do"]
4704
4747
  },
4705
4748
  {
4706
4749
  id: "planned",
4750
+ status_category: "unstarted",
4707
4751
  label: "Planned",
4708
4752
  description: "The request has been accepted and is on the roadmap. It is scheduled for a future release cycle.",
4709
4753
  transitions_to: ["in_progress", "wont_do"]
4710
4754
  },
4711
4755
  {
4712
4756
  id: "in_progress",
4757
+ status_category: "started",
4713
4758
  label: "In Progress",
4714
4759
  description: "Work on fulfilling the request is actively underway.",
4715
4760
  transitions_to: ["shipped"]
4716
4761
  },
4717
4762
  {
4718
4763
  id: "shipped",
4764
+ status_category: "completed",
4719
4765
  label: "Shipped",
4720
4766
  description: "The requested capability has been delivered to users.",
4721
4767
  transitions_to: []
4722
4768
  },
4723
4769
  {
4724
4770
  id: "wont_do",
4771
+ status_category: "cancelled",
4725
4772
  label: "Won't Do",
4726
4773
  description: "Declined: strategic misalignment, infeasibility, or insufficient demand.",
4727
4774
  transitions_to: []
@@ -4735,24 +4782,28 @@ var BETA_PROGRAM_LIFECYCLE = {
4735
4782
  phases: [
4736
4783
  {
4737
4784
  id: "recruiting",
4785
+ status_category: "started",
4738
4786
  label: "Recruiting",
4739
4787
  description: "The program is accepting applications. Beta participants are being identified and onboarded.",
4740
4788
  transitions_to: ["active"]
4741
4789
  },
4742
4790
  {
4743
4791
  id: "active",
4792
+ status_category: "started",
4744
4793
  label: "Active",
4745
4794
  description: "Beta participants have access and are using the feature. Feedback is being collected.",
4746
4795
  transitions_to: ["graduated", "closed"]
4747
4796
  },
4748
4797
  {
4749
4798
  id: "graduated",
4799
+ status_category: "completed",
4750
4800
  label: "Graduated",
4751
4801
  description: "The beta was successful and the feature has progressed to general availability.",
4752
4802
  transitions_to: []
4753
4803
  },
4754
4804
  {
4755
4805
  id: "closed",
4806
+ status_category: "completed",
4756
4807
  label: "Closed",
4757
4808
  description: "The beta ended without graduating to GA. The feature was deprioritised, pivoted, or missed exit criteria.",
4758
4809
  transitions_to: []
@@ -4766,24 +4817,28 @@ var USER_ADVISORY_BOARD_LIFECYCLE = {
4766
4817
  phases: [
4767
4818
  {
4768
4819
  id: "recruiting",
4820
+ status_category: "started",
4769
4821
  label: "Recruiting",
4770
4822
  description: "Members are being identified and invited. The board is not yet convened.",
4771
4823
  transitions_to: ["active"]
4772
4824
  },
4773
4825
  {
4774
4826
  id: "active",
4827
+ status_category: "started",
4775
4828
  label: "Active",
4776
4829
  description: "The board is convened and meeting regularly. Members are providing strategic input.",
4777
4830
  transitions_to: ["paused", "retired"]
4778
4831
  },
4779
4832
  {
4780
4833
  id: "paused",
4834
+ status_category: "backlog",
4781
4835
  label: "Paused",
4782
4836
  description: "Board activities are temporarily suspended. Membership is retained and sessions will resume.",
4783
4837
  transitions_to: ["active", "retired"]
4784
4838
  },
4785
4839
  {
4786
4840
  id: "retired",
4841
+ status_category: "completed",
4787
4842
  label: "Retired",
4788
4843
  description: "The board has been disbanded. Members are no longer engaged in an advisory capacity.",
4789
4844
  transitions_to: []
@@ -4797,30 +4852,35 @@ var OBJECTIVE_LIFECYCLE = {
4797
4852
  phases: [
4798
4853
  {
4799
4854
  id: "draft",
4855
+ status_category: "started",
4800
4856
  label: "Draft",
4801
4857
  description: "The objective is being written. Key results have not yet been attached or approved.",
4802
4858
  transitions_to: ["active"]
4803
4859
  },
4804
4860
  {
4805
4861
  id: "active",
4862
+ status_category: "started",
4806
4863
  label: "Active",
4807
4864
  description: "The objective is in the current planning period. Key results are being measured and progress is tracked.",
4808
4865
  transitions_to: ["achieved", "missed", "deferred"]
4809
4866
  },
4810
4867
  {
4811
4868
  id: "achieved",
4869
+ status_category: "completed",
4812
4870
  label: "Achieved",
4813
4871
  description: "The objective was met or exceeded within the planning period.",
4814
4872
  transitions_to: []
4815
4873
  },
4816
4874
  {
4817
4875
  id: "missed",
4876
+ status_category: "completed",
4818
4877
  label: "Missed",
4819
4878
  description: "The planning period ended without achieving the objective. Learnings inform the next cycle.",
4820
4879
  transitions_to: []
4821
4880
  },
4822
4881
  {
4823
4882
  id: "deferred",
4883
+ status_category: "backlog",
4824
4884
  label: "Deferred",
4825
4885
  description: "The objective was not completed this period and is being carried forward. Can be reopened as active.",
4826
4886
  transitions_to: ["active"]
@@ -4834,24 +4894,28 @@ var KEY_RESULT_LIFECYCLE = {
4834
4894
  phases: [
4835
4895
  {
4836
4896
  id: "on_track",
4897
+ status_category: "started",
4837
4898
  label: "On Track",
4838
4899
  description: "Current measured value is progressing at a rate that should reach the target by the deadline.",
4839
4900
  transitions_to: ["at_risk", "behind", "achieved"]
4840
4901
  },
4841
4902
  {
4842
4903
  id: "at_risk",
4904
+ status_category: "started",
4843
4905
  label: "At Risk",
4844
4906
  description: "Progress is slowing. Without intervention, the target may not be reached by the deadline.",
4845
4907
  transitions_to: ["on_track", "behind", "achieved"]
4846
4908
  },
4847
4909
  {
4848
4910
  id: "behind",
4911
+ status_category: "started",
4849
4912
  label: "Behind",
4850
4913
  description: "Unlikely to reach the target at the current rate. The team needs to reassess strategy or accept a miss.",
4851
4914
  transitions_to: ["on_track", "at_risk", "achieved"]
4852
4915
  },
4853
4916
  {
4854
4917
  id: "achieved",
4918
+ status_category: "completed",
4855
4919
  label: "Achieved",
4856
4920
  description: "The target value has been reached or exceeded.",
4857
4921
  transitions_to: []
@@ -4865,18 +4929,21 @@ var STRATEGIC_THEME_LIFECYCLE = {
4865
4929
  phases: [
4866
4930
  {
4867
4931
  id: "active",
4932
+ status_category: "started",
4868
4933
  label: "Active",
4869
4934
  description: "The theme is a current organisational focus. Initiatives and objectives are being run under it.",
4870
4935
  transitions_to: ["completed", "paused"]
4871
4936
  },
4872
4937
  {
4873
4938
  id: "paused",
4939
+ status_category: "backlog",
4874
4940
  label: "Paused",
4875
4941
  description: "The theme is deprioritised for this period but is not being retired. It will resume.",
4876
4942
  transitions_to: ["active", "completed"]
4877
4943
  },
4878
4944
  {
4879
4945
  id: "completed",
4946
+ status_category: "completed",
4880
4947
  label: "Completed",
4881
4948
  description: "The theme has run its course. The focus area has been addressed or superseded by a new theme.",
4882
4949
  transitions_to: []
@@ -4890,24 +4957,28 @@ var INITIATIVE_LIFECYCLE = {
4890
4957
  phases: [
4891
4958
  {
4892
4959
  id: "proposed",
4960
+ status_category: "triage",
4893
4961
  label: "Proposed",
4894
4962
  description: "The initiative has been put forward but not yet approved for resourcing. Business case is being evaluated.",
4895
4963
  transitions_to: ["in_progress", "abandoned"]
4896
4964
  },
4897
4965
  {
4898
4966
  id: "in_progress",
4967
+ status_category: "started",
4899
4968
  label: "In Progress",
4900
4969
  description: "The initiative has been approved and work is underway. Teams are executing against it.",
4901
4970
  transitions_to: ["completed", "abandoned"]
4902
4971
  },
4903
4972
  {
4904
4973
  id: "completed",
4974
+ status_category: "completed",
4905
4975
  label: "Completed",
4906
4976
  description: "The initiative has achieved its goals and been formally closed.",
4907
4977
  transitions_to: []
4908
4978
  },
4909
4979
  {
4910
4980
  id: "abandoned",
4981
+ status_category: "cancelled",
4911
4982
  label: "Abandoned",
4912
4983
  description: "Stopped before completion: changing strategy, resource constraints, or learning that the goal is no longer relevant.",
4913
4984
  transitions_to: []
@@ -4921,18 +4992,21 @@ var STRATEGIC_PILLAR_LIFECYCLE = {
4921
4992
  phases: [
4922
4993
  {
4923
4994
  id: "proposed",
4995
+ status_category: "triage",
4924
4996
  label: "Proposed",
4925
4997
  description: "The pillar has been articulated but not yet ratified by leadership as a strategic commitment.",
4926
4998
  transitions_to: ["active"]
4927
4999
  },
4928
5000
  {
4929
5001
  id: "active",
5002
+ status_category: "started",
4930
5003
  label: "Active",
4931
5004
  description: "The pillar is a live strategic commitment. Decisions, themes, and initiatives are aligned to it.",
4932
5005
  transitions_to: ["sunset"]
4933
5006
  },
4934
5007
  {
4935
5008
  id: "sunset",
5009
+ status_category: "completed",
4936
5010
  label: "Sunset",
4937
5011
  description: "Retired: achieved, superseded by a new direction, or no longer reflects strategic reality.",
4938
5012
  transitions_to: []
@@ -4944,8 +5018,8 @@ var STRATEGIC_QUESTION_LIFECYCLE = {
4944
5018
  initial_phase: "open",
4945
5019
  terminal_phases: ["resolved"],
4946
5020
  phases: [
4947
- { id: "open", label: "Open", description: "The question has been raised but not yet answered. The plan is exposed to it.", transitions_to: ["resolved"] },
4948
- { id: "resolved", label: "Resolved", description: "The question has been answered; the resolution is captured. The plan is no longer exposed to it. May reopen if the answer unravels.", transitions_to: ["open"] }
5021
+ { id: "open", status_category: "triage", label: "Open", description: "The question has been raised but not yet answered. The plan is exposed to it.", transitions_to: ["resolved"] },
5022
+ { id: "resolved", status_category: "completed", label: "Resolved", description: "The question has been answered; the resolution is captured. The plan is no longer exposed to it. May reopen if the answer unravels.", transitions_to: ["open"] }
4949
5023
  ]
4950
5024
  };
4951
5025
  var OUTCOME_LIFECYCLE = {
@@ -4953,10 +5027,10 @@ var OUTCOME_LIFECYCLE = {
4953
5027
  initial_phase: "identified",
4954
5028
  terminal_phases: ["achieved", "abandoned"],
4955
5029
  phases: [
4956
- { id: "identified", label: "Identified", description: "The outcome has been named: the team agrees on what success looks like, but is not yet measuring it.", transitions_to: ["measuring", "abandoned"] },
4957
- { id: "measuring", label: "Measuring", description: "Instrumentation is live. Progress is being tracked against the outcome.", transitions_to: ["achieved", "abandoned"] },
4958
- { id: "achieved", label: "Achieved", description: "The outcome was reached. Captured for the record; no further pursuit required.", transitions_to: [] },
4959
- { id: "abandoned", label: "Abandoned", description: "Pursuit was stopped. Strategy shifted, the outcome lost relevance, or the cost outweighed value. May resume to `measuring` if the team revisits it.", transitions_to: ["measuring"] }
5030
+ { id: "identified", status_category: "triage", label: "Identified", description: "The outcome has been named: the team agrees on what success looks like, but is not yet measuring it.", transitions_to: ["measuring", "abandoned"] },
5031
+ { id: "measuring", status_category: "started", label: "Measuring", description: "Instrumentation is live. Progress is being tracked against the outcome.", transitions_to: ["achieved", "abandoned"] },
5032
+ { id: "achieved", status_category: "completed", label: "Achieved", description: "The outcome was reached. Captured for the record; no further pursuit required.", transitions_to: [] },
5033
+ { id: "abandoned", status_category: "cancelled", label: "Abandoned", description: "Pursuit was stopped. Strategy shifted, the outcome lost relevance, or the cost outweighed value. May resume to `measuring` if the team revisits it.", transitions_to: ["measuring"] }
4960
5034
  ]
4961
5035
  };
4962
5036
  var VISION_LIFECYCLE = {
@@ -4964,10 +5038,10 @@ var VISION_LIFECYCLE = {
4964
5038
  initial_phase: "drafting",
4965
5039
  terminal_phases: ["ratified", "revised", "archived"],
4966
5040
  phases: [
4967
- { id: "drafting", label: "Drafting", description: "Vision is being authored or rewritten. Not yet adopted.", transitions_to: ["ratified", "archived"] },
4968
- { id: "ratified", label: "Ratified", description: "The current, in-force vision. The team has aligned around it.", transitions_to: ["revised", "archived"] },
4969
- { id: "revised", label: "Revised", description: "Superseded by a newer vision but kept as a recorded milestone. May reopen to drafting if revisited.", transitions_to: ["drafting"] },
4970
- { id: "archived", label: "Archived", description: "No longer in force. Retained for historical reference.", transitions_to: ["drafting"] }
5041
+ { id: "drafting", status_category: "started", label: "Drafting", description: "Vision is being authored or rewritten. Not yet adopted.", transitions_to: ["ratified", "archived"] },
5042
+ { id: "ratified", status_category: "completed", label: "Ratified", description: "The current, in-force vision. The team has aligned around it.", transitions_to: ["revised", "archived"] },
5043
+ { id: "revised", status_category: "completed", label: "Revised", description: "Superseded by a newer vision but kept as a recorded milestone. May reopen to drafting if revisited.", transitions_to: ["drafting"] },
5044
+ { id: "archived", status_category: "completed", label: "Archived", description: "No longer in force. Retained for historical reference.", transitions_to: ["drafting"] }
4971
5045
  ]
4972
5046
  };
4973
5047
  var MISSION_LIFECYCLE = {
@@ -4975,9 +5049,9 @@ var MISSION_LIFECYCLE = {
4975
5049
  initial_phase: "drafting",
4976
5050
  terminal_phases: ["active", "archived"],
4977
5051
  phases: [
4978
- { id: "drafting", label: "Drafting", description: "Mission is being authored or rewritten. Not yet adopted.", transitions_to: ["active", "archived"] },
4979
- { id: "active", label: "Active", description: "The current, in-force mission. Guides product and organisational decisions.", transitions_to: ["archived"] },
4980
- { id: "archived", label: "Archived", description: "No longer in force. May reopen to drafting if the team revisits.", transitions_to: ["drafting"] }
5052
+ { id: "drafting", status_category: "started", label: "Drafting", description: "Mission is being authored or rewritten. Not yet adopted.", transitions_to: ["active", "archived"] },
5053
+ { id: "active", status_category: "started", label: "Active", description: "The current, in-force mission. Guides product and organisational decisions.", transitions_to: ["archived"] },
5054
+ { id: "archived", status_category: "completed", label: "Archived", description: "No longer in force. May reopen to drafting if the team revisits.", transitions_to: ["drafting"] }
4981
5055
  ]
4982
5056
  };
4983
5057
  var CAPABILITY_LIFECYCLE = {
@@ -4985,10 +5059,10 @@ var CAPABILITY_LIFECYCLE = {
4985
5059
  initial_phase: "planned",
4986
5060
  terminal_phases: ["operational", "retired"],
4987
5061
  phases: [
4988
- { id: "planned", label: "Planned", description: "Capability has been identified as needed but development has not started.", transitions_to: ["building", "retired"] },
4989
- { id: "building", label: "Building", description: "Active development: people, processes, or systems are being put in place.", transitions_to: ["operational", "retired"] },
4990
- { id: "operational", label: "Operational", description: "Capability is in place and functioning. The organisation can rely on it.", transitions_to: ["retired"] },
4991
- { id: "retired", label: "Retired", description: "No longer maintained. May reopen to building if the capability is reinvested in.", transitions_to: ["building"] }
5062
+ { id: "planned", status_category: "unstarted", label: "Planned", description: "Capability has been identified as needed but development has not started.", transitions_to: ["building", "retired"] },
5063
+ { id: "building", status_category: "started", label: "Building", description: "Active development: people, processes, or systems are being put in place.", transitions_to: ["operational", "retired"] },
5064
+ { id: "operational", status_category: "started", label: "Operational", description: "Capability is in place and functioning. The organisation can rely on it.", transitions_to: ["retired"] },
5065
+ { id: "retired", status_category: "completed", label: "Retired", description: "No longer maintained. May reopen to building if the capability is reinvested in.", transitions_to: ["building"] }
4992
5066
  ]
4993
5067
  };
4994
5068
  var FEATURE_AREA_LIFECYCLE = {
@@ -4998,18 +5072,21 @@ var FEATURE_AREA_LIFECYCLE = {
4998
5072
  phases: [
4999
5073
  {
5000
5074
  id: "planned",
5075
+ status_category: "unstarted",
5001
5076
  label: "Planned",
5002
5077
  description: "The feature area has been defined as an organising concept but no features have been built under it yet.",
5003
5078
  transitions_to: ["active"]
5004
5079
  },
5005
5080
  {
5006
5081
  id: "active",
5082
+ status_category: "started",
5007
5083
  label: "Active",
5008
5084
  description: "The feature area contains live features and is actively being developed.",
5009
5085
  transitions_to: ["deprecated"]
5010
5086
  },
5011
5087
  {
5012
5088
  id: "deprecated",
5089
+ status_category: "completed",
5013
5090
  label: "Deprecated",
5014
5091
  description: "The feature area is no longer being developed. It may still exist in the product but no new features are being added.",
5015
5092
  transitions_to: []
@@ -5023,24 +5100,28 @@ var FEATURE_LIFECYCLE = {
5023
5100
  phases: [
5024
5101
  {
5025
5102
  id: "proposed",
5103
+ status_category: "triage",
5026
5104
  label: "Proposed",
5027
5105
  description: "The feature has been suggested and is under consideration. It is not yet on the roadmap.",
5028
5106
  transitions_to: ["in_progress", "archived"]
5029
5107
  },
5030
5108
  {
5031
5109
  id: "in_progress",
5110
+ status_category: "started",
5032
5111
  label: "In Progress",
5033
5112
  description: "The feature is actively being designed and built.",
5034
5113
  transitions_to: ["shipped"]
5035
5114
  },
5036
5115
  {
5037
5116
  id: "shipped",
5117
+ status_category: "completed",
5038
5118
  label: "Shipped",
5039
5119
  description: "The feature is live in the product and available to users.",
5040
5120
  transitions_to: ["archived"]
5041
5121
  },
5042
5122
  {
5043
5123
  id: "archived",
5124
+ status_category: "completed",
5044
5125
  label: "Archived",
5045
5126
  description: "The feature has been removed from the product or superseded. It is retained as a historical record.",
5046
5127
  transitions_to: []
@@ -5054,18 +5135,21 @@ var RELEASE_LIFECYCLE = {
5054
5135
  phases: [
5055
5136
  {
5056
5137
  id: "planned",
5138
+ status_category: "unstarted",
5057
5139
  label: "Planned",
5058
5140
  description: "The release is defined and scheduled. Features are scoped but not all completed.",
5059
5141
  transitions_to: ["in_progress"]
5060
5142
  },
5061
5143
  {
5062
5144
  id: "in_progress",
5145
+ status_category: "started",
5063
5146
  label: "In Progress",
5064
5147
  description: "Features are being built. The release is open for development.",
5065
5148
  transitions_to: ["shipped"]
5066
5149
  },
5067
5150
  {
5068
5151
  id: "shipped",
5152
+ status_category: "completed",
5069
5153
  label: "Shipped",
5070
5154
  description: "The release has been deployed to production and is available to users.",
5071
5155
  transitions_to: []
@@ -5079,24 +5163,28 @@ var ROADMAP_ITEM_LIFECYCLE = {
5079
5163
  phases: [
5080
5164
  {
5081
5165
  id: "planned",
5166
+ status_category: "unstarted",
5082
5167
  label: "Planned",
5083
5168
  description: "The item is on the roadmap and scheduled for a future period.",
5084
5169
  transitions_to: ["in_progress", "deferred"]
5085
5170
  },
5086
5171
  {
5087
5172
  id: "in_progress",
5173
+ status_category: "started",
5088
5174
  label: "In Progress",
5089
5175
  description: "Work on this roadmap item is underway.",
5090
5176
  transitions_to: ["shipped", "deferred"]
5091
5177
  },
5092
5178
  {
5093
5179
  id: "shipped",
5180
+ status_category: "completed",
5094
5181
  label: "Shipped",
5095
5182
  description: "The roadmap item has been delivered.",
5096
5183
  transitions_to: []
5097
5184
  },
5098
5185
  {
5099
5186
  id: "deferred",
5187
+ status_category: "backlog",
5100
5188
  label: "Deferred",
5101
5189
  description: "The item has been pushed to a later period. It remains on the roadmap.",
5102
5190
  transitions_to: ["planned"]
@@ -5110,30 +5198,35 @@ var IP_ASSET_LIFECYCLE = {
5110
5198
  phases: [
5111
5199
  {
5112
5200
  id: "filed",
5201
+ status_category: "started",
5113
5202
  label: "Filed",
5114
5203
  description: "The IP application has been submitted to the relevant authority. Acknowledgement of filing is pending.",
5115
5204
  transitions_to: ["pending", "abandoned"]
5116
5205
  },
5117
5206
  {
5118
5207
  id: "pending",
5208
+ status_category: "started",
5119
5209
  label: "Pending",
5120
5210
  description: "The application has been acknowledged and is under examination by the relevant authority.",
5121
5211
  transitions_to: ["granted", "abandoned"]
5122
5212
  },
5123
5213
  {
5124
5214
  id: "granted",
5215
+ status_category: "completed",
5125
5216
  label: "Granted",
5126
5217
  description: "The IP right has been formally granted. Protection is in force.",
5127
5218
  transitions_to: ["expired", "abandoned"]
5128
5219
  },
5129
5220
  {
5130
5221
  id: "expired",
5222
+ status_category: "completed",
5131
5223
  label: "Expired",
5132
5224
  description: "The IP protection period has ended naturally.",
5133
5225
  transitions_to: []
5134
5226
  },
5135
5227
  {
5136
5228
  id: "abandoned",
5229
+ status_category: "cancelled",
5137
5230
  label: "Abandoned",
5138
5231
  description: "Abandoned: non-payment of renewal fees, withdrawal of the application, or a decision to stop defending it.",
5139
5232
  transitions_to: []
@@ -5147,36 +5240,42 @@ var CONTRACT_LIFECYCLE = {
5147
5240
  phases: [
5148
5241
  {
5149
5242
  id: "draft",
5243
+ status_category: "started",
5150
5244
  label: "Draft",
5151
5245
  description: "The contract is being written. Terms are not yet agreed by all parties.",
5152
5246
  transitions_to: ["in_review"]
5153
5247
  },
5154
5248
  {
5155
5249
  id: "in_review",
5250
+ status_category: "started",
5156
5251
  label: "In Review",
5157
5252
  description: "The draft is under review by legal counsel or the counterparty. Negotiations may be ongoing.",
5158
5253
  transitions_to: ["signed", "draft"]
5159
5254
  },
5160
5255
  {
5161
5256
  id: "signed",
5257
+ status_category: "completed",
5162
5258
  label: "Signed",
5163
5259
  description: "All parties have signed. The contract is executed and legally binding, but the effective period may not have started yet.",
5164
5260
  transitions_to: ["active"]
5165
5261
  },
5166
5262
  {
5167
5263
  id: "active",
5264
+ status_category: "started",
5168
5265
  label: "Active",
5169
5266
  description: "The contract is in its effective period. Obligations are in force.",
5170
5267
  transitions_to: ["expired", "terminated"]
5171
5268
  },
5172
5269
  {
5173
5270
  id: "expired",
5271
+ status_category: "completed",
5174
5272
  label: "Expired",
5175
5273
  description: "The contract has reached its end date naturally.",
5176
5274
  transitions_to: []
5177
5275
  },
5178
5276
  {
5179
5277
  id: "terminated",
5278
+ status_category: "cancelled",
5180
5279
  label: "Terminated",
5181
5280
  description: "Ended before natural expiry: mutual agreement, breach, or exercise of a termination clause.",
5182
5281
  transitions_to: []
@@ -5190,24 +5289,28 @@ var DESIGN_CONCEPT_LIFECYCLE = {
5190
5289
  phases: [
5191
5290
  {
5192
5291
  id: "sketched",
5292
+ status_category: "started",
5193
5293
  label: "Sketched",
5194
5294
  description: "The concept has been captured in early, rough form. It is an idea worth exploring but has not been refined or evaluated.",
5195
5295
  transitions_to: ["refined", "selected", "rejected"]
5196
5296
  },
5197
5297
  {
5198
5298
  id: "refined",
5299
+ status_category: "started",
5199
5300
  label: "Refined",
5200
5301
  description: "The concept has been developed with more detail. It is being compared to other concepts in the selection process.",
5201
5302
  transitions_to: ["selected", "rejected"]
5202
5303
  },
5203
5304
  {
5204
5305
  id: "selected",
5306
+ status_category: "completed",
5205
5307
  label: "Selected",
5206
5308
  description: "This concept has been chosen to move forward into prototyping or implementation.",
5207
5309
  transitions_to: []
5208
5310
  },
5209
5311
  {
5210
5312
  id: "rejected",
5313
+ status_category: "cancelled",
5211
5314
  label: "Rejected",
5212
5315
  description: "This concept was evaluated and not selected. It is retained as a record of design exploration.",
5213
5316
  transitions_to: []
@@ -5221,18 +5324,21 @@ var BRAND_IDENTITY_LIFECYCLE = {
5221
5324
  phases: [
5222
5325
  {
5223
5326
  id: "exploratory",
5327
+ status_category: "started",
5224
5328
  label: "Exploratory",
5225
5329
  description: "The brand is in early formation. Names, values, visual directions, and positioning are being explored without commitment.",
5226
5330
  transitions_to: ["defined"]
5227
5331
  },
5228
5332
  {
5229
5333
  id: "defined",
5334
+ status_category: "started",
5230
5335
  label: "Defined",
5231
5336
  description: "Core brand elements have been decided. Name, values, visual identity, and voice are articulated. The brand is being applied but may still be evolving.",
5232
5337
  transitions_to: ["mature"]
5233
5338
  },
5234
5339
  {
5235
5340
  id: "mature",
5341
+ status_category: "completed",
5236
5342
  label: "Mature",
5237
5343
  description: "The brand identity is fully articulated and consistently applied. Guidelines are documented and followed across all touchpoints.",
5238
5344
  transitions_to: []
@@ -5246,30 +5352,35 @@ var SCREEN_LIFECYCLE = {
5246
5352
  phases: [
5247
5353
  {
5248
5354
  id: "draft",
5355
+ status_category: "started",
5249
5356
  label: "Draft",
5250
5357
  description: "The screen is a rough idea: named and scoped, but not yet worked in a design tool.",
5251
5358
  transitions_to: ["in_design"]
5252
5359
  },
5253
5360
  {
5254
5361
  id: "in_design",
5362
+ status_category: "started",
5255
5363
  label: "In Design",
5256
5364
  description: "The screen is being designed: wireframes, mockups, or prototypes are in progress. May fall back to `draft` if the approach is rethought from scratch.",
5257
5365
  transitions_to: ["built", "draft"]
5258
5366
  },
5259
5367
  {
5260
5368
  id: "built",
5369
+ status_category: "started",
5261
5370
  label: "Built",
5262
5371
  description: "The screen has been implemented in code. It exists in a build but is not yet live for users. May return to `in_design` if implementation surfaces a design gap.",
5263
5372
  transitions_to: ["shipped", "in_design"]
5264
5373
  },
5265
5374
  {
5266
5375
  id: "shipped",
5376
+ status_category: "completed",
5267
5377
  label: "Shipped",
5268
5378
  description: "The screen is live in production and reachable by users.",
5269
5379
  transitions_to: ["deprecated"]
5270
5380
  },
5271
5381
  {
5272
5382
  id: "deprecated",
5383
+ status_category: "completed",
5273
5384
  label: "Deprecated",
5274
5385
  description: "The screen has been retired. It is no longer reachable, or is being phased out in favour of a replacement.",
5275
5386
  transitions_to: []
@@ -5283,24 +5394,28 @@ var SERVICE_LIFECYCLE = {
5283
5394
  phases: [
5284
5395
  {
5285
5396
  id: "development",
5397
+ status_category: "started",
5286
5398
  label: "Development",
5287
5399
  description: "The service is being built. It is not available in any shared environment.",
5288
5400
  transitions_to: ["staging"]
5289
5401
  },
5290
5402
  {
5291
5403
  id: "staging",
5404
+ status_category: "started",
5292
5405
  label: "Staging",
5293
5406
  description: "The service is deployed to a staging environment for integration testing and pre-release validation.",
5294
5407
  transitions_to: ["production", "development"]
5295
5408
  },
5296
5409
  {
5297
5410
  id: "production",
5411
+ status_category: "started",
5298
5412
  label: "Production",
5299
5413
  description: "The service is live and serving real users.",
5300
5414
  transitions_to: ["deprecated"]
5301
5415
  },
5302
5416
  {
5303
5417
  id: "deprecated",
5418
+ status_category: "completed",
5304
5419
  label: "Deprecated",
5305
5420
  description: "The service is being phased out. A successor service is in place or the capability is no longer needed.",
5306
5421
  transitions_to: []
@@ -5314,18 +5429,21 @@ var DEPLOYMENT_LIFECYCLE = {
5314
5429
  phases: [
5315
5430
  {
5316
5431
  id: "rolling",
5432
+ status_category: "started",
5317
5433
  label: "Rolling",
5318
5434
  description: "The deployment is in progress. Instances are being updated. Not all traffic has shifted yet.",
5319
5435
  transitions_to: ["success", "failure"]
5320
5436
  },
5321
5437
  {
5322
5438
  id: "success",
5439
+ status_category: "completed",
5323
5440
  label: "Success",
5324
5441
  description: "The deployment completed successfully. All instances are running the new version.",
5325
5442
  transitions_to: []
5326
5443
  },
5327
5444
  {
5328
5445
  id: "failure",
5446
+ status_category: "completed",
5329
5447
  label: "Failure",
5330
5448
  description: "The deployment failed or was rolled back. The previous version is restored.",
5331
5449
  transitions_to: []
@@ -5339,18 +5457,21 @@ var FEATURE_FLAG_LIFECYCLE = {
5339
5457
  phases: [
5340
5458
  {
5341
5459
  id: "off",
5460
+ status_category: "backlog",
5342
5461
  label: "Off",
5343
5462
  description: "The flag is disabled. The associated feature or code path is not active for any users.",
5344
5463
  transitions_to: ["rollout", "on"]
5345
5464
  },
5346
5465
  {
5347
5466
  id: "rollout",
5467
+ status_category: "started",
5348
5468
  label: "Rollout",
5349
5469
  description: "The flag is partially enabled. A percentage of users or a target segment has access.",
5350
5470
  transitions_to: ["on", "off"]
5351
5471
  },
5352
5472
  {
5353
5473
  id: "on",
5474
+ status_category: "completed",
5354
5475
  label: "On",
5355
5476
  description: "The flag is fully enabled for all users. The feature is live. The flag can be cleaned up.",
5356
5477
  transitions_to: []
@@ -5364,30 +5485,35 @@ var INVESTIGATION_LIFECYCLE = {
5364
5485
  phases: [
5365
5486
  {
5366
5487
  id: "open",
5488
+ status_category: "triage",
5367
5489
  label: "Open",
5368
5490
  description: "The investigation has been opened. A problem has been identified but not yet actively worked.",
5369
5491
  transitions_to: ["active"]
5370
5492
  },
5371
5493
  {
5372
5494
  id: "active",
5495
+ status_category: "started",
5373
5496
  label: "Active",
5374
5497
  description: "The investigation is being actively worked. Evidence is being gathered and hypotheses are being tested.",
5375
5498
  transitions_to: ["paused", "resolved", "abandoned"]
5376
5499
  },
5377
5500
  {
5378
5501
  id: "paused",
5502
+ status_category: "backlog",
5379
5503
  label: "Paused",
5380
5504
  description: "On hold: awaiting additional data, unblocking conditions, or reprioritisation.",
5381
5505
  transitions_to: ["active", "abandoned"]
5382
5506
  },
5383
5507
  {
5384
5508
  id: "resolved",
5509
+ status_category: "completed",
5385
5510
  label: "Resolved",
5386
5511
  description: "Root cause has been identified and documented. The investigation is closed.",
5387
5512
  transitions_to: []
5388
5513
  },
5389
5514
  {
5390
5515
  id: "abandoned",
5516
+ status_category: "cancelled",
5391
5517
  label: "Abandoned",
5392
5518
  description: "Closed without resolution: the problem could not be reproduced, was deemed not worth pursuing, or became moot.",
5393
5519
  transitions_to: []
@@ -5401,24 +5527,28 @@ var EXTERNAL_API_LIFECYCLE = {
5401
5527
  phases: [
5402
5528
  {
5403
5529
  id: "beta",
5530
+ status_category: "started",
5404
5531
  label: "Beta",
5405
5532
  description: "The API is available for early access or testing. It may be unstable and subject to breaking changes.",
5406
5533
  transitions_to: ["active"]
5407
5534
  },
5408
5535
  {
5409
5536
  id: "active",
5537
+ status_category: "started",
5410
5538
  label: "Active",
5411
5539
  description: "The API is stable and in production use. The provider guarantees availability per their SLA.",
5412
5540
  transitions_to: ["deprecated", "unavailable"]
5413
5541
  },
5414
5542
  {
5415
5543
  id: "deprecated",
5544
+ status_category: "started",
5416
5545
  label: "Deprecated",
5417
5546
  description: "The provider has announced end-of-life. The API still works but a migration to a successor is required.",
5418
5547
  transitions_to: ["unavailable"]
5419
5548
  },
5420
5549
  {
5421
5550
  id: "unavailable",
5551
+ status_category: "completed",
5422
5552
  label: "Unavailable",
5423
5553
  description: "The API is no longer accessible. Any dependent service is broken until migrated.",
5424
5554
  transitions_to: []
@@ -5432,18 +5562,21 @@ var DATABASE_SCHEMA_LIFECYCLE = {
5432
5562
  phases: [
5433
5563
  {
5434
5564
  id: "current",
5565
+ status_category: "started",
5435
5566
  label: "Current",
5436
5567
  description: "The schema is up to date with the applied migrations. No pending changes.",
5437
5568
  transitions_to: ["pending"]
5438
5569
  },
5439
5570
  {
5440
5571
  id: "pending",
5572
+ status_category: "unstarted",
5441
5573
  label: "Pending",
5442
5574
  description: "A migration is queued and ready to run. The schema will change when it is applied.",
5443
5575
  transitions_to: ["current", "failed"]
5444
5576
  },
5445
5577
  {
5446
5578
  id: "failed",
5579
+ status_category: "completed",
5447
5580
  label: "Failed",
5448
5581
  description: "A migration failed during application. The schema is in an inconsistent state and requires remediation before further changes can be applied.",
5449
5582
  transitions_to: ["pending"]
@@ -5457,30 +5590,35 @@ var INCIDENT_LIFECYCLE = {
5457
5590
  phases: [
5458
5591
  {
5459
5592
  id: "detected",
5593
+ status_category: "triage",
5460
5594
  label: "Detected",
5461
5595
  description: "Identified by an alert, a user report, or direct observation. Response has not yet started.",
5462
5596
  transitions_to: ["triaged"]
5463
5597
  },
5464
5598
  {
5465
5599
  id: "triaged",
5600
+ status_category: "triage",
5466
5601
  label: "Triaged",
5467
5602
  description: "The incident has been assessed for severity and impact. An on-call responder is assigned and is actively working it.",
5468
5603
  transitions_to: ["contained"]
5469
5604
  },
5470
5605
  {
5471
5606
  id: "contained",
5607
+ status_category: "started",
5472
5608
  label: "Contained",
5473
5609
  description: "Immediate user impact stopped via rollback, circuit breaker, or another emergency measure. Root cause fix is still pending.",
5474
5610
  transitions_to: ["resolved", "mitigated"]
5475
5611
  },
5476
5612
  {
5477
5613
  id: "resolved",
5614
+ status_category: "completed",
5478
5615
  label: "Resolved",
5479
5616
  description: "Root cause has been identified and fixed. The system is back to normal. A postmortem is recommended.",
5480
5617
  transitions_to: []
5481
5618
  },
5482
5619
  {
5483
5620
  id: "mitigated",
5621
+ status_category: "completed",
5484
5622
  label: "Mitigated",
5485
5623
  description: "A compensating control is in place and user impact is stopped, but the root cause remains unfixed. A follow-up investigation or fix is required.",
5486
5624
  transitions_to: []
@@ -5494,24 +5632,28 @@ var SECURITY_CONTROL_LIFECYCLE = {
5494
5632
  phases: [
5495
5633
  {
5496
5634
  id: "planned",
5635
+ status_category: "unstarted",
5497
5636
  label: "Planned",
5498
5637
  description: "The control has been identified as required but implementation has not started.",
5499
5638
  transitions_to: ["in_progress"]
5500
5639
  },
5501
5640
  {
5502
5641
  id: "in_progress",
5642
+ status_category: "started",
5503
5643
  label: "In Progress",
5504
5644
  description: "The control is being implemented.",
5505
5645
  transitions_to: ["implemented"]
5506
5646
  },
5507
5647
  {
5508
5648
  id: "implemented",
5649
+ status_category: "started",
5509
5650
  label: "Implemented",
5510
5651
  description: "The control is in place. It has not yet been independently tested or verified.",
5511
5652
  transitions_to: ["verified", "in_progress"]
5512
5653
  },
5513
5654
  {
5514
5655
  id: "verified",
5656
+ status_category: "completed",
5515
5657
  label: "Verified",
5516
5658
  description: "The control has been tested and confirmed effective. It provides the intended security assurance.",
5517
5659
  transitions_to: []
@@ -5525,30 +5667,35 @@ var DATA_PIPELINE_LIFECYCLE = {
5525
5667
  phases: [
5526
5668
  {
5527
5669
  id: "building",
5670
+ status_category: "started",
5528
5671
  label: "Building",
5529
5672
  description: "The pipeline is under construction. It is not yet processing real data.",
5530
5673
  transitions_to: ["active"]
5531
5674
  },
5532
5675
  {
5533
5676
  id: "active",
5677
+ status_category: "started",
5534
5678
  label: "Active",
5535
5679
  description: "The pipeline is running and processing data on its defined schedule.",
5536
5680
  transitions_to: ["paused", "failed", "deprecated"]
5537
5681
  },
5538
5682
  {
5539
5683
  id: "paused",
5684
+ status_category: "backlog",
5540
5685
  label: "Paused",
5541
5686
  description: "Deliberately suspended: maintenance, cost control, or upstream data unavailability.",
5542
5687
  transitions_to: ["active", "deprecated"]
5543
5688
  },
5544
5689
  {
5545
5690
  id: "failed",
5691
+ status_category: "started",
5546
5692
  label: "Failed",
5547
5693
  description: "The pipeline has errored and is not processing data. Intervention is required to restore it.",
5548
5694
  transitions_to: ["active"]
5549
5695
  },
5550
5696
  {
5551
5697
  id: "deprecated",
5698
+ status_category: "completed",
5552
5699
  label: "Deprecated",
5553
5700
  description: "The pipeline is being retired. It is no longer maintained and will be shut down.",
5554
5701
  transitions_to: []
@@ -5562,30 +5709,35 @@ var AI_MODEL_LIFECYCLE = {
5562
5709
  phases: [
5563
5710
  {
5564
5711
  id: "evaluating",
5712
+ status_category: "started",
5565
5713
  label: "Evaluating",
5566
5714
  description: "The model is being assessed for quality, cost, safety, and fit. Eval runs are being analysed. No production traffic.",
5567
5715
  transitions_to: ["staging", "retired"]
5568
5716
  },
5569
5717
  {
5570
5718
  id: "staging",
5719
+ status_category: "started",
5571
5720
  label: "Staging",
5572
5721
  description: "The model has passed evaluation and is deployed to a staging environment for integration testing.",
5573
5722
  transitions_to: ["production", "evaluating", "retired"]
5574
5723
  },
5575
5724
  {
5576
5725
  id: "production",
5726
+ status_category: "started",
5577
5727
  label: "Production",
5578
5728
  description: "The model is serving live product traffic.",
5579
5729
  transitions_to: ["deprecated", "retired"]
5580
5730
  },
5581
5731
  {
5582
5732
  id: "deprecated",
5733
+ status_category: "started",
5583
5734
  label: "Deprecated",
5584
5735
  description: "A successor model is in production. This model is being phased out. Traffic is being migrated.",
5585
5736
  transitions_to: ["retired"]
5586
5737
  },
5587
5738
  {
5588
5739
  id: "retired",
5740
+ status_category: "completed",
5589
5741
  label: "Retired",
5590
5742
  description: "The model is fully decommissioned. No traffic. Historical records are preserved.",
5591
5743
  transitions_to: []
@@ -5599,36 +5751,42 @@ var WORKFLOW_RUN_LIFECYCLE = {
5599
5751
  phases: [
5600
5752
  {
5601
5753
  id: "pending",
5754
+ status_category: "unstarted",
5602
5755
  label: "Pending",
5603
5756
  description: "The run has been queued and is awaiting execution. Resources or dependencies are being provisioned.",
5604
5757
  transitions_to: ["running", "cancelled"]
5605
5758
  },
5606
5759
  {
5607
5760
  id: "running",
5761
+ status_category: "started",
5608
5762
  label: "Running",
5609
5763
  description: "The workflow is actively executing its steps.",
5610
5764
  transitions_to: ["blocked", "completed", "failed", "cancelled"]
5611
5765
  },
5612
5766
  {
5613
5767
  id: "blocked",
5768
+ status_category: "started",
5614
5769
  label: "Blocked",
5615
5770
  description: "Execution is paused at a review_gate awaiting human or automated approval before proceeding.",
5616
5771
  transitions_to: ["running", "cancelled"]
5617
5772
  },
5618
5773
  {
5619
5774
  id: "completed",
5775
+ status_category: "completed",
5620
5776
  label: "Completed",
5621
5777
  description: "All steps executed successfully. Outputs are available.",
5622
5778
  transitions_to: []
5623
5779
  },
5624
5780
  {
5625
5781
  id: "failed",
5782
+ status_category: "completed",
5626
5783
  label: "Failed",
5627
5784
  description: "The run encountered an unrecoverable error and stopped. Partial outputs may be available.",
5628
5785
  transitions_to: []
5629
5786
  },
5630
5787
  {
5631
5788
  id: "cancelled",
5789
+ status_category: "cancelled",
5632
5790
  label: "Cancelled",
5633
5791
  description: "The run was deliberately stopped before completion.",
5634
5792
  transitions_to: []
@@ -5642,30 +5800,35 @@ var AGENT_DEFINITION_LIFECYCLE = {
5642
5800
  phases: [
5643
5801
  {
5644
5802
  id: "testing",
5803
+ status_category: "started",
5645
5804
  label: "Testing",
5646
5805
  description: "The agent is being validated in a controlled environment. Sessions are not running against real product data.",
5647
5806
  transitions_to: ["active", "disabled"]
5648
5807
  },
5649
5808
  {
5650
5809
  id: "active",
5810
+ status_category: "started",
5651
5811
  label: "Active",
5652
5812
  description: "The agent is operational and creating sessions on demand.",
5653
5813
  transitions_to: ["paused", "disabled", "retired"]
5654
5814
  },
5655
5815
  {
5656
5816
  id: "paused",
5817
+ status_category: "backlog",
5657
5818
  label: "Paused",
5658
5819
  description: "The agent is temporarily suspended. It is not creating new sessions but its configuration is preserved.",
5659
5820
  transitions_to: ["active", "retired"]
5660
5821
  },
5661
5822
  {
5662
5823
  id: "disabled",
5824
+ status_category: "backlog",
5663
5825
  label: "Disabled",
5664
5826
  description: "Turned off: bug, policy change, or safety concern. Can be re-enabled after remediation.",
5665
5827
  transitions_to: ["testing", "active", "retired"]
5666
5828
  },
5667
5829
  {
5668
5830
  id: "retired",
5831
+ status_category: "completed",
5669
5832
  label: "Retired",
5670
5833
  description: "The agent has been permanently decommissioned. Sessions are no longer created from this definition.",
5671
5834
  transitions_to: []
@@ -5679,24 +5842,28 @@ var AGENT_SESSION_LIFECYCLE = {
5679
5842
  phases: [
5680
5843
  {
5681
5844
  id: "active",
5845
+ status_category: "started",
5682
5846
  label: "Active",
5683
5847
  description: "The session is running. The agent is processing input and producing output.",
5684
5848
  transitions_to: ["completed", "crashed", "timed_out"]
5685
5849
  },
5686
5850
  {
5687
5851
  id: "completed",
5852
+ status_category: "completed",
5688
5853
  label: "Completed",
5689
5854
  description: "The session ended normally. The task was completed or the conversation was concluded.",
5690
5855
  transitions_to: []
5691
5856
  },
5692
5857
  {
5693
5858
  id: "crashed",
5859
+ status_category: "completed",
5694
5860
  label: "Crashed",
5695
5861
  description: "The session terminated unexpectedly due to an unhandled error or infrastructure failure.",
5696
5862
  transitions_to: []
5697
5863
  },
5698
5864
  {
5699
5865
  id: "timed_out",
5866
+ status_category: "completed",
5700
5867
  label: "Timed Out",
5701
5868
  description: "The session exceeded its maximum allowed duration and was automatically terminated.",
5702
5869
  transitions_to: []
@@ -5710,24 +5877,28 @@ var REVIEW_GATE_LIFECYCLE = {
5710
5877
  phases: [
5711
5878
  {
5712
5879
  id: "pending",
5880
+ status_category: "unstarted",
5713
5881
  label: "Pending",
5714
5882
  description: "The gate is awaiting review. The workflow is blocked until a decision is made.",
5715
5883
  transitions_to: ["approved", "rejected", "bypassed"]
5716
5884
  },
5717
5885
  {
5718
5886
  id: "approved",
5887
+ status_category: "completed",
5719
5888
  label: "Approved",
5720
5889
  description: "The gate has been passed. The workflow continues.",
5721
5890
  transitions_to: []
5722
5891
  },
5723
5892
  {
5724
5893
  id: "rejected",
5894
+ status_category: "cancelled",
5725
5895
  label: "Rejected",
5726
5896
  description: "The gate was not passed. The workflow is blocked and the submitter must address the feedback before re-submitting.",
5727
5897
  transitions_to: ["pending"]
5728
5898
  },
5729
5899
  {
5730
5900
  id: "bypassed",
5901
+ status_category: "cancelled",
5731
5902
  label: "Bypassed",
5732
5903
  description: "Deliberately overridden without normal review by an authorised person in an emergency. Create an audit trail entry.",
5733
5904
  transitions_to: []
@@ -5741,18 +5912,21 @@ var TEST_SUITE_LIFECYCLE = {
5741
5912
  phases: [
5742
5913
  {
5743
5914
  id: "draft",
5915
+ status_category: "started",
5744
5916
  label: "Draft",
5745
5917
  description: "The test suite is being authored. It is not yet part of any CI or QA process.",
5746
5918
  transitions_to: ["active"]
5747
5919
  },
5748
5920
  {
5749
5921
  id: "active",
5922
+ status_category: "started",
5750
5923
  label: "Active",
5751
5924
  description: "The suite is running in CI or scheduled QA processes.",
5752
5925
  transitions_to: ["deprecated"]
5753
5926
  },
5754
5927
  {
5755
5928
  id: "deprecated",
5929
+ status_category: "completed",
5756
5930
  label: "Deprecated",
5757
5931
  description: "The suite is no longer being run. It may be superseded by a newer suite or the tested functionality may have been removed.",
5758
5932
  transitions_to: []
@@ -5766,18 +5940,21 @@ var TEST_CASE_LIFECYCLE = {
5766
5940
  phases: [
5767
5941
  {
5768
5942
  id: "draft",
5943
+ status_category: "started",
5769
5944
  label: "Draft",
5770
5945
  description: "The test case is being written. Preconditions, steps, and expected results are being defined.",
5771
5946
  transitions_to: ["active"]
5772
5947
  },
5773
5948
  {
5774
5949
  id: "active",
5950
+ status_category: "started",
5775
5951
  label: "Active",
5776
5952
  description: "The test case is included in one or more test suites and is being executed.",
5777
5953
  transitions_to: ["deprecated"]
5778
5954
  },
5779
5955
  {
5780
5956
  id: "deprecated",
5957
+ status_category: "completed",
5781
5958
  label: "Deprecated",
5782
5959
  description: "The test case is no longer executed. The feature it covered may have changed or been removed.",
5783
5960
  transitions_to: []
@@ -5789,10 +5966,10 @@ var INSIGHT_LIFECYCLE = {
5789
5966
  initial_phase: "proposed",
5790
5967
  terminal_phases: ["applied", "retired"],
5791
5968
  phases: [
5792
- { id: "proposed", label: "Proposed", description: "A pattern has been synthesised from observations. Not yet cross-checked.", transitions_to: ["validated", "retired"] },
5793
- { id: "validated", label: "Validated", description: "The insight has been cross-checked against additional evidence. Believed reliable.", transitions_to: ["applied", "retired"] },
5794
- { id: "applied", label: "Applied", description: "The insight drove a product decision. Captured for the record.", transitions_to: ["retired"] },
5795
- { id: "retired", label: "Retired", description: "Superseded by newer insight, or no longer relevant. May reopen to proposed if revisited.", transitions_to: ["proposed"] }
5969
+ { id: "proposed", status_category: "triage", label: "Proposed", description: "A pattern has been synthesised from observations. Not yet cross-checked.", transitions_to: ["validated", "retired"] },
5970
+ { id: "validated", status_category: "started", label: "Validated", description: "The insight has been cross-checked against additional evidence. Believed reliable.", transitions_to: ["applied", "retired"] },
5971
+ { id: "applied", status_category: "completed", label: "Applied", description: "The insight drove a product decision. Captured for the record.", transitions_to: ["retired"] },
5972
+ { id: "retired", status_category: "completed", label: "Retired", description: "Superseded by newer insight, or no longer relevant. May reopen to proposed if revisited.", transitions_to: ["proposed"] }
5796
5973
  ]
5797
5974
  };
5798
5975
  var RESEARCH_QUESTION_LIFECYCLE = {
@@ -5800,10 +5977,10 @@ var RESEARCH_QUESTION_LIFECYCLE = {
5800
5977
  initial_phase: "open",
5801
5978
  terminal_phases: ["answered", "parked"],
5802
5979
  phases: [
5803
- { id: "open", label: "Open", description: "Question has been articulated. Research has not started.", transitions_to: ["researching", "parked"] },
5804
- { id: "researching", label: "Researching", description: "Active investigation. Methods are being run, evidence is being gathered.", transitions_to: ["answered", "parked"] },
5805
- { id: "answered", label: "Answered", description: "Question has been resolved. Findings captured in linked insights.", transitions_to: [] },
5806
- { id: "parked", label: "Parked", description: "Set aside due to capacity, priority, or dependency. May reopen to researching.", transitions_to: ["researching"] }
5980
+ { id: "open", status_category: "triage", label: "Open", description: "Question has been articulated. Research has not started.", transitions_to: ["researching", "parked"] },
5981
+ { id: "researching", status_category: "started", label: "Researching", description: "Active investigation. Methods are being run, evidence is being gathered.", transitions_to: ["answered", "parked"] },
5982
+ { id: "answered", status_category: "completed", label: "Answered", description: "Question has been resolved. Findings captured in linked insights.", transitions_to: [] },
5983
+ { id: "parked", status_category: "backlog", label: "Parked", description: "Set aside due to capacity, priority, or dependency. May reopen to researching.", transitions_to: ["researching"] }
5807
5984
  ]
5808
5985
  };
5809
5986
  var INTERVIEW_GUIDE_LIFECYCLE = {
@@ -5811,10 +5988,10 @@ var INTERVIEW_GUIDE_LIFECYCLE = {
5811
5988
  initial_phase: "drafting",
5812
5989
  terminal_phases: ["archived"],
5813
5990
  phases: [
5814
- { id: "drafting", label: "Drafting", description: "Guide is being authored or revised. Not yet ready for use.", transitions_to: ["ready"] },
5815
- { id: "ready", label: "Ready", description: "Guide is approved for use. May be picked up by a study.", transitions_to: ["in_use", "drafting"] },
5816
- { id: "in_use", label: "In Use", description: "Currently being run in one or more research_study entities.", transitions_to: ["ready", "archived"] },
5817
- { id: "archived", label: "Archived", description: "Retired from active use. May reopen to drafting if revived.", transitions_to: ["drafting"] }
5991
+ { id: "drafting", status_category: "started", label: "Drafting", description: "Guide is being authored or revised. Not yet ready for use.", transitions_to: ["ready"] },
5992
+ { id: "ready", status_category: "unstarted", label: "Ready", description: "Guide is approved for use. May be picked up by a study.", transitions_to: ["in_use", "drafting"] },
5993
+ { id: "in_use", status_category: "started", label: "In Use", description: "Currently being run in one or more research_study entities.", transitions_to: ["ready", "archived"] },
5994
+ { id: "archived", status_category: "completed", label: "Archived", description: "Retired from active use. May reopen to drafting if revived.", transitions_to: ["drafting"] }
5818
5995
  ]
5819
5996
  };
5820
5997
  var TEST_PLAN_LIFECYCLE = {
@@ -5822,10 +5999,10 @@ var TEST_PLAN_LIFECYCLE = {
5822
5999
  initial_phase: "drafted",
5823
6000
  terminal_phases: ["completed", "cancelled"],
5824
6001
  phases: [
5825
- { id: "drafted", label: "Drafted", description: "Plan has been authored. Not yet started.", transitions_to: ["executing", "cancelled"] },
5826
- { id: "executing", label: "Executing", description: "Tests are running according to the plan.", transitions_to: ["completed", "cancelled"] },
5827
- { id: "completed", label: "Completed", description: "All tests in the plan have run. Outcomes captured in linked test_result entities.", transitions_to: ["executing"] },
5828
- { id: "cancelled", label: "Cancelled", description: "Plan was abandoned mid-flight: assumption changed, priorities shifted, or the underlying code went away.", transitions_to: [] }
6002
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Plan has been authored. Not yet started.", transitions_to: ["executing", "cancelled"] },
6003
+ { id: "executing", status_category: "started", label: "Executing", description: "Tests are running according to the plan.", transitions_to: ["completed", "cancelled"] },
6004
+ { id: "completed", status_category: "completed", label: "Completed", description: "All tests in the plan have run. Outcomes captured in linked test_result entities.", transitions_to: ["executing"] },
6005
+ { id: "cancelled", status_category: "cancelled", label: "Cancelled", description: "Plan was abandoned mid-flight: assumption changed, priorities shifted, or the underlying code went away.", transitions_to: [] }
5829
6006
  ]
5830
6007
  };
5831
6008
  var AI_DATASET_LIFECYCLE = {
@@ -5833,10 +6010,10 @@ var AI_DATASET_LIFECYCLE = {
5833
6010
  initial_phase: "collecting",
5834
6011
  terminal_phases: ["versioned", "archived"],
5835
6012
  phases: [
5836
- { id: "collecting", label: "Collecting", description: "Examples are being gathered. Schema and labelling rules may still be in flux.", transitions_to: ["curated", "archived"] },
5837
- { id: "curated", label: "Curated", description: "Examples have been cleaned, deduped, and labelled. Ready for versioning.", transitions_to: ["versioned", "collecting"] },
5838
- { id: "versioned", label: "Versioned", description: "A specific cut has been pinned and is citable. New collection continues in a successor version.", transitions_to: ["archived"] },
5839
- { id: "archived", label: "Archived", description: "No longer in active use. May reopen to collecting if revived.", transitions_to: ["collecting"] }
6013
+ { id: "collecting", status_category: "started", label: "Collecting", description: "Examples are being gathered. Schema and labelling rules may still be in flux.", transitions_to: ["curated", "archived"] },
6014
+ { id: "curated", status_category: "started", label: "Curated", description: "Examples have been cleaned, deduped, and labelled. Ready for versioning.", transitions_to: ["versioned", "collecting"] },
6015
+ { id: "versioned", status_category: "completed", label: "Versioned", description: "A specific cut has been pinned and is citable. New collection continues in a successor version.", transitions_to: ["archived"] },
6016
+ { id: "archived", status_category: "completed", label: "Archived", description: "No longer in active use. May reopen to collecting if revived.", transitions_to: ["collecting"] }
5840
6017
  ]
5841
6018
  };
5842
6019
  var AI_GUARDRAIL_LIFECYCLE = {
@@ -5844,10 +6021,10 @@ var AI_GUARDRAIL_LIFECYCLE = {
5844
6021
  initial_phase: "proposed",
5845
6022
  terminal_phases: ["active", "relaxed", "removed"],
5846
6023
  phases: [
5847
- { id: "proposed", label: "Proposed", description: "Guardrail has been suggested. Not yet enforced.", transitions_to: ["active", "removed"] },
5848
- { id: "active", label: "Active", description: "Guardrail is enforced as designed. Currently the steady state.", transitions_to: ["relaxed", "removed"] },
5849
- { id: "relaxed", label: "Relaxed", description: "Guardrail is enforced more loosely than originally specified. Captured separately because the looser form has different implications.", transitions_to: ["active", "removed"] },
5850
- { id: "removed", label: "Removed", description: "Guardrail is no longer enforced. May reopen to active if reinstated.", transitions_to: ["active"] }
6024
+ { id: "proposed", status_category: "triage", label: "Proposed", description: "Guardrail has been suggested. Not yet enforced.", transitions_to: ["active", "removed"] },
6025
+ { id: "active", status_category: "started", label: "Active", description: "Guardrail is enforced as designed. Currently the steady state.", transitions_to: ["relaxed", "removed"] },
6026
+ { id: "relaxed", status_category: "started", label: "Relaxed", description: "Guardrail is enforced more loosely than originally specified. Captured separately because the looser form has different implications.", transitions_to: ["active", "removed"] },
6027
+ { id: "removed", status_category: "cancelled", label: "Removed", description: "Guardrail is no longer enforced. May reopen to active if reinstated.", transitions_to: ["active"] }
5851
6028
  ]
5852
6029
  };
5853
6030
  var MODEL_COMPARISON_LIFECYCLE = {
@@ -5855,10 +6032,10 @@ var MODEL_COMPARISON_LIFECYCLE = {
5855
6032
  initial_phase: "planned",
5856
6033
  terminal_phases: ["published", "archived"],
5857
6034
  phases: [
5858
- { id: "planned", label: "Planned", description: "Comparison has been scoped: models, criteria, and methodology are agreed.", transitions_to: ["running", "archived"] },
5859
- { id: "running", label: "Running", description: "Models are being evaluated against the chosen criteria.", transitions_to: ["published", "archived"] },
5860
- { id: "published", label: "Published", description: "Results are written up and citable. Drives downstream model selection.", transitions_to: ["archived", "planned"] },
5861
- { id: "archived", label: "Archived", description: "Superseded by newer comparison. May reopen to planned if re-run.", transitions_to: ["planned"] }
6035
+ { id: "planned", status_category: "unstarted", label: "Planned", description: "Comparison has been scoped: models, criteria, and methodology are agreed.", transitions_to: ["running", "archived"] },
6036
+ { id: "running", status_category: "started", label: "Running", description: "Models are being evaluated against the chosen criteria.", transitions_to: ["published", "archived"] },
6037
+ { id: "published", status_category: "completed", label: "Published", description: "Results are written up and citable. Drives downstream model selection.", transitions_to: ["archived", "planned"] },
6038
+ { id: "archived", status_category: "completed", label: "Archived", description: "Superseded by newer comparison. May reopen to planned if re-run.", transitions_to: ["planned"] }
5862
6039
  ]
5863
6040
  };
5864
6041
  var PROMPT_VERSION_LIFECYCLE = {
@@ -5866,10 +6043,10 @@ var PROMPT_VERSION_LIFECYCLE = {
5866
6043
  initial_phase: "drafted",
5867
6044
  terminal_phases: ["active", "deprecated"],
5868
6045
  phases: [
5869
- { id: "drafted", label: "Drafted", description: "Prompt has been authored. Not yet evaluated.", transitions_to: ["testing", "deprecated"] },
5870
- { id: "testing", label: "Testing", description: "Running through eval benchmarks. Results inform whether to promote.", transitions_to: ["active", "drafted", "deprecated"] },
5871
- { id: "active", label: "Active", description: "In production use.", transitions_to: ["deprecated"] },
5872
- { id: "deprecated", label: "Deprecated", description: "Superseded by a successor version. Still available for backwards-compat. May reopen to testing if reinstated.", transitions_to: ["testing"] }
6046
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Prompt has been authored. Not yet evaluated.", transitions_to: ["testing", "deprecated"] },
6047
+ { id: "testing", status_category: "started", label: "Testing", description: "Running through eval benchmarks. Results inform whether to promote.", transitions_to: ["active", "drafted", "deprecated"] },
6048
+ { id: "active", status_category: "started", label: "Active", description: "In production use.", transitions_to: ["deprecated"] },
6049
+ { id: "deprecated", status_category: "completed", label: "Deprecated", description: "Superseded by a successor version. Still available for backwards-compat. May reopen to testing if reinstated.", transitions_to: ["testing"] }
5873
6050
  ]
5874
6051
  };
5875
6052
  var EVAL_BENCHMARK_LIFECYCLE = {
@@ -5877,10 +6054,10 @@ var EVAL_BENCHMARK_LIFECYCLE = {
5877
6054
  initial_phase: "drafted",
5878
6055
  terminal_phases: ["published", "deprecated"],
5879
6056
  phases: [
5880
- { id: "drafted", label: "Drafted", description: "Benchmark questions and scoring rubric are being designed.", transitions_to: ["running", "deprecated"] },
5881
- { id: "running", label: "Running", description: "Benchmark is being executed against models or prompt versions.", transitions_to: ["published", "deprecated"] },
5882
- { id: "published", label: "Published", description: "Results are citable. Benchmark is part of the standard eval rotation.", transitions_to: ["deprecated", "running"] },
5883
- { id: "deprecated", label: "Deprecated", description: "Benchmark no longer reflects what the team measures. May reopen to drafted if revisited.", transitions_to: ["drafted"] }
6057
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Benchmark questions and scoring rubric are being designed.", transitions_to: ["running", "deprecated"] },
6058
+ { id: "running", status_category: "started", label: "Running", description: "Benchmark is being executed against models or prompt versions.", transitions_to: ["published", "deprecated"] },
6059
+ { id: "published", status_category: "completed", label: "Published", description: "Results are citable. Benchmark is part of the standard eval rotation.", transitions_to: ["deprecated", "running"] },
6060
+ { id: "deprecated", status_category: "completed", label: "Deprecated", description: "Benchmark no longer reflects what the team measures. May reopen to drafted if revisited.", transitions_to: ["drafted"] }
5884
6061
  ]
5885
6062
  };
5886
6063
  var BUSINESS_MODEL_LIFECYCLE = {
@@ -5888,11 +6065,11 @@ var BUSINESS_MODEL_LIFECYCLE = {
5888
6065
  initial_phase: "drafted",
5889
6066
  terminal_phases: ["validated", "invalidated", "pivoted"],
5890
6067
  phases: [
5891
- { id: "drafted", label: "Drafted", description: "Model has been articulated. Not yet tested in market.", transitions_to: ["testing", "invalidated"] },
5892
- { id: "testing", label: "Testing", description: "Model is being tested against real customers and revenue. Evidence is accumulating.", transitions_to: ["validated", "invalidated", "pivoted"] },
5893
- { id: "validated", label: "Validated", description: "Model holds up under real customer behaviour. Forms the operating basis.", transitions_to: ["testing", "pivoted"] },
5894
- { id: "invalidated", label: "Invalidated", description: "Model failed to hold up. May reopen to drafted for a new attempt.", transitions_to: ["drafted"] },
5895
- { id: "pivoted", label: "Pivoted", description: "Model became something structurally different. Captured as a milestone before the new model takes over.", transitions_to: [] }
6068
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Model has been articulated. Not yet tested in market.", transitions_to: ["testing", "invalidated"] },
6069
+ { id: "testing", status_category: "started", label: "Testing", description: "Model is being tested against real customers and revenue. Evidence is accumulating.", transitions_to: ["validated", "invalidated", "pivoted"] },
6070
+ { id: "validated", status_category: "completed", label: "Validated", description: "Model holds up under real customer behaviour. Forms the operating basis.", transitions_to: ["testing", "pivoted"] },
6071
+ { id: "invalidated", status_category: "completed", label: "Invalidated", description: "Model failed to hold up. May reopen to drafted for a new attempt.", transitions_to: ["drafted"] },
6072
+ { id: "pivoted", status_category: "cancelled", label: "Pivoted", description: "Model became something structurally different. Captured as a milestone before the new model takes over.", transitions_to: [] }
5896
6073
  ]
5897
6074
  };
5898
6075
  var REVENUE_STREAM_LIFECYCLE = {
@@ -5900,10 +6077,10 @@ var REVENUE_STREAM_LIFECYCLE = {
5900
6077
  initial_phase: "proposed",
5901
6078
  terminal_phases: ["live", "sunset"],
5902
6079
  phases: [
5903
- { id: "proposed", label: "Proposed", description: "Stream has been hypothesised. Not yet built or sold.", transitions_to: ["piloting", "sunset"] },
5904
- { id: "piloting", label: "Piloting", description: "Stream is being trialled with a limited audience. Pricing and packaging may still be in flux.", transitions_to: ["live", "sunset"] },
5905
- { id: "live", label: "Live", description: "Stream is generally available and generating revenue.", transitions_to: ["sunset"] },
5906
- { id: "sunset", label: "Sunset", description: "Stream is being wound down. May reopen to piloting if revived.", transitions_to: ["piloting"] }
6080
+ { id: "proposed", status_category: "triage", label: "Proposed", description: "Stream has been hypothesised. Not yet built or sold.", transitions_to: ["piloting", "sunset"] },
6081
+ { id: "piloting", status_category: "started", label: "Piloting", description: "Stream is being trialled with a limited audience. Pricing and packaging may still be in flux.", transitions_to: ["live", "sunset"] },
6082
+ { id: "live", status_category: "started", label: "Live", description: "Stream is generally available and generating revenue.", transitions_to: ["sunset"] },
6083
+ { id: "sunset", status_category: "completed", label: "Sunset", description: "Stream is being wound down. May reopen to piloting if revived.", transitions_to: ["piloting"] }
5907
6084
  ]
5908
6085
  };
5909
6086
  var CUSTOMER_HEALTH_SCORE_LIFECYCLE = {
@@ -5911,11 +6088,11 @@ var CUSTOMER_HEALTH_SCORE_LIFECYCLE = {
5911
6088
  initial_phase: "monitoring",
5912
6089
  terminal_phases: ["recovered", "churned"],
5913
6090
  phases: [
5914
- { id: "monitoring", label: "Monitoring", description: "Customer is healthy. Score is being tracked passively.", transitions_to: ["at_risk", "churned", "recovered"] },
5915
- { id: "at_risk", label: "At Risk", description: "Signals indicate trouble. Customer Success has flagged the account for attention.", transitions_to: ["monitoring", "critical", "churned", "recovered"] },
5916
- { id: "critical", label: "Critical", description: "Customer is on the verge of churning. Active intervention is underway.", transitions_to: ["at_risk", "recovered", "churned"] },
5917
- { id: "recovered", label: "Recovered", description: "Customer health has returned to monitoring. Captured as a milestone. May reopen to monitoring naturally.", transitions_to: ["monitoring"] },
5918
- { id: "churned", label: "Churned", description: "Customer left. Captured for analysis; reopen would mean a new customer relationship.", transitions_to: [] }
6091
+ { id: "monitoring", status_category: "started", label: "Monitoring", description: "Customer is healthy. Score is being tracked passively.", transitions_to: ["at_risk", "churned", "recovered"] },
6092
+ { id: "at_risk", status_category: "started", label: "At Risk", description: "Signals indicate trouble. Customer Success has flagged the account for attention.", transitions_to: ["monitoring", "critical", "churned", "recovered"] },
6093
+ { id: "critical", status_category: "started", label: "Critical", description: "Customer is on the verge of churning. Active intervention is underway.", transitions_to: ["at_risk", "recovered", "churned"] },
6094
+ { id: "recovered", status_category: "completed", label: "Recovered", description: "Customer health has returned to monitoring. Captured as a milestone. May reopen to monitoring naturally.", transitions_to: ["monitoring"] },
6095
+ { id: "churned", status_category: "cancelled", label: "Churned", description: "Customer left. Captured for analysis; reopen would mean a new customer relationship.", transitions_to: [] }
5919
6096
  ]
5920
6097
  };
5921
6098
  var PLAYBOOK_LIFECYCLE = {
@@ -5923,10 +6100,10 @@ var PLAYBOOK_LIFECYCLE = {
5923
6100
  initial_phase: "drafted",
5924
6101
  terminal_phases: ["live", "retired"],
5925
6102
  phases: [
5926
- { id: "drafted", label: "Drafted", description: "Playbook is being authored. Not yet tested with customers.", transitions_to: ["tested", "retired"] },
5927
- { id: "tested", label: "Tested", description: "Playbook has been run through pilot customers. Adjustments may follow.", transitions_to: ["live", "drafted"] },
5928
- { id: "live", label: "Live", description: "Playbook is in active use across the customer success team.", transitions_to: ["retired", "tested"] },
5929
- { id: "retired", label: "Retired", description: "Playbook no longer in use. May reopen to drafted if revived.", transitions_to: ["drafted"] }
6103
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Playbook is being authored. Not yet tested with customers.", transitions_to: ["tested", "retired"] },
6104
+ { id: "tested", status_category: "started", label: "Tested", description: "Playbook has been run through pilot customers. Adjustments may follow.", transitions_to: ["live", "drafted"] },
6105
+ { id: "live", status_category: "started", label: "Live", description: "Playbook is in active use across the customer success team.", transitions_to: ["retired", "tested"] },
6106
+ { id: "retired", status_category: "completed", label: "Retired", description: "Playbook no longer in use. May reopen to drafted if revived.", transitions_to: ["drafted"] }
5930
6107
  ]
5931
6108
  };
5932
6109
  var TEAM_OKR_LIFECYCLE = {
@@ -5934,11 +6111,11 @@ var TEAM_OKR_LIFECYCLE = {
5934
6111
  initial_phase: "drafted",
5935
6112
  terminal_phases: ["completed", "missed"],
5936
6113
  phases: [
5937
- { id: "drafted", label: "Drafted", description: "OKR is being authored. Not yet committed to.", transitions_to: ["committed"] },
5938
- { id: "committed", label: "Committed", description: "Team has agreed to pursue the OKR. Cycle has not yet started.", transitions_to: ["in_progress", "drafted"] },
5939
- { id: "in_progress", label: "In Progress", description: "Cycle is underway. Progress is being tracked.", transitions_to: ["completed", "missed"] },
5940
- { id: "completed", label: "Completed", description: "OKR was achieved within the cycle.", transitions_to: [] },
5941
- { id: "missed", label: "Missed", description: "OKR was not achieved. May reopen to in_progress if carried forward.", transitions_to: ["in_progress"] }
6114
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "OKR is being authored. Not yet committed to.", transitions_to: ["committed"] },
6115
+ { id: "committed", status_category: "unstarted", label: "Committed", description: "Team has agreed to pursue the OKR. Cycle has not yet started.", transitions_to: ["in_progress", "drafted"] },
6116
+ { id: "in_progress", status_category: "started", label: "In Progress", description: "Cycle is underway. Progress is being tracked.", transitions_to: ["completed", "missed"] },
6117
+ { id: "completed", status_category: "completed", label: "Completed", description: "OKR was achieved within the cycle.", transitions_to: [] },
6118
+ { id: "missed", status_category: "completed", label: "Missed", description: "OKR was not achieved. May reopen to in_progress if carried forward.", transitions_to: ["in_progress"] }
5942
6119
  ]
5943
6120
  };
5944
6121
  var RETROSPECTIVE_LIFECYCLE = {
@@ -5946,10 +6123,10 @@ var RETROSPECTIVE_LIFECYCLE = {
5946
6123
  initial_phase: "scheduled",
5947
6124
  terminal_phases: ["completed", "actions_tracked"],
5948
6125
  phases: [
5949
- { id: "scheduled", label: "Scheduled", description: "Retro is on the calendar. Not yet held.", transitions_to: ["in_progress", "completed"] },
5950
- { id: "in_progress", label: "In Progress", description: "Retro is being held.", transitions_to: ["completed"] },
5951
- { id: "completed", label: "Completed", description: "Meeting is done. Action items captured but not yet tracked to closure.", transitions_to: ["actions_tracked"] },
5952
- { id: "actions_tracked", label: "Actions Tracked", description: "Retro action items have been completed or explicitly dropped. Full loop closed.", transitions_to: [] }
6126
+ { id: "scheduled", status_category: "unstarted", label: "Scheduled", description: "Retro is on the calendar. Not yet held.", transitions_to: ["in_progress", "completed"] },
6127
+ { id: "in_progress", status_category: "started", label: "In Progress", description: "Retro is being held.", transitions_to: ["completed"] },
6128
+ { id: "completed", status_category: "completed", label: "Completed", description: "Meeting is done. Action items captured but not yet tracked to closure.", transitions_to: ["actions_tracked"] },
6129
+ { id: "actions_tracked", status_category: "completed", label: "Actions Tracked", description: "Retro action items have been completed or explicitly dropped. Full loop closed.", transitions_to: [] }
5953
6130
  ]
5954
6131
  };
5955
6132
  var DEPENDENCY_LIFECYCLE = {
@@ -5957,10 +6134,10 @@ var DEPENDENCY_LIFECYCLE = {
5957
6134
  initial_phase: "identified",
5958
6135
  terminal_phases: ["resolved"],
5959
6136
  phases: [
5960
- { id: "identified", label: "Identified", description: "Dependency has been named. Not yet evaluated for impact.", transitions_to: ["blocked", "in_progress", "resolved"] },
5961
- { id: "blocked", label: "Blocked", description: "Dependency is currently blocking work. Awaiting upstream action.", transitions_to: ["in_progress", "resolved"] },
5962
- { id: "in_progress", label: "In Progress", description: "Active work is happening to resolve the dependency.", transitions_to: ["blocked", "resolved"] },
5963
- { id: "resolved", label: "Resolved", description: "Dependency is no longer blocking. May reopen to blocked if regression.", transitions_to: ["blocked"] }
6137
+ { id: "identified", status_category: "triage", label: "Identified", description: "Dependency has been named. Not yet evaluated for impact.", transitions_to: ["blocked", "in_progress", "resolved"] },
6138
+ { id: "blocked", status_category: "started", label: "Blocked", description: "Dependency is currently blocking work. Awaiting upstream action.", transitions_to: ["in_progress", "resolved"] },
6139
+ { id: "in_progress", status_category: "started", label: "In Progress", description: "Active work is happening to resolve the dependency.", transitions_to: ["blocked", "resolved"] },
6140
+ { id: "resolved", status_category: "completed", label: "Resolved", description: "Dependency is no longer blocking. May reopen to blocked if regression.", transitions_to: ["blocked"] }
5964
6141
  ]
5965
6142
  };
5966
6143
  var ROLE_LIFECYCLE = {
@@ -5968,10 +6145,10 @@ var ROLE_LIFECYCLE = {
5968
6145
  initial_phase: "proposed",
5969
6146
  terminal_phases: ["filled", "vacant"],
5970
6147
  phases: [
5971
- { id: "proposed", label: "Proposed", description: "Role has been described but not yet posted or staffed.", transitions_to: ["open", "vacant"] },
5972
- { id: "open", label: "Open", description: "Role is actively being recruited for.", transitions_to: ["filled", "vacant"] },
5973
- { id: "filled", label: "Filled", description: "Role is staffed. May reopen to open if the position becomes vacant again.", transitions_to: ["vacant"] },
5974
- { id: "vacant", label: "Vacant", description: "Role exists but is unfilled. May reopen to open to start recruiting.", transitions_to: ["open"] }
6148
+ { id: "proposed", status_category: "triage", label: "Proposed", description: "Role has been described but not yet posted or staffed.", transitions_to: ["open", "vacant"] },
6149
+ { id: "open", status_category: "started", label: "Open", description: "Role is actively being recruited for.", transitions_to: ["filled", "vacant"] },
6150
+ { id: "filled", status_category: "completed", label: "Filled", description: "Role is staffed. May reopen to open if the position becomes vacant again.", transitions_to: ["vacant"] },
6151
+ { id: "vacant", status_category: "backlog", label: "Vacant", description: "Role exists but is unfilled. May reopen to open to start recruiting.", transitions_to: ["open"] }
5975
6152
  ]
5976
6153
  };
5977
6154
  var CAPACITY_PLAN_LIFECYCLE = {
@@ -5979,11 +6156,11 @@ var CAPACITY_PLAN_LIFECYCLE = {
5979
6156
  initial_phase: "drafted",
5980
6157
  terminal_phases: ["completed", "revised"],
5981
6158
  phases: [
5982
- { id: "drafted", label: "Drafted", description: "Plan is being authored. Not yet agreed.", transitions_to: ["committed", "revised"] },
5983
- { id: "committed", label: "Committed", description: "Plan has been agreed by stakeholders. Cycle has not yet started.", transitions_to: ["in_flight", "revised"] },
5984
- { id: "in_flight", label: "In Flight", description: "Cycle is underway. Capacity is being consumed.", transitions_to: ["completed", "revised"] },
5985
- { id: "completed", label: "Completed", description: "Cycle is done. Plan executed as agreed.", transitions_to: [] },
5986
- { id: "revised", label: "Revised", description: "Plan was changed mid-flight. May reopen to drafted for the next iteration.", transitions_to: ["drafted"] }
6159
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Plan is being authored. Not yet agreed.", transitions_to: ["committed", "revised"] },
6160
+ { id: "committed", status_category: "unstarted", label: "Committed", description: "Plan has been agreed by stakeholders. Cycle has not yet started.", transitions_to: ["in_flight", "revised"] },
6161
+ { id: "in_flight", status_category: "started", label: "In Flight", description: "Cycle is underway. Capacity is being consumed.", transitions_to: ["completed", "revised"] },
6162
+ { id: "completed", status_category: "completed", label: "Completed", description: "Cycle is done. Plan executed as agreed.", transitions_to: [] },
6163
+ { id: "revised", status_category: "completed", label: "Revised", description: "Plan was changed mid-flight. May reopen to drafted for the next iteration.", transitions_to: ["drafted"] }
5987
6164
  ]
5988
6165
  };
5989
6166
  var VARIANT_LIFECYCLE = {
@@ -5991,11 +6168,11 @@ var VARIANT_LIFECYCLE = {
5991
6168
  initial_phase: "proposed",
5992
6169
  terminal_phases: ["winning", "losing", "retired"],
5993
6170
  phases: [
5994
- { id: "proposed", label: "Proposed", description: "Variant has been designed. Not yet running.", transitions_to: ["live", "retired"] },
5995
- { id: "live", label: "Live", description: "Variant is being shown to users as part of an active test.", transitions_to: ["winning", "losing", "retired"] },
5996
- { id: "winning", label: "Winning", description: "Variant beat the control. Captured for the record before rollout.", transitions_to: ["retired"] },
5997
- { id: "losing", label: "Losing", description: "Variant did not beat the control. Captured for the record.", transitions_to: ["retired"] },
5998
- { id: "retired", label: "Retired", description: "Variant is no longer running. May reopen to proposed if revisited in a future test.", transitions_to: ["proposed"] }
6171
+ { id: "proposed", status_category: "triage", label: "Proposed", description: "Variant has been designed. Not yet running.", transitions_to: ["live", "retired"] },
6172
+ { id: "live", status_category: "started", label: "Live", description: "Variant is being shown to users as part of an active test.", transitions_to: ["winning", "losing", "retired"] },
6173
+ { id: "winning", status_category: "completed", label: "Winning", description: "Variant beat the control. Captured for the record before rollout.", transitions_to: ["retired"] },
6174
+ { id: "losing", status_category: "completed", label: "Losing", description: "Variant did not beat the control. Captured for the record.", transitions_to: ["retired"] },
6175
+ { id: "retired", status_category: "completed", label: "Retired", description: "Variant is no longer running. May reopen to proposed if revisited in a future test.", transitions_to: ["proposed"] }
5999
6176
  ]
6000
6177
  };
6001
6178
  var GROWTH_CAMPAIGN_LIFECYCLE = {
@@ -6003,11 +6180,11 @@ var GROWTH_CAMPAIGN_LIFECYCLE = {
6003
6180
  initial_phase: "drafted",
6004
6181
  terminal_phases: ["completed", "paused"],
6005
6182
  phases: [
6006
- { id: "drafted", label: "Drafted", description: "Campaign concept exists. Not yet planned for launch.", transitions_to: ["planning", "paused"] },
6007
- { id: "planning", label: "Planning", description: "Campaign creative, channels, and timing are being finalised.", transitions_to: ["live", "paused"] },
6008
- { id: "live", label: "Live", description: "Campaign is running across channels.", transitions_to: ["completed", "paused"] },
6009
- { id: "completed", label: "Completed", description: "Campaign ran to completion. Outcomes captured.", transitions_to: [] },
6010
- { id: "paused", label: "Paused", description: "Campaign was halted before completion. May reopen to live if resumed.", transitions_to: ["live"] }
6183
+ { id: "drafted", status_category: "unstarted", label: "Drafted", description: "Campaign concept exists. Not yet planned for launch.", transitions_to: ["planning", "paused"] },
6184
+ { id: "planning", status_category: "unstarted", label: "Planning", description: "Campaign creative, channels, and timing are being finalised.", transitions_to: ["live", "paused"] },
6185
+ { id: "live", status_category: "started", label: "Live", description: "Campaign is running across channels.", transitions_to: ["completed", "paused"] },
6186
+ { id: "completed", status_category: "completed", label: "Completed", description: "Campaign ran to completion. Outcomes captured.", transitions_to: [] },
6187
+ { id: "paused", status_category: "backlog", label: "Paused", description: "Campaign was halted before completion. May reopen to live if resumed.", transitions_to: ["live"] }
6011
6188
  ]
6012
6189
  };
6013
6190
  function fromTemplate(entityType, template) {
@@ -6018,10 +6195,10 @@ var PUBLISHING_TEMPLATE = {
6018
6195
  initial_phase: "draft",
6019
6196
  terminal_phases: ["archived"],
6020
6197
  phases: [
6021
- { id: "draft", label: "Draft", description: "Being authored or revised. Not visible externally.", transitions_to: ["review"] },
6022
- { id: "review", label: "In Review", description: "Under editorial or stakeholder review before publishing.", transitions_to: ["draft", "published"] },
6023
- { id: "published", label: "Published", description: "Live and visible to the intended audience.", transitions_to: ["archived", "draft"] },
6024
- { id: "archived", label: "Archived", description: "No longer current. Retained for historical reference.", transitions_to: ["draft"] }
6198
+ { id: "draft", status_category: "started", label: "Draft", description: "Being authored or revised. Not visible externally.", transitions_to: ["review"] },
6199
+ { id: "review", status_category: "started", label: "In Review", description: "Under editorial or stakeholder review before publishing.", transitions_to: ["draft", "published"] },
6200
+ { id: "published", status_category: "completed", label: "Published", description: "Live and visible to the intended audience.", transitions_to: ["archived", "draft"] },
6201
+ { id: "archived", status_category: "completed", label: "Archived", description: "No longer current. Retained for historical reference.", transitions_to: ["draft"] }
6025
6202
  ]
6026
6203
  };
6027
6204
  var OPERATIONAL_TEMPLATE = {
@@ -6029,11 +6206,11 @@ var OPERATIONAL_TEMPLATE = {
6029
6206
  initial_phase: "planning",
6030
6207
  terminal_phases: ["completed", "sunset"],
6031
6208
  phases: [
6032
- { id: "planning", label: "Planning", description: "Being designed or scoped. Not yet started.", transitions_to: ["active"] },
6033
- { id: "active", label: "Active", description: "Currently running or in operation.", transitions_to: ["paused", "completed", "sunset"] },
6034
- { id: "paused", label: "Paused", description: "Temporarily halted. Can be resumed.", transitions_to: ["active", "sunset"] },
6035
- { id: "completed", label: "Completed", description: "Finished successfully. Outcomes captured.", transitions_to: [] },
6036
- { id: "sunset", label: "Sunset", description: "Winding down or discontinued.", transitions_to: [] }
6209
+ { id: "planning", status_category: "unstarted", label: "Planning", description: "Being designed or scoped. Not yet started.", transitions_to: ["active"] },
6210
+ { id: "active", status_category: "started", label: "Active", description: "Currently running or in operation.", transitions_to: ["paused", "completed", "sunset"] },
6211
+ { id: "paused", status_category: "backlog", label: "Paused", description: "Temporarily halted. Can be resumed.", transitions_to: ["active", "sunset"] },
6212
+ { id: "completed", status_category: "completed", label: "Completed", description: "Finished successfully. Outcomes captured.", transitions_to: [] },
6213
+ { id: "sunset", status_category: "completed", label: "Sunset", description: "Winding down or discontinued.", transitions_to: [] }
6037
6214
  ]
6038
6215
  };
6039
6216
  var APPROVAL_TEMPLATE = {
@@ -6045,22 +6222,23 @@ var APPROVAL_TEMPLATE = {
6045
6222
  // UPGLifecycle.terminal_phases contract.
6046
6223
  terminal_phases: ["approved", "rejected", "deprecated"],
6047
6224
  phases: [
6048
- { id: "proposed", label: "Proposed", description: "Submitted for consideration. Awaiting review.", transitions_to: ["reviewing"] },
6049
- { id: "reviewing", label: "Reviewing", description: "Under active review by approvers.", transitions_to: ["approved", "rejected", "proposed"] },
6050
- { id: "approved", label: "Approved", description: "Accepted and ready for implementation.", transitions_to: ["deprecated"] },
6051
- { id: "rejected", label: "Rejected", description: "Not accepted. Reasons should be documented.", transitions_to: ["proposed"] },
6052
- { id: "deprecated", label: "Deprecated", description: "Previously approved but no longer current.", transitions_to: [] }
6225
+ { id: "proposed", status_category: "triage", label: "Proposed", description: "Submitted for consideration. Awaiting review.", transitions_to: ["reviewing"] },
6226
+ { id: "reviewing", status_category: "started", label: "Reviewing", description: "Under active review by approvers.", transitions_to: ["approved", "rejected", "proposed"] },
6227
+ { id: "approved", status_category: "completed", label: "Approved", description: "Accepted and ready for implementation.", transitions_to: ["deprecated"] },
6228
+ { id: "rejected", status_category: "cancelled", label: "Rejected", description: "Not accepted. Reasons should be documented.", transitions_to: ["proposed"] },
6229
+ { id: "deprecated", status_category: "completed", label: "Deprecated", description: "Previously approved but no longer current.", transitions_to: [] }
6053
6230
  ]
6054
6231
  };
6055
6232
  var WORK_ITEM_TEMPLATE = {
6056
6233
  template_id: "WORK_ITEM",
6057
6234
  initial_phase: "todo",
6058
- terminal_phases: ["done"],
6235
+ terminal_phases: ["done", "cancelled"],
6059
6236
  phases: [
6060
- { id: "todo", label: "To Do", description: "Identified but not yet started.", transitions_to: ["in_progress"] },
6061
- { id: "in_progress", label: "In Progress", description: "Actively being worked on.", transitions_to: ["in_review", "todo"] },
6062
- { id: "in_review", label: "In Review", description: "Work completed, awaiting review or acceptance.", transitions_to: ["done", "in_progress"] },
6063
- { id: "done", label: "Done", description: "Completed and accepted.", transitions_to: [] }
6237
+ { id: "todo", status_category: "unstarted", label: "To Do", description: "Identified but not yet started.", transitions_to: ["in_progress", "cancelled"] },
6238
+ { id: "in_progress", status_category: "started", label: "In Progress", description: "Actively being worked on.", transitions_to: ["in_review", "todo", "cancelled"] },
6239
+ { id: "in_review", status_category: "started", label: "In Review", description: "Work completed, awaiting review or acceptance.", transitions_to: ["done", "in_progress", "cancelled"] },
6240
+ { id: "done", status_category: "completed", label: "Done", description: "Completed and accepted.", transitions_to: [] },
6241
+ { id: "cancelled", status_category: "cancelled", label: "Cancelled", description: "Deliberately closed without completion: won't-do, duplicate, or obsolete. May reopen to `todo` if circumstances change.", transitions_to: ["todo"] }
6064
6242
  ]
6065
6243
  };
6066
6244
  var DISCOVERY_TEMPLATE = {
@@ -6068,10 +6246,10 @@ var DISCOVERY_TEMPLATE = {
6068
6246
  initial_phase: "open",
6069
6247
  terminal_phases: ["resolved", "parked"],
6070
6248
  phases: [
6071
- { id: "open", label: "Open", description: "Identified as worth exploring. No work started yet.", transitions_to: ["exploring"] },
6072
- { id: "exploring", label: "Exploring", description: "Actively being investigated or researched.", transitions_to: ["resolved", "parked", "open"] },
6073
- { id: "resolved", label: "Resolved", description: "Answered or addressed. Findings captured.", transitions_to: [] },
6074
- { id: "parked", label: "Parked", description: "Set aside for now. May revisit later.", transitions_to: ["open"] }
6249
+ { id: "open", status_category: "triage", label: "Open", description: "Identified as worth exploring. No work started yet.", transitions_to: ["exploring"] },
6250
+ { id: "exploring", status_category: "started", label: "Exploring", description: "Actively being investigated or researched.", transitions_to: ["resolved", "parked", "open"] },
6251
+ { id: "resolved", status_category: "completed", label: "Resolved", description: "Answered or addressed. Findings captured.", transitions_to: [] },
6252
+ { id: "parked", status_category: "backlog", label: "Parked", description: "Set aside for now. May revisit later.", transitions_to: ["open"] }
6075
6253
  ]
6076
6254
  };
6077
6255
  var MATURITY_TEMPLATE = {
@@ -6079,10 +6257,10 @@ var MATURITY_TEMPLATE = {
6079
6257
  initial_phase: "alpha",
6080
6258
  terminal_phases: ["deprecated"],
6081
6259
  phases: [
6082
- { id: "alpha", label: "Alpha", description: "Early stage, internal use only. Expect breaking changes.", transitions_to: ["beta"] },
6083
- { id: "beta", label: "Beta", description: "Feature complete but may have rough edges. Limited external use.", transitions_to: ["ga", "alpha"] },
6084
- { id: "ga", label: "Generally Available", description: "Stable, production-ready. Widely available.", transitions_to: ["deprecated"] },
6085
- { id: "deprecated", label: "Deprecated", description: "Scheduled for removal. Migration path should be documented.", transitions_to: [] }
6260
+ { id: "alpha", status_category: "started", label: "Alpha", description: "Early stage, internal use only. Expect breaking changes.", transitions_to: ["beta"] },
6261
+ { id: "beta", status_category: "started", label: "Beta", description: "Feature complete but may have rough edges. Limited external use.", transitions_to: ["ga", "alpha"] },
6262
+ { id: "ga", status_category: "completed", label: "Generally Available", description: "Stable, production-ready. Widely available.", transitions_to: ["deprecated"] },
6263
+ { id: "deprecated", status_category: "completed", label: "Deprecated", description: "Scheduled for removal. Migration path should be documented.", transitions_to: [] }
6086
6264
  ]
6087
6265
  };
6088
6266
  var RISK_ITEM_TEMPLATE = {
@@ -6090,11 +6268,11 @@ var RISK_ITEM_TEMPLATE = {
6090
6268
  initial_phase: "identified",
6091
6269
  terminal_phases: ["mitigated", "accepted", "closed"],
6092
6270
  phases: [
6093
- { id: "identified", label: "Identified", description: "Risk has been recognised and named. Not yet assessed for likelihood or impact.", transitions_to: ["assessed"] },
6094
- { id: "assessed", label: "Assessed", description: "Likelihood and impact have been evaluated. Outcome is one of mitigated, accepted, or closed.", transitions_to: ["mitigated", "accepted", "closed"] },
6095
- { id: "mitigated", label: "Mitigated", description: "Action has been taken to reduce likelihood or impact. The risk is no longer active.", transitions_to: [] },
6096
- { id: "accepted", label: "Accepted", description: "Risk is acknowledged. Cost of mitigation outweighs exposure; the team chooses to live with it.", transitions_to: [] },
6097
- { id: "closed", label: "Closed", description: "Risk became irrelevant without action; underlying conditions changed. May reopen to `assessed` if conditions change again.", transitions_to: ["assessed"] }
6271
+ { id: "identified", status_category: "triage", label: "Identified", description: "Risk has been recognised and named. Not yet assessed for likelihood or impact.", transitions_to: ["assessed"] },
6272
+ { id: "assessed", status_category: "started", label: "Assessed", description: "Likelihood and impact have been evaluated. Outcome is one of mitigated, accepted, or closed.", transitions_to: ["mitigated", "accepted", "closed"] },
6273
+ { id: "mitigated", status_category: "completed", label: "Mitigated", description: "Action has been taken to reduce likelihood or impact. The risk is no longer active.", transitions_to: [] },
6274
+ { id: "accepted", status_category: "completed", label: "Accepted", description: "Risk is acknowledged. Cost of mitigation outweighs exposure; the team chooses to live with it.", transitions_to: [] },
6275
+ { id: "closed", status_category: "completed", label: "Closed", description: "Risk became irrelevant without action; underlying conditions changed. May reopen to `assessed` if conditions change again.", transitions_to: ["assessed"] }
6098
6276
  ]
6099
6277
  };
6100
6278
  var SALES_DEAL_TEMPLATE = {
@@ -6102,11 +6280,11 @@ var SALES_DEAL_TEMPLATE = {
6102
6280
  initial_phase: "qualified",
6103
6281
  terminal_phases: ["closed_won", "closed_lost"],
6104
6282
  phases: [
6105
- { id: "qualified", label: "Qualified", description: "Lead has been qualified: there's a real budget, need, and decision-maker. Not yet pitched.", transitions_to: ["proposal"] },
6106
- { id: "proposal", label: "Proposal", description: "A proposal has been delivered. Pricing and scope are on the table.", transitions_to: ["negotiation", "closed_lost"] },
6107
- { id: "negotiation", label: "Negotiation", description: "Terms are being finalised. Both sides are working toward agreement.", transitions_to: ["closed_won", "closed_lost"] },
6108
- { id: "closed_won", label: "Closed Won", description: "Deal signed. Customer is now active.", transitions_to: [] },
6109
- { id: "closed_lost", label: "Closed Lost", description: "Deal did not close. A re-engaged prospect becomes a new `deal` rather than reviving this one.", transitions_to: [] }
6283
+ { id: "qualified", status_category: "triage", label: "Qualified", description: "Lead has been qualified: there's a real budget, need, and decision-maker. Not yet pitched.", transitions_to: ["proposal"] },
6284
+ { id: "proposal", status_category: "started", label: "Proposal", description: "A proposal has been delivered. Pricing and scope are on the table.", transitions_to: ["negotiation", "closed_lost"] },
6285
+ { id: "negotiation", status_category: "started", label: "Negotiation", description: "Terms are being finalised. Both sides are working toward agreement.", transitions_to: ["closed_won", "closed_lost"] },
6286
+ { id: "closed_won", status_category: "completed", label: "Closed Won", description: "Deal signed. Customer is now active.", transitions_to: [] },
6287
+ { id: "closed_lost", status_category: "completed", label: "Closed Lost", description: "Deal did not close. A re-engaged prospect becomes a new `deal` rather than reviving this one.", transitions_to: [] }
6110
6288
  ]
6111
6289
  };
6112
6290
  var VALIDATION_TEMPLATE = {
@@ -6114,11 +6292,11 @@ var VALIDATION_TEMPLATE = {
6114
6292
  initial_phase: "untested",
6115
6293
  terminal_phases: ["validated", "invalidated", "archived"],
6116
6294
  phases: [
6117
- { id: "untested", label: "Untested", description: "Articulated but not yet examined against evidence.", transitions_to: ["testing"] },
6118
- { id: "testing", label: "Testing", description: "Actively gathering evidence for or against the claim.", transitions_to: ["validated", "invalidated"] },
6119
- { id: "validated", label: "Validated", description: "Evidence supports the claim. Treated as true until contradicted.", transitions_to: ["archived"] },
6120
- { id: "invalidated", label: "Invalidated", description: "Evidence contradicts the claim. May re-test if new evidence appears.", transitions_to: ["archived", "testing"] },
6121
- { id: "archived", label: "Archived", description: "Settled and retained for provenance. No longer active.", transitions_to: [] }
6295
+ { id: "untested", status_category: "triage", label: "Untested", description: "Articulated but not yet examined against evidence.", transitions_to: ["testing"] },
6296
+ { id: "testing", status_category: "started", label: "Testing", description: "Actively gathering evidence for or against the claim.", transitions_to: ["validated", "invalidated"] },
6297
+ { id: "validated", status_category: "completed", label: "Validated", description: "Evidence supports the claim. Treated as true until contradicted.", transitions_to: ["archived"] },
6298
+ { id: "invalidated", status_category: "completed", label: "Invalidated", description: "Evidence contradicts the claim. May re-test if new evidence appears.", transitions_to: ["archived", "testing"] },
6299
+ { id: "archived", status_category: "completed", label: "Archived", description: "Settled and retained for provenance. No longer active.", transitions_to: [] }
6122
6300
  ]
6123
6301
  };
6124
6302
  var INCIDENT_TEMPLATE = {
@@ -6126,12 +6304,12 @@ var INCIDENT_TEMPLATE = {
6126
6304
  initial_phase: "open",
6127
6305
  terminal_phases: ["resolved", "closed", "wont_fix"],
6128
6306
  phases: [
6129
- { id: "open", label: "Open", description: "Surfaced and logged. Not yet triaged.", transitions_to: ["triaged"] },
6130
- { id: "triaged", label: "Triaged", description: "Assessed for severity and ownership. Routed for work or dispositioned.", transitions_to: ["in_progress", "resolved", "wont_fix"] },
6131
- { id: "in_progress", label: "In Progress", description: "Actively being worked toward a fix.", transitions_to: ["resolved", "wont_fix"] },
6132
- { id: "resolved", label: "Resolved", description: "Addressed and verified. May reopen to `triaged` on regression.", transitions_to: ["closed", "triaged"] },
6133
- { id: "closed", label: "Closed", description: "Administratively closed (duplicate, withdrawn, or no longer relevant).", transitions_to: [] },
6134
- { id: "wont_fix", label: "Won't Fix", description: "Triaged as not to be actioned. Reason should be documented.", transitions_to: [] }
6307
+ { id: "open", status_category: "triage", label: "Open", description: "Surfaced and logged. Not yet triaged.", transitions_to: ["triaged"] },
6308
+ { id: "triaged", status_category: "triage", label: "Triaged", description: "Assessed for severity and ownership. Routed for work or dispositioned.", transitions_to: ["in_progress", "resolved", "wont_fix"] },
6309
+ { id: "in_progress", status_category: "started", label: "In Progress", description: "Actively being worked toward a fix.", transitions_to: ["resolved", "wont_fix"] },
6310
+ { id: "resolved", status_category: "completed", label: "Resolved", description: "Addressed and verified. May reopen to `triaged` on regression.", transitions_to: ["closed", "triaged"] },
6311
+ { id: "closed", status_category: "cancelled", label: "Closed", description: "Administratively closed (duplicate, withdrawn, or no longer relevant).", transitions_to: [] },
6312
+ { id: "wont_fix", status_category: "cancelled", label: "Won't Fix", description: "Triaged as not to be actioned. Reason should be documented.", transitions_to: [] }
6135
6313
  ]
6136
6314
  };
6137
6315
  var STUDY_TEMPLATE = {
@@ -6139,11 +6317,11 @@ var STUDY_TEMPLATE = {
6139
6317
  initial_phase: "planned",
6140
6318
  terminal_phases: ["complete", "abandoned"],
6141
6319
  phases: [
6142
- { id: "planned", label: "Planned", description: "Scoped and scheduled. Not yet started.", transitions_to: ["running"] },
6143
- { id: "running", label: "Running", description: "Actively executing: collecting data or running the protocol.", transitions_to: ["analysing", "abandoned"] },
6144
- { id: "analysing", label: "Analysing", description: "Execution done; results are being analysed and written up.", transitions_to: ["complete", "abandoned"] },
6145
- { id: "complete", label: "Complete", description: "Analysed and concluded. Findings captured.", transitions_to: [] },
6146
- { id: "abandoned", label: "Abandoned", description: "Stopped before completion (killed, timed out, or superseded).", transitions_to: [] }
6320
+ { id: "planned", status_category: "unstarted", label: "Planned", description: "Scoped and scheduled. Not yet started.", transitions_to: ["running"] },
6321
+ { id: "running", status_category: "started", label: "Running", description: "Actively executing: collecting data or running the protocol.", transitions_to: ["analysing", "abandoned"] },
6322
+ { id: "analysing", status_category: "started", label: "Analysing", description: "Execution done; results are being analysed and written up.", transitions_to: ["complete", "abandoned"] },
6323
+ { id: "complete", status_category: "completed", label: "Complete", description: "Analysed and concluded. Findings captured.", transitions_to: [] },
6324
+ { id: "abandoned", status_category: "cancelled", label: "Abandoned", description: "Stopped before completion (killed, timed out, or superseded).", transitions_to: [] }
6147
6325
  ]
6148
6326
  };
6149
6327
  var TEMPLATE_LIFECYCLES = [
@@ -6305,18 +6483,21 @@ var FRAMEWORK_EXERCISE_LIFECYCLE = {
6305
6483
  phases: [
6306
6484
  {
6307
6485
  id: "draft",
6486
+ status_category: "started",
6308
6487
  label: "Draft",
6309
6488
  description: "The exercise has been created and entities pulled into scope, but the framework's inputs have not all been filled in yet.",
6310
6489
  transitions_to: ["active", "archived"]
6311
6490
  },
6312
6491
  {
6313
6492
  id: "active",
6493
+ status_category: "started",
6314
6494
  label: "Active",
6315
6495
  description: "The current, authoritative run of its framework. Its include edges carry the live results consumers read, rank, and render by.",
6316
6496
  transitions_to: ["archived"]
6317
6497
  },
6318
6498
  {
6319
6499
  id: "archived",
6500
+ status_category: "completed",
6320
6501
  label: "Archived",
6321
6502
  description: "A past run, retained for provenance. Still queryable but superseded by a newer exercise and hidden from default views. Can be revived to active.",
6322
6503
  transitions_to: ["active"]
@@ -6330,24 +6511,28 @@ var SPECIFICATION_LIFECYCLE = {
6330
6511
  phases: [
6331
6512
  {
6332
6513
  id: "draft",
6514
+ status_category: "started",
6333
6515
  label: "Draft",
6334
6516
  description: "Being authored. Not yet adopted as the canonical specification.",
6335
6517
  transitions_to: ["active", "superseded"]
6336
6518
  },
6337
6519
  {
6338
6520
  id: "active",
6521
+ status_category: "started",
6339
6522
  label: "Active",
6340
6523
  description: "In force. The current authoritative version products implement and conform to.",
6341
6524
  transitions_to: ["deprecated", "superseded"]
6342
6525
  },
6343
6526
  {
6344
6527
  id: "deprecated",
6528
+ status_category: "started",
6345
6529
  label: "Deprecated",
6346
6530
  description: "Still valid but no longer recommended; a successor exists or is imminent.",
6347
6531
  transitions_to: ["superseded"]
6348
6532
  },
6349
6533
  {
6350
6534
  id: "superseded",
6535
+ status_category: "completed",
6351
6536
  label: "Superseded",
6352
6537
  description: "Replaced by a newer specification. Retained for historical reference.",
6353
6538
  transitions_to: []
@@ -6359,9 +6544,9 @@ var PLANNING_CYCLE_LIFECYCLE = {
6359
6544
  initial_phase: "planned",
6360
6545
  terminal_phases: ["closed"],
6361
6546
  phases: [
6362
- { id: "planned", label: "Planned", description: "The cycle is being shaped: dates set, goal written, work scheduled into it. It has not started yet.", transitions_to: ["active"] },
6363
- { id: "active", label: "Active", description: "The team is inside the interval; work is flowing through it.", transitions_to: ["closed"] },
6364
- { id: "closed", label: "Closed", description: "The interval has ended. Scheduled work has shipped, carried over, or been dropped. May reopen if the team extends or reruns it.", transitions_to: ["active"] }
6547
+ { id: "planned", status_category: "unstarted", label: "Planned", description: "The cycle is being shaped: dates set, goal written, work scheduled into it. It has not started yet.", transitions_to: ["active"] },
6548
+ { id: "active", status_category: "started", label: "Active", description: "The team is inside the interval; work is flowing through it.", transitions_to: ["closed"] },
6549
+ { id: "closed", status_category: "completed", label: "Closed", description: "The interval has ended. Scheduled work has shipped, carried over, or been dropped. May reopen if the team extends or reruns it.", transitions_to: ["active"] }
6365
6550
  ]
6366
6551
  };
6367
6552
  var UPG_LIFECYCLES = [
@@ -29980,6 +30165,28 @@ function portfolioBody(doc) {
29980
30165
  ...doc.signals && doc.signals.length > 0 ? { signals: sortNodes(doc.signals).map(canonicalNode) } : {}
29981
30166
  };
29982
30167
  }
30168
+ function deriveSingleCounts(doc) {
30169
+ return { nodes: doc.nodes?.length ?? 0, edges: doc.edges?.length ?? 0 };
30170
+ }
30171
+ function derivePortfolioCounts(doc) {
30172
+ const members = doc.products ?? [];
30173
+ const memberKindOf = (p) => p.member_kind ?? "product";
30174
+ const watchedCount = members.filter((p) => memberKindOf(p) === "watched").length;
30175
+ const rollupCount = members.filter((p) => memberKindOf(p) === "org_rollup").length;
30176
+ const operatingFunctionCount = members.filter((p) => memberKindOf(p) === "operating_function").length;
30177
+ return {
30178
+ products: members.filter((p) => memberKindOf(p) === "product").length,
30179
+ ...watchedCount > 0 ? { watched_products: watchedCount } : {},
30180
+ ...rollupCount > 0 ? { org_rollups: rollupCount } : {},
30181
+ ...operatingFunctionCount > 0 ? { operating_functions: operatingFunctionCount } : {},
30182
+ product_areas: doc.product_areas?.length ?? 0,
30183
+ portfolios: doc.portfolios?.length ?? 0,
30184
+ cross_edges: doc.cross_edges?.length ?? 0
30185
+ };
30186
+ }
30187
+ function deriveCounts(doc) {
30188
+ return isPortfolio(doc) ? derivePortfolioCounts(doc) : deriveSingleCounts(doc);
30189
+ }
29983
30190
  function computeBodyChecksum(doc) {
29984
30191
  const body = isPortfolio(doc) ? portfolioBody(doc) : singleBody(doc);
29985
30192
  const content = JSON.stringify(body);
@@ -30019,7 +30226,7 @@ function serializeSingleWithHeader(doc, opts) {
30019
30226
  };
30020
30227
  const summary = deriveSummary(product.description);
30021
30228
  if (summary) header.summary = summary;
30022
- header.counts = { nodes: doc.nodes?.length ?? 0, edges: doc.edges?.length ?? 0 };
30229
+ header.counts = deriveSingleCounts(doc);
30023
30230
  if (doc.member_kind === "org_rollup" || doc.member_kind === "watched" || doc.member_kind === "operating_function") {
30024
30231
  header.member_kind = doc.member_kind;
30025
30232
  }
@@ -30042,20 +30249,7 @@ function serializePortfolioWithHeader(doc, opts) {
30042
30249
  };
30043
30250
  const summary = deriveSummary(org.description);
30044
30251
  if (summary) header.summary = summary;
30045
- const members = doc.products ?? [];
30046
- const memberKindOf = (p) => p.member_kind ?? "product";
30047
- const watchedCount = members.filter((p) => memberKindOf(p) === "watched").length;
30048
- const rollupCount = members.filter((p) => memberKindOf(p) === "org_rollup").length;
30049
- const operatingFunctionCount = members.filter((p) => memberKindOf(p) === "operating_function").length;
30050
- header.counts = {
30051
- products: members.filter((p) => memberKindOf(p) === "product").length,
30052
- ...watchedCount > 0 ? { watched_products: watchedCount } : {},
30053
- ...rollupCount > 0 ? { org_rollups: rollupCount } : {},
30054
- ...operatingFunctionCount > 0 ? { operating_functions: operatingFunctionCount } : {},
30055
- product_areas: doc.product_areas?.length ?? 0,
30056
- portfolios: doc.portfolios?.length ?? 0,
30057
- cross_edges: doc.cross_edges?.length ?? 0
30058
- };
30252
+ header.counts = derivePortfolioCounts(doc);
30059
30253
  header.provenance = buildProvenance(doc, opts);
30060
30254
  header.integrity = { algorithm: INTEGRITY_ALGORITHM, body: computeBodyChecksum(doc) };
30061
30255
  return JSON.stringify({ $upg: header, ...body }, null, 2) + "\n";
@@ -30123,9 +30317,61 @@ function isCanonical(text) {
30123
30317
  const parsed = parseUpg(text);
30124
30318
  return text === serializeCanonical(parsed);
30125
30319
  }
30320
+ function checkHeaderSeal(obj) {
30321
+ const raw = obj;
30322
+ const header = raw?.$upg;
30323
+ const report = {
30324
+ header_present: !!header,
30325
+ counts_checked: false,
30326
+ integrity_checked: false,
30327
+ counts_drift: [],
30328
+ integrity_drift: []
30329
+ };
30330
+ if (!header) return report;
30331
+ if (header.format_version !== UPG_CANONICAL_FORMAT_VERSION) {
30332
+ report.skipped_reason = `format_version "${header.format_version}" is not this serialiser's "${UPG_CANONICAL_FORMAT_VERSION}"; counts keys and body layout are format-version contracts, so neither seal can be judged here.`;
30333
+ return report;
30334
+ }
30335
+ const doc = normalizeDocument(raw);
30336
+ const declaredCounts = header.counts ?? {};
30337
+ const actualCounts = deriveCounts(doc);
30338
+ if (header.counts === void 0) {
30339
+ report.skipped_reason = "header has no `counts` block to compare.";
30340
+ } else {
30341
+ report.counts_checked = true;
30342
+ const fields = /* @__PURE__ */ new Set([...Object.keys(declaredCounts), ...Object.keys(actualCounts)]);
30343
+ for (const field of [...fields].sort()) {
30344
+ const declaredRaw = declaredCounts[field];
30345
+ const declared = typeof declaredRaw === "number" ? declaredRaw : 0;
30346
+ const actual = actualCounts[field] ?? 0;
30347
+ if (declared !== actual) report.counts_drift.push({ field, declared, actual });
30348
+ }
30349
+ }
30350
+ const integrity = header.integrity;
30351
+ if (!integrity || typeof integrity.body !== "string") {
30352
+ report.skipped_reason = report.skipped_reason ?? "header has no `integrity.body` seal to compare.";
30353
+ } else if (integrity.algorithm !== INTEGRITY_ALGORITHM) {
30354
+ report.skipped_reason = report.skipped_reason ?? `integrity.algorithm "${integrity.algorithm}" is not "${INTEGRITY_ALGORITHM}"; the declared digest cannot be recomputed here.`;
30355
+ } else {
30356
+ report.integrity_checked = true;
30357
+ const computed = computeBodyChecksum(doc);
30358
+ if (computed !== integrity.body) {
30359
+ report.integrity_drift.push({
30360
+ algorithm: integrity.algorithm,
30361
+ declared: integrity.body,
30362
+ computed
30363
+ });
30364
+ }
30365
+ }
30366
+ return report;
30367
+ }
30368
+ function checkHeaderSealText(text) {
30369
+ const noBom = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
30370
+ return checkHeaderSeal(JSON.parse(noBom));
30371
+ }
30126
30372
 
30127
30373
  // src/index.ts
30128
- var UPG_VERSION = "0.25.1";
30374
+ var UPG_VERSION = "0.26.1";
30129
30375
  var UPG_FORMAT_VERSION = "0.4.0";
30130
30376
  var MARKDOWN_FORMAT_VERSION = "0.1";
30131
30377
  var UPG_TYPES = getTypes();
@@ -30295,6 +30541,8 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
30295
30541
  backfillSlug,
30296
30542
  buildTypeAliases,
30297
30543
  canBeChildOf,
30544
+ checkHeaderSeal,
30545
+ checkHeaderSealText,
30298
30546
  coerceProductStage,
30299
30547
  collectSlugsForType,
30300
30548
  compareVersions,
@@ -30303,6 +30551,9 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
30303
30551
  concernFor,
30304
30552
  concernGatesFor,
30305
30553
  crossProductScope,
30554
+ deriveCounts,
30555
+ derivePortfolioCounts,
30556
+ deriveSingleCounts,
30306
30557
  describeTreePattern,
30307
30558
  edgeCarriesProperties,
30308
30559
  evaluateAntiPatterns,