thinkwork-cli 0.12.17 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/{api-client-JUBCQQDF.js → api-client-4DZ266J5.js} +1 -1
  2. package/dist/{chunk-STY44FQO.js → chunk-Y2WHJECR.js} +44 -12
  3. package/dist/cli.js +36715 -12965
  4. package/dist/drizzle/0227_analyst_reader_role.sql +100 -38
  5. package/dist/drizzle/0230_analyst_rls.sql +183 -66
  6. package/dist/drizzle/0232_memory_source_thin_ledger.sql +176 -0
  7. package/dist/drizzle/0232_message_source_event_id.sql +9 -0
  8. package/dist/drizzle/0233_msteams_install_and_links.sql +151 -0
  9. package/dist/drizzle/0233_workflow_memory_stage_tokens.sql +20 -0
  10. package/dist/drizzle/0234_memory_claim_lifecycle.sql +160 -0
  11. package/dist/drizzle/0235_workflow_token_execution_claim.sql +34 -0
  12. package/dist/drizzle/0236_memory_retraction_fencing.sql +50 -0
  13. package/dist/drizzle/0237_memory_claims_active_value_uidx.sql +172 -0
  14. package/dist/drizzle/0238_memory_erase_generation_fence.sql +97 -0
  15. package/dist/drizzle/0239_canonical_entity_identity.sql +257 -0
  16. package/dist/drizzle/0240_memory_personal_scope.sql +45 -0
  17. package/dist/drizzle/0241_knowledge_base_document_manifest.sql +67 -0
  18. package/dist/drizzle/0242_search_queries.sql +28 -0
  19. package/dist/drizzle/0243_section_sources_thread_refs.sql +12 -0
  20. package/dist/drizzle/0244_system_automations_and_memory_stage_overrides.sql +45 -0
  21. package/dist/drizzle/0245_wiki_page_render.sql +21 -0
  22. package/dist/drizzle/0246_automation_workflow_ownership.sql +30 -0
  23. package/dist/drizzle/0247_capability_runtime.sql +402 -0
  24. package/dist/drizzle/0248_capability_private_interpreter.sql +13 -0
  25. package/dist/drizzle/0249_capability_headless_execution_evidence.sql +40 -0
  26. package/dist/drizzle/0250_kg_schema_extraction.sql +549 -0
  27. package/dist/drizzle/0251_agents_json_render_ui.sql +25 -0
  28. package/dist/drizzle/0251_brain_stragglers.sql +242 -0
  29. package/dist/drizzle/0252_drop_kg_and_straggler_compat_views.sql +100 -0
  30. package/dist/drizzle/0253_drop_brain_substrate.sql +91 -0
  31. package/dist/drizzle/0254_capability_autonomous_admission.sql +29 -0
  32. package/dist/drizzle/0255_capability_autonomous_approval_mode.sql +16 -0
  33. package/dist/drizzle/0256_agent_profile_manifest_authority.sql +18 -0
  34. package/dist/drizzle/0257_capability_approvals.sql +53 -0
  35. package/dist/drizzle/0258_pending_tool_approvals.sql +84 -0
  36. package/dist/drizzle/0259_tenant_capability_registry_trust.sql +19 -0
  37. package/dist/drizzle/0260_scheduled_jobs_run_as_user.sql +20 -0
  38. package/dist/drizzle/0261_thread_turns_origin_turn_index.sql +11 -0
  39. package/dist/terraform/examples/greenfield/main.tf +40 -0
  40. package/dist/terraform/modules/app/agentcore-admin/main.tf +341 -0
  41. package/dist/terraform/modules/app/agentcore-admin/outputs.tf +20 -0
  42. package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +61 -0
  43. package/dist/terraform/modules/app/agentcore-harness/main.tf +101 -0
  44. package/dist/terraform/modules/app/agentcore-harness/outputs.tf +9 -0
  45. package/dist/terraform/modules/app/agentcore-harness/variables.tf +25 -0
  46. package/dist/terraform/modules/app/agentcore-pi/main.tf +7 -0
  47. package/dist/terraform/modules/app/capability-broker/main.tf +393 -0
  48. package/dist/terraform/modules/app/capability-broker/outputs.tf +54 -0
  49. package/dist/terraform/modules/app/capability-broker/variables.tf +98 -0
  50. package/dist/terraform/modules/app/deployment-control-plane/runner.py +46 -5
  51. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +94 -0
  52. package/dist/terraform/modules/app/lambda-api/capability-search-alarms.tf +60 -0
  53. package/dist/terraform/modules/app/lambda-api/handlers.tf +361 -16
  54. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +131 -5
  55. package/dist/terraform/modules/app/lambda-api/main.tf +11 -0
  56. package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +92 -0
  57. package/dist/terraform/modules/app/lambda-api/msteams-app-secrets.tf +46 -0
  58. package/dist/terraform/modules/app/lambda-api/variables.tf +92 -0
  59. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/alarms.tf +47 -0
  60. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +43 -2
  61. package/dist/terraform/modules/foundation/cognito/main.tf +32 -8
  62. package/dist/terraform/modules/foundation/cognito/variables.tf +12 -0
  63. package/dist/terraform/modules/foundation/vpc/outputs.tf +5 -0
  64. package/dist/terraform/modules/thinkwork/main.tf +152 -5
  65. package/dist/terraform/modules/thinkwork/outputs.tf +55 -0
  66. package/dist/terraform/modules/thinkwork/variables.tf +42 -0
  67. package/dist/workspace-defaults/files/TOOLS.md +39 -0
  68. package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +18 -0
  69. package/dist/workspace-defaults/files/agents/coding/INSTRUCTIONS.md +11 -0
  70. package/dist/workspace-defaults/files/agents/research/INSTRUCTIONS.md +12 -0
  71. package/dist/workspace-defaults/files/agents/reviewer/INSTRUCTIONS.md +15 -0
  72. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +6 -2
  73. package/package.json +4 -2
  74. /package/dist/workspace-defaults/files/{AGENTS.md → INSTRUCTIONS.md} +0 -0
@@ -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;
@@ -0,0 +1,402 @@
1
+ -- THINK-280 U1: governed capability runtime persistence.
2
+ --
3
+ -- Immutable definition/version records, tenant service principals,
4
+ -- per-version credential bindings, external confidential clients,
5
+ -- research/admission and Routine proposals, and append-only broker
6
+ -- session/call evidence. Shared semantics (descriptor shape, taxonomies,
7
+ -- fingerprints, twcap references) live in @thinkwork/capability-contracts.
8
+ --
9
+ -- Admitted definition versions are immutable: a trigger rejects UPDATEs that
10
+ -- touch anything but lifecycle/admission metadata once lifecycle = 'admitted',
11
+ -- and rejects DELETE outright. Refreshes create a new candidate version row.
12
+ --
13
+ -- Hand-rolled (CHECK constraints, trigger, precise FK ordering); not in
14
+ -- meta/_journal.json. Apply with: psql "$DATABASE_URL" -f <this file>.
15
+ -- creates: public.tenant_service_principals
16
+ -- creates: public.capability_definitions
17
+ -- creates: public.capability_definition_versions
18
+ -- creates: public.capability_credential_bindings
19
+ -- creates: public.capability_external_clients
20
+ -- creates: public.capability_connection_proposals
21
+ -- creates: public.capability_routine_proposals
22
+ -- creates: public.capability_broker_sessions
23
+ -- creates: public.capability_broker_calls
24
+ -- creates-column: public.capability_catalog.definition_version_id
25
+ -- creates-column: public.routines.capability_dependencies
26
+ -- creates-column: public.routines.execution_principal
27
+ -- creates-column: public.agent_loops.execution_principal
28
+ -- creates-column: public.routine_executions.execution_principal
29
+ -- creates-column: public.routine_code_cache.capability_dependencies
30
+
31
+ BEGIN;
32
+
33
+ -- ---------------------------------------------------------------------------
34
+ -- tenant_service_principals
35
+ -- ---------------------------------------------------------------------------
36
+
37
+ CREATE TABLE IF NOT EXISTS public.tenant_service_principals (
38
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
39
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
40
+ slug text NOT NULL,
41
+ display_name text NOT NULL,
42
+ purpose text,
43
+ status text NOT NULL DEFAULT 'active',
44
+ revoked_at timestamptz,
45
+ revoked_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
46
+ created_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
47
+ metadata_json jsonb NOT NULL DEFAULT '{}'::jsonb,
48
+ created_at timestamptz NOT NULL DEFAULT now(),
49
+ updated_at timestamptz NOT NULL DEFAULT now(),
50
+ CONSTRAINT tenant_service_principals_status_check
51
+ CHECK (status IN ('active', 'revoked'))
52
+ );
53
+
54
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_tenant_service_principals_tenant_slug
55
+ ON public.tenant_service_principals (tenant_id, slug);
56
+ CREATE INDEX IF NOT EXISTS idx_tenant_service_principals_tenant
57
+ ON public.tenant_service_principals (tenant_id);
58
+
59
+ -- ---------------------------------------------------------------------------
60
+ -- capability_definitions
61
+ -- ---------------------------------------------------------------------------
62
+
63
+ CREATE TABLE IF NOT EXISTS public.capability_definitions (
64
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
65
+ tenant_id uuid REFERENCES public.tenants(id) ON DELETE CASCADE,
66
+ namespace text NOT NULL,
67
+ class text NOT NULL,
68
+ slug text NOT NULL,
69
+ display_name text NOT NULL,
70
+ status text NOT NULL DEFAULT 'active',
71
+ created_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
72
+ created_at timestamptz NOT NULL DEFAULT now(),
73
+ updated_at timestamptz NOT NULL DEFAULT now(),
74
+ CONSTRAINT capability_definitions_status_check
75
+ CHECK (status IN ('active', 'retired'))
76
+ );
77
+
78
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_capability_definitions_identity
79
+ ON public.capability_definitions (namespace, class, slug);
80
+ CREATE INDEX IF NOT EXISTS idx_capability_definitions_tenant
81
+ ON public.capability_definitions (tenant_id);
82
+
83
+ -- ---------------------------------------------------------------------------
84
+ -- capability_definition_versions (append-only)
85
+ -- ---------------------------------------------------------------------------
86
+
87
+ CREATE TABLE IF NOT EXISTS public.capability_definition_versions (
88
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
89
+ definition_id uuid NOT NULL
90
+ REFERENCES public.capability_definitions(id) ON DELETE CASCADE,
91
+ version integer NOT NULL,
92
+ descriptor_json jsonb NOT NULL,
93
+ descriptor_fingerprint text NOT NULL,
94
+ contract_hashes_json jsonb NOT NULL,
95
+ signature_json jsonb,
96
+ lifecycle text NOT NULL DEFAULT 'candidate',
97
+ provenance_json jsonb NOT NULL DEFAULT '{}'::jsonb,
98
+ source_proposal_id uuid,
99
+ admitted_at timestamptz,
100
+ admitted_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
101
+ created_at timestamptz NOT NULL DEFAULT now(),
102
+ CONSTRAINT capability_definition_versions_lifecycle_check
103
+ CHECK (lifecycle IN ('candidate', 'admitted', 'rejected', 'retired'))
104
+ );
105
+
106
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_capability_definition_versions_def_version
107
+ ON public.capability_definition_versions (definition_id, version);
108
+ CREATE INDEX IF NOT EXISTS idx_capability_definition_versions_def
109
+ ON public.capability_definition_versions (definition_id);
110
+ CREATE INDEX IF NOT EXISTS idx_capability_definition_versions_fingerprint
111
+ ON public.capability_definition_versions (descriptor_fingerprint);
112
+
113
+ -- Admitted versions are immutable. Once lifecycle = 'admitted', the signed
114
+ -- payload columns can never change; only lifecycle may move forward
115
+ -- (admitted -> retired). Direct DELETEs are rejected (append-only history);
116
+ -- FK CASCADE deletes (definition/tenant removal) run inside the RI trigger
117
+ -- (pg_trigger_depth() > 1) and are allowed through.
118
+ CREATE OR REPLACE FUNCTION public.capability_definition_versions_immutable()
119
+ RETURNS trigger
120
+ LANGUAGE plpgsql
121
+ AS $$
122
+ BEGIN
123
+ IF TG_OP = 'DELETE' THEN
124
+ IF pg_trigger_depth() <= 1 THEN
125
+ RAISE EXCEPTION 'capability_definition_versions rows are append-only';
126
+ END IF;
127
+ RETURN OLD;
128
+ END IF;
129
+ IF OLD.lifecycle = 'admitted' THEN
130
+ IF NEW.descriptor_json IS DISTINCT FROM OLD.descriptor_json
131
+ OR NEW.descriptor_fingerprint IS DISTINCT FROM OLD.descriptor_fingerprint
132
+ OR NEW.contract_hashes_json IS DISTINCT FROM OLD.contract_hashes_json
133
+ OR NEW.signature_json IS DISTINCT FROM OLD.signature_json
134
+ OR NEW.provenance_json IS DISTINCT FROM OLD.provenance_json
135
+ OR NEW.source_proposal_id IS DISTINCT FROM OLD.source_proposal_id
136
+ OR NEW.version IS DISTINCT FROM OLD.version
137
+ OR NEW.definition_id IS DISTINCT FROM OLD.definition_id
138
+ OR NEW.admitted_at IS DISTINCT FROM OLD.admitted_at
139
+ OR NEW.admitted_by_user_id IS DISTINCT FROM OLD.admitted_by_user_id
140
+ THEN
141
+ RAISE EXCEPTION 'admitted capability definition versions are immutable';
142
+ END IF;
143
+ IF NEW.lifecycle NOT IN ('admitted', 'retired') THEN
144
+ RAISE EXCEPTION 'admitted versions may only move to retired';
145
+ END IF;
146
+ END IF;
147
+ RETURN NEW;
148
+ END;
149
+ $$;
150
+
151
+ DROP TRIGGER IF EXISTS trg_capability_definition_versions_immutable
152
+ ON public.capability_definition_versions;
153
+ CREATE TRIGGER trg_capability_definition_versions_immutable
154
+ BEFORE UPDATE OR DELETE ON public.capability_definition_versions
155
+ FOR EACH ROW
156
+ EXECUTE FUNCTION public.capability_definition_versions_immutable();
157
+
158
+ -- ---------------------------------------------------------------------------
159
+ -- capability_credential_bindings
160
+ -- ---------------------------------------------------------------------------
161
+
162
+ CREATE TABLE IF NOT EXISTS public.capability_credential_bindings (
163
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
164
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
165
+ definition_version_id uuid NOT NULL
166
+ REFERENCES public.capability_definition_versions(id) ON DELETE CASCADE,
167
+ principal_mode text NOT NULL,
168
+ service_principal_id uuid
169
+ REFERENCES public.tenant_service_principals(id) ON DELETE RESTRICT,
170
+ subject_user_id uuid REFERENCES public.users(id) ON DELETE CASCADE,
171
+ credential_refs_json jsonb NOT NULL DEFAULT '{}'::jsonb,
172
+ readiness text NOT NULL DEFAULT 'pending_setup',
173
+ readiness_evidence_json jsonb NOT NULL DEFAULT '{}'::jsonb,
174
+ last_verified_at timestamptz,
175
+ revoked_at timestamptz,
176
+ created_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
177
+ created_at timestamptz NOT NULL DEFAULT now(),
178
+ updated_at timestamptz NOT NULL DEFAULT now(),
179
+ CONSTRAINT capability_credential_bindings_mode_check
180
+ CHECK (principal_mode IN ('requester', 'agent_owner', 'service')),
181
+ CONSTRAINT capability_credential_bindings_readiness_check
182
+ CHECK (readiness IN ('pending_setup', 'verifying', 'ready', 'degraded', 'revoked')),
183
+ -- exactly one explicit subject per mode: service mode names a service
184
+ -- principal and never a user; user modes never name a service principal
185
+ CONSTRAINT capability_credential_bindings_subject_check
186
+ CHECK (
187
+ (principal_mode = 'service'
188
+ AND service_principal_id IS NOT NULL
189
+ AND subject_user_id IS NULL)
190
+ OR
191
+ (principal_mode IN ('requester', 'agent_owner')
192
+ AND service_principal_id IS NULL)
193
+ )
194
+ );
195
+
196
+ CREATE INDEX IF NOT EXISTS idx_capability_credential_bindings_tenant
197
+ ON public.capability_credential_bindings (tenant_id);
198
+ CREATE INDEX IF NOT EXISTS idx_capability_credential_bindings_version
199
+ ON public.capability_credential_bindings (definition_version_id);
200
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_capability_credential_bindings_subject
201
+ ON public.capability_credential_bindings (
202
+ definition_version_id,
203
+ principal_mode,
204
+ coalesce(service_principal_id, '00000000-0000-0000-0000-000000000000'::uuid),
205
+ coalesce(subject_user_id, '00000000-0000-0000-0000-000000000000'::uuid)
206
+ );
207
+
208
+ -- ---------------------------------------------------------------------------
209
+ -- capability_external_clients
210
+ -- ---------------------------------------------------------------------------
211
+
212
+ CREATE TABLE IF NOT EXISTS public.capability_external_clients (
213
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
214
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
215
+ client_id text NOT NULL,
216
+ client_secret_hash text NOT NULL,
217
+ service_principal_id uuid NOT NULL
218
+ REFERENCES public.tenant_service_principals(id) ON DELETE RESTRICT,
219
+ allowed_resource text NOT NULL,
220
+ allowed_scopes_json jsonb NOT NULL DEFAULT '[]'::jsonb,
221
+ status text NOT NULL DEFAULT 'active',
222
+ revoked_at timestamptz,
223
+ rotated_at timestamptz,
224
+ created_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
225
+ created_at timestamptz NOT NULL DEFAULT now(),
226
+ updated_at timestamptz NOT NULL DEFAULT now(),
227
+ CONSTRAINT capability_external_clients_status_check
228
+ CHECK (status IN ('active', 'revoked'))
229
+ );
230
+
231
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_capability_external_clients_client_id
232
+ ON public.capability_external_clients (client_id);
233
+ CREATE INDEX IF NOT EXISTS idx_capability_external_clients_tenant
234
+ ON public.capability_external_clients (tenant_id);
235
+
236
+ -- ---------------------------------------------------------------------------
237
+ -- capability_connection_proposals
238
+ -- ---------------------------------------------------------------------------
239
+
240
+ CREATE TABLE IF NOT EXISTS public.capability_connection_proposals (
241
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
242
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
243
+ definition_id uuid
244
+ REFERENCES public.capability_definitions(id) ON DELETE SET NULL,
245
+ payload_json jsonb NOT NULL,
246
+ payload_fingerprint text NOT NULL,
247
+ provenance_json jsonb NOT NULL DEFAULT '{}'::jsonb,
248
+ status text NOT NULL DEFAULT 'draft',
249
+ inbox_item_id uuid,
250
+ created_by_actor_type text,
251
+ created_by_actor_id uuid,
252
+ decided_at timestamptz,
253
+ decided_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
254
+ created_at timestamptz NOT NULL DEFAULT now(),
255
+ CONSTRAINT capability_connection_proposals_status_check
256
+ CHECK (status IN ('draft', 'submitted', 'admitted', 'rejected', 'superseded'))
257
+ );
258
+
259
+ CREATE INDEX IF NOT EXISTS idx_capability_connection_proposals_tenant
260
+ ON public.capability_connection_proposals (tenant_id);
261
+ CREATE INDEX IF NOT EXISTS idx_capability_connection_proposals_definition
262
+ ON public.capability_connection_proposals (definition_id);
263
+ CREATE INDEX IF NOT EXISTS idx_capability_connection_proposals_status
264
+ ON public.capability_connection_proposals (tenant_id, status);
265
+
266
+ -- ---------------------------------------------------------------------------
267
+ -- capability_routine_proposals
268
+ -- ---------------------------------------------------------------------------
269
+
270
+ CREATE TABLE IF NOT EXISTS public.capability_routine_proposals (
271
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
272
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
273
+ routine_id uuid,
274
+ payload_json jsonb NOT NULL,
275
+ payload_fingerprint text NOT NULL,
276
+ evidence_refs_json jsonb NOT NULL DEFAULT '[]'::jsonb,
277
+ status text NOT NULL DEFAULT 'draft',
278
+ inbox_item_id uuid,
279
+ approval_mode text,
280
+ approval_evidence_json jsonb NOT NULL DEFAULT '{}'::jsonb,
281
+ created_by_actor_type text,
282
+ created_by_actor_id uuid,
283
+ decided_at timestamptz,
284
+ decided_by_user_id uuid REFERENCES public.users(id) ON DELETE SET NULL,
285
+ promoted_commit_sha text,
286
+ created_at timestamptz NOT NULL DEFAULT now(),
287
+ CONSTRAINT capability_routine_proposals_status_check
288
+ CHECK (status IN ('draft', 'submitted', 'approved', 'rejected', 'superseded', 'promoted')),
289
+ CONSTRAINT capability_routine_proposals_approval_mode_check
290
+ CHECK (approval_mode IS NULL OR approval_mode IN ('operator', 'repair'))
291
+ );
292
+
293
+ CREATE INDEX IF NOT EXISTS idx_capability_routine_proposals_tenant
294
+ ON public.capability_routine_proposals (tenant_id);
295
+ CREATE INDEX IF NOT EXISTS idx_capability_routine_proposals_routine
296
+ ON public.capability_routine_proposals (routine_id);
297
+ CREATE INDEX IF NOT EXISTS idx_capability_routine_proposals_status
298
+ ON public.capability_routine_proposals (tenant_id, status);
299
+
300
+ -- ---------------------------------------------------------------------------
301
+ -- capability_broker_sessions
302
+ -- ---------------------------------------------------------------------------
303
+
304
+ CREATE TABLE IF NOT EXISTS public.capability_broker_sessions (
305
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
306
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
307
+ session_id text NOT NULL,
308
+ audience text NOT NULL,
309
+ context_fingerprint text NOT NULL,
310
+ principal_mode text NOT NULL,
311
+ service_principal_id uuid
312
+ REFERENCES public.tenant_service_principals(id) ON DELETE SET NULL,
313
+ subject_user_id uuid,
314
+ grant_snapshot_json jsonb NOT NULL DEFAULT '{}'::jsonb,
315
+ budgets_json jsonb NOT NULL DEFAULT '{}'::jsonb,
316
+ routine_execution_id uuid,
317
+ thread_turn_id uuid,
318
+ status text NOT NULL DEFAULT 'active',
319
+ expires_at timestamptz NOT NULL,
320
+ closed_at timestamptz,
321
+ created_at timestamptz NOT NULL DEFAULT now(),
322
+ CONSTRAINT capability_broker_sessions_mode_check
323
+ CHECK (principal_mode IN ('requester', 'agent_owner', 'service')),
324
+ CONSTRAINT capability_broker_sessions_status_check
325
+ CHECK (status IN ('active', 'expired', 'cancelled', 'closed'))
326
+ );
327
+
328
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_capability_broker_sessions_session_id
329
+ ON public.capability_broker_sessions (session_id);
330
+ CREATE INDEX IF NOT EXISTS idx_capability_broker_sessions_tenant
331
+ ON public.capability_broker_sessions (tenant_id);
332
+ CREATE INDEX IF NOT EXISTS idx_capability_broker_sessions_created
333
+ ON public.capability_broker_sessions (tenant_id, created_at);
334
+
335
+ -- ---------------------------------------------------------------------------
336
+ -- capability_broker_calls (append-only)
337
+ -- ---------------------------------------------------------------------------
338
+
339
+ CREATE TABLE IF NOT EXISTS public.capability_broker_calls (
340
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
341
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
342
+ broker_session_id uuid NOT NULL
343
+ REFERENCES public.capability_broker_sessions(id) ON DELETE CASCADE,
344
+ client_request_id text NOT NULL,
345
+ sequence bigint,
346
+ operation_ref text,
347
+ contract_hash text,
348
+ definition_version_id uuid
349
+ REFERENCES public.capability_definition_versions(id) ON DELETE SET NULL,
350
+ binding_id uuid
351
+ REFERENCES public.capability_credential_bindings(id) ON DELETE SET NULL,
352
+ status text NOT NULL,
353
+ policy_decisions_json jsonb NOT NULL DEFAULT '{}'::jsonb,
354
+ request_digest text,
355
+ result_digest text,
356
+ error_category text,
357
+ effect text,
358
+ budget_delta_json jsonb NOT NULL DEFAULT '{}'::jsonb,
359
+ adapter_kind text,
360
+ duration_ms integer,
361
+ durable_ref_json jsonb,
362
+ routine_execution_id uuid,
363
+ thread_turn_id uuid,
364
+ compliance_event_id uuid,
365
+ authorized_at timestamptz,
366
+ finalized_at timestamptz,
367
+ created_at timestamptz NOT NULL DEFAULT now(),
368
+ CONSTRAINT capability_broker_calls_status_check
369
+ CHECK (status IN ('rejected', 'authorized', 'completed', 'accepted', 'failed', 'indeterminate'))
370
+ );
371
+
372
+ CREATE UNIQUE INDEX IF NOT EXISTS uq_capability_broker_calls_session_request
373
+ ON public.capability_broker_calls (broker_session_id, client_request_id);
374
+ CREATE INDEX IF NOT EXISTS idx_capability_broker_calls_tenant
375
+ ON public.capability_broker_calls (tenant_id);
376
+ CREATE INDEX IF NOT EXISTS idx_capability_broker_calls_session
377
+ ON public.capability_broker_calls (broker_session_id);
378
+ CREATE INDEX IF NOT EXISTS idx_capability_broker_calls_routine_exec
379
+ ON public.capability_broker_calls (routine_execution_id);
380
+
381
+ -- ---------------------------------------------------------------------------
382
+ -- Additive columns on existing tables (legacy semantics unchanged)
383
+ -- ---------------------------------------------------------------------------
384
+
385
+ ALTER TABLE public.capability_catalog
386
+ ADD COLUMN IF NOT EXISTS definition_version_id uuid
387
+ REFERENCES public.capability_definition_versions(id) ON DELETE SET NULL;
388
+
389
+ ALTER TABLE public.routines
390
+ ADD COLUMN IF NOT EXISTS capability_dependencies jsonb,
391
+ ADD COLUMN IF NOT EXISTS execution_principal jsonb;
392
+
393
+ ALTER TABLE public.agent_loops
394
+ ADD COLUMN IF NOT EXISTS execution_principal jsonb;
395
+
396
+ ALTER TABLE public.routine_executions
397
+ ADD COLUMN IF NOT EXISTS execution_principal jsonb;
398
+
399
+ ALTER TABLE public.routine_code_cache
400
+ ADD COLUMN IF NOT EXISTS capability_dependencies jsonb;
401
+
402
+ COMMIT;
@@ -0,0 +1,13 @@
1
+ -- THINK-280 U4: capability-private VPC-mode Code Interpreter id.
2
+ --
3
+ -- Additive nullable column on tenants for the third per-tenant interpreter (no
4
+ -- NAT; reaches only the capability broker's private execute-api VPCE). Populated
5
+ -- by the agentcore-admin Lambda only when the broker is enabled; NULL otherwise.
6
+ -- Existing sandbox selection (default-public / internal-only) is unchanged.
7
+ --
8
+ -- Hand-rolled additive column; not in meta/_journal.json. Apply with:
9
+ -- psql "$DATABASE_URL" -f <this file>.
10
+ -- creates-column: public.tenants.sandbox_interpreter_capability_private_id
11
+
12
+ ALTER TABLE public.tenants
13
+ ADD COLUMN IF NOT EXISTS sandbox_interpreter_capability_private_id text;
@@ -0,0 +1,40 @@
1
+ -- THINK-280 U7: capability-headless execution evidence chain.
2
+ --
3
+ -- Additive nullable columns that let the execution-detail UI reconstruct the
4
+ -- full evidence chain of a governed capability-headless Routine run WITHOUT an
5
+ -- AWS call: the exact resolved dependency manifest (twcap + contract hashes),
6
+ -- the config/manifest fingerprint checked at preflight, the readiness verdict,
7
+ -- operator remediation for a blocked/degraded run, the minted broker-session
8
+ -- evidence row, and per-step broker-call / artifact linkage.
9
+ --
10
+ -- Broker call/session evidence itself already lives in
11
+ -- capability_broker_calls / capability_broker_sessions (migration 0247); these
12
+ -- columns are the join anchors + the run-level preflight verdict the broker
13
+ -- tables do not carry. All columns are NULL on every legacy git_python /
14
+ -- user-run-as / Step Functions execution and step — the capability-headless
15
+ -- executor is the only writer.
16
+ --
17
+ -- Hand-rolled additive columns (not in meta/_journal.json). Apply with:
18
+ -- psql "$DATABASE_URL" -f <this file>.
19
+ -- creates-column: public.routine_executions.capability_dependencies_json
20
+ -- creates-column: public.routine_executions.config_fingerprint
21
+ -- creates-column: public.routine_executions.readiness_outcome
22
+ -- creates-column: public.routine_executions.remediation_json
23
+ -- creates-column: public.routine_executions.broker_session_id
24
+ -- creates-column: public.routine_step_events.broker_call_id
25
+ -- creates-column: public.routine_step_events.artifact_id
26
+
27
+ BEGIN;
28
+
29
+ ALTER TABLE public.routine_executions
30
+ ADD COLUMN IF NOT EXISTS capability_dependencies_json jsonb,
31
+ ADD COLUMN IF NOT EXISTS config_fingerprint text,
32
+ ADD COLUMN IF NOT EXISTS readiness_outcome text,
33
+ ADD COLUMN IF NOT EXISTS remediation_json jsonb,
34
+ ADD COLUMN IF NOT EXISTS broker_session_id uuid;
35
+
36
+ ALTER TABLE public.routine_step_events
37
+ ADD COLUMN IF NOT EXISTS broker_call_id uuid,
38
+ ADD COLUMN IF NOT EXISTS artifact_id uuid;
39
+
40
+ COMMIT;