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.
- package/dist/{api-client-JUBCQQDF.js → api-client-JYZXYQJR.js} +3 -1
- package/dist/bowser-6Z6JFAIR.js +2822 -0
- package/dist/chunk-DV3MRBR5.js +43 -0
- package/dist/chunk-DVPBI5HM.js +1728 -0
- package/dist/chunk-EI5ZX7CN.js +522 -0
- package/dist/chunk-EUJ7X6YD.js +126 -0
- package/dist/chunk-GG5WKBOX.js +436 -0
- package/dist/chunk-I64EZSU5.js +358 -0
- package/dist/chunk-ILZKG5WV.js +6151 -0
- package/dist/chunk-KMIJ5KGT.js +128 -0
- package/dist/chunk-OCPHU34C.js +996 -0
- package/dist/chunk-QOERT44A.js +3286 -0
- package/dist/chunk-XYM7PE2A.js +2264 -0
- package/dist/{chunk-STY44FQO.js → chunk-Z2F6RJFR.js} +12 -18
- package/dist/cli.js +72564 -18884
- package/dist/dist-es-CRV46D5B.js +315 -0
- package/dist/dist-es-DCY4IC3Y.js +2000 -0
- package/dist/dist-es-ENBUC3JP.js +14726 -0
- package/dist/dist-es-G54LBMRN.js +48 -0
- package/dist/dist-es-G7PTG75M.js +176 -0
- package/dist/dist-es-GKDBE7E6.js +88 -0
- package/dist/dist-es-HY3535OI.js +70 -0
- package/dist/dist-es-KL7Y5NB2.js +377 -0
- package/dist/dist-es-LDE437AM.js +170 -0
- package/dist/dist-es-P26FWFLT.js +485 -0
- package/dist/dist-es-Q57SZXZ7.js +70 -0
- package/dist/dist-es-R7FGL2IB.js +88 -0
- package/dist/dist-es-USORBXZ5.js +318 -0
- package/dist/dist-es-ZKC2QKD2.js +377 -0
- package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +2 -1
- package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +1 -0
- package/dist/drizzle/0090_brain_schema_extraction.sql +10 -0
- package/dist/drizzle/0132_drop_computer_tables.sql +3 -0
- package/dist/drizzle/0160_compliance_event_types_plugins.sql +2 -0
- package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +1 -0
- package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +1 -0
- package/dist/drizzle/0227_analyst_reader_role.sql +106 -38
- package/dist/drizzle/0230_analyst_rls.sql +192 -66
- package/dist/drizzle/0232_memory_source_thin_ledger.sql +176 -0
- package/dist/drizzle/0232_message_source_event_id.sql +9 -0
- package/dist/drizzle/0233_msteams_install_and_links.sql +151 -0
- package/dist/drizzle/0233_workflow_memory_stage_tokens.sql +20 -0
- package/dist/drizzle/0234_memory_claim_lifecycle.sql +160 -0
- package/dist/drizzle/0235_workflow_token_execution_claim.sql +34 -0
- package/dist/drizzle/0236_memory_retraction_fencing.sql +50 -0
- package/dist/drizzle/0237_memory_claims_active_value_uidx.sql +172 -0
- package/dist/drizzle/0238_memory_erase_generation_fence.sql +97 -0
- package/dist/drizzle/0239_canonical_entity_identity.sql +257 -0
- package/dist/drizzle/0240_memory_personal_scope.sql +45 -0
- package/dist/drizzle/0241_knowledge_base_document_manifest.sql +67 -0
- package/dist/drizzle/0242_search_queries.sql +28 -0
- package/dist/drizzle/0243_section_sources_thread_refs.sql +12 -0
- package/dist/drizzle/0244_system_automations_and_memory_stage_overrides.sql +45 -0
- package/dist/drizzle/0245_wiki_page_render.sql +21 -0
- package/dist/drizzle/0246_automation_workflow_ownership.sql +30 -0
- package/dist/drizzle/0247_capability_runtime.sql +402 -0
- package/dist/drizzle/0248_capability_private_interpreter.sql +13 -0
- package/dist/drizzle/0249_capability_headless_execution_evidence.sql +40 -0
- package/dist/drizzle/0250_kg_schema_extraction.sql +576 -0
- package/dist/drizzle/0251_agents_json_render_ui.sql +25 -0
- package/dist/drizzle/0251_brain_stragglers.sql +263 -0
- package/dist/drizzle/0252_drop_kg_and_straggler_compat_views.sql +100 -0
- package/dist/drizzle/0253_drop_brain_substrate.sql +93 -0
- package/dist/drizzle/0254_capability_autonomous_admission.sql +29 -0
- package/dist/drizzle/0255_capability_autonomous_approval_mode.sql +16 -0
- package/dist/drizzle/0256_agent_profile_manifest_authority.sql +18 -0
- package/dist/drizzle/0257_agents_runtime_allow_harness.sql +24 -0
- package/dist/drizzle/0257_capability_approvals.sql +53 -0
- package/dist/drizzle/0258_pending_tool_approvals.sql +84 -0
- package/dist/drizzle/0259_tenant_capability_registry_trust.sql +19 -0
- package/dist/drizzle/0260_scheduled_jobs_run_as_user.sql +20 -0
- package/dist/drizzle/0261_managed_harness_multiplayer.sql +313 -0
- package/dist/drizzle/0261_native_auth_control_plane.sql +328 -0
- package/dist/drizzle/0262_auth_subscription_tickets.sql +59 -0
- package/dist/drizzle/0262_parallel_harness_threads.sql +9 -0
- package/dist/drizzle/0263_agentcore_runtime_identifier.sql +69 -0
- package/dist/drizzle/0263_drop_workos_auth_runtime.sql +236 -0
- package/dist/drizzle/0264_auth_enrollment_attempt_limits.sql +15 -0
- package/dist/drizzle/0264_harness_tool_execution_ledger.sql +113 -0
- package/dist/drizzle/0265_eval_runs_requester_identity.sql +28 -0
- package/dist/drizzle/0265_require_fully_valid_auth_publication.sql +27 -0
- package/dist/drizzle/0266_auth_identity_recovery_grants.sql +9 -0
- package/dist/drizzle/0266_eval_profiles_runtime_type.sql +12 -0
- package/dist/drizzle/0267_ontology_candidate_rejections.sql +53 -0
- package/dist/drizzle/0268_identity_crosswalk_routing.sql +182 -0
- package/dist/drizzle/0269_ontology_system_map.sql +31 -0
- package/dist/event-streams-7JNLJEEL.js +894 -0
- package/dist/event-streams-KDF5RWR6.js +1515 -0
- package/dist/loadSso-DJVB7BXE.js +576 -0
- package/dist/loadSso-JAMNA3WY.js +583 -0
- package/dist/plugins/catalog/package.json +1 -2
- package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
- package/dist/plugins/catalog/src/__tests__/contracts.test.ts +0 -69
- package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
- package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
- package/dist/plugins/catalog/src/contracts.ts +2 -179
- package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
- package/dist/signin-UGDWTGS4.js +821 -0
- package/dist/sso-oidc-Q4VXANXY.js +837 -0
- package/dist/sts-CWLSE3GH.js +1241 -0
- package/dist/sts-DNZLNVOV.js +1245 -0
- package/dist/terraform/examples/greenfield/main.tf +247 -50
- package/dist/terraform/examples/greenfield/terraform.tfvars.example +15 -1
- package/dist/terraform/modules/app/agentcore-admin/main.tf +341 -0
- package/dist/terraform/modules/app/agentcore-admin/outputs.tf +20 -0
- package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +61 -0
- package/dist/terraform/modules/app/agentcore-gateway/main.tf +305 -0
- package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +44 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +93 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +33 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +543 -0
- package/dist/terraform/modules/app/agentcore-gateway/variables.tf +70 -0
- package/dist/terraform/modules/app/agentcore-harness/main.tf +330 -0
- package/dist/terraform/modules/app/agentcore-harness/outputs.tf +72 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +430 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +180 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +193 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/variables.tf +96 -0
- package/dist/terraform/modules/app/agentcore-identity/main.tf +173 -0
- package/dist/terraform/modules/app/agentcore-identity/outputs.tf +51 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +122 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +25 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_twenty_identity.sh +16 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +40 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_identity.sh +73 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +74 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +61 -0
- package/dist/terraform/modules/app/agentcore-identity/variables.tf +54 -0
- package/dist/terraform/modules/app/agentcore-pi/main.tf +7 -0
- package/dist/terraform/modules/app/appsync-subscriptions/main.tf +127 -21
- package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +0 -6
- package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +5 -0
- package/dist/terraform/modules/app/capability-broker/main.tf +393 -0
- package/dist/terraform/modules/app/capability-broker/outputs.tf +54 -0
- package/dist/terraform/modules/app/capability-broker/variables.tf +98 -0
- package/dist/terraform/modules/app/deployment-control-plane/runner.py +1011 -31
- package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +655 -2
- package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +88 -0
- package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +91 -0
- package/dist/terraform/modules/app/lambda-api/capability-search-alarms.tf +60 -0
- package/dist/terraform/modules/app/lambda-api/handlers.tf +606 -37
- package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +192 -21
- package/dist/terraform/modules/app/lambda-api/main.tf +35 -0
- package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +181 -4
- package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +92 -0
- package/dist/terraform/modules/app/lambda-api/msteams-app-secrets.tf +46 -0
- package/dist/terraform/modules/app/lambda-api/outputs.tf +35 -0
- package/dist/terraform/modules/app/lambda-api/runtime-config.tf +3 -21
- package/dist/terraform/modules/app/lambda-api/variables.tf +188 -3
- package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/alarms.tf +47 -0
- package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +43 -2
- package/dist/terraform/modules/foundation/cognito/main.tf +319 -73
- package/dist/terraform/modules/foundation/cognito/outputs.tf +42 -0
- package/dist/terraform/modules/foundation/cognito/variables.tf +124 -2
- package/dist/terraform/modules/foundation/vpc/outputs.tf +5 -0
- package/dist/terraform/modules/thinkwork/main.tf +396 -26
- package/dist/terraform/modules/thinkwork/outputs.tf +188 -5
- package/dist/terraform/modules/thinkwork/variables.tf +154 -5
- package/dist/terraform/schema.graphql +69 -36
- package/dist/workspace-defaults/files/TOOLS.md +39 -0
- package/dist/workspace-defaults/files/USER.md +1 -0
- package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +18 -0
- package/dist/workspace-defaults/files/agents/coding/INSTRUCTIONS.md +11 -0
- package/dist/workspace-defaults/files/agents/research/INSTRUCTIONS.md +12 -0
- package/dist/workspace-defaults/files/agents/reviewer/INSTRUCTIONS.md +15 -0
- package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +6 -2
- package/package.json +6 -3
- package/dist/plugins/workos-auth/package.json +0 -22
- package/dist/plugins/workos-auth/src/index.ts +0 -30
- package/dist/plugins/workos-auth/src/manifest.ts +0 -40
- package/dist/plugins/workos-auth/src/provider-contract.ts +0 -39
- package/dist/plugins/workos-auth/test/manifest.test.ts +0 -94
- package/dist/plugins/workos-auth/tsconfig.json +0 -8
- /package/dist/workspace-defaults/files/{AGENTS.md → INSTRUCTIONS.md} +0 -0
|
@@ -14,6 +14,12 @@ locals {
|
|
|
14
14
|
# deployment jobs — plan 2026-06-12-001 U10); the TWENTY config key is
|
|
15
15
|
# retired.
|
|
16
16
|
optional_integration_handler_names = concat(
|
|
17
|
+
var.auth_retirement_phase == "retired" ? [
|
|
18
|
+
# The native login UI never publishes this handler. It remains reachable
|
|
19
|
+
# only as an operator-controlled rollback seam through coexistence and
|
|
20
|
+
# cutover/soak, then Terraform removes the Lambda and routes atomically.
|
|
21
|
+
"workos-auth",
|
|
22
|
+
] : [],
|
|
17
23
|
var.deployment_control_plane_enabled ? [] : [
|
|
18
24
|
# Host-only onboarding/deployment API. Customer foundations disable the
|
|
19
25
|
# deployment control plane, so release-based customer installs must not
|
|
@@ -30,10 +36,22 @@ locals {
|
|
|
30
36
|
"oauth-authorize",
|
|
31
37
|
"oauth-callback",
|
|
32
38
|
"slack-events",
|
|
33
|
-
"slack-slash-command",
|
|
34
|
-
"slack-interactivity",
|
|
35
39
|
"slack-oauth-install",
|
|
36
40
|
],
|
|
41
|
+
var.enable_msteams_app ? [] : [
|
|
42
|
+
"msteams-install-start",
|
|
43
|
+
"msteams-install-complete",
|
|
44
|
+
"msteams-account-link-complete",
|
|
45
|
+
],
|
|
46
|
+
var.enable_agentcore_multiplayer_proof ? [] : [
|
|
47
|
+
"turn-assertion-mint",
|
|
48
|
+
"agentcore-proof-oauth-provider",
|
|
49
|
+
"agentcore-identity-boundary-target",
|
|
50
|
+
"harness-capability-mcp",
|
|
51
|
+
"harness-code-interpreter-target",
|
|
52
|
+
"harness-builtin-tools-target",
|
|
53
|
+
"harness-platform-tools-target",
|
|
54
|
+
],
|
|
37
55
|
)
|
|
38
56
|
|
|
39
57
|
# Config-class configuration shared by all API handlers. As of plan
|
|
@@ -44,20 +62,30 @@ locals {
|
|
|
44
62
|
# The reader-coverage fixture test in apps/cli fails CI if a key in this
|
|
45
63
|
# map still has a direct process.env reader. Identity values (STAGE,
|
|
46
64
|
# AWS_ACCOUNT_ID, NODE_OPTIONS) and secrets (DATABASE_URL,
|
|
47
|
-
# API_AUTH_SECRET
|
|
65
|
+
# API_AUTH_SECRET) stay out of this map — identity stays
|
|
48
66
|
# env forever, secrets live in Secrets Manager (R4), never in the String
|
|
49
67
|
# document.
|
|
50
68
|
config_env = merge({
|
|
51
69
|
# THINK-173: PUBLIC verification key (not a secret) + the NAME of the
|
|
52
70
|
# private-key secret (resolved via runtime-config's secret loader —
|
|
53
71
|
# the PEM itself never enters the env or the String document).
|
|
54
|
-
CAPABILITY_SIGNING_PUBLIC_KEY
|
|
55
|
-
CAPABILITY_SIGNING_PRIVATE_KEY_SECRET
|
|
72
|
+
CAPABILITY_SIGNING_PUBLIC_KEY = var.capability_signing_public_key
|
|
73
|
+
CAPABILITY_SIGNING_PRIVATE_KEY_SECRET = var.capability_signing_private_key_secret
|
|
74
|
+
SUBSCRIPTION_TICKET_SIGNING_KEY_ID = var.subscription_ticket_signing_key_id
|
|
75
|
+
SUBSCRIPTION_TICKET_PUBLIC_KEYS = var.subscription_ticket_public_keys
|
|
76
|
+
SUBSCRIPTION_TICKET_PRIVATE_KEY_SECRET = var.subscription_ticket_private_key_secret
|
|
77
|
+
APPSYNC_API_ID = var.appsync_api_id
|
|
56
78
|
# THINK-229 U3/KTD5 — the analyst policy-source enforcement flip.
|
|
57
79
|
# "row" (default) keeps sidecar policy shadow-only; "sidecar" makes the
|
|
58
80
|
# signed sidecar block authoritative (budgets/policyClaims flow). Flip
|
|
59
81
|
# ONLY after clean shadow parity on live traffic.
|
|
60
82
|
ANALYST_POLICY_SOURCE = var.analyst_policy_source
|
|
83
|
+
# Governed autonomy — per-tenant opt-in allowlist for autonomous capability
|
|
84
|
+
# self-extension (the two self_admit_connection / self_approve_routine
|
|
85
|
+
# actions on capability-control-service). Comma/space-separated tenant ids;
|
|
86
|
+
# empty (default) = NO tenant enabled, so self-extension ships inert and
|
|
87
|
+
# fail-closed. Read via getConfig() (env-wins) in isSelfExtensionEnabled.
|
|
88
|
+
CAPABILITY_SELF_EXTENSION_TENANTS = var.capability_self_extension_tenants
|
|
61
89
|
# THINK-230 — the operator-facing provisionAnalystConnector mutation runs
|
|
62
90
|
# the analyst connector provisioning ceremony inside graphql-http, so the
|
|
63
91
|
# shared api handlers read the same broker-secret ARN + rds_iam connect
|
|
@@ -74,8 +102,13 @@ locals {
|
|
|
74
102
|
DATABASE_SECRET_ARN = var.graphql_db_secret_arn
|
|
75
103
|
DATABASE_HOST = var.db_cluster_endpoint
|
|
76
104
|
DATABASE_NAME = var.database_name
|
|
105
|
+
# THINK-280 U8: the LAST rollout gate. External capability search + the
|
|
106
|
+
# Inspector governed-runtime operation layer stay inert until the broker is
|
|
107
|
+
# enabled for the stage. Off by default — read via getConfig() (env-wins).
|
|
108
|
+
CAPABILITY_EXTERNAL_SEARCH_ENABLED = var.enable_capability_broker ? "true" : "false"
|
|
109
|
+
ENABLE_CAPABILITY_BROKER = var.enable_capability_broker ? "true" : "false"
|
|
77
110
|
# BUCKET_NAME and USER_POOL_ID were duplicate aliases of WORKSPACE_BUCKET
|
|
78
|
-
# and COGNITO_USER_POOL_ID; GRAPHQL_API_KEY
|
|
111
|
+
# and COGNITO_USER_POOL_ID; the legacy GRAPHQL_API_KEY alias is retired;
|
|
79
112
|
# THINKWORK_API_SECRET and EMAIL_HMAC_SECRET duplicated API_AUTH_SECRET
|
|
80
113
|
# (~310 serialized bytes total). graphql-http sits at Lambda's hard 4KB
|
|
81
114
|
# env ceiling (#2375) — every reader falls back to the canonical name.
|
|
@@ -217,18 +250,35 @@ locals {
|
|
|
217
250
|
# window (R8). Config-class keys live ONLY in the SSM runtime-config
|
|
218
251
|
# document now — adding a key here is guarded by the identity-allowlist
|
|
219
252
|
# fixture test in apps/cli (R10). Follow-up release: DATABASE_URL,
|
|
220
|
-
#
|
|
253
|
+
# API_AUTH_SECRET drops too (readers already resolve
|
|
221
254
|
# via Secrets Manager prefetch when the env copies are absent), bringing
|
|
222
255
|
# every handler under the ≤1KB R1 target.
|
|
223
256
|
common_env = {
|
|
224
257
|
STAGE = var.stage
|
|
225
258
|
DATABASE_URL = "postgresql://${var.db_username}:${urlencode(var.db_password)}@${var.db_cluster_endpoint}:5432/${var.database_name}?sslmode=no-verify"
|
|
226
|
-
APPSYNC_API_KEY = var.appsync_api_key
|
|
227
259
|
API_AUTH_SECRET = var.api_auth_secret
|
|
228
260
|
AWS_ACCOUNT_ID = var.account_id
|
|
229
261
|
NODE_OPTIONS = "--enable-source-maps"
|
|
230
262
|
}
|
|
231
263
|
|
|
264
|
+
# THINK-316 U1: the assertion mint runs on a sibling role and receives only
|
|
265
|
+
# the database connection plus immutable stage identity. In particular it
|
|
266
|
+
# does not inherit API_AUTH_SECRET or APPSYNC_API_KEY from common_env.
|
|
267
|
+
turn_assertion_mint_env = {
|
|
268
|
+
STAGE = var.stage
|
|
269
|
+
DATABASE_URL = "postgresql://${var.db_username}:${urlencode(var.db_password)}@${var.db_cluster_endpoint}:5432/${var.database_name}?sslmode=no-verify"
|
|
270
|
+
AWS_ACCOUNT_ID = var.account_id
|
|
271
|
+
NODE_OPTIONS = "--enable-source-maps"
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
# THINK-316 U1: the synthetic provider/target are proof-only public
|
|
275
|
+
# boundaries. They receive no database URL, platform bearer, or AppSync key.
|
|
276
|
+
agentcore_proof_boundary_env = {
|
|
277
|
+
STAGE = var.stage
|
|
278
|
+
AWS_ACCOUNT_ID = var.account_id
|
|
279
|
+
NODE_OPTIONS = "--enable-source-maps"
|
|
280
|
+
}
|
|
281
|
+
|
|
232
282
|
# Per-handler env-var overrides. ARNs are constructed from the naming
|
|
233
283
|
# pattern (same trick as the api-cross-function-invoke statement in
|
|
234
284
|
# iam-grouped.tf) so we don't introduce a self-referential dependency
|
|
@@ -237,7 +287,90 @@ locals {
|
|
|
237
287
|
SLACK_APP_CREDENTIALS_SECRET_ARN = var.enable_slack_workspace_app ? aws_secretsmanager_secret.slack_app_credentials[0].arn : ""
|
|
238
288
|
}
|
|
239
289
|
|
|
290
|
+
msteams_handler_env = {
|
|
291
|
+
MSTEAMS_APP_CREDENTIALS_SECRET_ARN = var.enable_msteams_app ? aws_secretsmanager_secret.msteams_app_credentials[0].arn : ""
|
|
292
|
+
}
|
|
293
|
+
|
|
240
294
|
handler_extra_env = {
|
|
295
|
+
# THINK-316 U1: short-lived, server-minted identity assertions for
|
|
296
|
+
# AgentCore Harness and Gateway. The public mcp-oauth handler receives the
|
|
297
|
+
# key id only to publish GetPublicKey-derived JWKS; its role cannot Sign.
|
|
298
|
+
"mcp-oauth" = {
|
|
299
|
+
AGENTCORE_TURN_ASSERTION_ISSUER = local.agentcore_turn_assertion_issuer
|
|
300
|
+
AGENTCORE_TURN_ASSERTION_JWKS_KEYS = jsonencode([
|
|
301
|
+
for key in values(local.agentcore_turn_assertion_keys) : {
|
|
302
|
+
keyId = key.key_id
|
|
303
|
+
kid = key.kid
|
|
304
|
+
}
|
|
305
|
+
])
|
|
306
|
+
}
|
|
307
|
+
"skills" = {
|
|
308
|
+
AGENTCORE_IDENTITY_WORKLOAD_NAME = "thinkwork-${var.stage}-multiplayer-proof"
|
|
309
|
+
AGENTCORE_TWENTY_CREDENTIAL_PROVIDER_NAME = "thinkwork-${var.stage}-twenty-crm"
|
|
310
|
+
AGENTCORE_USER_OAUTH_RETURN_URL = "${local.mcp_oauth_api_base_url}/api/skills/mcp-oauth/agentcore/complete"
|
|
311
|
+
AGENTCORE_TWENTY_OAUTH_RESOURCE = "https://crm.thinkwork.ai/mcp"
|
|
312
|
+
}
|
|
313
|
+
"turn-assertion-mint" = {
|
|
314
|
+
AGENTCORE_TURN_ASSERTION_ISSUER = local.agentcore_turn_assertion_issuer
|
|
315
|
+
AGENTCORE_HARNESS_AUDIENCE = local.agentcore_harness_audience
|
|
316
|
+
AGENTCORE_GATEWAY_AUDIENCE = local.agentcore_gateway_audience
|
|
317
|
+
AGENTCORE_TURN_ASSERTION_KMS_KEY_ID = local.agentcore_turn_assertion_active_key.key_id
|
|
318
|
+
AGENTCORE_TURN_ASSERTION_KID = local.agentcore_turn_assertion_active_key.kid
|
|
319
|
+
}
|
|
320
|
+
"agentcore-proof-oauth-provider" = {
|
|
321
|
+
AGENTCORE_PROOF_OAUTH_ISSUER = "${local.mcp_oauth_api_base_url}/agentcore-proof/oauth"
|
|
322
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_ID = var.agentcore_proof_oauth_client_id
|
|
323
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_SECRET = var.agentcore_proof_oauth_client_secret
|
|
324
|
+
AGENTCORE_ASSERTION_ISSUER = local.agentcore_turn_assertion_issuer
|
|
325
|
+
AGENTCORE_HARNESS_AUDIENCE = local.agentcore_harness_audience
|
|
326
|
+
AGENTCORE_GATEWAY_AUDIENCE = local.agentcore_gateway_audience
|
|
327
|
+
AGENTCORE_TURN_ASSERTION_KMS_KEY_ID = local.agentcore_turn_assertion_active_key.key_id
|
|
328
|
+
AGENTCORE_TURN_ASSERTION_KID = local.agentcore_turn_assertion_active_key.kid
|
|
329
|
+
AGENTCORE_PROOF_OWNER_ALLOWLIST = var.agentcore_proof_owner_allowlist
|
|
330
|
+
}
|
|
331
|
+
"agentcore-identity-boundary-target" = {
|
|
332
|
+
AGENTCORE_PROOF_OAUTH_ISSUER = "${local.mcp_oauth_api_base_url}/agentcore-proof/oauth"
|
|
333
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_SECRET = var.agentcore_proof_oauth_client_secret
|
|
334
|
+
AGENTCORE_PROOF_OWNER_ALLOWLIST = var.agentcore_proof_owner_allowlist
|
|
335
|
+
}
|
|
336
|
+
"harness-capability-mcp" = {
|
|
337
|
+
AGENTCORE_PROOF_OAUTH_ISSUER = "${local.mcp_oauth_api_base_url}/agentcore-proof/oauth"
|
|
338
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_SECRET = var.agentcore_proof_oauth_client_secret
|
|
339
|
+
AGENTCORE_GATEWAY_POLICY_REVISION = "mcp-list-call-v2-tenant-admission"
|
|
340
|
+
AGENTCORE_IDENTITY_WORKLOAD_NAME = "thinkwork-${var.stage}-multiplayer-proof"
|
|
341
|
+
AGENTCORE_TWENTY_CREDENTIAL_PROVIDER_NAME = "thinkwork-${var.stage}-twenty-crm"
|
|
342
|
+
AGENTCORE_TWENTY_OAUTH_RESOURCE = "https://crm.thinkwork.ai/mcp"
|
|
343
|
+
}
|
|
344
|
+
"harness-code-interpreter-target" = {
|
|
345
|
+
AGENTCORE_PROOF_OAUTH_ISSUER = "${local.mcp_oauth_api_base_url}/agentcore-proof/oauth"
|
|
346
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_SECRET = var.agentcore_proof_oauth_client_secret
|
|
347
|
+
AGENTCORE_GATEWAY_POLICY_REVISION = "sandbox-execute-v1-tenant-admission"
|
|
348
|
+
}
|
|
349
|
+
"harness-builtin-tools-target" = {
|
|
350
|
+
AGENTCORE_PROOF_OAUTH_ISSUER = "${local.mcp_oauth_api_base_url}/agentcore-proof/oauth"
|
|
351
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_SECRET = var.agentcore_proof_oauth_client_secret
|
|
352
|
+
AGENTCORE_GATEWAY_POLICY_REVISION = "builtin-web-v1-tenant-admission"
|
|
353
|
+
}
|
|
354
|
+
"harness-platform-tools-target" = {
|
|
355
|
+
AGENTCORE_PROOF_OAUTH_ISSUER = "${local.mcp_oauth_api_base_url}/agentcore-proof/oauth"
|
|
356
|
+
AGENTCORE_PROOF_OAUTH_CLIENT_SECRET = var.agentcore_proof_oauth_client_secret
|
|
357
|
+
AGENTCORE_GATEWAY_POLICY_REVISION = "platform-tools-v4-user-questions"
|
|
358
|
+
}
|
|
359
|
+
"workos-auth" = {
|
|
360
|
+
# During cutover/soak the callback, bridge, and logout paths remain for
|
|
361
|
+
# already-issued state, but the handler independently refuses every new
|
|
362
|
+
# WorkOS authorize start. Terraform removes the handler in retired.
|
|
363
|
+
AUTH_RETIREMENT_PHASE = var.auth_retirement_phase
|
|
364
|
+
}
|
|
365
|
+
"public-auth-options" = {
|
|
366
|
+
AUTH_RETIREMENT_PHASE = var.auth_retirement_phase
|
|
367
|
+
}
|
|
368
|
+
"auth-me" = {
|
|
369
|
+
AUTH_MIGRATION_RECOVERY_DEADLINE = var.auth_migration_recovery_deadline
|
|
370
|
+
}
|
|
371
|
+
"auth-enrollment" = {
|
|
372
|
+
AUTH_MIGRATION_RECOVERY_DEADLINE = var.auth_migration_recovery_deadline
|
|
373
|
+
}
|
|
241
374
|
# Analyst query broker (THINK-228 U3). Reader role + caller credential
|
|
242
375
|
# secrets, and the workspace bucket's analyst-staging/ prefix for
|
|
243
376
|
# large-result CSVs (lifecycle TTL lives on the bucket module). The
|
|
@@ -302,6 +435,17 @@ locals {
|
|
|
302
435
|
THINKWORK_RELEASE_VERSION = var.deployment_release_version
|
|
303
436
|
THINKWORK_RELEASE_MANIFEST_URL = var.deployment_release_manifest_url
|
|
304
437
|
THINKWORK_RELEASE_MANIFEST_SHA256 = var.deployment_release_manifest_sha256
|
|
438
|
+
# THINK-280 — createTenant RequestResponse-invokes agentcore-admin to
|
|
439
|
+
# provision the per-tenant sandbox. sandbox-provisioning.ts reads both
|
|
440
|
+
# from process.env directly (the token is a secret → env, never the SSM
|
|
441
|
+
# String doc). Broker-session build reads the three broker values below
|
|
442
|
+
# (broker-session.ts); all EMPTY when the broker is disabled → inert.
|
|
443
|
+
AGENTCORE_ADMIN_LAMBDA_ARN = var.agentcore_admin_lambda_arn
|
|
444
|
+
AGENTCORE_ADMIN_TOKEN = var.agentcore_admin_token
|
|
445
|
+
CAPABILITY_BROKER_AUDIENCE = var.capability_broker_audience
|
|
446
|
+
CAPABILITY_BROKER_API_ID = var.capability_broker_api_id
|
|
447
|
+
CAPABILITY_BROKER_VPCE_DNS = var.capability_broker_vpce_dns
|
|
448
|
+
CAPABILITY_BROKER_SESSION_TABLE = var.capability_broker_session_table
|
|
305
449
|
}
|
|
306
450
|
# Compounding Memory compile Lambda. Any Converse-compatible Bedrock
|
|
307
451
|
# model works; the planner + section-writer cap themselves at ~500
|
|
@@ -343,12 +487,25 @@ locals {
|
|
|
343
487
|
BRAIN_ARTIFACTS_BUCKET = aws_s3_bucket.brain_artifacts.bucket
|
|
344
488
|
OKF_EFS_ROOT = var.okf_efs_mount_path
|
|
345
489
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
"
|
|
350
|
-
|
|
351
|
-
|
|
490
|
+
# THINK-193 U1 (Codex F6): normalized evidence snapshots live in the
|
|
491
|
+
# encrypted brain-artifacts bucket under evidence-snapshots/ — Postgres
|
|
492
|
+
# keeps only the s3:// ref + hash. 30-day lifecycle expiration below.
|
|
493
|
+
"memory-stage-worker" = {
|
|
494
|
+
BRAIN_ARTIFACTS_BUCKET = aws_s3_bucket.brain_artifacts.bucket
|
|
495
|
+
}
|
|
496
|
+
# THINK-193 U2 (Codex S1/S2): the retraction drainer performs the
|
|
497
|
+
# versioned evidence-snapshot deletion for source erases under its
|
|
498
|
+
# DEDICATED role (below) — the only place bulk destructive S3 runs.
|
|
499
|
+
"memory-retraction-drainer" = {
|
|
500
|
+
BRAIN_ARTIFACTS_BUCKET = aws_s3_bucket.brain_artifacts.bucket
|
|
501
|
+
}
|
|
502
|
+
"oauth-authorize" = local.slack_handler_env
|
|
503
|
+
"oauth-callback" = local.slack_handler_env
|
|
504
|
+
"slack-events" = local.slack_handler_env
|
|
505
|
+
"slack-oauth-install" = local.slack_handler_env
|
|
506
|
+
"msteams-install-start" = local.msteams_handler_env
|
|
507
|
+
"msteams-install-complete" = local.msteams_handler_env
|
|
508
|
+
"msteams-account-link-complete" = local.msteams_handler_env
|
|
352
509
|
"thread-attachments-finalize" = {
|
|
353
510
|
REQUESTER_IDLE_MEMORY_LEARNING_ENABLED = tostring(var.requester_idle_memory_learning_enabled)
|
|
354
511
|
}
|
|
@@ -364,7 +521,15 @@ locals {
|
|
|
364
521
|
# knowledge_graph_search tool; the per-agent tool policy gates on top.
|
|
365
522
|
"chat-agent-invoke" = {
|
|
366
523
|
KNOWLEDGE_GRAPH_TOOL_ENABLED = tostring(var.knowledge_graph_tool_enabled)
|
|
367
|
-
|
|
524
|
+
# THINK-311 U5: no HARNESS_RUNNER_FUNCTION_NAME env — derivable
|
|
525
|
+
# thinkwork-<stage>-api-* names never ride env (R1/R10 identity-only
|
|
526
|
+
# rule); resolveRuntimeFunctionName derives it from STAGE at call
|
|
527
|
+
# time, exactly like workspace-renderer.
|
|
528
|
+
}
|
|
529
|
+
# THINK-316 U5: the runner reads the server-only attested profile and
|
|
530
|
+
# invokes its named endpoint with a purpose-bound CUSTOM_JWT. It receives
|
|
531
|
+
# no Harness control-plane inputs or permissions.
|
|
532
|
+
"harness-runner" = {}
|
|
368
533
|
# 240s: sync Hindsight retain (LLM extraction + auto-consolidation) can
|
|
369
534
|
# exceed 60s; the client timeout must stay below the Lambda timeout (300s)
|
|
370
535
|
# and below the Hindsight ALB idle_timeout (300s) so failures classify as
|
|
@@ -395,6 +560,15 @@ locals {
|
|
|
395
560
|
# invocation (never Lambda self-invoke — AWS recursive-loop
|
|
396
561
|
# detection terminates worker-to-self Event chains).
|
|
397
562
|
KG_OBS_MAX_CANDIDATES_PER_RUN = var.kg_obs_max_candidates_per_run
|
|
563
|
+
# THINK-193 U4 dead-handoff fix: a successful observations ingest
|
|
564
|
+
# enqueues the tenant graph wiki-compile job inside its own commit
|
|
565
|
+
# and Event-invokes wiki-compile post-commit. WIKI_SOURCE must match
|
|
566
|
+
# the wiki-compile handler's dispatch flag (stage-global); the
|
|
567
|
+
# per-tenant kill switch stays tenants.wiki_compile_enabled. The
|
|
568
|
+
# invoke rides the shared lambda role's existing wiki-compile
|
|
569
|
+
# lambda:InvokeFunction grant (iam-grouped.tf); the function name is
|
|
570
|
+
# derived from STAGE (common_env) at call time.
|
|
571
|
+
WIKI_SOURCE = var.wiki_source
|
|
398
572
|
}
|
|
399
573
|
# routine-task-python (Phase B U6) needs the AgentCore code-interpreter
|
|
400
574
|
# id + the per-stage S3 routine-output bucket. The interpreter id is
|
|
@@ -414,6 +588,14 @@ locals {
|
|
|
414
588
|
"routine-exec-git" = {
|
|
415
589
|
SANDBOX_INTERPRETER_ID = var.agentcore_code_interpreter_id
|
|
416
590
|
ROUTINE_OUTPUT_BUCKET = "thinkwork-${var.stage}-routine-output"
|
|
591
|
+
# THINK-280 U7 — the headless capability executor runs inside
|
|
592
|
+
# routine-exec-git and mints broker sessions. routine-exec-git.ts +
|
|
593
|
+
# capability-headless-executor.ts read all four from process.env; all
|
|
594
|
+
# EMPTY when the broker is disabled → the executor stays inert.
|
|
595
|
+
CAPABILITY_BROKER_SESSION_TABLE = var.capability_broker_session_table
|
|
596
|
+
CAPABILITY_BROKER_AUDIENCE = var.capability_broker_audience
|
|
597
|
+
CAPABILITY_BROKER_API_ID = var.capability_broker_api_id
|
|
598
|
+
CAPABILITY_BROKER_VPCE_DNS = var.capability_broker_vpce_dns
|
|
417
599
|
}
|
|
418
600
|
# graphql-http hosts the createRoutine / publishRoutineVersion / etc.
|
|
419
601
|
# resolvers (Phase B U7) AND the routine-approval-bridge (Phase B
|
|
@@ -561,6 +743,23 @@ resource "aws_lambda_function" "handler" {
|
|
|
561
743
|
# Bearer API_AUTH_SECRET. Idempotent on thread_turns.finalized_at
|
|
562
744
|
# (migration 0123). Plan: 2026-05-22-006.
|
|
563
745
|
"chat-agent-finalize",
|
|
746
|
+
# harness-runner — THINK-311 U5: Event-mode target for harness-flagged
|
|
747
|
+
# agents. The chat dispatch selector (resolveRuntimeFunctionName) routes
|
|
748
|
+
# a trial agent's turn here instead of the Pi container Lambda; the
|
|
749
|
+
# runner projects the payload into an AWS AgentCore Harness config,
|
|
750
|
+
# drives InvokeHarness, fulfills emit_document, and finalizes the turn
|
|
751
|
+
# via processFinalize. No API route — direct Event invoke only.
|
|
752
|
+
"harness-runner",
|
|
753
|
+
# THINK-316 U1: direct-invoke-only assertion mint. It derives all identity
|
|
754
|
+
# claims from the persisted turn tuple and signs with a dedicated KMS key;
|
|
755
|
+
# there is intentionally no public API Gateway route.
|
|
756
|
+
"turn-assertion-mint",
|
|
757
|
+
"agentcore-proof-oauth-provider",
|
|
758
|
+
"agentcore-identity-boundary-target",
|
|
759
|
+
"harness-capability-mcp",
|
|
760
|
+
"harness-code-interpreter-target",
|
|
761
|
+
"harness-builtin-tools-target",
|
|
762
|
+
"harness-platform-tools-target",
|
|
564
763
|
# canvas-refresh — headless Living Artifacts data-refresh (THINK-145 U6).
|
|
565
764
|
# Invoked RequestResponse by the refreshCanvasData mutation (graphql-http)
|
|
566
765
|
# and by job-trigger's canvas_refresh branch (U7). Re-runs the saved
|
|
@@ -594,7 +793,13 @@ resource "aws_lambda_function" "handler" {
|
|
|
594
793
|
"stripe-subscription",
|
|
595
794
|
"deployment-sessions",
|
|
596
795
|
"auth-me",
|
|
796
|
+
"auth-revoke",
|
|
797
|
+
"auth-enrollment",
|
|
798
|
+
"auth-subscription-ticket",
|
|
799
|
+
"appsync-subscription-authorizer",
|
|
800
|
+
"subscription-invalidation",
|
|
597
801
|
"public-auth-options",
|
|
802
|
+
"auth-provider-reconcile",
|
|
598
803
|
"workos-auth",
|
|
599
804
|
# Public artifact share links (THINK-208): GET /share/{token}, token
|
|
600
805
|
# verified in handler code (no gateway auth, uniform 404 on any miss).
|
|
@@ -608,6 +813,8 @@ resource "aws_lambda_function" "handler" {
|
|
|
608
813
|
"mcp-user-memory",
|
|
609
814
|
"mcp-context-engine",
|
|
610
815
|
"mcp-open-engine",
|
|
816
|
+
# THINK-280 U8: scoped external capability search MCP facade.
|
|
817
|
+
"mcp-capability-search",
|
|
611
818
|
"activity",
|
|
612
819
|
"routines",
|
|
613
820
|
"budgets",
|
|
@@ -642,13 +849,28 @@ resource "aws_lambda_function" "handler" {
|
|
|
642
849
|
"email-provider-webhook",
|
|
643
850
|
"email-readiness-probe",
|
|
644
851
|
"slack-events",
|
|
645
|
-
"slack-slash-command",
|
|
646
|
-
"slack-interactivity",
|
|
647
852
|
"slack-oauth-install",
|
|
853
|
+
"msteams-install-start",
|
|
854
|
+
"msteams-install-complete",
|
|
855
|
+
"msteams-account-link-complete",
|
|
648
856
|
"github-app",
|
|
649
857
|
"memory",
|
|
650
858
|
"memory-retain",
|
|
651
859
|
"brain-dream-state",
|
|
860
|
+
"memory-stage-worker",
|
|
861
|
+
# THINK-193 U2 (Codex P1 #3): scheduled retry drainer for the retraction
|
|
862
|
+
# saga ledger. Claims due/stale memory_retraction_attempts rows with the
|
|
863
|
+
# locked_by + lock_generation fence, processes each via the saga, sweeps
|
|
864
|
+
# exhausted rows to dead_lettered, and emits structured-log metrics.
|
|
865
|
+
# rate(5 minutes) EventBridge Scheduler + MaxRetryAttempts=0 (dedicated
|
|
866
|
+
# resources below) — the next tick IS the retry.
|
|
867
|
+
"memory-retraction-drainer",
|
|
868
|
+
# THINK-193 U3: stalled memory_stage token sweeper — re-invokes the
|
|
869
|
+
# memory-stage-worker for pending/executing tokens past their lease and
|
|
870
|
+
# redrives consumed-but-unsent results; unrecoverable parks get a
|
|
871
|
+
# terminal step event + SendTaskFailure. rate(15 minutes) schedule
|
|
872
|
+
# (dedicated resource below).
|
|
873
|
+
"memory-stage-sweeper",
|
|
652
874
|
"wiki-compile",
|
|
653
875
|
"knowledge-graph-observations-ingest",
|
|
654
876
|
"ontology-scan",
|
|
@@ -791,6 +1013,14 @@ resource "aws_lambda_function" "handler" {
|
|
|
791
1013
|
# POSTs one row per agent-session-start. Shared
|
|
792
1014
|
# API_AUTH_SECRET bearer (runtime→API; no tenant OAuth).
|
|
793
1015
|
"manifest-log",
|
|
1016
|
+
# Governed capability runtime control-plane service (THINK-280 U2).
|
|
1017
|
+
# NO HTTP route: the Pi container invokes it directly (RequestResponse)
|
|
1018
|
+
# via lambda:InvokeFunction over the approved in-account path — public
|
|
1019
|
+
# execute-api is not reliable from Pi's private VPC. Identity comes
|
|
1020
|
+
# exclusively from the Ed25519-signed capability caller context (the
|
|
1021
|
+
# CAPABILITY_SIGNING_PUBLIC_KEY in the shared runtime-config document
|
|
1022
|
+
# verifies it); plaintext payload fields are never trusted.
|
|
1023
|
+
"capability-control-service",
|
|
794
1024
|
# SI-7 catalog-list read endpoint (plan §U15 pt 3/3). The runtime
|
|
795
1025
|
# fetches the allowed builtin-tool slug set once per
|
|
796
1026
|
# session-start + feature-flag-gated enforcement filter drops
|
|
@@ -831,9 +1061,13 @@ resource "aws_lambda_function" "handler" {
|
|
|
831
1061
|
]), toset(local.optional_integration_handler_names)) : toset([])
|
|
832
1062
|
|
|
833
1063
|
function_name = "thinkwork-${var.stage}-api-${each.key}"
|
|
834
|
-
role
|
|
835
|
-
|
|
836
|
-
|
|
1064
|
+
# S2 (THINK-193 U2): memory-retraction-drainer runs under a DEDICATED role
|
|
1065
|
+
# so its destructive evidence-snapshot S3 capability (version enumeration +
|
|
1066
|
+
# bulk version deletion) never leaks into the 90+ handlers on the shared
|
|
1067
|
+
# role. Everything else keeps the shared role.
|
|
1068
|
+
role = each.key == "memory-retraction-drainer" ? aws_iam_role.memory_retraction_drainer.arn : each.key == "turn-assertion-mint" ? aws_iam_role.turn_assertion_mint[0].arn : each.key == "agentcore-proof-oauth-provider" ? aws_iam_role.agentcore_proof_provider[0].arn : each.key == "agentcore-identity-boundary-target" ? aws_iam_role.agentcore_proof_boundary[0].arn : aws_iam_role.lambda.arn
|
|
1069
|
+
handler = "index.handler"
|
|
1070
|
+
runtime = local.runtime
|
|
837
1071
|
# Parameters and Secrets extension: container-local cache for the SSM
|
|
838
1072
|
# runtime-config document + Secrets Manager reads (runtime-config.tf).
|
|
839
1073
|
layers = local.api_handler_layers
|
|
@@ -844,7 +1078,6 @@ resource "aws_lambda_function" "handler" {
|
|
|
844
1078
|
depends_on = [
|
|
845
1079
|
aws_ssm_parameter.runtime_config,
|
|
846
1080
|
aws_secretsmanager_secret_version.api_auth,
|
|
847
|
-
aws_secretsmanager_secret_version.appsync_api_key,
|
|
848
1081
|
]
|
|
849
1082
|
# eval-runner walks every test case sequentially, invoking an agent +
|
|
850
1083
|
# waiting up to 2 min for spans to propagate per test, so a 10-test run
|
|
@@ -859,8 +1092,11 @@ resource "aws_lambda_function" "handler" {
|
|
|
859
1092
|
# validates the agent, builds the AgentCore invoke payload, dispatches
|
|
860
1093
|
# Event-mode, and returns. Setup is ~5s in practice; 60s gives 12×
|
|
861
1094
|
# headroom for transient slowness.
|
|
862
|
-
|
|
863
|
-
|
|
1095
|
+
# harness-runner holds the Lambda open for the full Harness turn (the
|
|
1096
|
+
# reference QBR run was ~2 min; 900s is the ceiling — a longer run is a
|
|
1097
|
+
# legitimate trial limitation, recorded, not engineered around).
|
|
1098
|
+
timeout = each.key == "harness-runner" ? 900 : each.key == "wakeup-processor" ? 300 : each.key == "chat-agent-invoke" ? 60 : each.key == "chat-agent-finalize" ? 60 : each.key == "workspace-event-dispatcher" ? 60 : each.key == "eval-runner" ? 900 : each.key == "eval-worker" ? 240 : each.key == "wiki-compile" ? 480 : each.key == "knowledge-graph-observations-ingest" ? 480 : each.key == "requester-memory-dreaming" ? 300 : each.key == "ontology-scan" ? 300 : each.key == "ontology-reprocess" ? 300 : each.key == "wiki-lint" ? 300 : each.key == "wiki-export" ? 600 : each.key == "okf-materialize" ? 600 : each.key == "okf-efs-refresh" ? 600 : each.key == "wiki-bootstrap-import" ? 900 : each.key == "folder-bundle-import" ? 300 : each.key == "routine-task-python" ? 360 : each.key == "routine-exec-git" ? 360 : each.key == "job-trigger" ? 600 : each.key == "model-converse" ? 60 : each.key == "memory-retain" ? 300 : each.key == "brain-dream-state" ? 900 : each.key == "memory-stage-worker" ? 900 : each.key == "memory-stage-sweeper" ? 120 : each.key == "memory-retraction-drainer" ? 300 : each.key == "canvas-refresh" ? 120 : each.key == "document-conformance-judge" ? 300 : each.key == "workflow-step-dispatch" ? 600 : each.key == "workflow-execution-callback" ? 60 : each.key == "workflow-resume" ? 60 : 30
|
|
1099
|
+
memory_size = each.key == "harness-runner" ? 512 : each.key == "graphql-http" ? 512 : each.key == "wakeup-processor" ? 512 : each.key == "workspace-event-dispatcher" ? 512 : each.key == "eval-runner" ? 512 : each.key == "eval-worker" ? 512 : each.key == "wiki-compile" ? 1024 : each.key == "knowledge-graph-observations-ingest" ? 1024 : each.key == "requester-memory-dreaming" ? 512 : each.key == "ontology-scan" ? 512 : each.key == "wiki-export" ? 1024 : each.key == "okf-materialize" ? 1024 : each.key == "okf-efs-refresh" ? 1024 : each.key == "wiki-bootstrap-import" ? 1024 : each.key == "folder-bundle-import" ? 1024 : 256
|
|
864
1100
|
|
|
865
1101
|
filename = local.use_local_zips ? "${var.lambda_zips_dir}/${each.key}.zip" : null
|
|
866
1102
|
source_code_hash = local.use_local_zips ? filebase64sha256("${var.lambda_zips_dir}/${each.key}.zip") : null
|
|
@@ -889,7 +1125,10 @@ resource "aws_lambda_function" "handler" {
|
|
|
889
1125
|
|
|
890
1126
|
environment {
|
|
891
1127
|
variables = merge(
|
|
892
|
-
local.
|
|
1128
|
+
each.key == "turn-assertion-mint" ? local.turn_assertion_mint_env : contains([
|
|
1129
|
+
"agentcore-proof-oauth-provider",
|
|
1130
|
+
"agentcore-identity-boundary-target",
|
|
1131
|
+
], each.key) ? local.agentcore_proof_boundary_env : local.common_env,
|
|
893
1132
|
{ FUNCTION_NAME = each.key },
|
|
894
1133
|
lookup(local.handler_extra_env, each.key, {}),
|
|
895
1134
|
)
|
|
@@ -904,6 +1143,19 @@ resource "aws_lambda_function" "handler" {
|
|
|
904
1143
|
}
|
|
905
1144
|
}
|
|
906
1145
|
|
|
1146
|
+
# Analyst data-path handlers get a stable NAT egress IP when
|
|
1147
|
+
# analyst_egress_subnet_ids is set — external Postgres sources behind an IP
|
|
1148
|
+
# allowlist admit that one EIP. Disjoint from the okf-efs-refresh block
|
|
1149
|
+
# above (a function takes at most one vpc_config).
|
|
1150
|
+
dynamic "vpc_config" {
|
|
1151
|
+
for_each = contains(local.analyst_vpc_handlers, each.key) && local.analyst_vpc_enabled ? [1] : []
|
|
1152
|
+
|
|
1153
|
+
content {
|
|
1154
|
+
subnet_ids = var.analyst_egress_subnet_ids
|
|
1155
|
+
security_group_ids = var.analyst_egress_security_group_ids
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
907
1159
|
dynamic "file_system_config" {
|
|
908
1160
|
for_each = each.key == "okf-efs-refresh" && local.okf_efs_vpc_enabled ? [1] : []
|
|
909
1161
|
|
|
@@ -973,6 +1225,20 @@ resource "aws_lambda_function_event_invoke_config" "chat_agent_invoke" {
|
|
|
973
1225
|
maximum_event_age_in_seconds = 3600
|
|
974
1226
|
}
|
|
975
1227
|
|
|
1228
|
+
# harness-runner retry-0 (THINK-311 U5, async-retry idempotency): an AWS
|
|
1229
|
+
# async retry would re-execute a whole agent turn. Failures finalize the
|
|
1230
|
+
# turn in-process (finalize-through-failure); a hard crash is reconciled
|
|
1231
|
+
# by the stall monitor (timed_out + checkout release, no retry enqueue
|
|
1232
|
+
# for harness turns). No DLQ destination for the same reason as
|
|
1233
|
+
# chat-agent-invoke above: the shared role's inline policy budget is at
|
|
1234
|
+
# the AWS cap, and the stall monitor is the operational surface.
|
|
1235
|
+
resource "aws_lambda_function_event_invoke_config" "harness_runner" {
|
|
1236
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
1237
|
+
function_name = aws_lambda_function.handler["harness-runner"].function_name
|
|
1238
|
+
maximum_retry_attempts = 0
|
|
1239
|
+
maximum_event_age_in_seconds = 3600
|
|
1240
|
+
}
|
|
1241
|
+
|
|
976
1242
|
resource "aws_lambda_function_event_invoke_config" "wiki_compile" {
|
|
977
1243
|
count = local.deploy_lambda_handlers ? 1 : 0
|
|
978
1244
|
function_name = aws_lambda_function.handler["wiki-compile"].function_name
|
|
@@ -1061,6 +1327,21 @@ resource "aws_lambda_function_event_invoke_config" "routine_approval_callback" {
|
|
|
1061
1327
|
# retain-cost path (Bedrock tokens charged in adapter.retainConversation)
|
|
1062
1328
|
# is NOT idempotent — retries multiply LLM cost. Per
|
|
1063
1329
|
# project_async_retry_idempotency_lessons.
|
|
1330
|
+
# memory-stage-worker (THINK-193 U1): Event-invoked by workflow-step-dispatch
|
|
1331
|
+
# AFTER the memory_stage task token is stored. Lambda async retries are
|
|
1332
|
+
# disabled like its memory siblings — the worker's stages are idempotent, but
|
|
1333
|
+
# an automatic re-execution would race the original's token CAS and turn a
|
|
1334
|
+
# completed stage into a spurious failure. A worker that dies without
|
|
1335
|
+
# resuming the token is bounded by the state machine's HeartbeatSeconds
|
|
1336
|
+
# (3600s): the parked step times out and the run fails visibly, and a
|
|
1337
|
+
# re-triggered run self-heals from the durable checkpoint/evidence ledger.
|
|
1338
|
+
resource "aws_lambda_function_event_invoke_config" "memory_stage_worker" {
|
|
1339
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
1340
|
+
function_name = aws_lambda_function.handler["memory-stage-worker"].function_name
|
|
1341
|
+
maximum_retry_attempts = 0
|
|
1342
|
+
maximum_event_age_in_seconds = 3600
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1064
1345
|
resource "aws_lambda_function_event_invoke_config" "memory_retain" {
|
|
1065
1346
|
count = local.deploy_lambda_handlers ? 1 : 0
|
|
1066
1347
|
function_name = aws_lambda_function.handler["memory-retain"].function_name
|
|
@@ -1068,6 +1349,132 @@ resource "aws_lambda_function_event_invoke_config" "memory_retain" {
|
|
|
1068
1349
|
maximum_event_age_in_seconds = 3600
|
|
1069
1350
|
}
|
|
1070
1351
|
|
|
1352
|
+
# ---------------------------------------------------------------------------
|
|
1353
|
+
# THINK-193 U2 (Codex S2): dedicated IAM role for memory-retraction-drainer.
|
|
1354
|
+
#
|
|
1355
|
+
# The drainer is the ONLY principal allowed to enumerate and bulk-delete
|
|
1356
|
+
# evidence-snapshot object VERSIONS (S1: the brain-artifacts bucket is
|
|
1357
|
+
# versioned; erase completeness requires deleting every noncurrent version
|
|
1358
|
+
# and delete marker under the source prefix). Granting that on the shared
|
|
1359
|
+
# api-lambda role would let every unrelated handler destroy any tenant's
|
|
1360
|
+
# evidence — hence the sibling-role pattern (same as
|
|
1361
|
+
# compliance-anchor-watchdog). The role otherwise carries only what the
|
|
1362
|
+
# drainer actually uses: logs (managed basic policy), Secrets Manager +
|
|
1363
|
+
# SSM runtime-config reads, and conditional KMS for the encrypted bucket.
|
|
1364
|
+
# ---------------------------------------------------------------------------
|
|
1365
|
+
|
|
1366
|
+
resource "aws_iam_role" "memory_retraction_drainer" {
|
|
1367
|
+
name = "thinkwork-${var.stage}-memory-retraction-drainer-role"
|
|
1368
|
+
|
|
1369
|
+
assume_role_policy = jsonencode({
|
|
1370
|
+
Version = "2012-10-17"
|
|
1371
|
+
Statement = [{
|
|
1372
|
+
Effect = "Allow"
|
|
1373
|
+
Principal = { Service = "lambda.amazonaws.com" }
|
|
1374
|
+
Action = "sts:AssumeRole"
|
|
1375
|
+
}]
|
|
1376
|
+
})
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
resource "aws_iam_role_policy_attachment" "memory_retraction_drainer_basic" {
|
|
1380
|
+
role = aws_iam_role.memory_retraction_drainer.name
|
|
1381
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
resource "aws_iam_role_policy" "memory_retraction_drainer" {
|
|
1385
|
+
name = "memory-retraction-drainer"
|
|
1386
|
+
role = aws_iam_role.memory_retraction_drainer.id
|
|
1387
|
+
|
|
1388
|
+
policy = jsonencode({
|
|
1389
|
+
Version = "2012-10-17"
|
|
1390
|
+
Statement = concat(
|
|
1391
|
+
[
|
|
1392
|
+
# Versioned evidence-snapshot destruction, evidence-snapshots/ only.
|
|
1393
|
+
{
|
|
1394
|
+
Effect = "Allow"
|
|
1395
|
+
Action = [
|
|
1396
|
+
"s3:DeleteObject",
|
|
1397
|
+
"s3:DeleteObjectVersion",
|
|
1398
|
+
]
|
|
1399
|
+
Resource = "${aws_s3_bucket.brain_artifacts.arn}/evidence-snapshots/*"
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
Effect = "Allow"
|
|
1403
|
+
Action = [
|
|
1404
|
+
"s3:ListBucket",
|
|
1405
|
+
"s3:ListBucketVersions",
|
|
1406
|
+
]
|
|
1407
|
+
Resource = aws_s3_bucket.brain_artifacts.arn
|
|
1408
|
+
Condition = {
|
|
1409
|
+
StringLike = {
|
|
1410
|
+
"s3:prefix" = "evidence-snapshots/*"
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
},
|
|
1414
|
+
# Runtime-config document + platform secrets (DATABASE_URL rides the
|
|
1415
|
+
# env during the R8 transition window; the loader prefetches the
|
|
1416
|
+
# api-auth/appsync secrets at cold start).
|
|
1417
|
+
{
|
|
1418
|
+
Effect = "Allow"
|
|
1419
|
+
Action = ["ssm:GetParameter", "ssm:GetParameters"]
|
|
1420
|
+
Resource = "arn:aws:ssm:${var.region}:${var.account_id}:parameter/thinkwork/${var.stage}/*"
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
Effect = "Allow"
|
|
1424
|
+
Action = ["secretsmanager:GetSecretValue"]
|
|
1425
|
+
Resource = "arn:aws:secretsmanager:${var.region}:${var.account_id}:secret:thinkwork/*"
|
|
1426
|
+
},
|
|
1427
|
+
],
|
|
1428
|
+
var.brain_artifacts_kms_key_arn != "" ? [
|
|
1429
|
+
{
|
|
1430
|
+
Effect = "Allow"
|
|
1431
|
+
Action = [
|
|
1432
|
+
"kms:Decrypt",
|
|
1433
|
+
"kms:GenerateDataKey",
|
|
1434
|
+
]
|
|
1435
|
+
Resource = var.brain_artifacts_kms_key_arn
|
|
1436
|
+
},
|
|
1437
|
+
] : [],
|
|
1438
|
+
)
|
|
1439
|
+
})
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
# memory-retraction-drainer (THINK-193 U2, Codex P1 #3): the retraction
|
|
1443
|
+
# saga's product-owned retry path. Lambda async retries are disabled — every
|
|
1444
|
+
# transition on memory_retraction_attempts is a fenced CAS, so a duplicate
|
|
1445
|
+
# invocation is harmless but pointless; the rate(5 minutes) schedule below
|
|
1446
|
+
# is the retry. Attempts exceeding max_attempts are swept to dead_lettered
|
|
1447
|
+
# by the drainer itself instead of retrying forever.
|
|
1448
|
+
resource "aws_lambda_function_event_invoke_config" "memory_retraction_drainer" {
|
|
1449
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
1450
|
+
function_name = aws_lambda_function.handler["memory-retraction-drainer"].function_name
|
|
1451
|
+
maximum_retry_attempts = 0
|
|
1452
|
+
maximum_event_age_in_seconds = 3600
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
resource "aws_scheduler_schedule" "memory_retraction_drainer" {
|
|
1456
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
1457
|
+
|
|
1458
|
+
name = "thinkwork-${var.stage}-memory-retraction-drainer"
|
|
1459
|
+
group_name = "default"
|
|
1460
|
+
schedule_expression = "rate(5 minutes)"
|
|
1461
|
+
state = "ENABLED"
|
|
1462
|
+
|
|
1463
|
+
flexible_time_window {
|
|
1464
|
+
mode = "OFF"
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
target {
|
|
1468
|
+
arn = aws_lambda_function.handler["memory-retraction-drainer"].arn
|
|
1469
|
+
role_arn = aws_iam_role.scheduler.arn
|
|
1470
|
+
input = jsonencode({ limit = 25 })
|
|
1471
|
+
|
|
1472
|
+
retry_policy {
|
|
1473
|
+
maximum_retry_attempts = 0
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1071
1478
|
# Product-owned retry path for memory-retain. Lambda async retries remain
|
|
1072
1479
|
# disabled above; this scheduled drain claims due rows from
|
|
1073
1480
|
# memory_retain_attempts and replays bounded retry payloads idempotently.
|
|
@@ -1202,8 +1609,13 @@ locals {
|
|
|
1202
1609
|
# Public login capabilities. Unauthenticated by design; the handler
|
|
1203
1610
|
# resolves tenant-scoped OAuth options only from trusted API Gateway
|
|
1204
1611
|
# domain metadata and fails closed for unknown/shared hosts.
|
|
1205
|
-
"GET /api/auth/options"
|
|
1206
|
-
"OPTIONS /api/auth/options"
|
|
1612
|
+
"GET /api/auth/options" = "public-auth-options"
|
|
1613
|
+
"OPTIONS /api/auth/options" = "public-auth-options"
|
|
1614
|
+
# Operator/deployment-only metadata seam. The Lambda independently
|
|
1615
|
+
# verifies API_AUTH_SECRET and rejects raw secret values.
|
|
1616
|
+
"POST /api/auth/providers/reconcile" = "auth-provider-reconcile"
|
|
1617
|
+
# Rollback-only routes. No native client links to these, and the entire
|
|
1618
|
+
# handler is filtered from Lambda/API Gateway in the retired phase.
|
|
1207
1619
|
"GET /api/auth/workos/authorize" = "workos-auth"
|
|
1208
1620
|
"OPTIONS /api/auth/workos/authorize" = "workos-auth"
|
|
1209
1621
|
"GET /api/auth/workos/callback" = "workos-auth"
|
|
@@ -1303,14 +1715,43 @@ locals {
|
|
|
1303
1715
|
"GET /.well-known/oauth-authorization-server" = "mcp-oauth"
|
|
1304
1716
|
"GET /.well-known/openid-configuration" = "mcp-oauth"
|
|
1305
1717
|
"GET /mcp/oauth/jwks" = "mcp-oauth"
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
"GET /
|
|
1309
|
-
"
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
"
|
|
1718
|
+
# THINK-316 U1: AgentCore CUSTOM_JWT discovery is deliberately isolated
|
|
1719
|
+
# under /agentcore so the existing user-memory OAuth issuer is unchanged.
|
|
1720
|
+
"GET /agentcore/.well-known/openid-configuration" = "mcp-oauth"
|
|
1721
|
+
"GET /agentcore/oauth/jwks" = "mcp-oauth"
|
|
1722
|
+
# THINK-316 U1 proof-only provider and downstream HTTPS target. Both
|
|
1723
|
+
# handlers validate their own credentials; the route filter removes all
|
|
1724
|
+
# five when enable_agentcore_multiplayer_proof is false.
|
|
1725
|
+
"GET /agentcore-proof/oauth/.well-known/openid-configuration" = "agentcore-proof-oauth-provider"
|
|
1726
|
+
"GET /agentcore-proof/oauth/authorize" = "agentcore-proof-oauth-provider"
|
|
1727
|
+
"POST /agentcore-proof/oauth/token" = "agentcore-proof-oauth-provider"
|
|
1728
|
+
"GET /agentcore-proof/target/owner" = "agentcore-identity-boundary-target"
|
|
1729
|
+
"GET /agentcore-proof/target/mixed" = "agentcore-identity-boundary-target"
|
|
1730
|
+
"POST /agentcore/capabilities/mcp/tools/list" = "harness-capability-mcp"
|
|
1731
|
+
"POST /agentcore/capabilities/mcp/tools/call" = "harness-capability-mcp"
|
|
1732
|
+
"POST /agentcore/capabilities/sandbox/execute" = "harness-code-interpreter-target"
|
|
1733
|
+
"POST /agentcore/capabilities/web/search" = "harness-builtin-tools-target"
|
|
1734
|
+
"POST /agentcore/capabilities/web/extract" = "harness-builtin-tools-target"
|
|
1735
|
+
"POST /agentcore/capabilities/brain/query" = "harness-platform-tools-target"
|
|
1736
|
+
"POST /agentcore/capabilities/workspace/skills/list" = "harness-platform-tools-target"
|
|
1737
|
+
"POST /agentcore/capabilities/workspace/skills/load" = "harness-platform-tools-target"
|
|
1738
|
+
"POST /agentcore/capabilities/message/attachments/list" = "harness-platform-tools-target"
|
|
1739
|
+
"POST /agentcore/capabilities/message/attachments/read" = "harness-platform-tools-target"
|
|
1740
|
+
"POST /agentcore/capabilities/user/questions/ask" = "harness-platform-tools-target"
|
|
1741
|
+
"POST /agentcore/capabilities/email/send" = "harness-platform-tools-target"
|
|
1742
|
+
"POST /mcp/oauth/register" = "mcp-oauth"
|
|
1743
|
+
"GET /mcp/oauth/authorize" = "mcp-oauth"
|
|
1744
|
+
"GET /mcp/oauth/callback" = "mcp-oauth"
|
|
1745
|
+
"POST /mcp/oauth/token" = "mcp-oauth"
|
|
1746
|
+
"POST /mcp/oauth/revoke" = "mcp-oauth"
|
|
1747
|
+
"ANY /mcp/user-memory" = "mcp-user-memory"
|
|
1748
|
+
"ANY /mcp/context-engine" = "mcp-context-engine"
|
|
1749
|
+
"ANY /mcp/open-engine" = "mcp-open-engine"
|
|
1750
|
+
# THINK-280 U8: scoped external capability search facade. The handler is
|
|
1751
|
+
# inert unless CAPABILITY_EXTERNAL_SEARCH_ENABLED (gated on
|
|
1752
|
+
# enable_capability_broker) is on — routing it while disabled returns an
|
|
1753
|
+
# empty, no-data projection.
|
|
1754
|
+
"ANY /mcp/capabilities" = "mcp-capability-search"
|
|
1314
1755
|
|
|
1315
1756
|
# Brain v0 service-auth writeback.
|
|
1316
1757
|
"POST /api/brain/agent-write" = "brain-agent-write"
|
|
@@ -1350,6 +1791,18 @@ locals {
|
|
|
1350
1791
|
"OPTIONS /api/deployment-sessions/{sessionId}/teardown" = "deployment-sessions"
|
|
1351
1792
|
"GET /api/auth/me" = "auth-me"
|
|
1352
1793
|
"OPTIONS /api/auth/me" = "auth-me"
|
|
1794
|
+
"POST /api/auth/revoke" = "auth-revoke"
|
|
1795
|
+
"OPTIONS /api/auth/revoke" = "auth-revoke"
|
|
1796
|
+
"POST /api/auth/subscription-ticket" = "auth-subscription-ticket"
|
|
1797
|
+
"OPTIONS /api/auth/subscription-ticket" = "auth-subscription-ticket"
|
|
1798
|
+
"POST /api/auth/enrollment/consume" = "auth-enrollment"
|
|
1799
|
+
"OPTIONS /api/auth/enrollment/consume" = "auth-enrollment"
|
|
1800
|
+
"POST /api/auth/enrollment/recover" = "auth-enrollment"
|
|
1801
|
+
"OPTIONS /api/auth/enrollment/recover" = "auth-enrollment"
|
|
1802
|
+
"POST /api/auth/enrollment/migrate" = "auth-enrollment"
|
|
1803
|
+
"OPTIONS /api/auth/enrollment/migrate" = "auth-enrollment"
|
|
1804
|
+
"POST /api/auth/enrollment/auto-link" = "auth-enrollment"
|
|
1805
|
+
"OPTIONS /api/auth/enrollment/auto-link" = "auth-enrollment"
|
|
1353
1806
|
"ANY /api/extensions/{extensionId}" = "extension-proxy"
|
|
1354
1807
|
"ANY /api/extensions/{extensionId}/{proxy+}" = "extension-proxy"
|
|
1355
1808
|
|
|
@@ -1419,11 +1872,18 @@ locals {
|
|
|
1419
1872
|
# Slack workspace app ingress. These unauthenticated public endpoints
|
|
1420
1873
|
# verify Slack signatures in handler code before any tenant work happens.
|
|
1421
1874
|
"POST /slack/events" = "slack-events"
|
|
1422
|
-
"POST /slack/slash-command" = "slack-slash-command"
|
|
1423
|
-
"POST /slack/interactivity" = "slack-interactivity"
|
|
1424
1875
|
"GET /slack/oauth/install" = "slack-oauth-install"
|
|
1425
1876
|
"POST /slack/oauth/install" = "slack-oauth-install"
|
|
1426
1877
|
|
|
1878
|
+
# Microsoft Teams install + account-link ingress. Like the Slack block
|
|
1879
|
+
# above, these routes have no gateway authorizer: install/start and
|
|
1880
|
+
# account-link/complete verify the Cognito JWT in-handler, and
|
|
1881
|
+
# install/complete (the Microsoft admin-consent redirect) verifies the
|
|
1882
|
+
# HMAC-signed install state in-handler before any tenant work happens.
|
|
1883
|
+
"POST /msteams/install/start" = "msteams-install-start"
|
|
1884
|
+
"GET /msteams/install/complete" = "msteams-install-complete"
|
|
1885
|
+
"POST /msteams/account-link/complete" = "msteams-account-link-complete"
|
|
1886
|
+
|
|
1427
1887
|
# Memory
|
|
1428
1888
|
"ANY /api/memory/{proxy+}" = "memory"
|
|
1429
1889
|
|
|
@@ -1557,7 +2017,9 @@ locals {
|
|
|
1557
2017
|
"GET /api/runtime/capability-catalog" = "capability-catalog-list"
|
|
1558
2018
|
"OPTIONS /api/runtime/capability-catalog" = "capability-catalog-list"
|
|
1559
2019
|
} : route_key => handler_name
|
|
1560
|
-
if !contains(local.optional_integration_handler_names, handler_name)
|
|
2020
|
+
if !contains(local.optional_integration_handler_names, handler_name) && (
|
|
2021
|
+
var.enable_agentcore_multiplayer_proof || !startswith(route_key, "GET /agentcore/")
|
|
2022
|
+
)
|
|
1561
2023
|
} : {}
|
|
1562
2024
|
}
|
|
1563
2025
|
|
|
@@ -1578,6 +2040,16 @@ resource "aws_apigatewayv2_route" "handler" {
|
|
|
1578
2040
|
target = "integrations/${aws_apigatewayv2_integration.handler[each.key].id}"
|
|
1579
2041
|
}
|
|
1580
2042
|
|
|
2043
|
+
resource "aws_lambda_permission" "appsync_subscription_authorizer" {
|
|
2044
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
2045
|
+
|
|
2046
|
+
statement_id = "AllowAppSyncSubscriptionAuthorization"
|
|
2047
|
+
action = "lambda:InvokeFunction"
|
|
2048
|
+
function_name = aws_lambda_function.handler["appsync-subscription-authorizer"].function_name
|
|
2049
|
+
principal = "appsync.amazonaws.com"
|
|
2050
|
+
source_arn = "arn:aws:appsync:${var.region}:${var.account_id}:apis/${var.appsync_api_id}"
|
|
2051
|
+
}
|
|
2052
|
+
|
|
1581
2053
|
resource "aws_lambda_permission" "handler_apigw" {
|
|
1582
2054
|
for_each = local.deploy_lambda_handlers ? toset(distinct(values(local.api_routes))) : toset([])
|
|
1583
2055
|
|
|
@@ -1653,6 +2125,32 @@ resource "aws_scheduler_schedule" "wakeup_processor" {
|
|
|
1653
2125
|
}
|
|
1654
2126
|
}
|
|
1655
2127
|
|
|
2128
|
+
# Replays durable authorization-revocation invalidations. The worker owns its
|
|
2129
|
+
# retry state in Aurora and suppresses tenant realtime fan-out until AppSync
|
|
2130
|
+
# confirms every sensitive subscription class has been invalidated.
|
|
2131
|
+
resource "aws_scheduler_schedule" "subscription_invalidation" {
|
|
2132
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
2133
|
+
|
|
2134
|
+
name = "thinkwork-${var.stage}-subscription-invalidation"
|
|
2135
|
+
group_name = "default"
|
|
2136
|
+
schedule_expression = "rate(1 minutes)"
|
|
2137
|
+
state = "ENABLED"
|
|
2138
|
+
|
|
2139
|
+
flexible_time_window {
|
|
2140
|
+
mode = "OFF"
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
target {
|
|
2144
|
+
arn = aws_lambda_function.handler["subscription-invalidation"].arn
|
|
2145
|
+
role_arn = aws_iam_role.scheduler.arn
|
|
2146
|
+
input = jsonencode({ limit = 25 })
|
|
2147
|
+
|
|
2148
|
+
retry_policy {
|
|
2149
|
+
maximum_retry_attempts = 0
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
|
|
1656
2154
|
# ---------------------------------------------------------------------------
|
|
1657
2155
|
# webhook_deliveries retention cron — daily delete of rows older than 90 days
|
|
1658
2156
|
# ---------------------------------------------------------------------------
|
|
@@ -1740,6 +2238,25 @@ resource "aws_scheduler_schedule" "requester_memory_dreaming" {
|
|
|
1740
2238
|
# the audit log.
|
|
1741
2239
|
# ---------------------------------------------------------------------------
|
|
1742
2240
|
|
|
2241
|
+
# THINK-193 U3: memory_stage stall recovery — every 15 minutes, bounded batch.
|
|
2242
|
+
resource "aws_scheduler_schedule" "memory_stage_sweeper" {
|
|
2243
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
2244
|
+
|
|
2245
|
+
name = "thinkwork-${var.stage}-memory-stage-sweeper"
|
|
2246
|
+
group_name = "default"
|
|
2247
|
+
schedule_expression = "rate(15 minutes)"
|
|
2248
|
+
state = "ENABLED"
|
|
2249
|
+
|
|
2250
|
+
flexible_time_window {
|
|
2251
|
+
mode = "OFF"
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
target {
|
|
2255
|
+
arn = aws_lambda_function.handler["memory-stage-sweeper"].arn
|
|
2256
|
+
role_arn = aws_iam_role.scheduler.arn
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
|
|
1743
2260
|
resource "aws_scheduler_schedule" "mcp_approval_sweeper" {
|
|
1744
2261
|
count = local.deploy_lambda_handlers ? 1 : 0
|
|
1745
2262
|
|
|
@@ -2256,6 +2773,37 @@ resource "aws_scheduler_schedule" "knowledge_graph_observations_ingest" {
|
|
|
2256
2773
|
}
|
|
2257
2774
|
}
|
|
2258
2775
|
|
|
2776
|
+
# Ontology suggestion scan sweep (THINK-320 U4/KTD-3). Enumerates tenants and
|
|
2777
|
+
# starts a suggestion scan job per tenant; tenants with a pending/running scan
|
|
2778
|
+
# are skipped in the handler, and the scan-job dedupe key drops same-bucket
|
|
2779
|
+
# duplicate starts. Ships DISABLED — enabled per stage via
|
|
2780
|
+
# ontology_scan_sweep_enabled after the Living Map review surfaces land.
|
|
2781
|
+
resource "aws_scheduler_schedule" "ontology_scan_sweep" {
|
|
2782
|
+
count = local.deploy_lambda_handlers ? 1 : 0
|
|
2783
|
+
|
|
2784
|
+
name = "thinkwork-${var.stage}-ontology-scan-sweep"
|
|
2785
|
+
group_name = "default"
|
|
2786
|
+
schedule_expression = "rate(1 days)"
|
|
2787
|
+
state = var.ontology_scan_sweep_enabled ? "ENABLED" : "DISABLED"
|
|
2788
|
+
|
|
2789
|
+
flexible_time_window {
|
|
2790
|
+
mode = "OFF"
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
target {
|
|
2794
|
+
arn = aws_lambda_function.handler["ontology-scan"].arn
|
|
2795
|
+
role_arn = aws_iam_role.scheduler.arn
|
|
2796
|
+
input = jsonencode({ sweep = true, trigger = "scheduled" })
|
|
2797
|
+
|
|
2798
|
+
# Periodic idempotent worker: the next daily tick IS the retry (mirrors
|
|
2799
|
+
# the knowledge_graph_observations_ingest precedent — scheduler retries
|
|
2800
|
+
# only stack invocations onto a self-correcting cadence).
|
|
2801
|
+
retry_policy {
|
|
2802
|
+
maximum_retry_attempts = 0
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2259
2807
|
resource "aws_scheduler_schedule" "wiki_lint" {
|
|
2260
2808
|
count = local.deploy_lambda_handlers ? 1 : 0
|
|
2261
2809
|
|
|
@@ -2447,6 +2995,27 @@ resource "aws_s3_bucket_lifecycle_configuration" "brain_artifacts" {
|
|
|
2447
2995
|
}
|
|
2448
2996
|
}
|
|
2449
2997
|
|
|
2998
|
+
# THINK-193 U1 (Codex F6): normalized evidence snapshots are short-lived
|
|
2999
|
+
# working copies — the durable record is the evidence row (hash + ref) and
|
|
3000
|
+
# the Hindsight projection. Expire content after 30 days; the app mirrors
|
|
3001
|
+
# this via memory_evidence_items.snapshot_expires_at.
|
|
3002
|
+
rule {
|
|
3003
|
+
id = "expire-evidence-snapshots"
|
|
3004
|
+
status = "Enabled"
|
|
3005
|
+
|
|
3006
|
+
filter {
|
|
3007
|
+
prefix = "evidence-snapshots/"
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
expiration {
|
|
3011
|
+
days = 30
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
noncurrent_version_expiration {
|
|
3015
|
+
noncurrent_days = 30
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
|
|
2450
3019
|
rule {
|
|
2451
3020
|
id = "exports-expiration"
|
|
2452
3021
|
status = "Enabled"
|