thinkwork-cli 0.13.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -14
- package/dist/{api-client-JYZXYQJR.js → api-client-4P4JZOBX.js} +1 -1
- package/dist/{chunk-Z2F6RJFR.js → chunk-4OMDWYZQ.js} +4 -5
- package/dist/{chunk-ILZKG5WV.js → chunk-AD2NIWB5.js} +434 -69
- package/dist/chunk-MWQ7RO76.js +137 -0
- package/dist/{chunk-DVPBI5HM.js → chunk-OLUQ4U2Z.js} +26 -26
- package/dist/{chunk-QOERT44A.js → chunk-YQCYD6NE.js} +57 -44
- package/dist/cli.js +4400 -16431
- package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +0 -1
- package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +0 -1
- package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +0 -14
- package/dist/{dist-es-CRV46D5B.js → dist-es-2OTNTL4N.js} +4 -4
- package/dist/{dist-es-ENBUC3JP.js → dist-es-2XVAH4BQ.js} +2 -2
- package/dist/{dist-es-DCY4IC3Y.js → dist-es-3DPDUJAH.js} +2 -2
- package/dist/{dist-es-G7PTG75M.js → dist-es-BNZTBBVC.js} +1 -1
- package/dist/{dist-es-GKDBE7E6.js → dist-es-CD2RBDAC.js} +1 -1
- package/dist/{dist-es-R7FGL2IB.js → dist-es-I4FW57PS.js} +1 -1
- package/dist/{dist-es-USORBXZ5.js → dist-es-KVFWJNDY.js} +4 -4
- package/dist/{dist-es-HY3535OI.js → dist-es-PS73DWNL.js} +2 -2
- package/dist/{dist-es-LDE437AM.js → dist-es-S3NZQFGT.js} +1 -1
- package/dist/{dist-es-G54LBMRN.js → dist-es-SGCA4P32.js} +1 -1
- package/dist/{dist-es-Q57SZXZ7.js → dist-es-WBM6J4RA.js} +2 -2
- package/dist/{dist-es-P26FWFLT.js → dist-es-ZGVADYIF.js} +8 -8
- package/dist/drizzle/0227_analyst_reader_role.sql +17 -26
- package/dist/drizzle/0230_analyst_rls.sql +28 -45
- package/dist/drizzle/0261_native_auth_control_plane.sql +7 -3
- package/dist/drizzle/0270_tool_execution_ledger.sql +115 -0
- package/dist/drizzle/0271_ontology_twin_declarations.sql +47 -0
- package/dist/drizzle/0272_identity_graph_projection_cursor.sql +23 -0
- package/dist/drizzle/0273_twin_materialization_suggestions.sql +29 -0
- package/dist/drizzle/0274_tenant_mcp_twin_keys.sql +59 -0
- package/dist/drizzle/0275_identity_bulk_rebuild_fence.sql +30 -0
- package/dist/drizzle/0276_tool_execution_ledger_allow_cascade_delete.sql +18 -0
- package/dist/drizzle/0277_knowledge_base_sources.sql +107 -0
- package/dist/drizzle/0278_kb_page_transcription.sql +55 -0
- package/dist/drizzle/0279_mcp_servers_off_plugin_provenance.sql +93 -0
- package/dist/drizzle/0280_work_item_external_refs_drop_plane_provider.sql +46 -0
- package/dist/drizzle/0281_tenant_mcp_twin_keys_expiry_suffix.sql +9 -0
- package/dist/drizzle/0282_tenant_mcp_twin_keys_grants.sql +24 -0
- package/dist/drizzle/0283_agents_agentcore_runtime_dispatch.sql +13 -0
- package/dist/drizzle/0284_user_brain_claims.sql +69 -0
- package/dist/drizzle/0285_tenant_mcp_twin_keys_trusted_subsystem.sql +30 -0
- package/dist/drizzle/0286_brain_analytics_key.sql +26 -0
- package/dist/drizzle/0287_brain_subject.sql +25 -0
- package/dist/drizzle/0288_multi_lane_identities.sql +25 -0
- package/dist/{loadSso-DJVB7BXE.js → loadSso-ETCXTR4I.js} +2 -2
- package/dist/{loadSso-JAMNA3WY.js → loadSso-UBD7KUHE.js} +2 -2
- package/dist/plugins/README.md +2 -2
- package/dist/plugins/catalog/package.json +0 -3
- package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +6 -3
- package/dist/plugins/catalog/src/__tests__/catalog.test.ts +21 -21
- package/dist/plugins/catalog/src/__tests__/contracts.test.ts +102 -25
- package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +7 -6
- package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -15
- package/dist/plugins/catalog/src/contracts.ts +15 -0
- package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -18
- package/dist/plugins/n8n/test/integrated-app-contract.test.ts +1 -1
- package/dist/plugins/twenty/package.json +2 -1
- package/dist/plugins/twenty/scripts/LAMBDA_DEPLOY.md +114 -0
- package/dist/plugins/twenty/scripts/build-lambda.sh +29 -0
- package/dist/plugins/twenty/scripts/configure-product-views.ts +195 -0
- package/dist/plugins/twenty/scripts/lambda-handler.ts +49 -0
- package/dist/plugins/twenty/scripts/lib/__tests__/load-attachments.test.ts +38 -0
- package/dist/plugins/twenty/scripts/lib/__tests__/load-records.test.ts +145 -2
- package/dist/plugins/twenty/scripts/lib/__tests__/mappers.test.ts +397 -151
- package/dist/plugins/twenty/scripts/lib/__tests__/members-ensure.test.ts +28 -129
- package/dist/plugins/twenty/scripts/lib/__tests__/provision-members-db.test.ts +10 -0
- package/dist/plugins/twenty/scripts/lib/__tests__/schema-ensure.test.ts +13 -8
- package/dist/plugins/twenty/scripts/lib/lastmile-reader.ts +222 -2
- package/dist/plugins/twenty/scripts/lib/load-attachments.ts +29 -0
- package/dist/plugins/twenty/scripts/lib/load-records.ts +160 -43
- package/dist/plugins/twenty/scripts/lib/mappers.ts +368 -152
- package/dist/plugins/twenty/scripts/lib/members-ensure.ts +43 -268
- package/dist/plugins/twenty/scripts/lib/provision-members-db.ts +57 -0
- package/dist/plugins/twenty/scripts/lib/schema-ensure.ts +136 -31
- package/dist/plugins/twenty/scripts/migrate-lastmile.ts +254 -152
- package/dist/plugins/twenty/scripts/provision-twenty-members.ts +44 -1
- package/dist/plugins/twenty/scripts/purge-lastmile-import.ts +178 -0
- package/dist/plugins/twenty/scripts/restructure-products.ts +312 -0
- package/dist/plugins/twenty/scripts/retag-stage-values.ts +362 -0
- package/dist/plugins/twenty/test/manifest.test.ts +2 -4
- package/dist/scripts/post-deploy.sh +79 -1
- package/dist/{signin-UGDWTGS4.js → signin-5QZNRSOO.js} +2 -2
- package/dist/{sso-oidc-Q4VXANXY.js → sso-oidc-XK673P54.js} +2 -2
- package/dist/{sts-CWLSE3GH.js → sts-OXI2UALF.js} +6 -134
- package/dist/{sts-DNZLNVOV.js → sts-SQW4NBK3.js} +6 -134
- package/dist/terraform/examples/greenfield/main.tf +233 -175
- package/dist/terraform/examples/greenfield/terraform.tfvars.example +12 -8
- package/dist/terraform/modules/app/agentcore-admin/main.tf +47 -0
- package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +39 -47
- package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +13 -66
- package/dist/terraform/modules/app/agentcore-identity/main.tf +106 -26
- package/dist/terraform/modules/app/agentcore-identity/outputs.tf +6 -6
- package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +216 -99
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +6 -9
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_workload_identity.sh +19 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/ensure_workload_identity.sh +29 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +22 -7
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +17 -46
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +65 -3
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/after.tf +15 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/before.tf +7 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-after.tf +8 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-before.tf +9 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-after.tf +3 -0
- package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-before.tf +3 -0
- package/dist/terraform/modules/app/agentcore-identity/variables.tf +6 -0
- package/dist/terraform/modules/app/agentcore-memory/README.md +46 -9
- package/dist/terraform/modules/app/agentcore-memory/main.tf +27 -10
- package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +156 -24
- package/dist/terraform/modules/app/agentcore-pi/README.md +1 -3
- package/dist/terraform/modules/app/agentcore-pi/main.tf +42 -52
- package/dist/terraform/modules/app/agentcore-pi/outputs.tf +3 -3
- package/dist/terraform/modules/app/agentcore-pi/scripts/reconcile_pi_runtime.mjs +175 -0
- package/dist/terraform/modules/app/agentcore-pi/variables.tf +35 -28
- package/dist/terraform/modules/app/agentcore-platform/main.tf +68 -0
- package/dist/terraform/modules/app/agentcore-runtime/main.tf +4 -20
- package/dist/terraform/modules/app/capability-broker/main.tf +2 -2
- package/dist/terraform/modules/app/capability-broker/variables.tf +11 -0
- package/dist/terraform/modules/app/deployment-control-plane/README.md +264 -0
- package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +4 -1
- package/dist/terraform/modules/app/deployment-control-plane/main.tf +94 -0
- package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +5 -0
- package/dist/terraform/modules/app/deployment-control-plane/runner.py +2641 -124
- package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +2034 -154
- package/dist/terraform/modules/app/deployment-control-plane/variables.tf +33 -0
- package/dist/terraform/modules/app/lambda-api/auth-state.tf +72 -0
- package/dist/terraform/modules/app/lambda-api/chat-latency-observability.tf +466 -0
- package/dist/terraform/modules/app/lambda-api/dispatch-dlq.tf +55 -0
- package/dist/terraform/modules/app/lambda-api/handlers.tf +411 -723
- package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +262 -198
- package/dist/terraform/modules/app/lambda-api/main.tf +51 -13
- package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +4 -181
- package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +3 -28
- package/dist/terraform/modules/app/lambda-api/oauth-secrets.tf +1 -2
- package/dist/terraform/modules/app/lambda-api/outputs.tf +17 -45
- package/dist/terraform/modules/app/lambda-api/turn-assertion.tf +45 -0
- package/dist/terraform/modules/app/lambda-api/variables.tf +219 -126
- package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/README.md +1 -1
- package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/main.tf +18 -18
- package/dist/terraform/modules/app/sandbox-log-scrubber/README.md +11 -10
- package/dist/terraform/modules/app/sandbox-log-scrubber/main.tf +5 -5
- package/dist/terraform/modules/app/static-site/main.tf +1 -1
- package/dist/terraform/modules/app/www-dns/main.tf +9 -27
- package/dist/terraform/modules/app/www-dns/variables.tf +4 -10
- package/dist/terraform/modules/data/aurora-postgres/README.md +34 -0
- package/dist/terraform/modules/data/aurora-postgres/alarms.tf +82 -0
- package/dist/terraform/modules/data/aurora-postgres/main.tf +27 -57
- package/dist/terraform/modules/data/aurora-postgres/outputs.tf +0 -9
- package/dist/terraform/modules/data/aurora-postgres/variables.tf +41 -0
- package/dist/terraform/modules/data/s3-buckets/main.tf +5 -6
- package/dist/terraform/modules/foundation/cognito/main.tf +81 -8
- package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
- package/dist/terraform/modules/foundation/cognito/variables.tf +24 -12
- package/dist/terraform/modules/thinkwork/README.md +5 -1
- package/dist/terraform/modules/thinkwork/main.tf +376 -374
- package/dist/terraform/modules/thinkwork/outputs.tf +12 -158
- package/dist/terraform/modules/thinkwork/variables.tf +246 -89
- package/dist/workspace-defaults/files/INSTRUCTIONS.md +9 -11
- package/dist/workspace-defaults/files/MEMORY_GUIDE.md +38 -35
- package/dist/workspace-defaults/files/ROUTER.md +1 -1
- package/dist/workspace-defaults/files/TOOLS.md +9 -39
- package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +6 -3
- package/dist/workspace-defaults/files/catalog-skills/brain-brief-builder/SKILL.md +165 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/SKILL.md +75 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
- package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/workflow-authoring.md +46 -0
- package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +1 -1
- package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +22 -3
- package/package.json +1 -1
- package/dist/drizzle/0261_managed_harness_multiplayer.sql +0 -313
- package/dist/drizzle/0262_parallel_harness_threads.sql +0 -9
- package/dist/drizzle/0264_harness_tool_execution_ledger.sql +0 -113
- package/dist/plugins/company-data/README.md +0 -49
- package/dist/plugins/company-data/package.json +0 -21
- package/dist/plugins/company-data/src/index.ts +0 -30
- package/dist/plugins/company-data/src/manifest.ts +0 -26
- package/dist/plugins/company-data/test/manifest.test.ts +0 -116
- package/dist/plugins/company-data/tsconfig.json +0 -8
- package/dist/plugins/company-etl/README.md +0 -46
- package/dist/plugins/company-etl/package.json +0 -21
- package/dist/plugins/company-etl/src/index.ts +0 -29
- package/dist/plugins/company-etl/src/manifest.ts +0 -26
- package/dist/plugins/company-etl/test/manifest.test.ts +0 -108
- package/dist/plugins/company-etl/tsconfig.json +0 -8
- package/dist/plugins/lastmile/README.md +0 -50
- package/dist/plugins/lastmile/package.json +0 -23
- package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +0 -661
- package/dist/plugins/lastmile/src/api/tasks-adapter.ts +0 -572
- package/dist/plugins/lastmile/src/discovery.fixture.ts +0 -64
- package/dist/plugins/lastmile/src/index.ts +0 -46
- package/dist/plugins/lastmile/src/manifest.ts +0 -139
- package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +0 -266
- package/dist/plugins/lastmile/test/discovery.test.ts +0 -88
- package/dist/plugins/lastmile/tsconfig.json +0 -8
- package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +0 -409
- package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +0 -359
- package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +0 -61
- package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +0 -227
- package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +0 -277
- package/dist/terraform/modules/app/agentcore-code-interpreter/scripts/build_and_push_sandbox_base.sh +0 -70
- package/dist/terraform/modules/app/agentcore-gateway/main.tf +0 -305
- package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +0 -44
- package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +0 -93
- package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +0 -33
- package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +0 -543
- package/dist/terraform/modules/app/agentcore-gateway/variables.tf +0 -70
- package/dist/terraform/modules/app/agentcore-harness/main.tf +0 -330
- package/dist/terraform/modules/app/agentcore-harness/outputs.tf +0 -72
- package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +0 -430
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +0 -180
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +0 -193
- package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +0 -5
- package/dist/terraform/modules/app/agentcore-harness/variables.tf +0 -96
- package/dist/terraform/modules/app/hindsight-memory/README.md +0 -89
- package/dist/terraform/modules/app/hindsight-memory/main.tf +0 -411
- package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +0 -88
- package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +0 -91
- package/dist/terraform/modules/data/bedrock-knowledge-base/main.tf +0 -102
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/outputs.tf +0 -0
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/sync-database.py +0 -0
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/test_sync_database.py +0 -0
- /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/variables.tf +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/README.md +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/main.tf +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/outputs.tf +0 -0
- /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/variables.tf +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
-- Purpose: Company Brain twin declarations (plan 2026-07-21-001 U3 / KTD-3) —
|
|
2
|
+
-- per-entity-type facet declarations (clone policy + cadence + attribute
|
|
3
|
+
-- mappings) and page-section declarations, per-relationship-type source
|
|
4
|
+
-- bindings (deterministic FK edge population), plus the three change-set
|
|
5
|
+
-- item types that govern edits (`facet_declaration`, `relationship_binding`,
|
|
6
|
+
-- `page_section`). The compiled twin mapping export is regenerated from
|
|
7
|
+
-- these columns on every change-set apply.
|
|
8
|
+
-- Plan: docs/plans/2026-07-21-001-feat-company-brain-digital-twin-plan.md (U3)
|
|
9
|
+
-- Apply manually: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f packages/database-pg/drizzle/0271_ontology_twin_declarations.sql
|
|
10
|
+
-- creates-column: ontology.entity_types.twin_facets
|
|
11
|
+
-- creates-column: ontology.entity_types.twin_facets_version
|
|
12
|
+
-- creates-column: ontology.entity_types.page_sections
|
|
13
|
+
-- creates-column: ontology.entity_types.page_sections_version
|
|
14
|
+
-- creates-column: ontology.relationship_types.source_binding
|
|
15
|
+
-- creates-column: ontology.relationship_types.source_binding_version
|
|
16
|
+
-- creates-constraint: ontology.change_set_items.ontology_change_set_items_type_allowed
|
|
17
|
+
|
|
18
|
+
\set ON_ERROR_STOP on
|
|
19
|
+
|
|
20
|
+
BEGIN;
|
|
21
|
+
|
|
22
|
+
SET LOCAL lock_timeout = '5s';
|
|
23
|
+
SET LOCAL statement_timeout = '120s';
|
|
24
|
+
|
|
25
|
+
ALTER TABLE ontology.entity_types
|
|
26
|
+
ADD COLUMN IF NOT EXISTS twin_facets jsonb NOT NULL DEFAULT '[]'::jsonb;
|
|
27
|
+
ALTER TABLE ontology.entity_types
|
|
28
|
+
ADD COLUMN IF NOT EXISTS twin_facets_version integer NOT NULL DEFAULT 0;
|
|
29
|
+
ALTER TABLE ontology.entity_types
|
|
30
|
+
ADD COLUMN IF NOT EXISTS page_sections jsonb NOT NULL DEFAULT '[]'::jsonb;
|
|
31
|
+
ALTER TABLE ontology.entity_types
|
|
32
|
+
ADD COLUMN IF NOT EXISTS page_sections_version integer NOT NULL DEFAULT 0;
|
|
33
|
+
|
|
34
|
+
ALTER TABLE ontology.relationship_types
|
|
35
|
+
ADD COLUMN IF NOT EXISTS source_binding jsonb NOT NULL DEFAULT '{}'::jsonb;
|
|
36
|
+
ALTER TABLE ontology.relationship_types
|
|
37
|
+
ADD COLUMN IF NOT EXISTS source_binding_version integer NOT NULL DEFAULT 0;
|
|
38
|
+
|
|
39
|
+
-- Widen the item-type CHECK to admit the three twin declaration item types
|
|
40
|
+
-- (constraint-widening deploys before writer code per house convention).
|
|
41
|
+
ALTER TABLE ontology.change_set_items
|
|
42
|
+
DROP CONSTRAINT IF EXISTS ontology_change_set_items_type_allowed;
|
|
43
|
+
ALTER TABLE ontology.change_set_items
|
|
44
|
+
ADD CONSTRAINT ontology_change_set_items_type_allowed
|
|
45
|
+
CHECK (item_type IN ('entity_type','relationship_type','facet_template','external_mapping','identity_map','facet_declaration','relationship_binding','page_section'));
|
|
46
|
+
|
|
47
|
+
COMMIT;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
-- Purpose: twin graph projector consumer state (Company Brain U5 / KTD-4) —
|
|
2
|
+
-- per-tenant cursor over identity.entity_resolution_events. The cursor is
|
|
3
|
+
-- the source of truth for the projector; nudge invokes are latency only.
|
|
4
|
+
-- Plan: docs/plans/2026-07-21-001-feat-company-brain-digital-twin-plan.md (U5)
|
|
5
|
+
-- Apply manually: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f packages/database-pg/drizzle/0272_identity_graph_projection_cursor.sql
|
|
6
|
+
-- creates: identity.graph_projection_cursors
|
|
7
|
+
|
|
8
|
+
\set ON_ERROR_STOP on
|
|
9
|
+
|
|
10
|
+
BEGIN;
|
|
11
|
+
|
|
12
|
+
SET LOCAL lock_timeout = '5s';
|
|
13
|
+
SET LOCAL statement_timeout = '60s';
|
|
14
|
+
|
|
15
|
+
CREATE TABLE IF NOT EXISTS identity.graph_projection_cursors (
|
|
16
|
+
tenant_id UUID PRIMARY KEY REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
17
|
+
last_event_created_at TIMESTAMPTZ,
|
|
18
|
+
last_event_id UUID,
|
|
19
|
+
last_snapshot_cursor TEXT,
|
|
20
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
COMMIT;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- Purpose: materialization suggestions (Company Brain U8 / R8) — when a
|
|
2
|
+
-- cohort question needs a limited/unclonable facet, the gap surfaces to
|
|
3
|
+
-- operators on the ontology surface as a persisted, deduped, dismissible
|
|
4
|
+
-- suggestion with a hit counter (one row per tenant + entity type + facet).
|
|
5
|
+
-- Plan: docs/plans/2026-07-21-001-feat-company-brain-digital-twin-plan.md (U8)
|
|
6
|
+
-- Apply manually: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f packages/database-pg/drizzle/0273_twin_materialization_suggestions.sql
|
|
7
|
+
-- creates: public.twin_materialization_suggestions
|
|
8
|
+
|
|
9
|
+
\set ON_ERROR_STOP on
|
|
10
|
+
|
|
11
|
+
BEGIN;
|
|
12
|
+
|
|
13
|
+
SET LOCAL lock_timeout = '5s';
|
|
14
|
+
SET LOCAL statement_timeout = '60s';
|
|
15
|
+
|
|
16
|
+
CREATE TABLE IF NOT EXISTS public.twin_materialization_suggestions (
|
|
17
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
18
|
+
tenant_id UUID NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
19
|
+
entity_type_slug TEXT NOT NULL,
|
|
20
|
+
facet_slug TEXT NOT NULL,
|
|
21
|
+
hit_count INTEGER NOT NULL DEFAULT 1,
|
|
22
|
+
last_question TEXT,
|
|
23
|
+
dismissed_at TIMESTAMPTZ,
|
|
24
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
25
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
26
|
+
UNIQUE (tenant_id, entity_type_slug, facet_slug)
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
COMMIT;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
-- tenant_mcp_twin_keys — per-tenant Bearer keys for the Company Brain MCP
|
|
2
|
+
-- server (THINK-333).
|
|
3
|
+
--
|
|
4
|
+
-- The agent path to /mcp/twin authenticates with a `tkt_`-prefixed key.
|
|
5
|
+
-- The mcp-twin handler hashes the incoming Bearer with SHA-256 and looks
|
|
6
|
+
-- it up here where revoked_at IS NULL — the matched row IS the tenant
|
|
7
|
+
-- selection (no tenant id is embedded in the token, so there is no
|
|
8
|
+
-- select-then-verify ambiguity). Raw keys are never stored — only the
|
|
9
|
+
-- hash + metadata. Rotation inserts a fresh row and revokes the old one.
|
|
10
|
+
--
|
|
11
|
+
-- Mirrors tenant_mcp_admin_keys (drizzle/0024) structurally; a separate
|
|
12
|
+
-- table so twin revocation never entangles the admin-ops scope.
|
|
13
|
+
--
|
|
14
|
+
-- Apply manually (matches the 0018+ hand-rolled convention):
|
|
15
|
+
-- psql "$DATABASE_URL" -f packages/database-pg/drizzle/0274_tenant_mcp_twin_keys.sql
|
|
16
|
+
--
|
|
17
|
+
-- Drift detection:
|
|
18
|
+
-- pnpm db:migrate-manual
|
|
19
|
+
--
|
|
20
|
+
-- Pre-migration invariants:
|
|
21
|
+
-- - tenants exists.
|
|
22
|
+
-- - tenant_mcp_twin_keys does not yet exist.
|
|
23
|
+
-- SELECT to_regclass('public.tenant_mcp_twin_keys'); -- must be NULL
|
|
24
|
+
--
|
|
25
|
+
-- creates: public.tenant_mcp_twin_keys
|
|
26
|
+
-- creates: public.uq_tenant_mcp_twin_keys_hash
|
|
27
|
+
-- creates: public.uq_tenant_mcp_twin_keys_active_name
|
|
28
|
+
-- creates: public.idx_tenant_mcp_twin_keys_tenant
|
|
29
|
+
|
|
30
|
+
CREATE TABLE "tenant_mcp_twin_keys" (
|
|
31
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
32
|
+
"tenant_id" uuid NOT NULL REFERENCES "tenants"("id") ON DELETE CASCADE,
|
|
33
|
+
-- SHA-256 hex digest of the raw key. 64 chars; text keeps tooling friendly.
|
|
34
|
+
"key_hash" text NOT NULL,
|
|
35
|
+
-- Human label; "default" for the provisioned connector key.
|
|
36
|
+
"name" text NOT NULL,
|
|
37
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
38
|
+
-- Who created the key. Nullable for service-provisioned keys.
|
|
39
|
+
"created_by_user_id" uuid,
|
|
40
|
+
-- Bumped on every successful auth by the mcp-twin handler. Async,
|
|
41
|
+
-- best-effort (failure to update does not block the request).
|
|
42
|
+
"last_used_at" timestamptz,
|
|
43
|
+
-- Soft-delete. NULL = active. Rotation sets now() on the old row; the
|
|
44
|
+
-- row is retained for audit + to prevent hash reuse.
|
|
45
|
+
"revoked_at" timestamptz
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
-- Global uniqueness on hash — a single-row lookup resolves the tenant.
|
|
49
|
+
CREATE UNIQUE INDEX "uq_tenant_mcp_twin_keys_hash"
|
|
50
|
+
ON "tenant_mcp_twin_keys" ("key_hash");
|
|
51
|
+
|
|
52
|
+
-- Per-tenant uniqueness on name among active rows. Partial index so a
|
|
53
|
+
-- rotated/revoked "default" does not block minting a fresh "default".
|
|
54
|
+
CREATE UNIQUE INDEX "uq_tenant_mcp_twin_keys_active_name"
|
|
55
|
+
ON "tenant_mcp_twin_keys" ("tenant_id", "name")
|
|
56
|
+
WHERE "revoked_at" IS NULL;
|
|
57
|
+
|
|
58
|
+
CREATE INDEX "idx_tenant_mcp_twin_keys_tenant"
|
|
59
|
+
ON "tenant_mcp_twin_keys" ("tenant_id", "created_at");
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- Purpose: bulk-rebuild lane fence + extract-time watermark (THINK-331) —
|
|
2
|
+
-- per-tenant CAS fence on the projector cursor row. bulk_load_started_at
|
|
3
|
+
-- non-null = a bulk-rebuild holds the fence (heartbeat, refreshed on every
|
|
4
|
+
-- resume/poll); bulk_load_id is the Neptune loader job id (null until the
|
|
5
|
+
-- loader starts). The watermark pair is captured SQL-side BEFORE the
|
|
6
|
+
-- Postgres extract so the success tail fast-forwards the cursor only past
|
|
7
|
+
-- events the extract reflected — events committed during the load window
|
|
8
|
+
-- replay through the nudge lane. Additive-only; lands before the code that
|
|
9
|
+
-- reads it (safe ordering).
|
|
10
|
+
-- Plan: docs/plans/2026-07-22-004-feat-identity-projector-bulk-rebuild-plan.md (U2)
|
|
11
|
+
-- Apply manually: psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f packages/database-pg/drizzle/0275_identity_bulk_rebuild_fence.sql
|
|
12
|
+
-- creates-column: identity.graph_projection_cursors.bulk_load_id
|
|
13
|
+
-- creates-column: identity.graph_projection_cursors.bulk_load_started_at
|
|
14
|
+
-- creates-column: identity.graph_projection_cursors.bulk_watermark_created_at
|
|
15
|
+
-- creates-column: identity.graph_projection_cursors.bulk_watermark_event_id
|
|
16
|
+
|
|
17
|
+
\set ON_ERROR_STOP on
|
|
18
|
+
|
|
19
|
+
BEGIN;
|
|
20
|
+
|
|
21
|
+
SET LOCAL lock_timeout = '5s';
|
|
22
|
+
SET LOCAL statement_timeout = '60s';
|
|
23
|
+
|
|
24
|
+
ALTER TABLE identity.graph_projection_cursors
|
|
25
|
+
ADD COLUMN IF NOT EXISTS bulk_load_id TEXT,
|
|
26
|
+
ADD COLUMN IF NOT EXISTS bulk_load_started_at TIMESTAMPTZ,
|
|
27
|
+
ADD COLUMN IF NOT EXISTS bulk_watermark_created_at TIMESTAMPTZ,
|
|
28
|
+
ADD COLUMN IF NOT EXISTS bulk_watermark_event_id UUID;
|
|
29
|
+
|
|
30
|
+
COMMIT;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- creates-trigger: public.tool_execution_events.trg_reject_tool_execution_event_mutation
|
|
2
|
+
-- Thread deletion was impossible for any thread whose agent ran tools: the
|
|
3
|
+
-- ledger declares thread_id/turn_id/tenant_id FKs ON DELETE CASCADE, but the
|
|
4
|
+
-- append-only guard trigger fired on the cascaded DELETE too and aborted the
|
|
5
|
+
-- whole deleteThread transaction with `tool_execution_events_are_append_only`.
|
|
6
|
+
--
|
|
7
|
+
-- Recreate the guard with WHEN (pg_trigger_depth() = 0): direct UPDATE/DELETE
|
|
8
|
+
-- statements are still rejected (the WHEN clause sees depth 0 and the guard
|
|
9
|
+
-- raises), while deletes arriving through FK referential-action triggers run
|
|
10
|
+
-- at depth >= 1 and are allowed — which is exactly the lifecycle the CASCADE
|
|
11
|
+
-- clauses on this table already promised.
|
|
12
|
+
DROP TRIGGER IF EXISTS trg_reject_tool_execution_event_mutation
|
|
13
|
+
ON public.tool_execution_events;
|
|
14
|
+
CREATE TRIGGER trg_reject_tool_execution_event_mutation
|
|
15
|
+
BEFORE UPDATE OR DELETE ON public.tool_execution_events
|
|
16
|
+
FOR EACH ROW
|
|
17
|
+
WHEN (pg_trigger_depth() = 0)
|
|
18
|
+
EXECUTE FUNCTION public.reject_tool_execution_event_mutation();
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
-- External S3 KB source U1: a Knowledge Base holds N data sources instead of
|
|
2
|
+
-- one implied upload prefix.
|
|
3
|
+
-- Contents:
|
|
4
|
+
-- * public.knowledge_base_sources — one row per Bedrock data source of a
|
|
5
|
+
-- KB. kind 'managed-upload' is the platform upload prefix (backfilled as
|
|
6
|
+
-- source #0 from the KB's implied prefix + aws_data_source_id);
|
|
7
|
+
-- 's3-connect' points at an existing customer bucket/prefix read in
|
|
8
|
+
-- place; 'snapshot' is a reserved enum value only. `bucket` is NULL for
|
|
9
|
+
-- managed-upload (workspace bucket resolved at runtime).
|
|
10
|
+
-- * uq_kb_sources_managed_upload — one managed-upload source per KB.
|
|
11
|
+
-- * public.knowledge_base_documents.source_id — nullable FK to the source
|
|
12
|
+
-- row (data_source_id keeps the AWS identity; this is the row reference),
|
|
13
|
+
-- backfilled to the managed-upload source.
|
|
14
|
+
--
|
|
15
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
16
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0277_knowledge_base_sources.sql
|
|
17
|
+
-- creates: public.knowledge_base_sources
|
|
18
|
+
-- creates: public.idx_kb_sources_kb
|
|
19
|
+
-- creates: public.idx_kb_sources_tenant
|
|
20
|
+
-- creates: public.uq_kb_sources_managed_upload
|
|
21
|
+
-- creates: public.idx_kb_documents_source
|
|
22
|
+
-- creates-column: public.knowledge_base_documents.source_id
|
|
23
|
+
-- creates-constraint: public.knowledge_base_sources.knowledge_base_sources_kind_check
|
|
24
|
+
-- creates-constraint: public.knowledge_base_sources.knowledge_base_sources_access_status_check
|
|
25
|
+
-- creates-constraint: public.knowledge_base_sources.knowledge_base_sources_s3_connect_location_check
|
|
26
|
+
|
|
27
|
+
\set ON_ERROR_STOP on
|
|
28
|
+
|
|
29
|
+
BEGIN;
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS public.knowledge_base_sources (
|
|
32
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
33
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id),
|
|
34
|
+
knowledge_base_id uuid NOT NULL REFERENCES public.knowledge_bases(id) ON DELETE CASCADE,
|
|
35
|
+
kind text NOT NULL,
|
|
36
|
+
bucket text,
|
|
37
|
+
prefix text,
|
|
38
|
+
filter_patterns jsonb,
|
|
39
|
+
bucket_owner_account_id text,
|
|
40
|
+
parsing_strategy text NOT NULL DEFAULT 'DEFAULT',
|
|
41
|
+
aws_data_source_id text,
|
|
42
|
+
access_status text NOT NULL DEFAULT 'pending',
|
|
43
|
+
last_sync_at timestamptz,
|
|
44
|
+
last_sync_status text,
|
|
45
|
+
document_count integer DEFAULT 0,
|
|
46
|
+
error_message text,
|
|
47
|
+
sentinel_document_key text,
|
|
48
|
+
sentinel_phrase text,
|
|
49
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
50
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
51
|
+
CONSTRAINT knowledge_base_sources_kind_check
|
|
52
|
+
CHECK (kind IN ('managed-upload', 's3-connect', 'snapshot')),
|
|
53
|
+
CONSTRAINT knowledge_base_sources_access_status_check
|
|
54
|
+
CHECK (access_status IN ('pending', 'healthy', 'degraded', 'access_revoked', 'failed')),
|
|
55
|
+
CONSTRAINT knowledge_base_sources_s3_connect_location_check
|
|
56
|
+
CHECK (kind <> 's3-connect' OR (bucket IS NOT NULL AND prefix IS NOT NULL))
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_kb_sources_kb
|
|
60
|
+
ON public.knowledge_base_sources (knowledge_base_id);
|
|
61
|
+
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_kb_sources_tenant
|
|
63
|
+
ON public.knowledge_base_sources (tenant_id);
|
|
64
|
+
|
|
65
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uq_kb_sources_managed_upload
|
|
66
|
+
ON public.knowledge_base_sources (knowledge_base_id)
|
|
67
|
+
WHERE kind = 'managed-upload';
|
|
68
|
+
|
|
69
|
+
ALTER TABLE public.knowledge_base_documents
|
|
70
|
+
ADD COLUMN IF NOT EXISTS source_id uuid
|
|
71
|
+
REFERENCES public.knowledge_base_sources(id) ON DELETE SET NULL;
|
|
72
|
+
|
|
73
|
+
CREATE INDEX IF NOT EXISTS idx_kb_documents_source
|
|
74
|
+
ON public.knowledge_base_documents (source_id);
|
|
75
|
+
|
|
76
|
+
-- Backfill source #0: one managed-upload row per existing KB, carrying the
|
|
77
|
+
-- KB's implied upload prefix and its current Bedrock data-source identity.
|
|
78
|
+
-- Backfilled sources are the platform's own bucket — access is 'healthy'.
|
|
79
|
+
INSERT INTO public.knowledge_base_sources
|
|
80
|
+
(tenant_id, knowledge_base_id, kind, prefix, aws_data_source_id,
|
|
81
|
+
access_status, last_sync_at, last_sync_status, document_count)
|
|
82
|
+
SELECT
|
|
83
|
+
kb.tenant_id,
|
|
84
|
+
kb.id,
|
|
85
|
+
'managed-upload',
|
|
86
|
+
'tenants/' || t.slug || '/knowledge-bases/' || kb.slug || '/documents/',
|
|
87
|
+
kb.aws_data_source_id,
|
|
88
|
+
'healthy',
|
|
89
|
+
kb.last_sync_at,
|
|
90
|
+
kb.last_sync_status,
|
|
91
|
+
kb.document_count
|
|
92
|
+
FROM public.knowledge_bases kb
|
|
93
|
+
JOIN public.tenants t ON t.id = kb.tenant_id
|
|
94
|
+
WHERE NOT EXISTS (
|
|
95
|
+
SELECT 1 FROM public.knowledge_base_sources s
|
|
96
|
+
WHERE s.knowledge_base_id = kb.id AND s.kind = 'managed-upload'
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
-- Attribute existing manifest rows to their KB's managed-upload source.
|
|
100
|
+
UPDATE public.knowledge_base_documents d
|
|
101
|
+
SET source_id = s.id
|
|
102
|
+
FROM public.knowledge_base_sources s
|
|
103
|
+
WHERE d.source_id IS NULL
|
|
104
|
+
AND s.knowledge_base_id = d.knowledge_base_id
|
|
105
|
+
AND s.kind = 'managed-upload';
|
|
106
|
+
|
|
107
|
+
COMMIT;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- KB page transcription U1: image-bearing source documents are transcribed
|
|
2
|
+
-- page-by-page before ingestion, so the manifest has to record what the
|
|
3
|
+
-- preprocessor produced.
|
|
4
|
+
--
|
|
5
|
+
-- Background: Bedrock's default parser "only parses text in text files" and
|
|
6
|
+
-- the platform never sends a parsingConfiguration, so scanned pages and
|
|
7
|
+
-- embedded screenshots index as nothing. 71 of McPherson's 80 CX SOP PDFs
|
|
8
|
+
-- (89%) keep most of their substance inside images. The fix is a preprocessor
|
|
9
|
+
-- that splits each PDF page and transcribes it with a Claude vision model,
|
|
10
|
+
-- then ingests one IN_LINE document per page under id '<key>#p=<n>'.
|
|
11
|
+
--
|
|
12
|
+
-- Contents:
|
|
13
|
+
-- * knowledge_base_sources.parsing_strategy CHECK widened from the implicit
|
|
14
|
+
-- 'DEFAULT' to ('DEFAULT','TRANSCRIBE'). The column already exists and
|
|
15
|
+
-- defaults to 'DEFAULT'; it was previously wired to nothing.
|
|
16
|
+
-- * knowledge_base_documents gains the preprocessor result: derived_prefix
|
|
17
|
+
-- (workspace-bucket location of pages/<n>.md + report.json), page_count,
|
|
18
|
+
-- preprocessor_version (joins the change-detection predicate so a
|
|
19
|
+
-- pipeline bump forces reprocessing), page_report (per-page route, model
|
|
20
|
+
-- used, flags) and needs_review (any page the preprocessor flagged as
|
|
21
|
+
-- low-signal — indexed with a warning, never silently dropped).
|
|
22
|
+
--
|
|
23
|
+
-- Manifest identity is unchanged: ONE row per source document. Page documents
|
|
24
|
+
-- are an ingestion-level fan-out; their Bedrock statuses fold back up to the
|
|
25
|
+
-- base document_key.
|
|
26
|
+
--
|
|
27
|
+
-- Hand-rolled (drizzle meta journal is not in use for this change);
|
|
28
|
+
-- apply with: psql "$DATABASE_URL" -f drizzle/0278_kb_page_transcription.sql
|
|
29
|
+
-- creates-column: public.knowledge_base_documents.derived_prefix
|
|
30
|
+
-- creates-column: public.knowledge_base_documents.page_count
|
|
31
|
+
-- creates-column: public.knowledge_base_documents.preprocessor_version
|
|
32
|
+
-- creates-column: public.knowledge_base_documents.page_report
|
|
33
|
+
-- creates-column: public.knowledge_base_documents.needs_review
|
|
34
|
+
-- creates: public.idx_kb_documents_needs_review
|
|
35
|
+
-- creates-constraint: public.knowledge_base_sources.knowledge_base_sources_parsing_strategy_check
|
|
36
|
+
|
|
37
|
+
ALTER TABLE public.knowledge_base_documents
|
|
38
|
+
ADD COLUMN IF NOT EXISTS derived_prefix text,
|
|
39
|
+
ADD COLUMN IF NOT EXISTS page_count integer,
|
|
40
|
+
ADD COLUMN IF NOT EXISTS preprocessor_version text,
|
|
41
|
+
ADD COLUMN IF NOT EXISTS page_report jsonb,
|
|
42
|
+
ADD COLUMN IF NOT EXISTS needs_review boolean NOT NULL DEFAULT false;
|
|
43
|
+
|
|
44
|
+
-- Operator surface: "which documents came back with pages the preprocessor
|
|
45
|
+
-- was unsure about". Partial — the overwhelming majority are false.
|
|
46
|
+
CREATE INDEX IF NOT EXISTS idx_kb_documents_needs_review
|
|
47
|
+
ON public.knowledge_base_documents (knowledge_base_id)
|
|
48
|
+
WHERE needs_review;
|
|
49
|
+
|
|
50
|
+
ALTER TABLE public.knowledge_base_sources
|
|
51
|
+
DROP CONSTRAINT IF EXISTS knowledge_base_sources_parsing_strategy_check;
|
|
52
|
+
|
|
53
|
+
ALTER TABLE public.knowledge_base_sources
|
|
54
|
+
ADD CONSTRAINT knowledge_base_sources_parsing_strategy_check
|
|
55
|
+
CHECK (parsing_strategy IN ('DEFAULT', 'TRANSCRIBE'));
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
-- Hand-rolled — apply manually to each stage via:
|
|
2
|
+
-- psql "$DATABASE_URL" -f packages/database-pg/drizzle/0279_mcp_servers_off_plugin_provenance.sql
|
|
3
|
+
--
|
|
4
|
+
-- See docs/solutions/workflow-issues/manually-applied-drizzle-migrations-drift-from-dev-2026-04-21.md
|
|
5
|
+
--
|
|
6
|
+
-- Plugin-system removal. The plugin engine's MCP component handler adopted
|
|
7
|
+
-- surviving MCP servers as management_source='plugin' + plugin_install_id
|
|
8
|
+
-- (migrations 0159/0161). Twenty CRM and n8n keep running after the plugin
|
|
9
|
+
-- system is deleted, so their MCP rows move back to plain 'manual'
|
|
10
|
+
-- registration — the same shape lastmile-dispatch and digital-twin already
|
|
11
|
+
-- use.
|
|
12
|
+
--
|
|
13
|
+
-- data-only-migration
|
|
14
|
+
-- No durable schema objects: this only rewrites provenance columns. The
|
|
15
|
+
-- in-transaction assertions below are the correctness gate, and the
|
|
16
|
+
-- verification queries at the bottom are the post-apply check.
|
|
17
|
+
--
|
|
18
|
+
-- Why this is safe:
|
|
19
|
+
--
|
|
20
|
+
-- * Credentials do not move. packages/api/src/lib/mcp-configs.ts resolves
|
|
21
|
+
-- service_credential from auth_config.secretRef and oauth from
|
|
22
|
+
-- user_mcp_tokens — in the plugin branch and the manual branch alike.
|
|
23
|
+
-- plugin_install_id is used for dispatch *ordering* (plugin rows win a
|
|
24
|
+
-- URL dedupe pass), never for auth.
|
|
25
|
+
-- * Both target shapes are already proven on the manual path:
|
|
26
|
+
-- manual|oauth (lastmile-dispatch, with live per-user tokens) and
|
|
27
|
+
-- manual|service_credential (digital-twin, thinkwork-hindsight,
|
|
28
|
+
-- postgres-dev).
|
|
29
|
+
-- * Nothing re-adopts these rows. The only writers of
|
|
30
|
+
-- management_source='plugin' are lib/plugins/handlers/mcp.ts and
|
|
31
|
+
-- lib/plugins/cutover/deps.ts, both reached only by an explicit plugin
|
|
32
|
+
-- install/activate — and both are deleted with the plugin system.
|
|
33
|
+
--
|
|
34
|
+
-- The CHECK constraint tenant_mcp_servers_managed_application_shape_check_v2
|
|
35
|
+
-- requires manual rows to carry NO ownership key, so managed_application_key
|
|
36
|
+
-- is cleared alongside plugin_install_id. Only dev's twenty--crm still has
|
|
37
|
+
-- one (its pre-plugin identity, retained through the 0161 cutover); the
|
|
38
|
+
-- customer stages already have it NULL.
|
|
39
|
+
--
|
|
40
|
+
-- Per-stage effect at time of writing:
|
|
41
|
+
-- dev twenty--crm (oauth, 2 tokens), n8n--workflow-management,
|
|
42
|
+
-- company-brain--brain, plane--issues
|
|
43
|
+
-- tei-e2e twenty--crm (oauth, 3 tokens)
|
|
44
|
+
-- mcpherson n8n--workflow-management
|
|
45
|
+
--
|
|
46
|
+
-- company-brain--brain and plane--issues are flipped too rather than left
|
|
47
|
+
-- dangling: their plugin_install_id would become a broken reference once the
|
|
48
|
+
-- plugin tables drop. Their own removal is a separate decision.
|
|
49
|
+
|
|
50
|
+
BEGIN;
|
|
51
|
+
|
|
52
|
+
UPDATE tenant_mcp_servers
|
|
53
|
+
SET management_source = 'manual',
|
|
54
|
+
plugin_install_id = NULL,
|
|
55
|
+
managed_application_key = NULL,
|
|
56
|
+
updated_at = now()
|
|
57
|
+
WHERE management_source = 'plugin';
|
|
58
|
+
|
|
59
|
+
-- Fail loudly rather than commit a half-migration: no row anywhere may still
|
|
60
|
+
-- claim plugin provenance, and none may violate the manual shape.
|
|
61
|
+
DO $$
|
|
62
|
+
DECLARE
|
|
63
|
+
leftover integer;
|
|
64
|
+
malformed integer;
|
|
65
|
+
BEGIN
|
|
66
|
+
SELECT count(*) INTO leftover
|
|
67
|
+
FROM tenant_mcp_servers
|
|
68
|
+
WHERE management_source = 'plugin' OR plugin_install_id IS NOT NULL;
|
|
69
|
+
IF leftover > 0 THEN
|
|
70
|
+
RAISE EXCEPTION 'plugin provenance still present on % tenant_mcp_servers row(s)', leftover;
|
|
71
|
+
END IF;
|
|
72
|
+
|
|
73
|
+
SELECT count(*) INTO malformed
|
|
74
|
+
FROM tenant_mcp_servers
|
|
75
|
+
WHERE management_source = 'manual' AND managed_application_key IS NOT NULL;
|
|
76
|
+
IF malformed > 0 THEN
|
|
77
|
+
RAISE EXCEPTION 'manual rows still carry managed_application_key on % row(s)', malformed;
|
|
78
|
+
END IF;
|
|
79
|
+
END $$;
|
|
80
|
+
|
|
81
|
+
COMMIT;
|
|
82
|
+
|
|
83
|
+
-- Verification (run after applying):
|
|
84
|
+
--
|
|
85
|
+
-- SELECT slug, management_source, auth_type,
|
|
86
|
+
-- (plugin_install_id IS NOT NULL) AS has_plugin
|
|
87
|
+
-- FROM tenant_mcp_servers ORDER BY slug;
|
|
88
|
+
--
|
|
89
|
+
-- -- per-user OAuth tokens must be untouched
|
|
90
|
+
-- SELECT s.slug, count(t.id)
|
|
91
|
+
-- FROM tenant_mcp_servers s
|
|
92
|
+
-- LEFT JOIN user_mcp_tokens t ON t.mcp_server_id = s.id
|
|
93
|
+
-- GROUP BY s.slug ORDER BY s.slug;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
-- 0280_work_item_external_refs_drop_plane_provider.sql
|
|
2
|
+
--
|
|
3
|
+
-- Purpose: drop 'plane' from the work_item_external_refs provider allowlist.
|
|
4
|
+
-- Plane is retired — its deployment, DNS, S3 bucket, database, credentials and
|
|
5
|
+
-- MCP registration are all gone, so the provider can never be written again.
|
|
6
|
+
-- Apply manually:
|
|
7
|
+
-- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f packages/database-pg/drizzle/0280_work_item_external_refs_drop_plane_provider.sql
|
|
8
|
+
--
|
|
9
|
+
-- Recreates an existing constraint rather than adding a new object, so the
|
|
10
|
+
-- drift reporter is given the constraint it should find afterwards.
|
|
11
|
+
--
|
|
12
|
+
-- creates-constraint: public.work_item_external_refs.work_item_external_refs_provider_allowed
|
|
13
|
+
|
|
14
|
+
\set ON_ERROR_STOP on
|
|
15
|
+
|
|
16
|
+
BEGIN;
|
|
17
|
+
|
|
18
|
+
SET LOCAL lock_timeout = '5s';
|
|
19
|
+
|
|
20
|
+
-- Fail loudly rather than silently dropping rows the narrowed CHECK would
|
|
21
|
+
-- reject. dev had zero 'plane' rows when this was written; another stage
|
|
22
|
+
-- carrying them is a signal to migrate that data first, not to force through.
|
|
23
|
+
DO $$
|
|
24
|
+
DECLARE
|
|
25
|
+
offending bigint;
|
|
26
|
+
BEGIN
|
|
27
|
+
SELECT count(*) INTO offending
|
|
28
|
+
FROM public.work_item_external_refs
|
|
29
|
+
WHERE provider = 'plane';
|
|
30
|
+
|
|
31
|
+
IF offending > 0 THEN
|
|
32
|
+
RAISE EXCEPTION
|
|
33
|
+
'work_item_external_refs still has % row(s) with provider=''plane''; migrate or delete them before narrowing the constraint',
|
|
34
|
+
offending;
|
|
35
|
+
END IF;
|
|
36
|
+
END
|
|
37
|
+
$$;
|
|
38
|
+
|
|
39
|
+
ALTER TABLE public.work_item_external_refs
|
|
40
|
+
DROP CONSTRAINT IF EXISTS work_item_external_refs_provider_allowed;
|
|
41
|
+
|
|
42
|
+
ALTER TABLE public.work_item_external_refs
|
|
43
|
+
ADD CONSTRAINT work_item_external_refs_provider_allowed
|
|
44
|
+
CHECK (provider IN ('thinkwork', 'lastmile', 'linear', 'twenty'));
|
|
45
|
+
|
|
46
|
+
COMMIT;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- Brain API keys: display suffix + expiry on tenant_mcp_twin_keys.
|
|
2
|
+
-- Hand-rolled (mirrors 0274 convention; not registered in meta/_journal.json).
|
|
3
|
+
-- Apply via: psql "$DATABASE_URL" -f drizzle/0281_tenant_mcp_twin_keys_expiry_suffix.sql
|
|
4
|
+
-- creates-column: public.tenant_mcp_twin_keys.key_suffix
|
|
5
|
+
-- creates-column: public.tenant_mcp_twin_keys.expires_at
|
|
6
|
+
|
|
7
|
+
ALTER TABLE public.tenant_mcp_twin_keys
|
|
8
|
+
ADD COLUMN IF NOT EXISTS key_suffix text,
|
|
9
|
+
ADD COLUMN IF NOT EXISTS expires_at timestamptz;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- Brain API keys: per-key grants (security groups + KB collections) on
|
|
2
|
+
-- tenant_mcp_twin_keys — the write side of key manifest v2
|
|
3
|
+
-- (twin-mcp-keys/v2; reader is company-brain brain-mcp/src/auth.ts).
|
|
4
|
+
-- Hand-rolled (mirrors 0274/0281 convention; not registered in
|
|
5
|
+
-- meta/_journal.json).
|
|
6
|
+
-- Apply via: psql "$DATABASE_URL" -f drizzle/0282_tenant_mcp_twin_keys_grants.sql
|
|
7
|
+
-- creates-column: public.tenant_mcp_twin_keys.security_groups
|
|
8
|
+
-- creates-column: public.tenant_mcp_twin_keys.kb_collections
|
|
9
|
+
|
|
10
|
+
ALTER TABLE public.tenant_mcp_twin_keys
|
|
11
|
+
ADD COLUMN IF NOT EXISTS security_groups text[] NOT NULL DEFAULT ARRAY[]::text[],
|
|
12
|
+
ADD COLUMN IF NOT EXISTS kb_collections text[] NOT NULL DEFAULT ARRAY[]::text[];
|
|
13
|
+
|
|
14
|
+
-- The platform-provisioned connector key ("default") backs the console
|
|
15
|
+
-- proxy and must never be narrowed by this migration: grandfather every
|
|
16
|
+
-- active one to the wildcard grant that re-provisioning would write
|
|
17
|
+
-- anyway. User-minted keys stay empty = PUBLIC graph only, no KB.
|
|
18
|
+
UPDATE public.tenant_mcp_twin_keys
|
|
19
|
+
SET security_groups = ARRAY['*']::text[],
|
|
20
|
+
kb_collections = ARRAY['*']::text[]
|
|
21
|
+
WHERE name = 'default'
|
|
22
|
+
AND revoked_at IS NULL
|
|
23
|
+
AND security_groups = ARRAY[]::text[]
|
|
24
|
+
AND kb_collections = ARRAY[]::text[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- THINK-585 U6 (KTD3): per-agent AgentCore Runtime dispatch flag.
|
|
2
|
+
-- When true AND the stage kill-switch (AGENTCORE_RUNTIME_DISPATCH_ENABLED
|
|
3
|
+
-- runtime-config key) is on, chat turns dispatch through the
|
|
4
|
+
-- agentcore-runtime-dispatch Lambda to the Bedrock AgentCore Runtime with a
|
|
5
|
+
-- per-thread session instead of the Pi Lambda. Additive + default false —
|
|
6
|
+
-- 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/0283_agents_agentcore_runtime_dispatch.sql
|
|
10
|
+
-- creates-column: public.agents.agentcore_runtime_dispatch
|
|
11
|
+
|
|
12
|
+
ALTER TABLE public.agents
|
|
13
|
+
ADD COLUMN IF NOT EXISTS agentcore_runtime_dispatch boolean NOT NULL DEFAULT false;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
-- User brain claims (THINK-625): per-(tenant, user) Company Brain
|
|
2
|
+
-- authorization, the write side of the user-claims/v1 manifest published to
|
|
3
|
+
-- `user-claims/<tenantId>/latest.json` in the brain-artifacts bucket.
|
|
4
|
+
--
|
|
5
|
+
-- Ships three things that must land together, because the publisher is
|
|
6
|
+
-- useless without the safety interlock and the audit row cannot be written
|
|
7
|
+
-- without the widened event-type constraint:
|
|
8
|
+
-- 1. the user_brain_claims table,
|
|
9
|
+
-- 2. tenant_settings.brain_user_claims_enabled (default false),
|
|
10
|
+
-- 3. the tenant_policy_events event_type CHECK widened to accept
|
|
11
|
+
-- 'user_brain_claims' (renamed to _v2 so drift is detectable).
|
|
12
|
+
--
|
|
13
|
+
-- Hand-rolled (partial-index-free but with a NULL-vs-empty array column the
|
|
14
|
+
-- generator flattens; mirrors the 0274/0281/0282 convention). Not registered
|
|
15
|
+
-- in meta/_journal.json.
|
|
16
|
+
-- Apply via: psql "$DATABASE_URL" -f drizzle/0284_user_brain_claims.sql
|
|
17
|
+
-- creates: public.user_brain_claims
|
|
18
|
+
-- creates: public.uq_user_brain_claims_tenant_user
|
|
19
|
+
-- creates: public.idx_user_brain_claims_tenant
|
|
20
|
+
-- creates-column: public.tenant_settings.brain_user_claims_enabled
|
|
21
|
+
-- creates-constraint: public.tenant_policy_events.tenant_policy_events_event_type_allowed_v2
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS public.user_brain_claims (
|
|
24
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
25
|
+
tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE,
|
|
26
|
+
user_id uuid NOT NULL REFERENCES public.users(id) ON DELETE CASCADE,
|
|
27
|
+
-- '[]' = PUBLIC graph only; ARRAY['*'] = every group.
|
|
28
|
+
security_groups text[] NOT NULL DEFAULT ARRAY[]::text[],
|
|
29
|
+
-- KB is grant-only: '[]' = no KB at all; ARRAY['*'] = every collection.
|
|
30
|
+
kb_collections text[] NOT NULL DEFAULT ARRAY[]::text[],
|
|
31
|
+
kb_bundles jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
32
|
+
default_kb_bundle text,
|
|
33
|
+
-- NULL is DISTINCT from '{}': NULL = the Brain surface default applies,
|
|
34
|
+
-- '{}' = no tools at all. Never coalesce one into the other.
|
|
35
|
+
tool_allowlist text[],
|
|
36
|
+
is_operator boolean NOT NULL DEFAULT false,
|
|
37
|
+
kb_trace boolean NOT NULL DEFAULT false,
|
|
38
|
+
-- false still publishes an entry (disabled: true) so the Brain fails
|
|
39
|
+
-- closed rather than falling back to legacy group grants.
|
|
40
|
+
enabled boolean NOT NULL DEFAULT true,
|
|
41
|
+
notes text,
|
|
42
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
43
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
44
|
+
updated_by_user_id uuid
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
CREATE UNIQUE INDEX IF NOT EXISTS uq_user_brain_claims_tenant_user
|
|
48
|
+
ON public.user_brain_claims (tenant_id, user_id);
|
|
49
|
+
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_user_brain_claims_tenant
|
|
51
|
+
ON public.user_brain_claims (tenant_id);
|
|
52
|
+
|
|
53
|
+
-- Per-tenant enable flag. Default false everywhere: claims rows are
|
|
54
|
+
-- editable with no publish until an operator flips this on.
|
|
55
|
+
ALTER TABLE public.tenant_settings
|
|
56
|
+
ADD COLUMN IF NOT EXISTS brain_user_claims_enabled boolean NOT NULL DEFAULT false;
|
|
57
|
+
|
|
58
|
+
-- Widen the audited event types. The old constraint is dropped and a
|
|
59
|
+
-- freshly-named one created so `pnpm db:migrate-manual` can prove the
|
|
60
|
+
-- widened version is actually present in the target database.
|
|
61
|
+
ALTER TABLE public.tenant_policy_events
|
|
62
|
+
DROP CONSTRAINT IF EXISTS tenant_policy_events_event_type_allowed;
|
|
63
|
+
|
|
64
|
+
ALTER TABLE public.tenant_policy_events
|
|
65
|
+
DROP CONSTRAINT IF EXISTS tenant_policy_events_event_type_allowed_v2;
|
|
66
|
+
|
|
67
|
+
ALTER TABLE public.tenant_policy_events
|
|
68
|
+
ADD CONSTRAINT tenant_policy_events_event_type_allowed_v2
|
|
69
|
+
CHECK (event_type IN ('sandbox_enabled','compliance_tier','user_brain_claims'));
|