@opengeni/db 0.36.1 → 3.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/dist/attached-browser-devices.d.ts +7 -0
  2. package/dist/automations.d.ts +154 -0
  3. package/dist/canonical-human-identities.js +3 -3
  4. package/dist/capability-integrations.d.ts +13 -0
  5. package/dist/child-lifecycle-notices.d.ts +68 -0
  6. package/dist/{chunk-GYO7ED2Q.js → chunk-EULAN2NP.js} +2 -2
  7. package/dist/{chunk-VTPRIXKG.js → chunk-NJVZPWXY.js} +3 -3
  8. package/dist/{chunk-HSOWSYOX.js → chunk-NMUBV7Z5.js} +19 -11
  9. package/dist/chunk-NMUBV7Z5.js.map +1 -0
  10. package/dist/chunk-OF5OBB76.js +4457 -0
  11. package/dist/chunk-OF5OBB76.js.map +1 -0
  12. package/dist/{chunk-5KTIEDX7.js → chunk-PR2WMLOQ.js} +7714 -4443
  13. package/dist/chunk-PR2WMLOQ.js.map +1 -0
  14. package/dist/{chunk-Z7VYMNPZ.js → chunk-SCPUJS53.js} +41 -4
  15. package/dist/chunk-SCPUJS53.js.map +1 -0
  16. package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
  17. package/dist/chunk-SIBYBA2D.js.map +1 -0
  18. package/dist/chunk-TIKF3KTI.js +383 -0
  19. package/dist/chunk-TIKF3KTI.js.map +1 -0
  20. package/dist/chunk-ZZ5LJEFX.js +516 -0
  21. package/dist/chunk-ZZ5LJEFX.js.map +1 -0
  22. package/dist/codemode-operations.d.ts +1 -6
  23. package/dist/company-brain-context-selection-schema.d.ts +705 -0
  24. package/dist/company-brain-context-selection.d.ts +94 -0
  25. package/dist/company-brain-governed-writes.d.ts +24 -0
  26. package/dist/company-brain.d.ts +55 -0
  27. package/dist/company-profile-agent-admin.d.ts +15 -0
  28. package/dist/company-profile-schema.d.ts +619 -2
  29. package/dist/company-profile.d.ts +9 -4
  30. package/dist/connection-authority.d.ts +95 -0
  31. package/dist/connection-scopes.d.ts +8 -0
  32. package/dist/connection-tenancy-backfill.d.ts +41 -0
  33. package/dist/connection-token-resolver.d.ts +30 -1
  34. package/dist/database.d.ts +19 -0
  35. package/dist/editable-artifact-durable-export.d.ts +10 -0
  36. package/dist/editable-artifact-durable-export.js +18 -3
  37. package/dist/editable-artifact-durable-export.js.map +1 -1
  38. package/dist/editable-artifacts.d.ts +2 -2
  39. package/dist/editable-artifacts.js +3 -3
  40. package/dist/governed-learning-activation-schema.d.ts +984 -0
  41. package/dist/governed-learning-activation.d.ts +98 -0
  42. package/dist/governed-learning-evaluator-schema.d.ts +633 -0
  43. package/dist/governed-learning-evaluator.d.ts +28 -0
  44. package/dist/index.d.ts +1633 -87
  45. package/dist/index.js +22004 -8109
  46. package/dist/index.js.map +1 -1
  47. package/dist/insights.d.ts +18 -0
  48. package/dist/integration-bindings.d.ts +1 -0
  49. package/dist/integration-facets.d.ts +30 -0
  50. package/dist/interaction-placement-loss.d.ts +22 -0
  51. package/dist/knowledge-source-sync-schema.d.ts +730 -0
  52. package/dist/knowledge-source-sync.d.ts +60 -0
  53. package/dist/managed-human-provisioning.d.ts +25 -0
  54. package/dist/memory-domain.d.ts +3 -3
  55. package/dist/migrate.d.ts +11 -1
  56. package/dist/migrate.js +1 -1
  57. package/dist/new-session-drafts.d.ts +43 -5
  58. package/dist/organization-membership-backfill.d.ts +174 -0
  59. package/dist/organization-membership-lifecycle.d.ts +162 -0
  60. package/dist/pr-review.d.ts +107 -0
  61. package/dist/preference-registry-schema.d.ts +2 -0
  62. package/dist/preference-registry.d.ts +2 -0
  63. package/dist/provision-roles.js +1 -1
  64. package/dist/runtime-posture.d.ts +23 -9
  65. package/dist/schema.d.ts +24925 -13697
  66. package/dist/schema.js +103 -1
  67. package/dist/scoped-knowledge-schema.d.ts +52 -1
  68. package/dist/session-background-commands.d.ts +125 -0
  69. package/dist/session-background-commands.js +34 -0
  70. package/dist/session-background-commands.js.map +1 -0
  71. package/dist/session-control.d.ts +156 -3
  72. package/dist/session-goal-pacing.d.ts +68 -0
  73. package/dist/session-queue-commands.d.ts +42 -5
  74. package/dist/session-realtime-ledger.d.ts +3 -0
  75. package/dist/session-tenancy.d.ts +71 -1
  76. package/dist/session-tenancy.js +25 -3
  77. package/dist/session-tool-call-settlement.d.ts +9 -4
  78. package/dist/slack-routing-personal-workspace.d.ts +23 -0
  79. package/dist/slack-routing.d.ts +153 -0
  80. package/dist/slack-task-policy-schema.d.ts +34 -0
  81. package/dist/slack-task-policy.d.ts +8 -0
  82. package/dist/slack-user-link-access.d.ts +1 -0
  83. package/dist/task-notes-schema.d.ts +594 -0
  84. package/dist/task-notes.d.ts +39 -0
  85. package/dist/turn-initiator.d.ts +2 -0
  86. package/dist/user-resource-authority.d.ts +109 -0
  87. package/dist/video-generation.js +3 -3
  88. package/dist/workspace-authority.d.ts +81 -0
  89. package/dist/workspace-instruction-policies-schema.d.ts +279 -0
  90. package/dist/workspace-instruction-policies.d.ts +62 -0
  91. package/dist/workspace-learning-policy.d.ts +1 -0
  92. package/dist/workspace-membership-permissions.d.ts +2 -0
  93. package/drizzle/0240_enrollment_connection_authority.sql +39 -0
  94. package/drizzle/0240_model_context_user_messages.sql +204 -0
  95. package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
  96. package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
  97. package/drizzle/0243_google_drive_object_acl_authority.sql +554 -0
  98. package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
  99. package/drizzle/0245_model_context_contribution_facts.sql +88 -0
  100. package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
  101. package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
  102. package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
  103. package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
  104. package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
  105. package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
  106. package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
  107. package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
  108. package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
  109. package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
  110. package/drizzle/0256_connection_authority_delegation.sql +703 -0
  111. package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
  112. package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
  113. package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
  114. package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
  115. package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
  116. package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
  117. package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
  118. package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
  119. package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
  120. package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
  121. package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
  122. package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
  123. package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
  124. package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
  125. package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
  126. package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
  127. package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
  128. package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
  129. package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
  130. package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
  131. package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
  132. package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
  133. package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
  134. package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
  135. package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
  136. package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
  137. package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
  138. package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
  139. package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
  140. package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
  141. package/drizzle/0289_session_composer_policy_authority.sql +597 -0
  142. package/drizzle/0290_organization_membership_backfill.sql +268 -0
  143. package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
  144. package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
  145. package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
  146. package/drizzle/0294_preference_activation_authority.sql +237 -0
  147. package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
  148. package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
  149. package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
  150. package/drizzle/0298_organization_tenancy_parity.sql +609 -0
  151. package/drizzle/0299_organization_membership_lock_order.sql +291 -0
  152. package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
  153. package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
  154. package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
  155. package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
  156. package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
  157. package/drizzle/0305_personal_resource_grant_management.sql +584 -0
  158. package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
  159. package/drizzle/0307_session_attention_state.sql +51 -0
  160. package/drizzle/0308_session_archives.sql +35 -0
  161. package/drizzle/0309_channel_project_pins.sql +6 -0
  162. package/drizzle/0310_channel_project_order.sql +27 -0
  163. package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
  164. package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
  165. package/drizzle/0313_private_child_session_authority.sql +365 -0
  166. package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
  167. package/drizzle/0315_personal_github_repository_selection.sql +624 -0
  168. package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
  169. package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
  170. package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
  171. package/drizzle/0319_event_triggered_automations.sql +254 -0
  172. package/drizzle/0320_pr_review_pack.sql +113 -0
  173. package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
  174. package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
  175. package/drizzle/0323_organization_private_session_enablement.sql +489 -0
  176. package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
  177. package/drizzle/0325_child_lifecycle_notices.sql +44 -0
  178. package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
  179. package/drizzle/0327_slack_first_task_hint.sql +29 -0
  180. package/drizzle/0328_session_background_commands.sql +590 -0
  181. package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
  182. package/drizzle/0330_api_key_descriptions.sql +20 -0
  183. package/drizzle/0331_managed_organization_creation.sql +163 -0
  184. package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
  185. package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
  186. package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
  187. package/drizzle/0335_slack_workspace_routing.sql +460 -0
  188. package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
  189. package/drizzle/0337_slack_routed_action_handles.sql +189 -0
  190. package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
  191. package/drizzle/0339_document_authority_reclassification.sql +1153 -0
  192. package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
  193. package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
  194. package/package.json +10 -6
  195. package/src/attached-browser-devices.ts +233 -5
  196. package/src/automations.ts +911 -0
  197. package/src/browser-sessions.ts +10 -0
  198. package/src/capability-integrations.ts +175 -1
  199. package/src/child-lifecycle-notices.ts +241 -0
  200. package/src/codemode-operations.ts +1 -35
  201. package/src/company-brain-context-selection-schema.ts +100 -0
  202. package/src/company-brain-context-selection.ts +359 -0
  203. package/src/company-brain-governed-writes.ts +1170 -0
  204. package/src/company-brain.ts +309 -0
  205. package/src/company-profile-agent-admin.ts +225 -0
  206. package/src/company-profile-schema.ts +121 -1
  207. package/src/company-profile.ts +21 -0
  208. package/src/computer-sessions.ts +10 -1
  209. package/src/connection-authority.ts +290 -0
  210. package/src/connection-scopes.ts +20 -0
  211. package/src/connection-tenancy-backfill.ts +81 -0
  212. package/src/connection-token-resolver.ts +263 -31
  213. package/src/database.ts +75 -2
  214. package/src/editable-artifact-durable-export.ts +27 -0
  215. package/src/editable-artifacts-schema.ts +10 -5
  216. package/src/editable-artifacts.ts +21 -11
  217. package/src/governed-learning-activation-schema.ts +121 -0
  218. package/src/governed-learning-activation.ts +588 -0
  219. package/src/governed-learning-evaluator-schema.ts +72 -0
  220. package/src/governed-learning-evaluator.ts +217 -0
  221. package/src/index.ts +12001 -1699
  222. package/src/insights.ts +107 -0
  223. package/src/integration-bindings.ts +88 -6
  224. package/src/integration-facets.ts +287 -84
  225. package/src/interaction-placement-loss.ts +234 -0
  226. package/src/knowledge-source-sync-schema.ts +83 -0
  227. package/src/knowledge-source-sync.ts +530 -0
  228. package/src/managed-human-provisioning.ts +116 -0
  229. package/src/memory-domain.ts +27 -32
  230. package/src/migrate.ts +77 -1
  231. package/src/new-session-drafts.ts +229 -35
  232. package/src/organization-membership-backfill.ts +735 -0
  233. package/src/organization-membership-lifecycle.ts +985 -0
  234. package/src/pr-review.ts +890 -0
  235. package/src/preference-registry.ts +31 -1
  236. package/src/provision-roles.ts +931 -24
  237. package/src/runtime-posture-cli.ts +2 -0
  238. package/src/runtime-posture.ts +1315 -52
  239. package/src/schema.ts +3336 -438
  240. package/src/scoped-knowledge-schema.ts +16 -8
  241. package/src/scoped-knowledge.ts +1 -1
  242. package/src/session-background-commands.ts +759 -0
  243. package/src/session-control.ts +640 -74
  244. package/src/session-goal-pacing.ts +126 -0
  245. package/src/session-queue-commands.ts +450 -98
  246. package/src/session-realtime-context.ts +19 -3
  247. package/src/session-realtime-ledger.ts +75 -12
  248. package/src/session-realtime-mirror.ts +1 -1
  249. package/src/session-tenancy.ts +403 -49
  250. package/src/session-tool-call-settlement.ts +38 -29
  251. package/src/slack-routing-personal-workspace.ts +67 -0
  252. package/src/slack-routing.ts +469 -0
  253. package/src/slack-task-policy-schema.ts +5 -0
  254. package/src/slack-task-policy.ts +18 -0
  255. package/src/slack-user-link-access.ts +17 -1
  256. package/src/task-notes-schema.ts +74 -0
  257. package/src/task-notes.ts +124 -2
  258. package/src/turn-initiator.ts +8 -0
  259. package/src/user-resource-authority.ts +377 -0
  260. package/src/workspace-authority.ts +160 -0
  261. package/src/workspace-instruction-policies-schema.ts +53 -1
  262. package/src/workspace-instruction-policies.ts +528 -77
  263. package/src/workspace-learning-policy.ts +21 -5
  264. package/src/workspace-membership-permissions.ts +9 -0
  265. package/dist/chunk-5KTIEDX7.js.map +0 -1
  266. package/dist/chunk-FPVAD4CO.js +0 -117
  267. package/dist/chunk-FPVAD4CO.js.map +0 -1
  268. package/dist/chunk-HSOWSYOX.js.map +0 -1
  269. package/dist/chunk-SK7YYHBI.js.map +0 -1
  270. package/dist/chunk-VKLB2ZGI.js +0 -2389
  271. package/dist/chunk-VKLB2ZGI.js.map +0 -1
  272. package/dist/chunk-Z7VYMNPZ.js.map +0 -1
  273. /package/dist/{chunk-GYO7ED2Q.js.map → chunk-EULAN2NP.js.map} +0 -0
  274. /package/dist/{chunk-VTPRIXKG.js.map → chunk-NJVZPWXY.js.map} +0 -0
@@ -0,0 +1,436 @@
1
+ -- deployment-mode: maintenance
2
+ -- Complete governed goal revision decisions and freeze bounded root constraints
3
+ -- into the existing accepted-turn goal authority.
4
+ -- This is a one-way application protocol cutover: stop every API, control
5
+ -- worker, and turn worker before applying it, and never restart a pre-0257
6
+ -- image after commit. Old workers strip root constraints from the accepted-turn
7
+ -- snapshot and therefore cannot safely execute against this schema.
8
+
9
+ SET LOCAL lock_timeout = '5s';
10
+ SET LOCAL statement_timeout = '10min';
11
+
12
+ -- Reject mixed-version writers before locking, then repeat after the locks to
13
+ -- close the connect-before-lock race. The deployment must keep every old image
14
+ -- stopped until a 0257-compatible application fleet is active.
15
+ DO $goal_revision_writer_drain_before_lock$
16
+ DECLARE
17
+ configured_roles_text text := nullif(
18
+ current_setting('opengeni.migration_application_roles', true),
19
+ ''
20
+ );
21
+ configured_roles jsonb;
22
+ BEGIN
23
+ IF configured_roles_text IS NULL THEN
24
+ RAISE EXCEPTION
25
+ 'goal revision authority activation requires an explicit application database role list'
26
+ USING ERRCODE = '55000';
27
+ END IF;
28
+ BEGIN
29
+ configured_roles := configured_roles_text::jsonb;
30
+ EXCEPTION WHEN OTHERS THEN
31
+ RAISE EXCEPTION
32
+ 'goal revision authority activation received a malformed application database role list'
33
+ USING ERRCODE = '55000';
34
+ END;
35
+ IF jsonb_typeof(configured_roles) <> 'array' THEN
36
+ RAISE EXCEPTION
37
+ 'goal revision authority activation received an invalid application database role list'
38
+ USING ERRCODE = '55000';
39
+ END IF;
40
+ IF jsonb_array_length(configured_roles) < 1
41
+ OR jsonb_array_length(configured_roles) > 16
42
+ OR EXISTS (
43
+ SELECT 1 FROM jsonb_array_elements(configured_roles) AS roles(value)
44
+ WHERE jsonb_typeof(value) <> 'string'
45
+ OR btrim(value #>> '{}') = ''
46
+ OR octet_length(value #>> '{}') > 63
47
+ )
48
+ OR (
49
+ SELECT count(*) FROM jsonb_array_elements_text(configured_roles)
50
+ ) <> (
51
+ SELECT count(DISTINCT value) FROM jsonb_array_elements_text(configured_roles) AS roles(value)
52
+ )
53
+ THEN
54
+ RAISE EXCEPTION
55
+ 'goal revision authority activation received an invalid application database role list'
56
+ USING ERRCODE = '55000';
57
+ END IF;
58
+ IF EXISTS (
59
+ SELECT 1
60
+ FROM pg_stat_activity AS activity
61
+ JOIN jsonb_array_elements_text(configured_roles) AS roles(role_name)
62
+ ON roles.role_name = activity.usename
63
+ WHERE activity.datname = current_database()
64
+ AND activity.pid <> pg_backend_pid()
65
+ )
66
+ THEN
67
+ RAISE EXCEPTION
68
+ 'goal revision authority activation requires all configured OpenGeni application database sessions to be stopped'
69
+ USING ERRCODE = '55000';
70
+ END IF;
71
+ END
72
+ $goal_revision_writer_drain_before_lock$;
73
+
74
+ LOCK TABLE "session_goals" IN ACCESS EXCLUSIVE MODE;
75
+ LOCK TABLE "session_goal_revisions" IN ACCESS EXCLUSIVE MODE;
76
+ LOCK TABLE "session_turns" IN ACCESS EXCLUSIVE MODE;
77
+
78
+ DO $goal_revision_writer_drain_after_lock$
79
+ DECLARE
80
+ configured_roles jsonb := current_setting(
81
+ 'opengeni.migration_application_roles',
82
+ false
83
+ )::jsonb;
84
+ BEGIN
85
+ IF EXISTS (
86
+ SELECT 1
87
+ FROM pg_stat_activity AS activity
88
+ JOIN jsonb_array_elements_text(configured_roles) AS roles(role_name)
89
+ ON roles.role_name = activity.usename
90
+ WHERE activity.datname = current_database()
91
+ AND activity.pid <> pg_backend_pid()
92
+ )
93
+ THEN
94
+ RAISE EXCEPTION
95
+ 'goal revision authority activation requires all configured OpenGeni application database sessions to be stopped'
96
+ USING ERRCODE = '55000';
97
+ END IF;
98
+ END
99
+ $goal_revision_writer_drain_after_lock$;
100
+
101
+ CREATE OR REPLACE FUNCTION session_goal_normalize_root_constraints(value jsonb)
102
+ RETURNS jsonb
103
+ LANGUAGE plpgsql
104
+ IMMUTABLE
105
+ AS $$
106
+ DECLARE
107
+ item jsonb;
108
+ normalized jsonb;
109
+ normalized_count integer;
110
+ aggregate_bytes integer;
111
+ BEGIN
112
+ IF value IS NULL THEN
113
+ RETURN '[]'::jsonb;
114
+ END IF;
115
+ IF jsonb_typeof(value) <> 'array' THEN
116
+ RAISE EXCEPTION 'goal root constraints must be a JSON array'
117
+ USING ERRCODE = '23514';
118
+ END IF;
119
+ FOR item IN SELECT value_item FROM jsonb_array_elements(value) AS items(value_item)
120
+ LOOP
121
+ IF jsonb_typeof(item) <> 'string' THEN
122
+ RAISE EXCEPTION 'goal root constraints must contain only strings'
123
+ USING ERRCODE = '23514';
124
+ END IF;
125
+ IF btrim(item #>> '{}') = '' THEN
126
+ RAISE EXCEPTION 'goal root constraints must not be blank'
127
+ USING ERRCODE = '23514';
128
+ END IF;
129
+ IF octet_length(btrim(item #>> '{}')) > 512 THEN
130
+ RAISE EXCEPTION 'goal root constraint exceeds 512 UTF-8 bytes'
131
+ USING ERRCODE = '22001';
132
+ END IF;
133
+ END LOOP;
134
+
135
+ SELECT
136
+ coalesce(jsonb_agg(to_jsonb(candidate) ORDER BY convert_to(candidate, 'UTF8')), '[]'::jsonb),
137
+ count(*)::integer,
138
+ coalesce(sum(octet_length(candidate)), 0)::integer
139
+ INTO normalized, normalized_count, aggregate_bytes
140
+ FROM (
141
+ SELECT DISTINCT btrim(value_item #>> '{}') AS candidate
142
+ FROM jsonb_array_elements(value) AS items(value_item)
143
+ ) normalized_items;
144
+
145
+ IF normalized_count > 16 THEN
146
+ RAISE EXCEPTION 'goal root constraints exceed 16 items'
147
+ USING ERRCODE = '22001';
148
+ END IF;
149
+ IF aggregate_bytes > 4096 THEN
150
+ RAISE EXCEPTION 'goal root constraints exceed 4096 aggregate UTF-8 bytes'
151
+ USING ERRCODE = '22001';
152
+ END IF;
153
+ RETURN normalized;
154
+ END;
155
+ $$;
156
+
157
+ ALTER TABLE "session_goals"
158
+ ADD COLUMN IF NOT EXISTS "root_constraints" jsonb NOT NULL DEFAULT '[]'::jsonb;
159
+
160
+ ALTER TABLE "session_goal_revisions"
161
+ ADD COLUMN IF NOT EXISTS "root_constraints" jsonb NOT NULL DEFAULT '[]'::jsonb,
162
+ ADD COLUMN IF NOT EXISTS "rollback_of_revision_id" uuid;
163
+
164
+ CREATE OR REPLACE FUNCTION session_goal_normalize_root_constraints_before_write()
165
+ RETURNS trigger
166
+ LANGUAGE plpgsql
167
+ AS $$
168
+ BEGIN
169
+ NEW."root_constraints" := session_goal_normalize_root_constraints(
170
+ NEW."root_constraints"
171
+ );
172
+ RETURN NEW;
173
+ END;
174
+ $$;
175
+
176
+ DROP TRIGGER IF EXISTS session_goal_00_normalize_root_constraints ON "session_goals";
177
+ CREATE TRIGGER session_goal_00_normalize_root_constraints
178
+ BEFORE INSERT OR UPDATE OF "root_constraints" ON "session_goals"
179
+ FOR EACH ROW EXECUTE FUNCTION session_goal_normalize_root_constraints_before_write();
180
+
181
+ DROP TRIGGER IF EXISTS session_goal_revisions_00_normalize_root_constraints
182
+ ON "session_goal_revisions";
183
+ CREATE TRIGGER session_goal_revisions_00_normalize_root_constraints
184
+ BEFORE INSERT OR UPDATE OF "root_constraints" ON "session_goal_revisions"
185
+ FOR EACH ROW EXECUTE FUNCTION session_goal_normalize_root_constraints_before_write();
186
+
187
+ ALTER TABLE "session_goals"
188
+ ADD CONSTRAINT "session_goals_root_constraints_chk"
189
+ CHECK (
190
+ jsonb_typeof("root_constraints") = 'array'
191
+ AND "root_constraints" = session_goal_normalize_root_constraints("root_constraints")
192
+ ) NOT VALID;
193
+
194
+ ALTER TABLE "session_goal_revisions"
195
+ ADD CONSTRAINT "session_goal_revisions_root_constraints_chk"
196
+ CHECK (
197
+ jsonb_typeof("root_constraints") = 'array'
198
+ AND "root_constraints" = session_goal_normalize_root_constraints("root_constraints")
199
+ ) NOT VALID;
200
+
201
+ ALTER TABLE "session_goals"
202
+ VALIDATE CONSTRAINT "session_goals_root_constraints_chk";
203
+ ALTER TABLE "session_goal_revisions"
204
+ VALIDATE CONSTRAINT "session_goal_revisions_root_constraints_chk";
205
+
206
+ ALTER TABLE "session_goal_revisions"
207
+ ADD CONSTRAINT "session_goal_revisions_rollback_of_revision_fk"
208
+ FOREIGN KEY ("workspace_id", "rollback_of_revision_id")
209
+ REFERENCES "session_goal_revisions"("workspace_id", "id") ON DELETE RESTRICT;
210
+
211
+ CREATE UNIQUE INDEX "session_goal_revisions_proposal_decision_uq"
212
+ ON "session_goal_revisions" ("workspace_id", "proposal_id")
213
+ WHERE "proposal_id" IS NOT NULL
214
+ AND "disposition" IN ('applied', 'rejected');
215
+
216
+ CREATE UNIQUE INDEX "session_goal_revisions_rollback_request_uq"
217
+ ON "session_goal_revisions" (
218
+ "workspace_id", "goal_id", "rollback_of_revision_id", "base_objective_revision"
219
+ )
220
+ WHERE "disposition" = 'applied' AND "rollback_of_revision_id" IS NOT NULL;
221
+
222
+ ALTER TABLE "session_goal_revisions"
223
+ ADD CONSTRAINT "session_goal_revisions_lineage_shape_chk" CHECK (
224
+ ("disposition" = 'proposed'
225
+ AND "proposal_id" IS NULL AND "rollback_of_revision_id" IS NULL)
226
+ OR
227
+ ("disposition" = 'rejected'
228
+ AND "proposal_id" IS NOT NULL AND "rollback_of_revision_id" IS NULL)
229
+ OR
230
+ ("disposition" = 'applied'
231
+ AND NOT ("proposal_id" IS NOT NULL AND "rollback_of_revision_id" IS NOT NULL))
232
+ ) NOT VALID;
233
+
234
+ ALTER TABLE "session_goal_revisions"
235
+ VALIDATE CONSTRAINT "session_goal_revisions_lineage_shape_chk";
236
+
237
+ ALTER TABLE "session_turns"
238
+ ADD CONSTRAINT "session_turns_goal_root_constraints_chk" CHECK (
239
+ "goal_snapshot" IS NULL
240
+ OR "goal_snapshot" ->> 'state' = 'none'
241
+ OR NOT ("goal_snapshot" ? 'rootConstraints')
242
+ OR (
243
+ jsonb_typeof("goal_snapshot" -> 'rootConstraints') = 'array'
244
+ AND ("goal_snapshot" -> 'rootConstraints') =
245
+ session_goal_normalize_root_constraints("goal_snapshot" -> 'rootConstraints')
246
+ )
247
+ ) NOT VALID;
248
+
249
+ ALTER TABLE "session_turns"
250
+ VALIDATE CONSTRAINT "session_turns_goal_root_constraints_chk";
251
+
252
+ CREATE OR REPLACE FUNCTION session_goal_revision_before_write()
253
+ RETURNS trigger
254
+ LANGUAGE plpgsql
255
+ AS $$
256
+ DECLARE
257
+ semantic_change boolean;
258
+ BEGIN
259
+ IF TG_OP = 'INSERT' THEN
260
+ IF octet_length(NEW."text") > 8192 THEN
261
+ RAISE EXCEPTION 'goal text exceeds 8192 UTF-8 bytes'
262
+ USING ERRCODE = '22001';
263
+ END IF;
264
+ IF NEW."success_criteria" IS NOT NULL
265
+ AND octet_length(NEW."success_criteria") > 8192 THEN
266
+ RAISE EXCEPTION 'goal success criteria exceeds 8192 UTF-8 bytes'
267
+ USING ERRCODE = '22001';
268
+ END IF;
269
+ IF NEW."objective_revision" <> 1 THEN
270
+ RAISE EXCEPTION 'a new goal must start at objective revision 1'
271
+ USING ERRCODE = '23514';
272
+ END IF;
273
+ RETURN NEW;
274
+ END IF;
275
+
276
+ semantic_change :=
277
+ NEW."text" IS DISTINCT FROM OLD."text"
278
+ OR NEW."success_criteria" IS DISTINCT FROM OLD."success_criteria"
279
+ OR NEW."root_constraints" IS DISTINCT FROM OLD."root_constraints"
280
+ OR NEW."mutation_policy" IS DISTINCT FROM OLD."mutation_policy";
281
+
282
+ IF semantic_change THEN
283
+ IF octet_length(NEW."text") > 8192 THEN
284
+ RAISE EXCEPTION 'goal text exceeds 8192 UTF-8 bytes'
285
+ USING ERRCODE = '22001';
286
+ END IF;
287
+ IF NEW."success_criteria" IS NOT NULL
288
+ AND octet_length(NEW."success_criteria") > 8192 THEN
289
+ RAISE EXCEPTION 'goal success criteria exceeds 8192 UTF-8 bytes'
290
+ USING ERRCODE = '22001';
291
+ END IF;
292
+ IF NEW."objective_revision" = OLD."objective_revision" THEN
293
+ NEW."objective_revision" := OLD."objective_revision" + 1;
294
+ ELSIF NEW."objective_revision" <> OLD."objective_revision" + 1 THEN
295
+ RAISE EXCEPTION 'goal objective revision must advance exactly once'
296
+ USING ERRCODE = '40001';
297
+ END IF;
298
+ ELSIF NEW."objective_revision" <> OLD."objective_revision" THEN
299
+ RAISE EXCEPTION 'goal objective revision changed without semantic content'
300
+ USING ERRCODE = '23514';
301
+ END IF;
302
+ RETURN NEW;
303
+ END;
304
+ $$;
305
+
306
+ CREATE OR REPLACE FUNCTION session_goal_revision_after_write()
307
+ RETURNS trigger
308
+ LANGUAGE plpgsql
309
+ AS $$
310
+ DECLARE
311
+ semantic_change boolean := TG_OP = 'INSERT';
312
+ base_revision integer := 0;
313
+ change_kind text := 'replacement';
314
+ change_rationale text := 'Goal created';
315
+ change_actor text;
316
+ change_turn_id uuid;
317
+ change_attempt_id uuid;
318
+ source_proposal_id uuid;
319
+ rollback_revision_id uuid;
320
+ BEGIN
321
+ IF TG_OP = 'UPDATE' THEN
322
+ semantic_change :=
323
+ NEW."text" IS DISTINCT FROM OLD."text"
324
+ OR NEW."success_criteria" IS DISTINCT FROM OLD."success_criteria"
325
+ OR NEW."root_constraints" IS DISTINCT FROM OLD."root_constraints"
326
+ OR NEW."mutation_policy" IS DISTINCT FROM OLD."mutation_policy";
327
+ base_revision := OLD."objective_revision";
328
+ change_rationale := 'Goal changed by a rolling-compatible writer';
329
+ END IF;
330
+ IF NOT semantic_change THEN
331
+ RETURN NEW;
332
+ END IF;
333
+
334
+ change_kind := COALESCE(
335
+ NULLIF(current_setting('opengeni.goal_change_kind', true), ''),
336
+ change_kind
337
+ );
338
+ change_rationale := COALESCE(
339
+ NULLIF(current_setting('opengeni.goal_change_rationale', true), ''),
340
+ change_rationale
341
+ );
342
+ change_actor := COALESCE(
343
+ NULLIF(current_setting('opengeni.goal_change_actor', true), ''),
344
+ CASE
345
+ WHEN NEW."created_by" = 'scheduled_task' THEN 'scheduled_task'
346
+ WHEN NEW."created_by" = 'agent' THEN 'agent'
347
+ ELSE 'api'
348
+ END
349
+ );
350
+ change_turn_id := NULLIF(
351
+ current_setting('opengeni.goal_change_turn_id', true), ''
352
+ )::uuid;
353
+ change_attempt_id := NULLIF(
354
+ current_setting('opengeni.goal_change_attempt_id', true), ''
355
+ )::uuid;
356
+ source_proposal_id := NULLIF(
357
+ current_setting('opengeni.goal_change_proposal_id', true), ''
358
+ )::uuid;
359
+ rollback_revision_id := NULLIF(
360
+ current_setting('opengeni.goal_change_rollback_of_revision_id', true), ''
361
+ )::uuid;
362
+
363
+ INSERT INTO "session_goal_revisions" (
364
+ "account_id", "workspace_id", "session_id", "goal_id", "disposition",
365
+ "change_kind", "base_objective_revision", "result_objective_revision",
366
+ "text", "success_criteria", "root_constraints", "mutation_policy",
367
+ "rationale", "actor", "actor_turn_id", "actor_attempt_id", "proposal_id",
368
+ "rollback_of_revision_id", "created_at"
369
+ ) VALUES (
370
+ NEW."account_id", NEW."workspace_id", NEW."session_id", NEW."id",
371
+ 'applied', change_kind, base_revision, NEW."objective_revision", NEW."text",
372
+ NEW."success_criteria", NEW."root_constraints", NEW."mutation_policy",
373
+ change_rationale, change_actor, change_turn_id, change_attempt_id,
374
+ source_proposal_id, rollback_revision_id, now()
375
+ )
376
+ ON CONFLICT ("workspace_id", "goal_id", "result_objective_revision")
377
+ WHERE "disposition" = 'applied'
378
+ DO NOTHING;
379
+ RETURN NEW;
380
+ END;
381
+ $$;
382
+
383
+ DROP TRIGGER IF EXISTS session_goal_revision_before_write_trigger ON "session_goals";
384
+ CREATE TRIGGER session_goal_revision_before_write_trigger
385
+ BEFORE INSERT OR UPDATE OF
386
+ "text", "success_criteria", "root_constraints", "mutation_policy", "objective_revision"
387
+ ON "session_goals"
388
+ FOR EACH ROW EXECUTE FUNCTION session_goal_revision_before_write();
389
+
390
+ DROP TRIGGER IF EXISTS session_goal_revision_after_write_trigger ON "session_goals";
391
+ CREATE TRIGGER session_goal_revision_after_write_trigger
392
+ AFTER INSERT OR UPDATE OF
393
+ "text", "success_criteria", "root_constraints", "mutation_policy"
394
+ ON "session_goals"
395
+ FOR EACH ROW EXECUTE FUNCTION session_goal_revision_after_write();
396
+
397
+ CREATE OR REPLACE FUNCTION session_goal_freeze_turn_snapshot()
398
+ RETURNS trigger
399
+ LANGUAGE plpgsql
400
+ AS $$
401
+ DECLARE
402
+ goal_row "session_goals"%ROWTYPE;
403
+ BEGIN
404
+ SELECT * INTO goal_row
405
+ FROM "session_goals"
406
+ WHERE "workspace_id" = NEW."workspace_id"
407
+ AND "session_id" = NEW."session_id";
408
+
409
+ IF FOUND THEN
410
+ NEW."goal_snapshot" := jsonb_build_object(
411
+ 'state', goal_row."status",
412
+ 'goalId', goal_row."id"::text,
413
+ 'objectiveRevision', goal_row."objective_revision",
414
+ 'text', session_goal_prompt_projection(goal_row."text", 8192),
415
+ 'successCriteria', to_jsonb(
416
+ session_goal_prompt_projection(goal_row."success_criteria", 8192)
417
+ ),
418
+ 'rootConstraints', goal_row."root_constraints",
419
+ 'mutationPolicy', goal_row."mutation_policy",
420
+ 'capturedAt', to_char(
421
+ NEW."created_at" AT TIME ZONE 'UTC',
422
+ 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
423
+ )
424
+ );
425
+ ELSE
426
+ NEW."goal_snapshot" := jsonb_build_object(
427
+ 'state', 'none',
428
+ 'capturedAt', to_char(
429
+ NEW."created_at" AT TIME ZONE 'UTC',
430
+ 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'
431
+ )
432
+ );
433
+ END IF;
434
+ RETURN NEW;
435
+ END;
436
+ $$;