thinkwork-cli 0.13.0 → 0.13.2

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 (178) hide show
  1. package/dist/{api-client-JUBCQQDF.js → api-client-JYZXYQJR.js} +3 -1
  2. package/dist/bowser-6Z6JFAIR.js +2822 -0
  3. package/dist/chunk-DV3MRBR5.js +43 -0
  4. package/dist/chunk-DVPBI5HM.js +1728 -0
  5. package/dist/chunk-EI5ZX7CN.js +522 -0
  6. package/dist/chunk-EUJ7X6YD.js +126 -0
  7. package/dist/chunk-GG5WKBOX.js +436 -0
  8. package/dist/chunk-I64EZSU5.js +358 -0
  9. package/dist/chunk-ILZKG5WV.js +6151 -0
  10. package/dist/chunk-KMIJ5KGT.js +128 -0
  11. package/dist/chunk-OCPHU34C.js +996 -0
  12. package/dist/chunk-QOERT44A.js +3286 -0
  13. package/dist/chunk-XYM7PE2A.js +2264 -0
  14. package/dist/{chunk-STY44FQO.js → chunk-Z2F6RJFR.js} +12 -18
  15. package/dist/cli.js +72564 -18884
  16. package/dist/dist-es-CRV46D5B.js +315 -0
  17. package/dist/dist-es-DCY4IC3Y.js +2000 -0
  18. package/dist/dist-es-ENBUC3JP.js +14726 -0
  19. package/dist/dist-es-G54LBMRN.js +48 -0
  20. package/dist/dist-es-G7PTG75M.js +176 -0
  21. package/dist/dist-es-GKDBE7E6.js +88 -0
  22. package/dist/dist-es-HY3535OI.js +70 -0
  23. package/dist/dist-es-KL7Y5NB2.js +377 -0
  24. package/dist/dist-es-LDE437AM.js +170 -0
  25. package/dist/dist-es-P26FWFLT.js +485 -0
  26. package/dist/dist-es-Q57SZXZ7.js +70 -0
  27. package/dist/dist-es-R7FGL2IB.js +88 -0
  28. package/dist/dist-es-USORBXZ5.js +318 -0
  29. package/dist/dist-es-ZKC2QKD2.js +377 -0
  30. package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +2 -1
  31. package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +1 -0
  32. package/dist/drizzle/0090_brain_schema_extraction.sql +10 -0
  33. package/dist/drizzle/0132_drop_computer_tables.sql +3 -0
  34. package/dist/drizzle/0160_compliance_event_types_plugins.sql +2 -0
  35. package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +1 -0
  36. package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +1 -0
  37. package/dist/drizzle/0227_analyst_reader_role.sql +106 -38
  38. package/dist/drizzle/0230_analyst_rls.sql +192 -66
  39. package/dist/drizzle/0232_memory_source_thin_ledger.sql +176 -0
  40. package/dist/drizzle/0232_message_source_event_id.sql +9 -0
  41. package/dist/drizzle/0233_msteams_install_and_links.sql +151 -0
  42. package/dist/drizzle/0233_workflow_memory_stage_tokens.sql +20 -0
  43. package/dist/drizzle/0234_memory_claim_lifecycle.sql +160 -0
  44. package/dist/drizzle/0235_workflow_token_execution_claim.sql +34 -0
  45. package/dist/drizzle/0236_memory_retraction_fencing.sql +50 -0
  46. package/dist/drizzle/0237_memory_claims_active_value_uidx.sql +172 -0
  47. package/dist/drizzle/0238_memory_erase_generation_fence.sql +97 -0
  48. package/dist/drizzle/0239_canonical_entity_identity.sql +257 -0
  49. package/dist/drizzle/0240_memory_personal_scope.sql +45 -0
  50. package/dist/drizzle/0241_knowledge_base_document_manifest.sql +67 -0
  51. package/dist/drizzle/0242_search_queries.sql +28 -0
  52. package/dist/drizzle/0243_section_sources_thread_refs.sql +12 -0
  53. package/dist/drizzle/0244_system_automations_and_memory_stage_overrides.sql +45 -0
  54. package/dist/drizzle/0245_wiki_page_render.sql +21 -0
  55. package/dist/drizzle/0246_automation_workflow_ownership.sql +30 -0
  56. package/dist/drizzle/0247_capability_runtime.sql +402 -0
  57. package/dist/drizzle/0248_capability_private_interpreter.sql +13 -0
  58. package/dist/drizzle/0249_capability_headless_execution_evidence.sql +40 -0
  59. package/dist/drizzle/0250_kg_schema_extraction.sql +576 -0
  60. package/dist/drizzle/0251_agents_json_render_ui.sql +25 -0
  61. package/dist/drizzle/0251_brain_stragglers.sql +263 -0
  62. package/dist/drizzle/0252_drop_kg_and_straggler_compat_views.sql +100 -0
  63. package/dist/drizzle/0253_drop_brain_substrate.sql +93 -0
  64. package/dist/drizzle/0254_capability_autonomous_admission.sql +29 -0
  65. package/dist/drizzle/0255_capability_autonomous_approval_mode.sql +16 -0
  66. package/dist/drizzle/0256_agent_profile_manifest_authority.sql +18 -0
  67. package/dist/drizzle/0257_agents_runtime_allow_harness.sql +24 -0
  68. package/dist/drizzle/0257_capability_approvals.sql +53 -0
  69. package/dist/drizzle/0258_pending_tool_approvals.sql +84 -0
  70. package/dist/drizzle/0259_tenant_capability_registry_trust.sql +19 -0
  71. package/dist/drizzle/0260_scheduled_jobs_run_as_user.sql +20 -0
  72. package/dist/drizzle/0261_managed_harness_multiplayer.sql +313 -0
  73. package/dist/drizzle/0261_native_auth_control_plane.sql +328 -0
  74. package/dist/drizzle/0262_auth_subscription_tickets.sql +59 -0
  75. package/dist/drizzle/0262_parallel_harness_threads.sql +9 -0
  76. package/dist/drizzle/0263_agentcore_runtime_identifier.sql +69 -0
  77. package/dist/drizzle/0263_drop_workos_auth_runtime.sql +236 -0
  78. package/dist/drizzle/0264_auth_enrollment_attempt_limits.sql +15 -0
  79. package/dist/drizzle/0264_harness_tool_execution_ledger.sql +113 -0
  80. package/dist/drizzle/0265_eval_runs_requester_identity.sql +28 -0
  81. package/dist/drizzle/0265_require_fully_valid_auth_publication.sql +27 -0
  82. package/dist/drizzle/0266_auth_identity_recovery_grants.sql +9 -0
  83. package/dist/drizzle/0266_eval_profiles_runtime_type.sql +12 -0
  84. package/dist/drizzle/0267_ontology_candidate_rejections.sql +53 -0
  85. package/dist/drizzle/0268_identity_crosswalk_routing.sql +182 -0
  86. package/dist/drizzle/0269_ontology_system_map.sql +31 -0
  87. package/dist/event-streams-7JNLJEEL.js +894 -0
  88. package/dist/event-streams-KDF5RWR6.js +1515 -0
  89. package/dist/loadSso-DJVB7BXE.js +576 -0
  90. package/dist/loadSso-JAMNA3WY.js +583 -0
  91. package/dist/plugins/catalog/package.json +1 -2
  92. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
  93. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +0 -69
  94. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
  95. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
  96. package/dist/plugins/catalog/src/contracts.ts +2 -179
  97. package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
  98. package/dist/signin-UGDWTGS4.js +821 -0
  99. package/dist/sso-oidc-Q4VXANXY.js +837 -0
  100. package/dist/sts-CWLSE3GH.js +1241 -0
  101. package/dist/sts-DNZLNVOV.js +1245 -0
  102. package/dist/terraform/examples/greenfield/main.tf +247 -50
  103. package/dist/terraform/examples/greenfield/terraform.tfvars.example +15 -1
  104. package/dist/terraform/modules/app/agentcore-admin/main.tf +341 -0
  105. package/dist/terraform/modules/app/agentcore-admin/outputs.tf +20 -0
  106. package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +61 -0
  107. package/dist/terraform/modules/app/agentcore-gateway/main.tf +305 -0
  108. package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +44 -0
  109. package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +93 -0
  110. package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +33 -0
  111. package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +543 -0
  112. package/dist/terraform/modules/app/agentcore-gateway/variables.tf +70 -0
  113. package/dist/terraform/modules/app/agentcore-harness/main.tf +330 -0
  114. package/dist/terraform/modules/app/agentcore-harness/outputs.tf +72 -0
  115. package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +5 -0
  116. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +430 -0
  117. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +180 -0
  118. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +193 -0
  119. package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +5 -0
  120. package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +5 -0
  121. package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +5 -0
  122. package/dist/terraform/modules/app/agentcore-harness/variables.tf +96 -0
  123. package/dist/terraform/modules/app/agentcore-identity/main.tf +173 -0
  124. package/dist/terraform/modules/app/agentcore-identity/outputs.tf +51 -0
  125. package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +122 -0
  126. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +25 -0
  127. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_twenty_identity.sh +16 -0
  128. package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +40 -0
  129. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_identity.sh +73 -0
  130. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +74 -0
  131. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +61 -0
  132. package/dist/terraform/modules/app/agentcore-identity/variables.tf +54 -0
  133. package/dist/terraform/modules/app/agentcore-pi/main.tf +7 -0
  134. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +127 -21
  135. package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +0 -6
  136. package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +5 -0
  137. package/dist/terraform/modules/app/capability-broker/main.tf +393 -0
  138. package/dist/terraform/modules/app/capability-broker/outputs.tf +54 -0
  139. package/dist/terraform/modules/app/capability-broker/variables.tf +98 -0
  140. package/dist/terraform/modules/app/deployment-control-plane/runner.py +1011 -31
  141. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +655 -2
  142. package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +88 -0
  143. package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +91 -0
  144. package/dist/terraform/modules/app/lambda-api/capability-search-alarms.tf +60 -0
  145. package/dist/terraform/modules/app/lambda-api/handlers.tf +606 -37
  146. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +192 -21
  147. package/dist/terraform/modules/app/lambda-api/main.tf +35 -0
  148. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +181 -4
  149. package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +92 -0
  150. package/dist/terraform/modules/app/lambda-api/msteams-app-secrets.tf +46 -0
  151. package/dist/terraform/modules/app/lambda-api/outputs.tf +35 -0
  152. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +3 -21
  153. package/dist/terraform/modules/app/lambda-api/variables.tf +188 -3
  154. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/alarms.tf +47 -0
  155. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +43 -2
  156. package/dist/terraform/modules/foundation/cognito/main.tf +319 -73
  157. package/dist/terraform/modules/foundation/cognito/outputs.tf +42 -0
  158. package/dist/terraform/modules/foundation/cognito/variables.tf +124 -2
  159. package/dist/terraform/modules/foundation/vpc/outputs.tf +5 -0
  160. package/dist/terraform/modules/thinkwork/main.tf +396 -26
  161. package/dist/terraform/modules/thinkwork/outputs.tf +188 -5
  162. package/dist/terraform/modules/thinkwork/variables.tf +154 -5
  163. package/dist/terraform/schema.graphql +69 -36
  164. package/dist/workspace-defaults/files/TOOLS.md +39 -0
  165. package/dist/workspace-defaults/files/USER.md +1 -0
  166. package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +18 -0
  167. package/dist/workspace-defaults/files/agents/coding/INSTRUCTIONS.md +11 -0
  168. package/dist/workspace-defaults/files/agents/research/INSTRUCTIONS.md +12 -0
  169. package/dist/workspace-defaults/files/agents/reviewer/INSTRUCTIONS.md +15 -0
  170. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +6 -2
  171. package/package.json +6 -3
  172. package/dist/plugins/workos-auth/package.json +0 -22
  173. package/dist/plugins/workos-auth/src/index.ts +0 -30
  174. package/dist/plugins/workos-auth/src/manifest.ts +0 -40
  175. package/dist/plugins/workos-auth/src/provider-contract.ts +0 -39
  176. package/dist/plugins/workos-auth/test/manifest.test.ts +0 -94
  177. package/dist/plugins/workos-auth/tsconfig.json +0 -8
  178. /package/dist/workspace-defaults/files/{AGENTS.md → INSTRUCTIONS.md} +0 -0
@@ -0,0 +1,576 @@
1
+ -- 0250_kg_schema_extraction.sql
2
+ --
3
+ -- Phase A of the knowledge-graph schema extraction (PR 1 of the THINK-290
4
+ -- arc). Moves the five public.knowledge_graph_* tables into the new `kg.*`
5
+ -- Postgres schema, drops the redundant `knowledge_graph_` prefix from table
6
+ -- and CHECK-constraint names, re-points the scope-guard trigger functions at
7
+ -- the new schema-qualified names, and creates compat views in public.* so
8
+ -- old bundled Lambda code keeps reading during the deploy bridge window.
9
+ --
10
+ -- Tables moved:
11
+ -- public.knowledge_graph_ingest_runs → kg.ingest_runs
12
+ -- public.knowledge_graph_entities → kg.entities
13
+ -- public.knowledge_graph_relationships → kg.relationships
14
+ -- public.knowledge_graph_evidence → kg.evidence
15
+ -- public.knowledge_graph_observation_cursors → kg.observation_cursors
16
+ --
17
+ -- Index names already use the `idx_kg_*` / `uq_kg_*` shorthand and are kept
18
+ -- verbatim; they move with their tables via SET SCHEMA. FK constraint names
19
+ -- and the `knowledge_graph_*_scope_guard` trigger names keep their original
20
+ -- prefixes — cosmetic cleanup deferred, same as the 0089/0090 precedent.
21
+ -- CHECK constraint names embed the table name in Drizzle's naming, so they
22
+ -- are renamed to the new stems to keep the Drizzle source and DB aligned.
23
+ --
24
+ -- The scope-guard trigger functions (0146/0147) query
25
+ -- public.knowledge_graph_* schema-qualified inside their plpgsql bodies.
26
+ -- Left alone they would resolve to the compat views (works during the
27
+ -- bridge) and break when the views drop, so this migration CREATE OR
28
+ -- REPLACEs the three functions that reference the moved tables with kg.*
29
+ -- qualified queries. enforce_knowledge_graph_ingest_run_scope references
30
+ -- only public.threads and is untouched.
31
+ --
32
+ -- Analyst surface: the semantic model deliberately includes public-schema
33
+ -- tables only (THINK-283), so the moved tables leave the analyst grants/RLS
34
+ -- surface, matching the wiki/ontology/brain extractions. Stale table-level
35
+ -- grants and analyst_tenant_isolation policies ride along harmlessly (the
36
+ -- app role owns the tables and bypasses RLS; analyst_reader has no USAGE on
37
+ -- kg).
38
+ --
39
+ -- Plan reference: docs/plans/2026-07-14-001-refactor-kg-schema-extraction-and-brain-cleanup-plan.md
40
+ -- Pattern doc: docs/solutions/database-issues/feature-schema-extraction-pattern.md
41
+ --
42
+ -- Apply manually (pause the observations-ingest schedule first — see the
43
+ -- writer runbook in the PR body):
44
+ -- psql "$DATABASE_URL" -f packages/database-pg/drizzle/0250_kg_schema_extraction.sql
45
+ -- Then verify:
46
+ -- bash scripts/db-migrate-manual.sh packages/database-pg/drizzle/0250_kg_schema_extraction.sql
47
+ -- psql -c "\dt kg.*" -- 5 tables expected
48
+ -- psql -c "\dv public.knowledge_graph_*" -- 5 compat views expected
49
+ -- psql -c "\dt public.knowledge_graph_*" -- 0 tables expected
50
+ --
51
+ -- Inverse runbook (rollback): drop the views, SET SCHEMA back, RENAME back,
52
+ -- restore the CHECK constraint names, and re-run the 0146/0147 function
53
+ -- bodies to restore the public.* qualification:
54
+ -- DROP VIEW IF EXISTS public.knowledge_graph_ingest_runs, ...; -- × 5
55
+ -- ALTER TABLE kg.evidence SET SCHEMA public;
56
+ -- ALTER TABLE public.evidence RENAME TO knowledge_graph_evidence;
57
+ -- ALTER TABLE public.knowledge_graph_evidence RENAME CONSTRAINT evidence_source_kind_allowed TO knowledge_graph_evidence_source_kind_allowed;
58
+ -- ... (× 5 tables, × 14 constraints, leaf-first)
59
+ -- -- re-apply 0146 + 0147 function definitions
60
+ -- DROP SCHEMA kg; -- last step; fails if any objects remain
61
+ --
62
+ -- Markers (consumed by scripts/db-migrate-manual.sh):
63
+ --
64
+ -- moves-owner: public.knowledge_graph_ingest_runs -> kg.ingest_runs
65
+ -- moves-owner: public.knowledge_graph_entities -> kg.entities
66
+ -- moves-owner: public.knowledge_graph_relationships -> kg.relationships
67
+ -- moves-owner: public.knowledge_graph_evidence -> kg.evidence
68
+ -- moves-owner: public.knowledge_graph_observation_cursors -> kg.observation_cursors
69
+ -- creates: kg.ingest_runs
70
+ -- creates: kg.entities
71
+ -- creates: kg.relationships
72
+ -- creates: kg.evidence
73
+ -- creates: kg.observation_cursors
74
+ -- creates: kg.uq_kg_entities_run_graph_node
75
+ -- creates: kg.uq_kg_relationships_run_graph_edge
76
+ -- drops: public.uq_kg_entities_run_graph_node
77
+ -- drops: public.uq_kg_relationships_run_graph_edge
78
+ -- drops-constraint: public.knowledge_graph_ingest_runs.knowledge_graph_ingest_runs_status_allowed
79
+ -- drops-constraint: public.knowledge_graph_ingest_runs.knowledge_graph_ingest_runs_trigger_allowed
80
+ -- drops-constraint: public.knowledge_graph_ingest_runs.knowledge_graph_ingest_runs_source_kind_allowed
81
+ -- drops-constraint: public.knowledge_graph_ingest_runs.knowledge_graph_ingest_runs_thread_scope_required
82
+ -- drops-constraint: public.knowledge_graph_entities.knowledge_graph_entities_grounding_allowed
83
+ -- drops-constraint: public.knowledge_graph_entities.knowledge_graph_entities_provenance_allowed
84
+ -- drops-constraint: public.knowledge_graph_entities.knowledge_graph_entities_source_kind_allowed
85
+ -- drops-constraint: public.knowledge_graph_entities.knowledge_graph_entities_resolution_state_allowed
86
+ -- drops-constraint: public.knowledge_graph_relationships.knowledge_graph_relationships_grounding_allowed
87
+ -- drops-constraint: public.knowledge_graph_relationships.knowledge_graph_relationships_provenance_allowed
88
+ -- drops-constraint: public.knowledge_graph_relationships.knowledge_graph_relationships_source_kind_allowed
89
+ -- drops-constraint: public.knowledge_graph_evidence.knowledge_graph_evidence_source_kind_allowed
90
+ -- drops-constraint: public.knowledge_graph_evidence.knowledge_graph_evidence_evidence_source_kind_allowed
91
+ -- drops-constraint: public.knowledge_graph_evidence.knowledge_graph_evidence_subject_required
92
+ -- creates-trigger: kg.ingest_runs.knowledge_graph_ingest_runs_scope_guard
93
+ -- creates-trigger: kg.entities.knowledge_graph_entities_scope_guard
94
+ -- creates-trigger: kg.relationships.knowledge_graph_relationships_scope_guard
95
+ -- creates-trigger: kg.evidence.knowledge_graph_evidence_scope_guard
96
+ -- creates-constraint: kg.ingest_runs.ingest_runs_status_allowed
97
+ -- creates-constraint: kg.ingest_runs.ingest_runs_trigger_allowed
98
+ -- creates-constraint: kg.ingest_runs.ingest_runs_source_kind_allowed
99
+ -- creates-constraint: kg.ingest_runs.ingest_runs_thread_scope_required
100
+ -- creates-constraint: kg.entities.entities_grounding_allowed
101
+ -- creates-constraint: kg.entities.entities_provenance_allowed
102
+ -- creates-constraint: kg.entities.entities_source_kind_allowed
103
+ -- creates-constraint: kg.entities.entities_resolution_state_allowed
104
+ -- creates-constraint: kg.relationships.relationships_grounding_allowed
105
+ -- creates-constraint: kg.relationships.relationships_provenance_allowed
106
+ -- creates-constraint: kg.relationships.relationships_source_kind_allowed
107
+ -- creates-constraint: kg.evidence.evidence_source_kind_allowed
108
+ -- creates-constraint: kg.evidence.evidence_evidence_source_kind_allowed
109
+ -- creates-constraint: kg.evidence.evidence_subject_required
110
+ -- creates: public.knowledge_graph_ingest_runs
111
+ -- creates: public.knowledge_graph_entities
112
+ -- creates: public.knowledge_graph_relationships
113
+ -- creates: public.knowledge_graph_evidence
114
+ -- creates: public.knowledge_graph_observation_cursors
115
+
116
+ \set ON_ERROR_STOP on
117
+
118
+ BEGIN;
119
+
120
+ -- Set timeouts BEFORE acquiring the advisory lock so the lock acquisition
121
+ -- itself is bounded.
122
+ SET LOCAL lock_timeout = '30s';
123
+ SET LOCAL statement_timeout = '300s';
124
+
125
+ -- Serialize concurrent application attempts.
126
+ SELECT pg_advisory_xact_lock(hashtext('kg_schema_extraction'));
127
+
128
+ -- Refuse to apply against an unexpected DB.
129
+ DO $$
130
+ BEGIN
131
+ IF current_database() != 'thinkwork' THEN
132
+ RAISE EXCEPTION 'wrong database: %, expected thinkwork', current_database();
133
+ END IF;
134
+ END $$;
135
+
136
+ -- Pre-flight invariants: for each table, assert old name exists AND new
137
+ -- name does not. Symmetric checks convert any partial-state scenario into a
138
+ -- clear pre-flight error. If the file was already applied (all five moved),
139
+ -- the customer runner's unattended re-sweep must be a no-op, so short-circuit
140
+ -- cleanly in that case.
141
+ DO $$
142
+ BEGIN
143
+ IF to_regclass('kg.ingest_runs') IS NOT NULL
144
+ AND to_regclass('kg.entities') IS NOT NULL
145
+ AND to_regclass('kg.relationships') IS NOT NULL
146
+ AND to_regclass('kg.evidence') IS NOT NULL
147
+ AND to_regclass('kg.observation_cursors') IS NOT NULL
148
+ AND to_regclass('public.knowledge_graph_ingest_runs') IS NOT NULL THEN
149
+ -- Already applied (views present at the old names). Nothing to do.
150
+ RETURN;
151
+ END IF;
152
+
153
+ IF to_regclass('public.knowledge_graph_ingest_runs') IS NULL THEN
154
+ RAISE EXCEPTION 'pre-flight: public.knowledge_graph_ingest_runs does not exist';
155
+ END IF;
156
+ IF to_regclass('kg.ingest_runs') IS NOT NULL THEN
157
+ RAISE EXCEPTION 'pre-flight: kg.ingest_runs already exists — refusing to re-apply';
158
+ END IF;
159
+ IF to_regclass('public.knowledge_graph_entities') IS NULL THEN
160
+ RAISE EXCEPTION 'pre-flight: public.knowledge_graph_entities does not exist';
161
+ END IF;
162
+ IF to_regclass('kg.entities') IS NOT NULL THEN
163
+ RAISE EXCEPTION 'pre-flight: kg.entities already exists — refusing to re-apply';
164
+ END IF;
165
+ IF to_regclass('public.knowledge_graph_relationships') IS NULL THEN
166
+ RAISE EXCEPTION 'pre-flight: public.knowledge_graph_relationships does not exist';
167
+ END IF;
168
+ IF to_regclass('kg.relationships') IS NOT NULL THEN
169
+ RAISE EXCEPTION 'pre-flight: kg.relationships already exists — refusing to re-apply';
170
+ END IF;
171
+ IF to_regclass('public.knowledge_graph_evidence') IS NULL THEN
172
+ RAISE EXCEPTION 'pre-flight: public.knowledge_graph_evidence does not exist';
173
+ END IF;
174
+ IF to_regclass('kg.evidence') IS NOT NULL THEN
175
+ RAISE EXCEPTION 'pre-flight: kg.evidence already exists — refusing to re-apply';
176
+ END IF;
177
+ IF to_regclass('public.knowledge_graph_observation_cursors') IS NULL THEN
178
+ RAISE EXCEPTION 'pre-flight: public.knowledge_graph_observation_cursors does not exist';
179
+ END IF;
180
+ IF to_regclass('kg.observation_cursors') IS NOT NULL THEN
181
+ RAISE EXCEPTION 'pre-flight: kg.observation_cursors already exists — refusing to re-apply';
182
+ END IF;
183
+ END $$;
184
+
185
+ -- Everything below is guarded so the whole file is idempotent for the
186
+ -- customer runner's unattended sweep: once applied, the pre-flight above
187
+ -- short-circuits nothing (DO blocks can't skip top-level DDL), so each DDL
188
+ -- statement carries its own existence guard.
189
+
190
+ -- Schema creation.
191
+ CREATE SCHEMA IF NOT EXISTS kg;
192
+ COMMENT ON SCHEMA kg IS 'Knowledge-graph mirror tables. Tenant-scoped entity/relationship/evidence snapshots and the ingest-run ledger. Extracted from public.knowledge_graph_* on 2026-07-14 (THINK-290).';
193
+
194
+ -- ── Move and rename tables ─────────────────────────────────────────────
195
+ -- FK-leaf-first ordering (evidence → relationships → entities →
196
+ -- observation_cursors → ingest_runs). Postgres preserves FKs across
197
+ -- SET SCHEMA automatically; ordering matters only for operator mental model.
198
+
199
+ DO $$
200
+ BEGIN
201
+ IF to_regclass('public.knowledge_graph_evidence') IS NOT NULL
202
+ AND to_regclass('kg.evidence') IS NULL THEN
203
+ ALTER TABLE public.knowledge_graph_evidence SET SCHEMA kg;
204
+ ALTER TABLE kg.knowledge_graph_evidence RENAME TO evidence;
205
+ END IF;
206
+
207
+ IF to_regclass('public.knowledge_graph_relationships') IS NOT NULL
208
+ AND to_regclass('kg.relationships') IS NULL THEN
209
+ ALTER TABLE public.knowledge_graph_relationships SET SCHEMA kg;
210
+ ALTER TABLE kg.knowledge_graph_relationships RENAME TO relationships;
211
+ END IF;
212
+
213
+ IF to_regclass('public.knowledge_graph_entities') IS NOT NULL
214
+ AND to_regclass('kg.entities') IS NULL THEN
215
+ ALTER TABLE public.knowledge_graph_entities SET SCHEMA kg;
216
+ ALTER TABLE kg.knowledge_graph_entities RENAME TO entities;
217
+ END IF;
218
+
219
+ IF to_regclass('public.knowledge_graph_observation_cursors') IS NOT NULL
220
+ AND to_regclass('kg.observation_cursors') IS NULL THEN
221
+ ALTER TABLE public.knowledge_graph_observation_cursors SET SCHEMA kg;
222
+ ALTER TABLE kg.knowledge_graph_observation_cursors RENAME TO observation_cursors;
223
+ END IF;
224
+
225
+ IF to_regclass('public.knowledge_graph_ingest_runs') IS NOT NULL
226
+ AND to_regclass('kg.ingest_runs') IS NULL THEN
227
+ ALTER TABLE public.knowledge_graph_ingest_runs SET SCHEMA kg;
228
+ ALTER TABLE kg.knowledge_graph_ingest_runs RENAME TO ingest_runs;
229
+ END IF;
230
+ END $$;
231
+
232
+ -- ── Rename CHECK constraints to drop the knowledge_graph_ prefix ────────
233
+ -- Drizzle's source names these after the (new) table stems; renaming keeps
234
+ -- the DB aligned with src/schema/knowledge-graph.ts.
235
+
236
+ DO $$
237
+ DECLARE
238
+ pair record;
239
+ BEGIN
240
+ FOR pair IN
241
+ SELECT * FROM (VALUES
242
+ ('kg.ingest_runs', 'knowledge_graph_ingest_runs_status_allowed', 'ingest_runs_status_allowed'),
243
+ ('kg.ingest_runs', 'knowledge_graph_ingest_runs_trigger_allowed', 'ingest_runs_trigger_allowed'),
244
+ ('kg.ingest_runs', 'knowledge_graph_ingest_runs_source_kind_allowed', 'ingest_runs_source_kind_allowed'),
245
+ ('kg.ingest_runs', 'knowledge_graph_ingest_runs_thread_scope_required', 'ingest_runs_thread_scope_required'),
246
+ ('kg.entities', 'knowledge_graph_entities_grounding_allowed', 'entities_grounding_allowed'),
247
+ ('kg.entities', 'knowledge_graph_entities_provenance_allowed', 'entities_provenance_allowed'),
248
+ ('kg.entities', 'knowledge_graph_entities_source_kind_allowed', 'entities_source_kind_allowed'),
249
+ ('kg.entities', 'knowledge_graph_entities_resolution_state_allowed', 'entities_resolution_state_allowed'),
250
+ ('kg.relationships', 'knowledge_graph_relationships_grounding_allowed', 'relationships_grounding_allowed'),
251
+ ('kg.relationships', 'knowledge_graph_relationships_provenance_allowed', 'relationships_provenance_allowed'),
252
+ ('kg.relationships', 'knowledge_graph_relationships_source_kind_allowed', 'relationships_source_kind_allowed'),
253
+ ('kg.evidence', 'knowledge_graph_evidence_source_kind_allowed', 'evidence_source_kind_allowed'),
254
+ ('kg.evidence', 'knowledge_graph_evidence_evidence_source_kind_allowed', 'evidence_evidence_source_kind_allowed'),
255
+ ('kg.evidence', 'knowledge_graph_evidence_subject_required', 'evidence_subject_required')
256
+ ) AS v(tbl, old_name, new_name)
257
+ LOOP
258
+ IF EXISTS (
259
+ SELECT 1 FROM pg_constraint
260
+ WHERE conrelid = to_regclass(pair.tbl) AND conname = pair.old_name
261
+ ) THEN
262
+ EXECUTE format('ALTER TABLE %s RENAME CONSTRAINT %I TO %I',
263
+ pair.tbl, pair.old_name, pair.new_name);
264
+ END IF;
265
+ END LOOP;
266
+ END $$;
267
+
268
+ -- ── Re-point scope-guard trigger functions at kg.* ─────────────────────
269
+ -- Bodies below are the 0146/0147 definitions with public.knowledge_graph_*
270
+ -- replaced by kg.* (and nothing else changed). CREATE OR REPLACE is
271
+ -- idempotent. Function and trigger names keep their original prefixes.
272
+
273
+ CREATE OR REPLACE FUNCTION public.enforce_knowledge_graph_entity_scope()
274
+ RETURNS trigger
275
+ LANGUAGE plpgsql
276
+ AS $$
277
+ DECLARE
278
+ run_tenant uuid;
279
+ run_thread uuid;
280
+ run_source_kind text;
281
+ run_source_ref text;
282
+ ontology_tenant uuid;
283
+ BEGIN
284
+ SELECT tenant_id, thread_id, source_kind, source_ref
285
+ INTO run_tenant, run_thread, run_source_kind, run_source_ref
286
+ FROM kg.ingest_runs
287
+ WHERE id = NEW.ingest_run_id;
288
+
289
+ IF run_tenant IS NOT NULL
290
+ AND (
291
+ run_tenant != NEW.tenant_id
292
+ OR run_thread IS DISTINCT FROM NEW.thread_id
293
+ OR run_source_kind != NEW.source_kind
294
+ OR run_source_ref != NEW.source_ref
295
+ ) THEN
296
+ RAISE EXCEPTION 'knowledge graph entity run scope mismatch for run %', NEW.ingest_run_id;
297
+ END IF;
298
+
299
+ IF NEW.ontology_entity_type_id IS NOT NULL THEN
300
+ SELECT tenant_id INTO ontology_tenant
301
+ FROM ontology.entity_types
302
+ WHERE id = NEW.ontology_entity_type_id;
303
+
304
+ IF ontology_tenant IS NOT NULL AND ontology_tenant != NEW.tenant_id THEN
305
+ RAISE EXCEPTION 'knowledge graph entity ontology tenant mismatch for entity type %', NEW.ontology_entity_type_id;
306
+ END IF;
307
+ END IF;
308
+
309
+ RETURN NEW;
310
+ END;
311
+ $$;
312
+
313
+ CREATE OR REPLACE FUNCTION public.enforce_knowledge_graph_relationship_scope()
314
+ RETURNS trigger
315
+ LANGUAGE plpgsql
316
+ AS $$
317
+ DECLARE
318
+ run_tenant uuid;
319
+ run_thread uuid;
320
+ run_source_kind text;
321
+ run_source_ref text;
322
+ source_tenant uuid;
323
+ source_thread uuid;
324
+ source_run uuid;
325
+ source_entity_kind text;
326
+ source_entity_ref text;
327
+ target_tenant uuid;
328
+ target_thread uuid;
329
+ target_run uuid;
330
+ target_kind text;
331
+ target_ref text;
332
+ ontology_tenant uuid;
333
+ BEGIN
334
+ SELECT
335
+ r.tenant_id,
336
+ r.thread_id,
337
+ r.source_kind,
338
+ r.source_ref
339
+ INTO run_tenant, run_thread, run_source_kind, run_source_ref
340
+ FROM kg.ingest_runs AS r
341
+ WHERE r.id = NEW.ingest_run_id;
342
+
343
+ IF run_tenant IS NOT NULL
344
+ AND (
345
+ run_tenant != NEW.tenant_id
346
+ OR run_thread IS DISTINCT FROM NEW.thread_id
347
+ OR run_source_kind != NEW.source_kind
348
+ OR run_source_ref != NEW.source_ref
349
+ ) THEN
350
+ RAISE EXCEPTION 'knowledge graph relationship run scope mismatch for run %', NEW.ingest_run_id;
351
+ END IF;
352
+
353
+ SELECT
354
+ e.tenant_id,
355
+ e.thread_id,
356
+ e.ingest_run_id,
357
+ e.source_kind,
358
+ e.source_ref
359
+ INTO source_tenant, source_thread, source_run, source_entity_kind, source_entity_ref
360
+ FROM kg.entities AS e
361
+ WHERE e.id = NEW.source_entity_id;
362
+
363
+ SELECT
364
+ e.tenant_id,
365
+ e.thread_id,
366
+ e.ingest_run_id,
367
+ e.source_kind,
368
+ e.source_ref
369
+ INTO target_tenant, target_thread, target_run, target_kind, target_ref
370
+ FROM kg.entities AS e
371
+ WHERE e.id = NEW.target_entity_id;
372
+
373
+ IF source_tenant IS NOT NULL
374
+ AND (
375
+ source_tenant != NEW.tenant_id
376
+ OR source_thread IS DISTINCT FROM NEW.thread_id
377
+ OR source_run != NEW.ingest_run_id
378
+ OR source_entity_kind != NEW.source_kind
379
+ OR source_entity_ref != NEW.source_ref
380
+ ) THEN
381
+ RAISE EXCEPTION 'knowledge graph relationship source scope mismatch for entity %', NEW.source_entity_id;
382
+ END IF;
383
+
384
+ IF target_tenant IS NOT NULL
385
+ AND (
386
+ target_tenant != NEW.tenant_id
387
+ OR target_thread IS DISTINCT FROM NEW.thread_id
388
+ OR target_run != NEW.ingest_run_id
389
+ OR target_kind != NEW.source_kind
390
+ OR target_ref != NEW.source_ref
391
+ ) THEN
392
+ RAISE EXCEPTION 'knowledge graph relationship target scope mismatch for entity %', NEW.target_entity_id;
393
+ END IF;
394
+
395
+ IF NEW.ontology_relationship_type_id IS NOT NULL THEN
396
+ SELECT rt.tenant_id INTO ontology_tenant
397
+ FROM ontology.relationship_types AS rt
398
+ WHERE rt.id = NEW.ontology_relationship_type_id;
399
+
400
+ IF ontology_tenant IS NOT NULL AND ontology_tenant != NEW.tenant_id THEN
401
+ RAISE EXCEPTION 'knowledge graph relationship ontology tenant mismatch for relationship type %', NEW.ontology_relationship_type_id;
402
+ END IF;
403
+ END IF;
404
+
405
+ RETURN NEW;
406
+ END;
407
+ $$;
408
+
409
+ CREATE OR REPLACE FUNCTION public.enforce_knowledge_graph_evidence_scope()
410
+ RETURNS trigger
411
+ LANGUAGE plpgsql
412
+ AS $$
413
+ DECLARE
414
+ run_tenant uuid;
415
+ run_thread uuid;
416
+ run_source_kind text;
417
+ run_source_ref text;
418
+ entity_tenant uuid;
419
+ entity_thread uuid;
420
+ entity_run uuid;
421
+ entity_kind text;
422
+ entity_ref text;
423
+ relationship_tenant uuid;
424
+ relationship_thread uuid;
425
+ relationship_run uuid;
426
+ relationship_kind text;
427
+ relationship_ref text;
428
+ message_tenant uuid;
429
+ message_thread uuid;
430
+ BEGIN
431
+ SELECT
432
+ r.tenant_id,
433
+ r.thread_id,
434
+ r.source_kind,
435
+ r.source_ref
436
+ INTO run_tenant, run_thread, run_source_kind, run_source_ref
437
+ FROM kg.ingest_runs AS r
438
+ WHERE r.id = NEW.ingest_run_id;
439
+
440
+ IF run_tenant IS NOT NULL
441
+ AND (
442
+ run_tenant != NEW.tenant_id
443
+ OR run_thread IS DISTINCT FROM NEW.thread_id
444
+ OR run_source_kind != NEW.source_kind
445
+ OR run_source_ref != NEW.source_ref
446
+ ) THEN
447
+ RAISE EXCEPTION 'knowledge graph evidence run scope mismatch for run %', NEW.ingest_run_id;
448
+ END IF;
449
+
450
+ IF NEW.entity_id IS NOT NULL THEN
451
+ SELECT
452
+ e.tenant_id,
453
+ e.thread_id,
454
+ e.ingest_run_id,
455
+ e.source_kind,
456
+ e.source_ref
457
+ INTO entity_tenant, entity_thread, entity_run, entity_kind, entity_ref
458
+ FROM kg.entities AS e
459
+ WHERE e.id = NEW.entity_id;
460
+
461
+ IF entity_tenant IS NOT NULL
462
+ AND (
463
+ entity_tenant != NEW.tenant_id
464
+ OR entity_thread IS DISTINCT FROM NEW.thread_id
465
+ OR entity_run != NEW.ingest_run_id
466
+ OR entity_kind != NEW.source_kind
467
+ OR entity_ref != NEW.source_ref
468
+ ) THEN
469
+ RAISE EXCEPTION 'knowledge graph evidence entity scope mismatch for entity %', NEW.entity_id;
470
+ END IF;
471
+ END IF;
472
+
473
+ IF NEW.relationship_id IS NOT NULL THEN
474
+ SELECT
475
+ r.tenant_id,
476
+ r.thread_id,
477
+ r.ingest_run_id,
478
+ r.source_kind,
479
+ r.source_ref
480
+ INTO relationship_tenant, relationship_thread, relationship_run, relationship_kind, relationship_ref
481
+ FROM kg.relationships AS r
482
+ WHERE r.id = NEW.relationship_id;
483
+
484
+ IF relationship_tenant IS NOT NULL
485
+ AND (
486
+ relationship_tenant != NEW.tenant_id
487
+ OR relationship_thread IS DISTINCT FROM NEW.thread_id
488
+ OR relationship_run != NEW.ingest_run_id
489
+ OR relationship_kind != NEW.source_kind
490
+ OR relationship_ref != NEW.source_ref
491
+ ) THEN
492
+ RAISE EXCEPTION 'knowledge graph evidence relationship scope mismatch for relationship %', NEW.relationship_id;
493
+ END IF;
494
+ END IF;
495
+
496
+ IF NEW.message_id IS NOT NULL THEN
497
+ SELECT m.tenant_id, m.thread_id INTO message_tenant, message_thread
498
+ FROM public.messages AS m
499
+ WHERE m.id = NEW.message_id;
500
+
501
+ IF message_tenant IS NOT NULL
502
+ AND (
503
+ message_tenant != NEW.tenant_id
504
+ OR message_thread IS DISTINCT FROM NEW.thread_id
505
+ ) THEN
506
+ RAISE EXCEPTION 'knowledge graph evidence message scope mismatch for message %', NEW.message_id;
507
+ END IF;
508
+ END IF;
509
+
510
+ RETURN NEW;
511
+ END;
512
+ $$;
513
+
514
+ -- ── Compat views in public.* ────────────────────────────────────────────
515
+ -- Old bundled Lambda code references public.knowledge_graph_*. Views are
516
+ -- column-enumerated per the plan's R6 (none of the five tables has a
517
+ -- generated column, so the enumeration is a stability guard, not a
518
+ -- workaround). Simple single-table views are auto-updatable, but the
519
+ -- ON CONFLICT writers are paused during the window regardless — views
520
+ -- reject ON CONFLICT at parse time. The U4 PR drops these.
521
+
522
+ DO $$
523
+ BEGIN
524
+ IF to_regclass('public.knowledge_graph_ingest_runs') IS NULL THEN
525
+ CREATE VIEW public.knowledge_graph_ingest_runs AS
526
+ SELECT id, tenant_id, thread_id, source_kind, source_ref, source_label,
527
+ requested_by_user_id, status, trigger, source_dataset_name,
528
+ source_dataset_id, started_at, finished_at, duration_ms, error,
529
+ entity_count, relationship_count, evidence_count,
530
+ diagnostic_count, message_count, input, metrics, metadata,
531
+ created_at, updated_at
532
+ FROM kg.ingest_runs;
533
+ END IF;
534
+
535
+ IF to_regclass('public.knowledge_graph_entities') IS NULL THEN
536
+ CREATE VIEW public.knowledge_graph_entities AS
537
+ SELECT id, tenant_id, thread_id, source_kind, source_ref,
538
+ ingest_run_id, graph_node_id, label, normalized_label,
539
+ type_label, ontology_entity_type_id, ontology_type_slug,
540
+ canonical_entity_id, resolution_state, grounding_status,
541
+ provenance_status, summary, aliases, properties, diagnostics,
542
+ relationship_count, evidence_count, last_seen_at, created_at,
543
+ updated_at
544
+ FROM kg.entities;
545
+ END IF;
546
+
547
+ IF to_regclass('public.knowledge_graph_relationships') IS NULL THEN
548
+ CREATE VIEW public.knowledge_graph_relationships AS
549
+ SELECT id, tenant_id, thread_id, source_kind, source_ref,
550
+ ingest_run_id, graph_edge_id, source_entity_id,
551
+ target_entity_id, label, ontology_relationship_type_id,
552
+ ontology_type_slug, grounding_status, provenance_status,
553
+ confidence, properties, diagnostics, evidence_count,
554
+ last_seen_at, created_at, updated_at
555
+ FROM kg.relationships;
556
+ END IF;
557
+
558
+ IF to_regclass('public.knowledge_graph_evidence') IS NULL THEN
559
+ CREATE VIEW public.knowledge_graph_evidence AS
560
+ SELECT id, tenant_id, thread_id, source_kind, source_ref,
561
+ ingest_run_id, entity_id, relationship_id, message_id,
562
+ message_role, message_created_at, speaker_label, snippet,
563
+ char_start, char_end, evidence_source_kind,
564
+ evidence_source_ref, metadata, observed_at, created_at
565
+ FROM kg.evidence;
566
+ END IF;
567
+
568
+ IF to_regclass('public.knowledge_graph_observation_cursors') IS NULL THEN
569
+ CREATE VIEW public.knowledge_graph_observation_cursors AS
570
+ SELECT tenant_id, bank_id, last_record_updated_at, last_record_id,
571
+ updated_at
572
+ FROM kg.observation_cursors;
573
+ END IF;
574
+ END $$;
575
+
576
+ COMMIT;
@@ -0,0 +1,25 @@
1
+ -- THINK-291: promote json-render-ui (emit_json_render_ui generated UI) from a
2
+ -- hidden agent_capabilities row to a standard platform-tool opt-in column on
3
+ -- agents, matching sandbox/browser/web_search/web_extract/send_email/
4
+ -- context_engine. Default-on so charts and rich result chunks work out of the
5
+ -- box on greenfield stages (the legacy row was unseeded and invisible).
6
+ --
7
+ -- The runtime cutover in the same PR reads this column and retires the
8
+ -- agent_capabilities 'thread-json-render-ui' read; existing agents inherit
9
+ -- enabled-on via the UPDATE below unless a legacy row explicitly disabled the
10
+ -- capability.
11
+ --
12
+ -- creates-column: public.agents.json_render_ui
13
+
14
+ ALTER TABLE public.agents
15
+ ADD COLUMN IF NOT EXISTS json_render_ui jsonb DEFAULT '{"enabled": true}'::jsonb;
16
+
17
+ -- Legacy carry-over: an agent whose capability row was explicitly disabled
18
+ -- stays disabled (ADD COLUMN already filled every existing row with the
19
+ -- enabled default).
20
+ UPDATE public.agents a
21
+ SET json_render_ui = '{"enabled": false}'::jsonb
22
+ FROM public.agent_capabilities c
23
+ WHERE c.agent_id = a.id
24
+ AND c.capability = 'thread-json-render-ui'
25
+ AND c.enabled = false;