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,257 @@
1
+ -- THINK-193 U4: canonical entity identity.
2
+ -- Contents:
3
+ -- * identity.* schema (greenfield pgSchema per the feature-schema
4
+ -- extraction pattern — no compat views needed for new tables):
5
+ -- - identity.canonical_entities — stable instance registry with
6
+ -- merged-redirect invariant CHECK.
7
+ -- - identity.entity_source_mappings — exact mapping wins; unique per
8
+ -- (tenant, source_system, namespace, external_id).
9
+ -- - identity.entity_identity_claims — natural-key evidence; plain
10
+ -- lookup index (per-rule uniqueness enforced in the matcher).
11
+ -- - identity.entity_resolution_cases — operator ambiguity queue;
12
+ -- partial unique coalesces open cases by signature.
13
+ -- - identity.entity_resolution_events — append-only audit (no split).
14
+ -- * knowledge_graph_entities.canonical_entity_id + resolution_state.
15
+ -- * wiki.pages.canonical_entity_id + partial unique for tenant Entity pages.
16
+ -- * ontology.entity_types.identity_rules + identity_rules_version.
17
+ -- * memory_claims.canonical_subject_id FK (column landed in 0234).
18
+ --
19
+ -- Hand-rolled (drizzle meta journal is not in use for this change);
20
+ -- apply with: psql "$DATABASE_URL" -f drizzle/0239_canonical_entity_identity.sql
21
+ -- creates: identity.canonical_entities
22
+ -- creates: identity.entity_source_mappings
23
+ -- creates: identity.entity_identity_claims
24
+ -- creates: identity.entity_resolution_cases
25
+ -- creates: identity.entity_resolution_events
26
+ -- creates: identity.uq_entity_source_mappings_source_identity
27
+ -- creates: identity.uq_entity_resolution_cases_open_signature
28
+ -- creates-column: public.knowledge_graph_entities.canonical_entity_id
29
+ -- creates-column: public.knowledge_graph_entities.resolution_state
30
+ -- creates-column: wiki.pages.canonical_entity_id
31
+ -- creates-column: ontology.entity_types.identity_rules
32
+ -- creates-column: ontology.entity_types.identity_rules_version
33
+ -- creates: public.idx_kg_entities_tenant_canonical
34
+ -- creates: wiki.uq_pages_tenant_canonical_entity
35
+ -- creates-constraint: public.knowledge_graph_entities.knowledge_graph_entities_resolution_state_allowed
36
+ -- creates-constraint: public.memory_claims.memory_claims_canonical_subject_id_fk
37
+
38
+ \set ON_ERROR_STOP on
39
+
40
+ BEGIN;
41
+
42
+ SELECT pg_advisory_xact_lock(hashtext('canonical_entity_identity_0239'));
43
+
44
+ SET LOCAL lock_timeout = '5s';
45
+ SET LOCAL statement_timeout = '60s';
46
+
47
+ CREATE SCHEMA IF NOT EXISTS identity;
48
+ COMMENT ON SCHEMA identity IS
49
+ 'Canonical entity instance registry (THINK-193 U4): mappings, natural-key claims, and operator resolution queue.';
50
+
51
+ -- ---------------------------------------------------------------------------
52
+ -- identity.canonical_entities
53
+ -- ---------------------------------------------------------------------------
54
+
55
+ CREATE TABLE IF NOT EXISTS identity.canonical_entities (
56
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
57
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
58
+ entity_type_slug text NOT NULL,
59
+ display_name text NOT NULL,
60
+ normalized_name text NOT NULL,
61
+ status text NOT NULL DEFAULT 'active',
62
+ merged_into_id uuid REFERENCES identity.canonical_entities(id) ON DELETE SET NULL,
63
+ version integer NOT NULL DEFAULT 1,
64
+ created_at timestamptz NOT NULL DEFAULT now(),
65
+ updated_at timestamptz NOT NULL DEFAULT now(),
66
+ CONSTRAINT canonical_entities_status_allowed
67
+ CHECK (status IN ('active','merged','archived')),
68
+ CONSTRAINT canonical_entities_merged_redirect_required
69
+ CHECK ((status = 'merged') = (merged_into_id IS NOT NULL))
70
+ );
71
+
72
+ CREATE INDEX IF NOT EXISTS idx_canonical_entities_tenant_status
73
+ ON identity.canonical_entities (tenant_id, status);
74
+
75
+ CREATE INDEX IF NOT EXISTS idx_canonical_entities_tenant_type_name
76
+ ON identity.canonical_entities (tenant_id, entity_type_slug, normalized_name);
77
+
78
+ -- ---------------------------------------------------------------------------
79
+ -- identity.entity_source_mappings
80
+ -- ---------------------------------------------------------------------------
81
+
82
+ CREATE TABLE IF NOT EXISTS identity.entity_source_mappings (
83
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
84
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
85
+ canonical_entity_id uuid NOT NULL
86
+ REFERENCES identity.canonical_entities(id) ON DELETE CASCADE,
87
+ source_system text NOT NULL,
88
+ namespace text NOT NULL DEFAULT '',
89
+ external_id text NOT NULL,
90
+ visibility text NOT NULL DEFAULT 'tenant',
91
+ created_by text NOT NULL,
92
+ created_at timestamptz NOT NULL DEFAULT now(),
93
+ CONSTRAINT entity_source_mappings_visibility_allowed
94
+ CHECK (visibility IN ('tenant','private')),
95
+ CONSTRAINT entity_source_mappings_created_by_allowed
96
+ CHECK (created_by IN ('rule','operator','backfill'))
97
+ );
98
+
99
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_entity_source_mappings_source_identity
100
+ ON identity.entity_source_mappings (tenant_id, source_system, namespace, external_id);
101
+
102
+ CREATE INDEX IF NOT EXISTS idx_entity_source_mappings_canonical
103
+ ON identity.entity_source_mappings (canonical_entity_id);
104
+
105
+ -- ---------------------------------------------------------------------------
106
+ -- identity.entity_identity_claims
107
+ -- ---------------------------------------------------------------------------
108
+
109
+ CREATE TABLE IF NOT EXISTS identity.entity_identity_claims (
110
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
111
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
112
+ canonical_entity_id uuid NOT NULL
113
+ REFERENCES identity.canonical_entities(id) ON DELETE CASCADE,
114
+ rule_slug text NOT NULL,
115
+ rule_version integer NOT NULL DEFAULT 1,
116
+ key_kind text NOT NULL,
117
+ normalized_value text NOT NULL,
118
+ value_hash text NOT NULL,
119
+ confidence numeric(5,4),
120
+ precedence integer NOT NULL DEFAULT 0,
121
+ visibility text NOT NULL DEFAULT 'tenant',
122
+ state text NOT NULL DEFAULT 'active',
123
+ evidence jsonb NOT NULL DEFAULT '{}'::jsonb,
124
+ created_at timestamptz NOT NULL DEFAULT now(),
125
+ updated_at timestamptz NOT NULL DEFAULT now(),
126
+ CONSTRAINT entity_identity_claims_visibility_allowed
127
+ CHECK (visibility IN ('tenant','private')),
128
+ CONSTRAINT entity_identity_claims_state_allowed
129
+ CHECK (state IN ('active','superseded','rejected'))
130
+ );
131
+
132
+ -- Plain lookup index: per-rule uniqueness scope is enforced by the matcher
133
+ -- against the approved rule's `unique` flag, not one global unique index.
134
+ CREATE INDEX IF NOT EXISTS idx_entity_identity_claims_lookup
135
+ ON identity.entity_identity_claims (tenant_id, key_kind, value_hash);
136
+
137
+ CREATE INDEX IF NOT EXISTS idx_entity_identity_claims_canonical
138
+ ON identity.entity_identity_claims (canonical_entity_id);
139
+
140
+ -- ---------------------------------------------------------------------------
141
+ -- identity.entity_resolution_cases
142
+ -- ---------------------------------------------------------------------------
143
+
144
+ CREATE TABLE IF NOT EXISTS identity.entity_resolution_cases (
145
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
146
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
147
+ signature_hash text NOT NULL,
148
+ entity_type_slug text NOT NULL,
149
+ display_hint text,
150
+ candidates jsonb NOT NULL DEFAULT '[]'::jsonb,
151
+ conflicting_claims jsonb NOT NULL DEFAULT '[]'::jsonb,
152
+ impact_summary jsonb NOT NULL DEFAULT '{}'::jsonb,
153
+ item_count integer NOT NULL DEFAULT 1,
154
+ status text NOT NULL DEFAULT 'open',
155
+ decision text,
156
+ decided_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
157
+ resolved_canonical_entity_id uuid
158
+ REFERENCES identity.canonical_entities(id) ON DELETE SET NULL,
159
+ decided_at timestamptz,
160
+ created_at timestamptz NOT NULL DEFAULT now(),
161
+ updated_at timestamptz NOT NULL DEFAULT now(),
162
+ CONSTRAINT entity_resolution_cases_status_allowed
163
+ CHECK (status IN ('open','resolved','expired')),
164
+ CONSTRAINT entity_resolution_cases_decision_allowed
165
+ CHECK (decision IS NULL OR decision IN ('link','create','defer','reject','merge'))
166
+ );
167
+
168
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_entity_resolution_cases_open_signature
169
+ ON identity.entity_resolution_cases (tenant_id, signature_hash)
170
+ WHERE status = 'open';
171
+
172
+ CREATE INDEX IF NOT EXISTS idx_entity_resolution_cases_tenant_status_created
173
+ ON identity.entity_resolution_cases (tenant_id, status, created_at);
174
+
175
+ -- ---------------------------------------------------------------------------
176
+ -- identity.entity_resolution_events — append-only audit
177
+ -- ---------------------------------------------------------------------------
178
+
179
+ CREATE TABLE IF NOT EXISTS identity.entity_resolution_events (
180
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
181
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
182
+ case_id uuid REFERENCES identity.entity_resolution_cases(id) ON DELETE SET NULL,
183
+ canonical_entity_id uuid
184
+ REFERENCES identity.canonical_entities(id) ON DELETE SET NULL,
185
+ event_type text NOT NULL,
186
+ actor_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
187
+ payload jsonb NOT NULL DEFAULT '{}'::jsonb,
188
+ created_at timestamptz NOT NULL DEFAULT now(),
189
+ CONSTRAINT entity_resolution_events_type_allowed
190
+ CHECK (event_type IN ('create','link','defer','reject','merge'))
191
+ );
192
+
193
+ CREATE INDEX IF NOT EXISTS idx_entity_resolution_events_tenant_created
194
+ ON identity.entity_resolution_events (tenant_id, created_at);
195
+
196
+ CREATE INDEX IF NOT EXISTS idx_entity_resolution_events_case
197
+ ON identity.entity_resolution_events (case_id);
198
+
199
+ -- ---------------------------------------------------------------------------
200
+ -- Projection columns
201
+ -- ---------------------------------------------------------------------------
202
+
203
+ ALTER TABLE public.knowledge_graph_entities
204
+ ADD COLUMN IF NOT EXISTS canonical_entity_id uuid
205
+ REFERENCES identity.canonical_entities(id) ON DELETE SET NULL;
206
+
207
+ ALTER TABLE public.knowledge_graph_entities
208
+ ADD COLUMN IF NOT EXISTS resolution_state text NOT NULL DEFAULT 'legacy';
209
+
210
+ DO $$
211
+ BEGIN
212
+ IF NOT EXISTS (
213
+ SELECT 1 FROM pg_constraint
214
+ WHERE conname = 'knowledge_graph_entities_resolution_state_allowed'
215
+ AND conrelid = 'public.knowledge_graph_entities'::regclass
216
+ ) THEN
217
+ ALTER TABLE public.knowledge_graph_entities
218
+ ADD CONSTRAINT knowledge_graph_entities_resolution_state_allowed
219
+ CHECK (resolution_state IN ('resolved','deferred','private','legacy'));
220
+ END IF;
221
+ END $$;
222
+
223
+ CREATE INDEX IF NOT EXISTS idx_kg_entities_tenant_canonical
224
+ ON public.knowledge_graph_entities (tenant_id, canonical_entity_id)
225
+ WHERE canonical_entity_id IS NOT NULL;
226
+
227
+ ALTER TABLE wiki.pages
228
+ ADD COLUMN IF NOT EXISTS canonical_entity_id uuid
229
+ REFERENCES identity.canonical_entities(id) ON DELETE SET NULL;
230
+
231
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_pages_tenant_canonical_entity
232
+ ON wiki.pages (tenant_id, canonical_entity_id)
233
+ WHERE owner_id IS NULL AND canonical_entity_id IS NOT NULL AND type = 'entity';
234
+
235
+ ALTER TABLE ontology.entity_types
236
+ ADD COLUMN IF NOT EXISTS identity_rules jsonb NOT NULL DEFAULT '[]'::jsonb;
237
+
238
+ ALTER TABLE ontology.entity_types
239
+ ADD COLUMN IF NOT EXISTS identity_rules_version integer NOT NULL DEFAULT 0;
240
+
241
+ -- memory_claims.canonical_subject_id landed as a bare uuid in 0234; the
242
+ -- identity registry now exists, so wire the FK.
243
+ DO $$
244
+ BEGIN
245
+ IF NOT EXISTS (
246
+ SELECT 1 FROM pg_constraint
247
+ WHERE conname = 'memory_claims_canonical_subject_id_fk'
248
+ AND conrelid = 'public.memory_claims'::regclass
249
+ ) THEN
250
+ ALTER TABLE public.memory_claims
251
+ ADD CONSTRAINT memory_claims_canonical_subject_id_fk
252
+ FOREIGN KEY (canonical_subject_id)
253
+ REFERENCES identity.canonical_entities(id) ON DELETE SET NULL;
254
+ END IF;
255
+ END $$;
256
+
257
+ COMMIT;
@@ -0,0 +1,45 @@
1
+ -- THINK-193 U6: personal (user-scoped) external-memory evidence + claims.
2
+ -- The Gmail email tracer writes evidence and claims into the owner's User
3
+ -- Bank (target_scope 'user'); the U1/U2 CHECK constraints only allowed the
4
+ -- shared scopes. Replace both constraints with _v2 versions that include
5
+ -- 'user'. Shared-only surfaces stay guarded in code (SharedTargetScope,
6
+ -- graph/wiki hard-reject user_* banks).
7
+ --
8
+ -- Hand-rolled (drizzle meta journal is not in use for this change);
9
+ -- apply with: psql "$DATABASE_URL" -f drizzle/0240_memory_personal_scope.sql
10
+ -- creates-constraint: public.memory_evidence_items.memory_evidence_items_target_scope_check_v2
11
+ -- drops-constraint: public.memory_evidence_items.memory_evidence_items_target_scope_check
12
+ -- creates-constraint: public.memory_claims.memory_claims_target_scope_check_v2
13
+ -- drops-constraint: public.memory_claims.memory_claims_target_scope_check
14
+
15
+ ALTER TABLE public.memory_evidence_items
16
+ DROP CONSTRAINT IF EXISTS memory_evidence_items_target_scope_check;
17
+
18
+ DO $$
19
+ BEGIN
20
+ IF NOT EXISTS (
21
+ SELECT 1 FROM pg_constraint
22
+ WHERE conname = 'memory_evidence_items_target_scope_check_v2'
23
+ AND conrelid = 'public.memory_evidence_items'::regclass
24
+ ) THEN
25
+ ALTER TABLE public.memory_evidence_items
26
+ ADD CONSTRAINT memory_evidence_items_target_scope_check_v2
27
+ CHECK (target_scope IN ('user', 'space', 'tenant'));
28
+ END IF;
29
+ END $$;
30
+
31
+ ALTER TABLE public.memory_claims
32
+ DROP CONSTRAINT IF EXISTS memory_claims_target_scope_check;
33
+
34
+ DO $$
35
+ BEGIN
36
+ IF NOT EXISTS (
37
+ SELECT 1 FROM pg_constraint
38
+ WHERE conname = 'memory_claims_target_scope_check_v2'
39
+ AND conrelid = 'public.memory_claims'::regclass
40
+ ) THEN
41
+ ALTER TABLE public.memory_claims
42
+ ADD CONSTRAINT memory_claims_target_scope_check_v2
43
+ CHECK (target_scope IN ('user', 'space', 'tenant'));
44
+ END IF;
45
+ END $$;
@@ -0,0 +1,67 @@
1
+ -- THINK-193 U7: Bedrock Knowledge Base document-projection manifest.
2
+ -- Contents:
3
+ -- * public.knowledge_base_documents — ONE row per (knowledge_base_id,
4
+ -- data_source_id, document_key). The row id is the document's stable
5
+ -- manifest identity across editions; `edition` increments on etag/content
6
+ -- change; effective_to closes only at verified deletion
7
+ -- (ingest_status 'absent_verified'). Edition history lives in
8
+ -- memory_evidence_items.source_version (edition + content hash).
9
+ -- * uq_kb_documents_identity — the manifest key.
10
+ -- * idx_kb_documents_kb_updated — the bedrock_kb adapter's acquisition
11
+ -- cursor (changed editions since (updated_at, id)).
12
+ -- * idx_kb_documents_kb_ingest_status — settlement scan for 'deleting'.
13
+ --
14
+ -- Hand-rolled (drizzle meta journal is not in use for this change);
15
+ -- apply with: psql "$DATABASE_URL" -f drizzle/0241_knowledge_base_document_manifest.sql
16
+ -- creates: public.knowledge_base_documents
17
+ -- creates: public.uq_kb_documents_identity
18
+ -- creates: public.idx_kb_documents_tenant
19
+ -- creates: public.idx_kb_documents_kb_updated
20
+ -- creates: public.idx_kb_documents_kb_ingest_status
21
+ -- creates-constraint: public.knowledge_base_documents.knowledge_base_documents_ingest_status_check
22
+ -- creates-constraint: public.knowledge_base_documents.knowledge_base_documents_projection_status_check
23
+ -- creates-constraint: public.knowledge_base_documents.knowledge_base_documents_edition_positive
24
+
25
+ \set ON_ERROR_STOP on
26
+
27
+ BEGIN;
28
+
29
+ CREATE TABLE IF NOT EXISTS public.knowledge_base_documents (
30
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
31
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id),
32
+ knowledge_base_id uuid NOT NULL REFERENCES public.knowledge_bases(id) ON DELETE CASCADE,
33
+ data_source_id text NOT NULL,
34
+ document_key text NOT NULL,
35
+ s3_version_id text,
36
+ etag text,
37
+ content_hash text,
38
+ edition integer NOT NULL DEFAULT 1,
39
+ effective_from timestamptz,
40
+ effective_to timestamptz,
41
+ ingest_status text NOT NULL DEFAULT 'pending',
42
+ projection_status text NOT NULL DEFAULT 'pending',
43
+ last_error text,
44
+ created_at timestamptz NOT NULL DEFAULT now(),
45
+ updated_at timestamptz NOT NULL DEFAULT now(),
46
+ CONSTRAINT knowledge_base_documents_ingest_status_check CHECK (
47
+ ingest_status IN ('pending', 'ingesting', 'indexed', 'failed', 'deleting', 'absent_verified')
48
+ ),
49
+ CONSTRAINT knowledge_base_documents_projection_status_check CHECK (
50
+ projection_status IN ('pending', 'projected', 'skipped', 'failed', 'retracting', 'retracted')
51
+ ),
52
+ CONSTRAINT knowledge_base_documents_edition_positive CHECK (edition >= 1)
53
+ );
54
+
55
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_kb_documents_identity
56
+ ON public.knowledge_base_documents (knowledge_base_id, data_source_id, document_key);
57
+
58
+ CREATE INDEX IF NOT EXISTS idx_kb_documents_tenant
59
+ ON public.knowledge_base_documents (tenant_id);
60
+
61
+ CREATE INDEX IF NOT EXISTS idx_kb_documents_kb_updated
62
+ ON public.knowledge_base_documents (knowledge_base_id, updated_at, id);
63
+
64
+ CREATE INDEX IF NOT EXISTS idx_kb_documents_kb_ingest_status
65
+ ON public.knowledge_base_documents (knowledge_base_id, ingest_status);
66
+
67
+ COMMIT;
@@ -0,0 +1,28 @@
1
+ -- THINK-263 R15/KTD-8: search-query telemetry (the flywheel sensor).
2
+ -- One append-only row per broker query with per-leg hit counts and statuses.
3
+ -- Raw query text is retained as the future wiki-compile demand-queue input;
4
+ -- retention policy: rows older than 180 days are eligible for deletion
5
+ -- (operational sweep, not enforced in-schema). Operator read paths must be
6
+ -- tenant-scoped. Additive — safe to apply ahead of code deploy.
7
+ --
8
+ -- Hand-rolled (drizzle meta journal is not in use for this change);
9
+ -- apply with: psql "$DATABASE_URL" -f drizzle/0242_search_queries.sql
10
+ -- creates: public.search_queries
11
+
12
+ CREATE TABLE IF NOT EXISTS public.search_queries (
13
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
14
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
15
+ user_id uuid,
16
+ query_id uuid,
17
+ query_text text NOT NULL,
18
+ sources jsonb NOT NULL,
19
+ leg_hit_counts jsonb NOT NULL,
20
+ leg_statuses jsonb NOT NULL,
21
+ total_hits integer NOT NULL DEFAULT 0,
22
+ escalated boolean NOT NULL DEFAULT false,
23
+ duration_ms integer,
24
+ created_at timestamptz NOT NULL DEFAULT now()
25
+ );
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_search_queries_tenant_created
28
+ ON public.search_queries (tenant_id, created_at DESC);
@@ -0,0 +1,12 @@
1
+ -- THINK-263 U2/R14: thread backpointers on wiki section provenance.
2
+ -- Nullable text[] stamped at compile time from cited memory records'
3
+ -- provenance (U1 write-time stamps); backfilled for historical rows by
4
+ -- packages/api/scripts/backfill-section-source-thread-refs.mts. Additive — safe to apply
5
+ -- ahead of code deploy.
6
+ --
7
+ -- Hand-rolled (drizzle meta journal is not in use for this change);
8
+ -- apply with: psql "$DATABASE_URL" -f drizzle/0243_section_sources_thread_refs.sql
9
+ -- creates-column: wiki.section_sources.source_thread_ids
10
+
11
+ ALTER TABLE wiki.section_sources
12
+ ADD COLUMN IF NOT EXISTS source_thread_ids text[];
@@ -0,0 +1,45 @@
1
+ -- THINK-264: Personal Memory Processing becomes a first-class system Automation.
2
+ --
3
+ -- Two independent additions:
4
+ --
5
+ -- 1. agent_loops.kind / .system_key — platform-provisioned Automations. A
6
+ -- `system` row renders in the Automations inventory like any other, can be
7
+ -- enabled/disabled, but is never hand-created and never deletable. The
8
+ -- partial unique index makes ensure-on-read provisioning idempotent under
9
+ -- concurrency (two parallel reads cannot mint two personal-memory loops).
10
+ --
11
+ -- 2. memory_processor_configs.stage_overrides — per-stage toggles for the
12
+ -- optional tail of the memory pipeline (compound/graph/wiki). The
13
+ -- acquire → project → resolve → retain spine is deliberately NOT
14
+ -- disableable; see the app-side TOGGLEABLE_MEMORY_STAGES allowlist, which
15
+ -- is the enforcement point. This column only stores intent.
16
+ --
17
+ -- Hand-rolled (partial unique index + CHECKs); not in meta/_journal.json.
18
+ --
19
+ -- creates-column: public.agent_loops.kind
20
+ -- creates-column: public.agent_loops.system_key
21
+ -- creates-column: public.memory_processor_configs.stage_overrides
22
+ -- creates: public.agent_loops_system_owner_uidx
23
+
24
+ ALTER TABLE public.agent_loops
25
+ ADD COLUMN IF NOT EXISTS kind text NOT NULL DEFAULT 'user',
26
+ ADD COLUMN IF NOT EXISTS system_key text;
27
+
28
+ ALTER TABLE public.agent_loops
29
+ DROP CONSTRAINT IF EXISTS agent_loops_kind_check;
30
+ ALTER TABLE public.agent_loops
31
+ ADD CONSTRAINT agent_loops_kind_check CHECK (kind IN ('user', 'system'));
32
+
33
+ -- A system row is exactly identified by its key; a user row must not carry one.
34
+ ALTER TABLE public.agent_loops
35
+ DROP CONSTRAINT IF EXISTS agent_loops_system_key_check;
36
+ ALTER TABLE public.agent_loops
37
+ ADD CONSTRAINT agent_loops_system_key_check
38
+ CHECK ((kind = 'system') = (system_key IS NOT NULL));
39
+
40
+ CREATE UNIQUE INDEX IF NOT EXISTS agent_loops_system_owner_uidx
41
+ ON public.agent_loops (tenant_id, system_key, owner_user_id)
42
+ WHERE system_key IS NOT NULL;
43
+
44
+ ALTER TABLE public.memory_processor_configs
45
+ ADD COLUMN IF NOT EXISTS stage_overrides jsonb NOT NULL DEFAULT '{}'::jsonb;
@@ -0,0 +1,21 @@
1
+ -- THINK-273 (THINK-270 U2): persisted wiki page plate renders.
2
+ -- Nullable render columns on wiki.pages: the compositor-produced
3
+ -- self-contained HTML plate render, the plate slug it was compiled with,
4
+ -- and the render timestamp. Best-effort — all three are set together or
5
+ -- all NULL (compile failure, oversize output, or a page that predates
6
+ -- render persistence). Additive — safe to apply ahead of code deploy.
7
+ --
8
+ -- Hand-rolled (drizzle meta journal is not in use for this change);
9
+ -- apply with: psql "$DATABASE_URL" -f drizzle/0245_wiki_page_render.sql
10
+ -- creates-column: wiki.pages.render_html
11
+ -- creates-column: wiki.pages.render_plate_slug
12
+ -- creates-column: wiki.pages.rendered_at
13
+
14
+ BEGIN;
15
+
16
+ ALTER TABLE wiki.pages
17
+ ADD COLUMN IF NOT EXISTS render_html text,
18
+ ADD COLUMN IF NOT EXISTS render_plate_slug text,
19
+ ADD COLUMN IF NOT EXISTS rendered_at timestamptz;
20
+
21
+ COMMIT;
@@ -0,0 +1,30 @@
1
+ -- Automations are private to their owning user on the main product surface.
2
+ -- Canonical Workflow projections previously inherited the workflows table
3
+ -- defaults (tenant_shared + no owner), which made a linked Automation callable
4
+ -- through triggerWorkflowRun even when the AgentLoop path was owner-scoped.
5
+ --
6
+ -- Reassert the source AgentLoop's ownership on every existing projection and
7
+ -- make all Automation-backed Workflows private. An ownerless legacy row then
8
+ -- fails closed at invocation instead of becoming tenant-callable.
9
+ --
10
+ -- Hand-rolled data backfill + partial owner index; not in meta/_journal.json.
11
+ -- creates: public.workflows_source_owner_idx
12
+
13
+ UPDATE public.workflows AS workflow
14
+ SET
15
+ visibility = 'agent_private',
16
+ owner_user_id = automation.owner_user_id,
17
+ owner_agent_id = automation.owner_agent_id,
18
+ updated_at = now()
19
+ FROM public.agent_loops AS automation
20
+ WHERE workflow.tenant_id = automation.tenant_id
21
+ AND workflow.source_agent_loop_id = automation.id
22
+ AND (
23
+ workflow.visibility IS DISTINCT FROM 'agent_private'
24
+ OR workflow.owner_user_id IS DISTINCT FROM automation.owner_user_id
25
+ OR workflow.owner_agent_id IS DISTINCT FROM automation.owner_agent_id
26
+ );
27
+
28
+ CREATE INDEX IF NOT EXISTS workflows_source_owner_idx
29
+ ON public.workflows (tenant_id, owner_user_id)
30
+ WHERE source_agent_loop_id IS NOT NULL;