thinkwork-cli 0.12.12 → 0.12.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (474) hide show
  1. package/README.md +42 -38
  2. package/dist/{api-client-ASJWIG3Z.js → api-client-4VT3FWOH.js} +1 -1
  3. package/dist/{chunk-JEHV35EU.js → chunk-H7AB42ES.js} +340 -30
  4. package/dist/cli.js +22123 -9219
  5. package/dist/commands/enterprise/templates/deploy-repo/.github/workflows/deploy.yml +17 -6
  6. package/dist/commands/enterprise/templates/deploy-repo/docs/runbook.md +81 -9
  7. package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +183 -21
  8. package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +1 -2
  9. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +286 -0
  10. package/dist/drizzle/0000_petite_marvel_apes.sql +1188 -0
  11. package/dist/drizzle/0001_milky_surge.sql +103 -0
  12. package/dist/drizzle/0002_aberrant_mattie_franklin.sql +41 -0
  13. package/dist/drizzle/0003_exotic_ogun.sql +3 -0
  14. package/dist/drizzle/0004_glamorous_magneto.sql +2 -0
  15. package/dist/drizzle/0005_ancient_nocturne.sql +2 -0
  16. package/dist/drizzle/0006_new_colonel_america.sql +2 -0
  17. package/dist/drizzle/0007_unique_external_task_id.sql +31 -0
  18. package/dist/drizzle/0008_external_task_id_column.sql +43 -0
  19. package/dist/drizzle/0009_evaluations.sql +64 -0
  20. package/dist/drizzle/0010_eval_agent_template.sql +2 -0
  21. package/dist/drizzle/0011_eval_run_template.sql +2 -0
  22. package/dist/drizzle/0012_eval_seed_unique.sql +16 -0
  23. package/dist/drizzle/0013_motionless_white_queen.sql +140 -0
  24. package/dist/drizzle/0014_wiki_aggregation.sql +11 -0
  25. package/dist/drizzle/0015_pg_trgm_alias_title_indexes.sql +9 -0
  26. package/dist/drizzle/0016_wiki_schema_drops.sql +24 -0
  27. package/dist/drizzle/0017_wiki_places.sql +46 -0
  28. package/dist/drizzle/0018_agent_workspace_overlay.sql +26 -0
  29. package/dist/drizzle/0018_cool_firebird.sql +24 -0
  30. package/dist/drizzle/0018_skill_runs.sql +84 -0
  31. package/dist/drizzle/0019_condemned_dragon_man.sql +95 -0
  32. package/dist/drizzle/0019_webhook_skill_runs.sql +58 -0
  33. package/dist/drizzle/0020_crazy_the_anarchist.sql +9 -0
  34. package/dist/drizzle/0020_mutation_idempotency.sql +64 -0
  35. package/dist/drizzle/0021_crm_work_links.sql +76 -0
  36. package/dist/drizzle/0021_skill_runs_completion_hmac.sql +33 -0
  37. package/dist/drizzle/0022_add_billing_tables.sql +70 -0
  38. package/dist/drizzle/0022_seed_thinkwork_admin_permissions.sql +160 -0
  39. package/dist/drizzle/0022_stripe_billing_indexes.sql +48 -0
  40. package/dist/drizzle/0023_tenants_deactivation.sql +27 -0
  41. package/dist/drizzle/0024_tenant_mcp_admin_keys.sql +63 -0
  42. package/dist/drizzle/0025_v1_agent_architecture.sql +182 -0
  43. package/dist/drizzle/0026_thread_turns_add_kind.sql +28 -0
  44. package/dist/drizzle/0027_capability_catalog_and_manifests.sql +219 -0
  45. package/dist/drizzle/0028_aws_s3_extension.sql +26 -0
  46. package/dist/drizzle/0029_collapse_execution_types.sql +42 -0
  47. package/dist/drizzle/0030_retire_composition_primitives.sql +48 -0
  48. package/dist/drizzle/0031_thread_cleanup_drops.sql +131 -0
  49. package/dist/drizzle/0032_add_browser_automation_template_config.sql +24 -0
  50. package/dist/drizzle/0033_agent_operation_leases.sql +32 -0
  51. package/dist/drizzle/0034_agent_workspace_events.sql +116 -0
  52. package/dist/drizzle/0035_workspace_review_decisions.sql +19 -0
  53. package/dist/drizzle/0036_user_scoped_memory_wiki.sql +152 -0
  54. package/dist/drizzle/0037_user_profile_operating_model.sql +34 -0
  55. package/dist/drizzle/0042_agent_runtime_selector.sql +41 -0
  56. package/dist/drizzle/0043_wiki_search_tsv_tokenization.sql +48 -0
  57. package/dist/drizzle/0044_add_web_search_template_config.sql +7 -0
  58. package/dist/drizzle/0045_add_send_email_template_config.sql +7 -0
  59. package/dist/drizzle/0046_tenant_mcp_context_tools.sql +26 -0
  60. package/dist/drizzle/0047_add_context_engine_template_config.sql +7 -0
  61. package/dist/drizzle/0048_tenant_context_provider_settings.sql +22 -0
  62. package/dist/drizzle/0050_brain_v0_entity_subtype.sql +29 -0
  63. package/dist/drizzle/0051_brain_v0_tenant_entity_pages.sql +170 -0
  64. package/dist/drizzle/0052_brain_v0_external_refs.sql +41 -0
  65. package/dist/drizzle/0053_brain_v0_unresolved_mentions_subtype.sql +48 -0
  66. package/dist/drizzle/0054_wiki_compile_jobs_input.sql +28 -0
  67. package/dist/drizzle/0055_routines_stepfunctions_substrate.sql +202 -0
  68. package/dist/drizzle/0056_routine_step_events_dedup_idx.sql +25 -0
  69. package/dist/drizzle/0057_archive_legacy_python_routines.sql +36 -0
  70. package/dist/drizzle/0058_routines_visibility_and_owning_agent.sql +61 -0
  71. package/dist/drizzle/0061_routine_execution_asl_version_id.sql +29 -0
  72. package/dist/drizzle/0062_migrate_pi_to_flue.sql +110 -0
  73. package/dist/drizzle/0063_threads_session_data.sql +23 -0
  74. package/dist/drizzle/0064_tenant_credentials.sql +65 -0
  75. package/dist/drizzle/0067_thinkwork_computers_phase_one.sql +174 -0
  76. package/dist/drizzle/0068_drop_system_workflows_and_activation.sql +115 -0
  77. package/dist/drizzle/0069_compliance_schema.sql +364 -0
  78. package/dist/drizzle/0070_compliance_aurora_roles.sql +171 -0
  79. package/dist/drizzle/0072_threads_computer_ownership.sql +24 -0
  80. package/dist/drizzle/0073_compliance_tenant_anchor_state.sql +105 -0
  81. package/dist/drizzle/0074_compliance_event_hash_index.sql +49 -0
  82. package/dist/drizzle/0075_scheduled_jobs_computer_ownership.sql +27 -0
  83. package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +69 -0
  84. package/dist/drizzle/0077_computers_primary_agent_id.sql +38 -0
  85. package/dist/drizzle/0078_tenant_customize_catalog.sql +46 -0
  86. package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +53 -0
  87. package/dist/drizzle/0081_routines_catalog_slug.sql +42 -0
  88. package/dist/drizzle/0082_messages_parts_jsonb.sql +52 -0
  89. package/dist/drizzle/0083_computer_runbooks.sql +103 -0
  90. package/dist/drizzle/0084_artifacts_favorited_at.sql +32 -0
  91. package/dist/drizzle/0085_seed_thinkwork_computer_default_template.sql +46 -0
  92. package/dist/drizzle/0086_update_default_template_models.sql +19 -0
  93. package/dist/drizzle/0087_retire_oss_connectors.sql +77 -0
  94. package/dist/drizzle/0088_compliance_event_types_finance_pilot.sql +37 -0
  95. package/dist/drizzle/0089_remove_maniflow_eval_seeds.sql +81 -0
  96. package/dist/drizzle/0089_wiki_schema_extraction.sql +315 -0
  97. package/dist/drizzle/0090_brain_schema_extraction.sql +274 -0
  98. package/dist/drizzle/0091_drop_wiki_brain_compat_views.sql +118 -0
  99. package/dist/drizzle/0092_finish_oss_connector_retirement.sql +97 -0
  100. package/dist/drizzle/0093_eval_runs_scheduled_job_id.sql +23 -0
  101. package/dist/drizzle/0094_slack_workspace_app.sql +140 -0
  102. package/dist/drizzle/0095_eval_runs_computer_id.sql +22 -0
  103. package/dist/drizzle/0096_true_redteam_eval_seed_cleanup.sql +67 -0
  104. package/dist/drizzle/0097_shared_computers.sql +191 -0
  105. package/dist/drizzle/0098_business_ontology.sql +587 -0
  106. package/dist/drizzle/0099_thread_idle_learning.sql +145 -0
  107. package/dist/drizzle/0100_ontology_gated_brain_dynamic_subtypes.sql +7 -0
  108. package/dist/drizzle/0101_ontology_gated_unresolved_mentions_dynamic_subtypes.sql +7 -0
  109. package/dist/drizzle/0102_wiki_brain_owner_repair.sql +87 -0
  110. package/dist/drizzle/0103_brain_section_source_trigger_repair.sql +75 -0
  111. package/dist/drizzle/0104_expand_seed_ontology_for_user_memory.sql +166 -0
  112. package/dist/drizzle/0105_spaces_domain.sql +349 -0
  113. package/dist/drizzle/0106_expand_seed_ontology_for_triples.sql +173 -0
  114. package/dist/drizzle/0106_space_threads_participants.sql +197 -0
  115. package/dist/drizzle/0107_linked_task_mirror.sql +245 -0
  116. package/dist/drizzle/0108_message_mentions.sql +95 -0
  117. package/dist/drizzle/0109_space_owned_threads.sql +217 -0
  118. package/dist/drizzle/0110_thread_participant_read_state.sql +21 -0
  119. package/dist/drizzle/0111_agents_tenant_name_unique.sql +38 -0
  120. package/dist/drizzle/0112_recast_spaces_as_contextual_workrooms.sql +138 -0
  121. package/dist/drizzle/0113_agents_own_runtime_fields.sql +48 -0
  122. package/dist/drizzle/0114_migrate_templates_to_agents_and_spaces.sql +361 -0
  123. package/dist/drizzle/0115_remove_computer_eval_template_dependencies.sql +69 -0
  124. package/dist/drizzle/0116_backfill_thread_participants_access.sql +126 -0
  125. package/dist/drizzle/0117_space_access_mode.sql +40 -0
  126. package/dist/drizzle/0118_normalize_tenant_member_principal_type.sql +41 -0
  127. package/dist/drizzle/0119_space_knowledge_bases.sql +126 -0
  128. package/dist/drizzle/0120_space_automations.sql +58 -0
  129. package/dist/drizzle/0121_drop_computer_runbooks.sql +26 -0
  130. package/dist/drizzle/0122_space_email_triggers.sql +24 -0
  131. package/dist/drizzle/0123_single_platform_agent_and_overrides.sql +58 -0
  132. package/dist/drizzle/0124_thread_turns_finalized_at.sql +17 -0
  133. package/dist/drizzle/0125_drop_space_agent_assignments.sql +42 -0
  134. package/dist/drizzle/0126_migrate_flue_to_pi.sql +42 -0
  135. package/dist/drizzle/0127_runtime_type_observability.sql +28 -0
  136. package/dist/drizzle/0128_drop_eval_test_cases_agent_id.sql +37 -0
  137. package/dist/drizzle/0129_drop_code_factory_tables.sql +43 -0
  138. package/dist/drizzle/0129_eval_results_system_prompt.sql +30 -0
  139. package/dist/drizzle/0130_drop_teams_and_team_id_columns.sql +54 -0
  140. package/dist/drizzle/0131_drop_skill_catalog_and_tenant_skills.sql +33 -0
  141. package/dist/drizzle/0132_drop_computer_tables.sql +31 -0
  142. package/dist/drizzle/0133_drop_seed_view_tombstones.sql +79 -0
  143. package/dist/drizzle/0133_thread_turns_system_prompt.sql +22 -0
  144. package/dist/drizzle/0134_drop_dead_agent_runtime_tables.sql +53 -0
  145. package/dist/drizzle/0135_native_checklist_linked_tasks.sql +48 -0
  146. package/dist/drizzle/0136_goal_ledger.sql +55 -0
  147. package/dist/drizzle/0136_space_email_trigger_status.sql +66 -0
  148. package/dist/drizzle/0137_thread_participant_pins.sql +25 -0
  149. package/dist/drizzle/0138_users_cognito_sub.sql +30 -0
  150. package/dist/drizzle/0139_mobile_turn_client_id.sql +23 -0
  151. package/dist/drizzle/0140_workspace_folder_names.sql +36 -0
  152. package/dist/drizzle/0141_eval_runs_desktop_pi_provenance.sql +31 -0
  153. package/dist/drizzle/0142_pi_only_agent_runtime.sql +61 -0
  154. package/dist/drizzle/0143_add_web_extract_builtin_config.sql +28 -0
  155. package/dist/drizzle/0144_skill_catalog_index.sql +40 -0
  156. package/dist/drizzle/0145_knowledge_graph_thread_ingest.sql +512 -0
  157. package/dist/drizzle/0146_knowledge_graph_source_scope.sql +413 -0
  158. package/dist/drizzle/0147_knowledge_graph_scope_trigger_qualification.sql +211 -0
  159. package/dist/drizzle/0148_user_cost_attribution.sql +171 -0
  160. package/dist/drizzle/0149_managed_mcp_servers.sql +64 -0
  161. package/dist/drizzle/0149_user_model_approvals.sql +89 -0
  162. package/dist/drizzle/0150_bootstrap_first_admin_claim.sql +11 -0
  163. package/dist/drizzle/0151_managed_deployments.sql +91 -0
  164. package/dist/drizzle/0152_agent_profiles.sql +81 -0
  165. package/dist/drizzle/0153_message_mentions_agent_profile.sql +9 -0
  166. package/dist/drizzle/0154_customer_deployment_sessions.sql +61 -0
  167. package/dist/drizzle/0155_tenant_model_catalog.sql +152 -0
  168. package/dist/drizzle/0156_bootstrap_credential_leases.sql +52 -0
  169. package/dist/drizzle/0157_knowledge_graph_observations_source.sql +79 -0
  170. package/dist/drizzle/0158_pending_user_questions.sql +80 -0
  171. package/dist/drizzle/0158_wiki_tenant_scope.sql +38 -0
  172. package/dist/drizzle/0159_agent_profiles_space_local.sql +49 -0
  173. package/dist/drizzle/0159_application_plugins.sql +193 -0
  174. package/dist/drizzle/0159_eval_scoring_version.sql +46 -0
  175. package/dist/drizzle/0160_compliance_event_types_plugins.sql +37 -0
  176. package/dist/drizzle/0160_eval_datasets.sql +75 -0
  177. package/dist/drizzle/0160_eval_results_thread_turn.sql +35 -0
  178. package/dist/drizzle/0161_eval_run_pinning.sql +54 -0
  179. package/dist/drizzle/0161_tenant_mcp_servers_plugin_source.sql +62 -0
  180. package/dist/drizzle/0162_eval_result_override.sql +49 -0
  181. package/dist/drizzle/0163_eval_replay_tool_allowlist.sql +50 -0
  182. package/dist/drizzle/0164_eval_replay_tool_override_mode.sql +52 -0
  183. package/dist/drizzle/0165_plugin_premium_entitlements.sql +153 -0
  184. package/dist/drizzle/0166_company_brain_substrate_contract.sql +386 -0
  185. package/dist/drizzle/0167_company_brain_artifact_manifest_runtime.sql +85 -0
  186. package/dist/drizzle/0168_eval_skill_gate.sql +44 -0
  187. package/dist/drizzle/0169_release_update_jobs.sql +67 -0
  188. package/dist/drizzle/0170_email_channel_plugin.sql +291 -0
  189. package/dist/drizzle/0171_linked_task_external_providers.sql +30 -0
  190. package/dist/drizzle/0172_email_channel_sendgrid_provider.sql +8 -0
  191. package/dist/drizzle/0173_auth_provider_resources.sql +83 -0
  192. package/dist/drizzle/0174_workos_auth_bridges.sql +37 -0
  193. package/dist/drizzle/0175_workos_auth_sessions.sql +38 -0
  194. package/dist/drizzle/0176_n8n_agent_step_runs.sql +107 -0
  195. package/dist/drizzle/0177_workflow_control_plane.sql +281 -0
  196. package/dist/drizzle/0178_workflow_backfill_existing_routines.sql +525 -0
  197. package/dist/drizzle/0179_tenant_goal_budget_settings.sql +21 -0
  198. package/dist/drizzle/0180_skill_drafts.sql +89 -0
  199. package/dist/drizzle/0181_skill_draft_publish_status.sql +21 -0
  200. package/dist/drizzle/0182_agent_loops.sql +260 -0
  201. package/dist/drizzle/0183_okf_artifact_manifests.sql +52 -0
  202. package/dist/drizzle/0184_skill_catalog_trust_cache.sql +35 -0
  203. package/dist/drizzle/0185_agent_loop_space.sql +16 -0
  204. package/dist/drizzle/0186_tenant_mcp_runtime_metadata.sql +10 -0
  205. package/dist/drizzle/0187_native_work_items.sql +220 -0
  206. package/dist/drizzle/0188_company_etl_plugin_rename.sql +99 -0
  207. package/dist/drizzle/0189_trace_cost_substrate.sql +247 -0
  208. package/dist/drizzle/0190_billing_export_reconciliation.sql +101 -0
  209. package/dist/drizzle/0191_open_engine_work_item_queue.sql +66 -0
  210. package/dist/drizzle/0192_work_item_labels.sql +44 -0
  211. package/dist/drizzle/0193_work_item_documents.sql +31 -0
  212. package/dist/drizzle/0194_memory_retain_attempts.sql +103 -0
  213. package/dist/drizzle/0194_work_item_comments.sql +35 -0
  214. package/dist/drizzle/0195_plugin_app_overlays.sql +45 -0
  215. package/dist/drizzle/0196_pi_extensions.sql +118 -0
  216. package/dist/drizzle/0197_eval_profiles.sql +150 -0
  217. package/dist/drizzle/0198_eval_runs_unstable.sql +27 -0
  218. package/dist/drizzle/0199_eval_runs_cost_partial.sql +27 -0
  219. package/dist/drizzle/meta/_journal.json +160 -0
  220. package/dist/plugins/README.md +162 -0
  221. package/dist/plugins/catalog/package.json +40 -0
  222. package/dist/plugins/catalog/scripts/build-catalog.ts +120 -0
  223. package/dist/plugins/catalog/scripts/generate-plugin-registry.ts +144 -0
  224. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +86 -0
  225. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +308 -0
  226. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +861 -0
  227. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +124 -0
  228. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +120 -0
  229. package/dist/plugins/catalog/src/catalog.ts +434 -0
  230. package/dist/plugins/catalog/src/contracts.ts +1498 -0
  231. package/dist/plugins/catalog/src/index.ts +4 -0
  232. package/dist/plugins/catalog/src/plugin-package.ts +171 -0
  233. package/dist/plugins/catalog/src/registry/generated-first-party.ts +76 -0
  234. package/dist/plugins/catalog/src/registry/index.ts +1 -0
  235. package/dist/plugins/catalog/tsconfig.json +8 -0
  236. package/dist/plugins/company-brain/README.md +37 -0
  237. package/dist/plugins/company-brain/package.json +33 -0
  238. package/dist/plugins/company-brain/runtime/cognee/Dockerfile +11 -0
  239. package/dist/plugins/company-brain/smoke/cognee-managed-app-smoke.mjs +458 -0
  240. package/dist/plugins/company-brain/smoke/cognee-memory-cutover-smoke.mjs +539 -0
  241. package/dist/plugins/company-brain/smoke/company-brain-context-engine-smoke.mjs +312 -0
  242. package/dist/plugins/company-brain/smoke/company-brain-operations-smoke.mjs +449 -0
  243. package/dist/plugins/company-brain/smoke/company-brain-plugin-smoke.mjs +655 -0
  244. package/dist/plugins/company-brain/smoke/hindsight-memory-isolation-smoke.mjs +474 -0
  245. package/dist/plugins/company-brain/src/api/cognee-client.ts +896 -0
  246. package/dist/plugins/company-brain/src/api/cognee-cluster-identity.ts +49 -0
  247. package/dist/plugins/company-brain/src/api/cognee-memory-scope.ts +84 -0
  248. package/dist/plugins/company-brain/src/api/context-engine-provider.ts +888 -0
  249. package/dist/plugins/company-brain/src/api/migration.ts +665 -0
  250. package/dist/plugins/company-brain/src/deployment/cognee-managed-app.ts +396 -0
  251. package/dist/plugins/company-brain/src/index.ts +62 -0
  252. package/dist/plugins/company-brain/src/manifest.ts +112 -0
  253. package/dist/plugins/company-brain/terraform/cognee/README.md +263 -0
  254. package/dist/plugins/company-brain/terraform/cognee/main.tf +766 -0
  255. package/dist/plugins/company-brain/terraform/cognee/outputs.tf +144 -0
  256. package/dist/plugins/company-brain/terraform/cognee/variables.tf +402 -0
  257. package/dist/plugins/company-brain/test/api/cognee-client.test.ts +562 -0
  258. package/dist/plugins/company-brain/test/api/cognee-memory-scope.test.ts +74 -0
  259. package/dist/plugins/company-brain/test/api/context-engine-provider.test.ts +447 -0
  260. package/dist/plugins/company-brain/test/api/migration.test.ts +465 -0
  261. package/dist/plugins/company-brain/test/manifest.test.ts +95 -0
  262. package/dist/plugins/company-brain/tsconfig.json +8 -0
  263. package/dist/plugins/company-data/README.md +49 -0
  264. package/dist/plugins/company-data/package.json +21 -0
  265. package/dist/plugins/company-data/src/index.ts +30 -0
  266. package/dist/plugins/company-data/src/manifest.ts +26 -0
  267. package/dist/plugins/company-data/test/manifest.test.ts +116 -0
  268. package/dist/plugins/company-data/tsconfig.json +8 -0
  269. package/dist/plugins/company-etl/README.md +46 -0
  270. package/dist/plugins/company-etl/package.json +21 -0
  271. package/dist/plugins/company-etl/src/index.ts +29 -0
  272. package/dist/plugins/company-etl/src/manifest.ts +26 -0
  273. package/dist/plugins/company-etl/test/manifest.test.ts +108 -0
  274. package/dist/plugins/company-etl/tsconfig.json +8 -0
  275. package/dist/plugins/email-channel/README.md +41 -0
  276. package/dist/plugins/email-channel/package.json +22 -0
  277. package/dist/plugins/email-channel/src/index.ts +36 -0
  278. package/dist/plugins/email-channel/src/manifest.ts +44 -0
  279. package/dist/plugins/email-channel/src/provider-contract.ts +36 -0
  280. package/dist/plugins/email-channel/test/manifest.test.ts +119 -0
  281. package/dist/plugins/email-channel/tsconfig.json +8 -0
  282. package/dist/plugins/lastmile/README.md +50 -0
  283. package/dist/plugins/lastmile/package.json +23 -0
  284. package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +661 -0
  285. package/dist/plugins/lastmile/src/api/tasks-adapter.ts +572 -0
  286. package/dist/plugins/lastmile/src/discovery.fixture.ts +64 -0
  287. package/dist/plugins/lastmile/src/index.ts +46 -0
  288. package/dist/plugins/lastmile/src/manifest.ts +139 -0
  289. package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +266 -0
  290. package/dist/plugins/lastmile/test/discovery.test.ts +88 -0
  291. package/dist/plugins/lastmile/tsconfig.json +8 -0
  292. package/dist/plugins/n8n/README.md +201 -0
  293. package/dist/plugins/n8n/n8n-app/README.md +33 -0
  294. package/dist/plugins/n8n/n8n-app/package.json +23 -0
  295. package/dist/plugins/n8n/n8n-app/src/application-config.ts +45 -0
  296. package/dist/plugins/n8n/n8n-app/src/front-components/thinkwork-workflows.front-component.tsx +970 -0
  297. package/dist/plugins/n8n/n8n-app/src/lib/n8n-app-data.ts +190 -0
  298. package/dist/plugins/n8n/n8n-app/src/vite-env.d.ts +7 -0
  299. package/dist/plugins/n8n/n8n-app/tsconfig.json +15 -0
  300. package/dist/plugins/n8n/package.json +35 -0
  301. package/dist/plugins/n8n/runtime/Dockerfile +18 -0
  302. package/dist/plugins/n8n/runtime/n8n-task-runners.json +14 -0
  303. package/dist/plugins/n8n/runtime/n8n-task-runners.json.template +14 -0
  304. package/dist/plugins/n8n/runtime/package-lock.json +13 -0
  305. package/dist/plugins/n8n/runtime/package.json +7 -0
  306. package/dist/plugins/n8n/scripts/sync-thinkwork-app.mjs +268 -0
  307. package/dist/plugins/n8n/smoke/README.md +95 -0
  308. package/dist/plugins/n8n/smoke/n8n-agent-step-bridge-smoke.mjs +866 -0
  309. package/dist/plugins/n8n/smoke/n8n-integrated-app-smoke.mjs +262 -0
  310. package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +409 -0
  311. package/dist/plugins/n8n/smoke/n8n-mcp-smoke.mjs +624 -0
  312. package/dist/plugins/n8n/src/deployment/image-build.ts +172 -0
  313. package/dist/plugins/n8n/src/deployment/managed-app.ts +429 -0
  314. package/dist/plugins/n8n/src/index.ts +79 -0
  315. package/dist/plugins/n8n/src/manifest.ts +403 -0
  316. package/dist/plugins/n8n/src/package-config.ts +186 -0
  317. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/SKILL.md +76 -0
  318. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
  319. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
  320. package/dist/plugins/n8n/src/skills/n8n-workflow-operator/references/workflow-authoring.md +45 -0
  321. package/dist/plugins/n8n/terraform/n8n/README.md +113 -0
  322. package/dist/plugins/n8n/terraform/n8n/main.tf +918 -0
  323. package/dist/plugins/n8n/terraform/n8n/outputs.tf +124 -0
  324. package/dist/plugins/n8n/terraform/n8n/scripts/sync-database.py +250 -0
  325. package/dist/plugins/n8n/terraform/n8n/scripts/test_sync_database.py +55 -0
  326. package/dist/plugins/n8n/terraform/n8n/variables.tf +354 -0
  327. package/dist/plugins/n8n/test/image-build.test.ts +118 -0
  328. package/dist/plugins/n8n/test/integrated-app-contract.test.ts +353 -0
  329. package/dist/plugins/n8n/test/manifest.test.ts +278 -0
  330. package/dist/plugins/n8n/test/package-config.test.ts +57 -0
  331. package/dist/plugins/n8n/tsconfig.json +8 -0
  332. package/dist/plugins/sendgrid/README.md +30 -0
  333. package/dist/plugins/sendgrid/package.json +22 -0
  334. package/dist/plugins/sendgrid/src/index.ts +36 -0
  335. package/dist/plugins/sendgrid/src/manifest.ts +37 -0
  336. package/dist/plugins/sendgrid/src/provider-contract.ts +14 -0
  337. package/dist/plugins/sendgrid/test/manifest.test.ts +80 -0
  338. package/dist/plugins/sendgrid/tsconfig.json +8 -0
  339. package/dist/plugins/twenty/README.md +78 -0
  340. package/dist/plugins/twenty/package.json +27 -0
  341. package/dist/plugins/twenty/scripts/__tests__/sync-thinkwork-app.test.mjs +67 -0
  342. package/dist/plugins/twenty/scripts/sync-thinkwork-app.mjs +185 -0
  343. package/dist/plugins/twenty/scripts/wire-thinkwork-workflow.mjs +658 -0
  344. package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +359 -0
  345. package/dist/plugins/twenty/smoke/twenty-mcp-oauth-smoke.mjs +574 -0
  346. package/dist/plugins/twenty/src/api/cutover.ts +209 -0
  347. package/dist/plugins/twenty/src/deployment/managed-app.ts +253 -0
  348. package/dist/plugins/twenty/src/index.ts +55 -0
  349. package/dist/plugins/twenty/src/manifest.ts +259 -0
  350. package/dist/plugins/twenty/terraform/twenty/README.md +97 -0
  351. package/dist/plugins/twenty/terraform/twenty/main.tf +829 -0
  352. package/dist/plugins/twenty/terraform/twenty/outputs.tf +79 -0
  353. package/dist/plugins/twenty/terraform/twenty/variables.tf +268 -0
  354. package/dist/plugins/twenty/test/api/cutover.test.ts +183 -0
  355. package/dist/plugins/twenty/test/manifest.test.ts +463 -0
  356. package/dist/plugins/twenty/tsconfig.json +9 -0
  357. package/dist/plugins/twenty/twenty-app/.nvmrc +1 -0
  358. package/dist/plugins/twenty/twenty-app/README.md +148 -0
  359. package/dist/plugins/twenty/twenty-app/package.json +30 -0
  360. package/dist/plugins/twenty/twenty-app/src/application-config.ts +44 -0
  361. package/dist/plugins/twenty/twenty-app/src/constants/universal-identifiers.ts +18 -0
  362. package/dist/plugins/twenty/twenty-app/src/default-role.ts +24 -0
  363. package/dist/plugins/twenty/twenty-app/src/front-components/thinkwork-settings.front-component.tsx +299 -0
  364. package/dist/plugins/twenty/twenty-app/src/logic-functions/thinkwork-webhook.logic-function.ts +354 -0
  365. package/dist/plugins/twenty/twenty-app/tsconfig.json +14 -0
  366. package/dist/plugins/twenty/twenty-app/yarn.lock +4144 -0
  367. package/dist/plugins/workos-auth/package.json +22 -0
  368. package/dist/plugins/workos-auth/src/index.ts +30 -0
  369. package/dist/plugins/workos-auth/src/manifest.ts +40 -0
  370. package/dist/plugins/workos-auth/src/provider-contract.ts +39 -0
  371. package/dist/plugins/workos-auth/test/manifest.test.ts +94 -0
  372. package/dist/plugins/workos-auth/tsconfig.json +8 -0
  373. package/dist/scripts/bootstrap-workspace.sh +162 -0
  374. package/dist/scripts/post-deploy.sh +290 -0
  375. package/dist/terraform/examples/greenfield/main.tf +903 -75
  376. package/dist/terraform/examples/greenfield/terraform.tfvars.example +67 -8
  377. package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +2 -2
  378. package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +8 -9
  379. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +227 -0
  380. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +277 -0
  381. package/dist/terraform/modules/app/agentcore-memory/README.md +6 -6
  382. package/dist/terraform/modules/app/agentcore-memory/main.tf +1 -1
  383. package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +40 -9
  384. package/dist/terraform/modules/app/agentcore-pi/README.md +61 -0
  385. package/dist/terraform/modules/app/agentcore-pi/main.tf +453 -0
  386. package/dist/terraform/modules/app/agentcore-pi/outputs.tf +38 -0
  387. package/dist/terraform/modules/app/agentcore-pi/variables.tf +145 -0
  388. package/dist/terraform/modules/app/agentcore-platform/main.tf +83 -0
  389. package/dist/terraform/modules/app/agentcore-runtime/main.tf +9 -11
  390. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +5 -1
  391. package/dist/terraform/modules/app/customer-domain/main.tf +483 -0
  392. package/dist/terraform/modules/app/deployment-control-plane/README.md +47 -0
  393. package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +24 -0
  394. package/dist/terraform/modules/app/deployment-control-plane/main.tf +614 -0
  395. package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +54 -0
  396. package/dist/terraform/modules/app/deployment-control-plane/runner.py +4720 -0
  397. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +3026 -0
  398. package/dist/terraform/modules/app/deployment-control-plane/variables.tf +96 -0
  399. package/dist/terraform/modules/app/hindsight-memory/README.md +25 -23
  400. package/dist/terraform/modules/app/hindsight-memory/main.tf +26 -2
  401. package/dist/terraform/modules/app/lambda-api/eval-fanout.tf +17 -50
  402. package/dist/terraform/modules/app/lambda-api/handlers.tf +1290 -679
  403. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +933 -0
  404. package/dist/terraform/modules/app/lambda-api/main.tf +14 -527
  405. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +3 -19
  406. package/dist/terraform/modules/app/lambda-api/outputs.tf +50 -6
  407. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +163 -0
  408. package/dist/terraform/modules/app/lambda-api/slack-app-secrets.tf +3 -1
  409. package/dist/terraform/modules/app/lambda-api/stripe-secrets.tf +3 -1
  410. package/dist/terraform/modules/app/lambda-api/variables.tf +240 -53
  411. package/dist/terraform/modules/app/lambda-api/workspace-events.tf +2 -25
  412. package/dist/terraform/modules/app/ses-email/main.tf +143 -30
  413. package/dist/terraform/modules/app/static-site/main.tf +4 -3
  414. package/dist/terraform/modules/app/www-dns/main.tf +45 -5
  415. package/dist/terraform/modules/app/www-dns/outputs.tf +10 -0
  416. package/dist/terraform/modules/app/www-dns/variables.tf +24 -0
  417. package/dist/terraform/modules/data/aurora-postgres/main.tf +15 -1
  418. package/dist/terraform/modules/data/compliance-exports-bucket/main.tf +1 -1
  419. package/dist/terraform/modules/data/compliance-exports-bucket/variables.tf +6 -0
  420. package/dist/terraform/modules/foundation/cognito/main.tf +167 -11
  421. package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
  422. package/dist/terraform/modules/foundation/cognito/variables.tf +110 -0
  423. package/dist/terraform/modules/foundation/vpc/main.tf +45 -3
  424. package/dist/terraform/modules/foundation/vpc/outputs.tf +20 -0
  425. package/dist/terraform/modules/foundation/vpc/variables.tf +18 -0
  426. package/dist/terraform/modules/thinkwork/README.md +71 -0
  427. package/dist/terraform/modules/thinkwork/main.tf +1325 -174
  428. package/dist/terraform/modules/thinkwork/outputs.tf +457 -24
  429. package/dist/terraform/modules/thinkwork/variables.tf +1169 -93
  430. package/dist/terraform/schema.graphql +82 -9
  431. package/dist/workspace-defaults/files/AGENTS.md +344 -0
  432. package/dist/workspace-defaults/files/CONTEXT.md +8 -0
  433. package/dist/workspace-defaults/files/GUARDRAILS.md +51 -0
  434. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +65 -0
  435. package/dist/workspace-defaults/files/ROUTER.md +24 -0
  436. package/dist/workspace-defaults/files/SPACE.md +62 -0
  437. package/dist/workspace-defaults/files/TOOLS.md +65 -0
  438. package/dist/workspace-defaults/files/USER.md +40 -0
  439. package/dist/workspace-defaults/files/mcp.json +3 -0
  440. package/dist/workspace-defaults/files/memory/contacts.md +13 -0
  441. package/dist/workspace-defaults/files/memory/lessons.md +13 -0
  442. package/dist/workspace-defaults/files/memory/preferences.md +12 -0
  443. package/dist/workspace-defaults/files/skills/.gitkeep +1 -0
  444. package/dist/workspace-defaults/files/skills/artifact-builder/SKILL.md +79 -0
  445. package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +166 -0
  446. package/dist/workspace-defaults/files/skills/automation-loop-designer/SKILL.md +120 -0
  447. package/dist/workspace-defaults/files/skills/skill-creator/LICENSE.txt +202 -0
  448. package/dist/workspace-defaults/files/skills/skill-creator/SKILL.md +485 -0
  449. package/dist/workspace-defaults/files/skills/skill-creator/UPSTREAM.json +124 -0
  450. package/dist/workspace-defaults/files/skills/skill-creator/agents/analyzer.md +274 -0
  451. package/dist/workspace-defaults/files/skills/skill-creator/agents/comparator.md +202 -0
  452. package/dist/workspace-defaults/files/skills/skill-creator/agents/grader.md +223 -0
  453. package/dist/workspace-defaults/files/skills/skill-creator/assets/eval_review.html +146 -0
  454. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  455. package/dist/workspace-defaults/files/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  456. package/dist/workspace-defaults/files/skills/skill-creator/references/schemas.md +430 -0
  457. package/dist/workspace-defaults/files/skills/skill-creator/scripts/__init__.py +0 -0
  458. package/dist/workspace-defaults/files/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  459. package/dist/workspace-defaults/files/skills/skill-creator/scripts/generate_report.py +326 -0
  460. package/dist/workspace-defaults/files/skills/skill-creator/scripts/improve_description.py +247 -0
  461. package/dist/workspace-defaults/files/skills/skill-creator/scripts/package_skill.py +136 -0
  462. package/dist/workspace-defaults/files/skills/skill-creator/scripts/quick_validate.py +103 -0
  463. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_eval.py +310 -0
  464. package/dist/workspace-defaults/files/skills/skill-creator/scripts/run_loop.py +328 -0
  465. package/dist/workspace-defaults/files/skills/skill-creator/scripts/utils.py +47 -0
  466. package/package.json +1 -1
  467. package/dist/terraform/modules/app/agentcore-flue/README.md +0 -58
  468. package/dist/terraform/modules/app/agentcore-flue/main.tf +0 -323
  469. package/dist/terraform/modules/app/agentcore-flue/outputs.tf +0 -23
  470. package/dist/terraform/modules/app/agentcore-flue/variables.tf +0 -97
  471. package/dist/terraform/modules/app/computer-runtime/README.md +0 -15
  472. package/dist/terraform/modules/app/computer-runtime/main.tf +0 -406
  473. package/dist/terraform/modules/app/computer-runtime/outputs.tf +0 -75
  474. package/dist/terraform/modules/app/computer-runtime/variables.tf +0 -66
@@ -0,0 +1,933 @@
1
+ ################################################################################
2
+ # R9 (plan 2026-06-11-006 U6) — Grouped customer-managed policies for the
3
+ # shared api Lambda role (aws_iam_role.lambda).
4
+ #
5
+ # On 2026-06-11 the role's ~25 inline aws_iam_role_policy resources hit IAM's
6
+ # 10,240-byte aggregate hard cap for inline policies (#2378 failed the dev
7
+ # apply with LimitExceeded; #2379 is this consolidation). Every grant that was
8
+ # inline on this role — plus the one-off standalone managed policies that had
9
+ # accreted as cap workarounds — now lives in exactly four grouped
10
+ # customer-managed policies:
11
+ #
12
+ # thinkwork-<stage>-api-data-plane — RDS Data API, Secrets Manager, S3,
13
+ # DynamoDB, Cognito, SSM reads, KMS,
14
+ # SQS (here for size balance, see
15
+ # the locals note)
16
+ # thinkwork-<stage>-api-orchestration — lambda:InvokeFunction, Scheduler,
17
+ # Step Functions, SES
18
+ # thinkwork-<stage>-api-ai — Bedrock invoke, Knowledge Bases,
19
+ # AgentCore memory/eval/code-interp
20
+ # thinkwork-<stage>-api-observability — CloudWatch Logs reads, ECS/ALB
21
+ # health reads
22
+ #
23
+ # STANDING RULE: new grants for aws_iam_role.lambda go into one of these four
24
+ # grouped policies — never a new inline aws_iam_role_policy and never a new
25
+ # standalone managed-policy attachment. (Managed-policy attachments have a
26
+ # default quota of 10 per role; the steady state here is
27
+ # AWSLambdaBasicExecutionRole + these four, plus the conditional AWS-managed
28
+ # VPC-access policy when Cognee workers are enabled.)
29
+ #
30
+ # Each managed policy document caps at 6,144 characters (JSON minus
31
+ # whitespace) — check rendered size before adding large statements, and
32
+ # rebalance between groups if one approaches the cap.
33
+ #
34
+ # Statements below are byte-equivalent relocations of the originals; the
35
+ # WHY comments moved with them. Do not widen/narrow/dedupe when editing.
36
+ ################################################################################
37
+
38
+ locals {
39
+ # ---------------------------------------------------------------------------
40
+ # Group 1: data plane — databases, secrets, object/parameter storage.
41
+ # ---------------------------------------------------------------------------
42
+ api_data_plane_statements = concat(
43
+ [
44
+ # (was inline policy "rds-data-api")
45
+ {
46
+ Effect = "Allow"
47
+ Action = [
48
+ "rds-data:ExecuteStatement",
49
+ "rds-data:BatchExecuteStatement",
50
+ "rds-data:BeginTransaction",
51
+ "rds-data:CommitTransaction",
52
+ "rds-data:RollbackTransaction",
53
+ ]
54
+ Resource = var.db_cluster_arn
55
+ },
56
+ # (was inline policy "secrets-manager")
57
+ {
58
+ Effect = "Allow"
59
+ Action = ["secretsmanager:GetSecretValue"]
60
+ Resource = var.graphql_db_secret_arn
61
+ },
62
+ {
63
+ Effect = "Allow"
64
+ Action = [
65
+ "secretsmanager:CreateSecret",
66
+ "secretsmanager:UpdateSecret",
67
+ "secretsmanager:DeleteSecret",
68
+ "secretsmanager:GetSecretValue"
69
+ ]
70
+ Resource = "arn:aws:secretsmanager:${var.region}:${var.account_id}:secret:thinkwork/*"
71
+ },
72
+ # Plugin app-level OAuth activation tokens (plan 2026-06-12-001 U6):
73
+ # thinkwork/{stage}/plugin-tokens/{userId}/{pluginInstallId}/{resourceKey}.
74
+ # Already covered by the thinkwork/* wildcard above — named here
75
+ # explicitly (additive, no behavior change) so the plugin-tokens
76
+ # path survives any future narrowing of that wildcard. Create/Update
77
+ # mint+refresh, Get resolves at dispatch, Delete is the real
78
+ # deactivation/uninstall teardown (ForceDeleteWithoutRecovery).
79
+ {
80
+ Effect = "Allow"
81
+ Action = [
82
+ "secretsmanager:CreateSecret",
83
+ "secretsmanager:UpdateSecret",
84
+ "secretsmanager:DeleteSecret",
85
+ "secretsmanager:GetSecretValue"
86
+ ]
87
+ Resource = "arn:aws:secretsmanager:${var.region}:${var.account_id}:secret:thinkwork/*/plugin-tokens/*"
88
+ },
89
+ # (was inline policy "s3-access" — the workspace bucket)
90
+ {
91
+ Effect = "Allow"
92
+ Action = [
93
+ "s3:GetObject",
94
+ "s3:PutObject",
95
+ "s3:DeleteObject",
96
+ "s3:ListBucket",
97
+ ]
98
+ Resource = [
99
+ var.bucket_arn,
100
+ "${var.bucket_arn}/*",
101
+ ]
102
+ },
103
+ # (was inline policy "wiki-exports-s3" in handlers.tf) — wiki-export
104
+ # writes markdown vault bundles to the per-stage wiki-exports bucket.
105
+ {
106
+ Effect = "Allow"
107
+ Action = ["s3:PutObject", "s3:AbortMultipartUpload"]
108
+ Resource = "${aws_s3_bucket.wiki_exports.arn}/*"
109
+ },
110
+ # Canonical Company Brain artifacts: durable source artifacts,
111
+ # ingestion manifests, migration snapshots, vault projections, and
112
+ # exports, and OKF Wiki Navigator bundles/current manifests.
113
+ # Tenant-visible APIs redact object keys; Lambdas need object read/write
114
+ # for replay and list access for migration enumeration.
115
+ {
116
+ Effect = "Allow"
117
+ Action = [
118
+ "s3:GetObject",
119
+ "s3:GetObjectVersion",
120
+ "s3:PutObject",
121
+ "s3:AbortMultipartUpload",
122
+ ]
123
+ Resource = "${aws_s3_bucket.brain_artifacts.arn}/*"
124
+ },
125
+ {
126
+ Effect = "Allow"
127
+ Action = ["s3:ListBucket"]
128
+ Resource = aws_s3_bucket.brain_artifacts.arn
129
+ },
130
+ # (was inline policy "cognito-access")
131
+ {
132
+ Effect = "Allow"
133
+ Action = [
134
+ "cognito-idp:AdminCreateUser",
135
+ "cognito-idp:AdminGetUser",
136
+ "cognito-idp:AdminInitiateAuth",
137
+ "cognito-idp:AdminRespondToAuthChallenge",
138
+ "cognito-idp:AdminSetUserPassword",
139
+ "cognito-idp:AdminUpdateUserAttributes",
140
+ "cognito-idp:ListUsers",
141
+ ]
142
+ Resource = var.user_pool_arn
143
+ },
144
+ # (was inline policy "mcp-oauth-revocations" in mcp-oauth.tf)
145
+ {
146
+ Effect = "Allow"
147
+ Action = [
148
+ "dynamodb:GetItem",
149
+ "dynamodb:PutItem"
150
+ ]
151
+ Resource = aws_dynamodb_table.mcp_oauth_revocations.arn
152
+ },
153
+ # (was inline policy "ssm-param-read")
154
+ # graphql-http's sendMessage mutation reads SSM parameters like
155
+ # /thinkwork/${stage}/chat-agent-invoke-fn-arn to discover the direct
156
+ # Lambda targets for cross-function invocation. Without this, the SSM
157
+ # GetParameter call fails with AccessDenied, the caller silently
158
+ # catches the error, and sendMessage falls back to the wakeup-processor
159
+ # path — which doesn't load messages_history from Aurora. That's why
160
+ # multi-turn chat was losing prior context: history was only loaded on
161
+ # the direct path, which never ran.
162
+ #
163
+ # This stage-wide grant also covers the customer-domain namespace
164
+ # token at /thinkwork/${stage}/cloudflare-namespace-token (plan
165
+ # 2026-06-12-002 U5/KTD7, declared in handlers.tf): tenant slug
166
+ # validation reads it to run the read-only Cloudflare availability
167
+ # check. A read failure there fails CLOSED (signup rejects with
168
+ # SLUG_VALIDATION_UNAVAILABLE), so narrowing this wildcard later must
169
+ # keep that path or tenant creation breaks.
170
+ {
171
+ Effect = "Allow"
172
+ Action = [
173
+ "ssm:GetParameter",
174
+ "ssm:GetParameters",
175
+ ]
176
+ Resource = "arn:aws:ssm:${var.region}:${var.account_id}:parameter/thinkwork/${var.stage}/*"
177
+ },
178
+ # SecureString parameters (e.g. /thinkwork/<stage>/google-places/api-key)
179
+ # are encrypted with the default AWS-managed SSM key. The default key's
180
+ # resource policy auto-grants Decrypt to any IAM principal with
181
+ # ssm:GetParameter on the parameter via `kms:ViaService = ssm.*`, so
182
+ # this explicit grant is a belt-and-suspenders clarification. If we
183
+ # later move to a customer-managed KMS key, this is the scope that
184
+ # needs updating.
185
+ {
186
+ Effect = "Allow"
187
+ Action = ["kms:Decrypt"]
188
+ Resource = "*"
189
+ Condition = {
190
+ StringEquals = {
191
+ "kms:ViaService" = "ssm.${var.region}.amazonaws.com"
192
+ }
193
+ }
194
+ },
195
+ # (was the SsmReadEvalRunnerCfg statement of inline policy
196
+ # "eval-runner-bedrock-agentcore" — the rest lives in the ai and
197
+ # observability groups)
198
+ {
199
+ Sid = "SsmReadEvalRunnerCfg"
200
+ Effect = "Allow"
201
+ Action = ["ssm:GetParameter", "ssm:GetParameters"]
202
+ Resource = "arn:aws:ssm:${var.region}:${var.account_id}:parameter/thinkwork/${var.stage}/agentcore/runtime-id-*"
203
+ },
204
+ # (was the RoutineTaskPythonS3Offload statement of inline policy
205
+ # "routines-step-functions" — the SFN statements live in the
206
+ # orchestration group)
207
+ # routine-task-python S3 offload — full stdout/stderr land in
208
+ # the per-stage routine-output bucket under
209
+ # <tenantId>/<sfn-execution-id>/<nodeId>/{stdout,stderr}.log.
210
+ # PutObject only — the read path is GraphQL-fronted and runs
211
+ # under the graphql-http handler's role, not this one.
212
+ {
213
+ Sid = "RoutineTaskPythonS3Offload"
214
+ Effect = "Allow"
215
+ Action = [
216
+ "s3:PutObject",
217
+ ]
218
+ Resource = "arn:aws:s3:::thinkwork-${var.stage}-routine-output/*"
219
+ },
220
+ # (was standalone managed policy "lambda_model_catalog_import_read")
221
+ # Settings -> Model Catalog imports call Bedrock's foundation-model
222
+ # catalog and AWS Price List APIs from graphql-http. These read/list
223
+ # APIs do not support useful resource scoping.
224
+ {
225
+ Effect = "Allow"
226
+ Action = [
227
+ "bedrock:ListFoundationModels",
228
+ ]
229
+ Resource = "*"
230
+ },
231
+ {
232
+ Effect = "Allow"
233
+ Action = [
234
+ "pricing:DescribeServices",
235
+ "pricing:GetAttributeValues",
236
+ "pricing:GetProducts",
237
+ ]
238
+ Resource = "*"
239
+ },
240
+ ],
241
+ var.plugin_catalog_github_token_secret_arn != "" ? [
242
+ {
243
+ Effect = "Allow"
244
+ Action = ["secretsmanager:GetSecretValue"]
245
+ Resource = var.plugin_catalog_github_token_secret_arn
246
+ },
247
+ ] : [],
248
+ # (was standalone managed policy "lambda_deployment_evidence_read")
249
+ # Access to the deployment evidence bucket: graphql-http's deployments
250
+ # resolvers read deployment/status/current.json (deployed-release pointer
251
+ # behind Settings > General and the sidebar release label) and session
252
+ # evidence artifacts. Settings release-update remediation also writes a
253
+ # backed-up runner, refreshed runner, and evidence JSON into this same
254
+ # bucket after verifying the selected release metadata. Without the reads
255
+ # the UI shows "unknown"; without PutObject the safe Settings runner
256
+ # refresh path cannot replace the old manual AWS CLI step.
257
+ var.deployment_evidence_bucket != "" ? [
258
+ {
259
+ Effect = "Allow"
260
+ Action = [
261
+ "s3:GetObject",
262
+ "s3:ListBucket",
263
+ "s3:PutObject",
264
+ ]
265
+ Resource = [
266
+ "arn:aws:s3:::${var.deployment_evidence_bucket}",
267
+ "arn:aws:s3:::${var.deployment_evidence_bucket}/*",
268
+ ]
269
+ },
270
+ ] : [],
271
+ var.billing_export_bucket_name != "" ? [
272
+ {
273
+ Effect = "Allow"
274
+ Action = [
275
+ "s3:GetObject",
276
+ "s3:ListBucket",
277
+ ]
278
+ Resource = [
279
+ "arn:aws:s3:::${var.billing_export_bucket_name}",
280
+ "arn:aws:s3:::${var.billing_export_bucket_name}/*",
281
+ ]
282
+ },
283
+ ] : [],
284
+ # SQS grants live here rather than in the orchestration group purely for
285
+ # size balance: with every conditional on, orchestration's rendered JSON
286
+ # would exceed IAM's 6,144-char per-managed-policy cap (R9 rebalance).
287
+ # Handler-gated SQS grants. Each statement was a count-gated inline
288
+ # policy whose queue exists only when local.deploy_lambda_handlers.
289
+ local.deploy_lambda_handlers ? [
290
+ # (was inline policy "thinkwork-${stage}-wiki-compile-dlq-send")
291
+ {
292
+ Sid = "WikiCompileDlqSend"
293
+ Effect = "Allow"
294
+ Action = ["sqs:SendMessage"]
295
+ Resource = aws_sqs_queue.wiki_compile_dlq[0].arn
296
+ },
297
+ # (was inline policy "thinkwork-${stage}-ontology-scan-dlq-send")
298
+ {
299
+ Sid = "OntologyScanDlqSend"
300
+ Effect = "Allow"
301
+ Action = ["sqs:SendMessage"]
302
+ Resource = aws_sqs_queue.ontology_scan_dlq[0].arn
303
+ },
304
+ # (was inline policy "thinkwork-${stage}-ontology-reprocess-dlq-send")
305
+ {
306
+ Sid = "OntologyReprocessDlqSend"
307
+ Effect = "Allow"
308
+ Action = ["sqs:SendMessage"]
309
+ Resource = aws_sqs_queue.ontology_reprocess_dlq[0].arn
310
+ },
311
+ # (was inline policy "compliance-drainer-dlq-send")
312
+ {
313
+ Sid = "ComplianceDrainerDlqSend"
314
+ Effect = "Allow"
315
+ Action = ["sqs:SendMessage"]
316
+ Resource = aws_sqs_queue.compliance_drainer_dlq[0].arn
317
+ },
318
+ # (was inline policy "compliance-exports-send")
319
+ # graphql-http needs sqs:SendMessage on the exports queue to dispatch
320
+ # jobIds from the createComplianceExport mutation. Attached to the
321
+ # shared lambda role (which graphql-http assumes); scope is
322
+ # queue-specific. (The runner's receive grants stay on the dedicated
323
+ # runner role — see compliance_exports_runner_sqs in handlers.tf.)
324
+ {
325
+ Sid = "ComplianceExportsSend"
326
+ Effect = "Allow"
327
+ Action = ["sqs:SendMessage"]
328
+ Resource = aws_sqs_queue.compliance_exports[0].arn
329
+ },
330
+ # (was inline policy "eval-fanout-send")
331
+ {
332
+ Sid = "EvalRunnerSendFanoutMessages"
333
+ Effect = "Allow"
334
+ Action = [
335
+ "sqs:SendMessage",
336
+ "sqs:SendMessageBatch",
337
+ ]
338
+ Resource = aws_sqs_queue.eval_fanout[0].arn
339
+ },
340
+ # (was inline policy "eval-worker-sqs")
341
+ {
342
+ Sid = "EvalWorkerReceiveFanoutMessages"
343
+ Effect = "Allow"
344
+ Action = [
345
+ "sqs:ReceiveMessage",
346
+ "sqs:DeleteMessage",
347
+ "sqs:GetQueueAttributes",
348
+ "sqs:ChangeMessageVisibility",
349
+ ]
350
+ Resource = aws_sqs_queue.eval_fanout[0].arn
351
+ },
352
+ {
353
+ Sid = "EvalWorkerSendDlqMessages"
354
+ Effect = "Allow"
355
+ Action = ["sqs:SendMessage"]
356
+ Resource = aws_sqs_queue.eval_fanout_dlq[0].arn
357
+ },
358
+ ] : [],
359
+ # (was inline policy "thinkwork-${stage}-lambda-workspace-events-sqs",
360
+ # count-gated on the same flag)
361
+ local.workspace_event_enabled ? [
362
+ {
363
+ Effect = "Allow"
364
+ Action = [
365
+ "sqs:ReceiveMessage",
366
+ "sqs:DeleteMessage",
367
+ "sqs:GetQueueAttributes",
368
+ "sqs:ChangeMessageVisibility",
369
+ ]
370
+ Resource = concat(
371
+ [for q in aws_sqs_queue.workspace_event : q.arn],
372
+ [for q in aws_sqs_queue.workspace_event_dlq : q.arn],
373
+ )
374
+ },
375
+ ] : [],
376
+ var.brain_artifacts_kms_key_arn != "" ? [
377
+ {
378
+ Effect = "Allow"
379
+ Action = [
380
+ "kms:Decrypt",
381
+ "kms:GenerateDataKey",
382
+ ]
383
+ Resource = var.brain_artifacts_kms_key_arn
384
+ Condition = {
385
+ StringEquals = {
386
+ "kms:ViaService" = "s3.${var.region}.amazonaws.com"
387
+ }
388
+ }
389
+ },
390
+ ] : [],
391
+ var.okf_efs_file_system_arn != "" && var.okf_efs_refresh_access_point_arn != "" ? [
392
+ {
393
+ Sid = "OkfEfsHydratorMountWrite"
394
+ Effect = "Allow"
395
+ Action = [
396
+ "elasticfilesystem:ClientMount",
397
+ "elasticfilesystem:ClientWrite",
398
+ ]
399
+ Resource = var.okf_efs_file_system_arn
400
+ Condition = {
401
+ StringEquals = {
402
+ "elasticfilesystem:AccessPointArn" = var.okf_efs_refresh_access_point_arn
403
+ }
404
+ }
405
+ },
406
+ ] : [],
407
+ )
408
+
409
+ # ---------------------------------------------------------------------------
410
+ # Group 2: orchestration — cross-function invokes, Scheduler, Step
411
+ # Functions, SQS, SES.
412
+ # ---------------------------------------------------------------------------
413
+ api_orchestration_statements = concat(
414
+ [
415
+ # (was inline policy "ses-send")
416
+ # SES send permissions for the email-send handler. Scoped to any
417
+ # verified identity in this account+region so the email-send Lambda
418
+ # can SendRawEmail from agents.thinkwork.ai (and any other domain
419
+ # identity a future deployment might add).
420
+ {
421
+ Effect = "Allow"
422
+ Action = [
423
+ "ses:SendEmail",
424
+ "ses:SendRawEmail",
425
+ ]
426
+ Resource = [
427
+ "arn:aws:ses:${var.region}:${var.account_id}:identity/*",
428
+ "arn:aws:ses:${var.region}:${var.account_id}:configuration-set/*",
429
+ ]
430
+ },
431
+ # (was inline policy "eventbridge-scheduler-rw")
432
+ # job-schedule-manager creates/updates/deletes EventBridge Scheduler
433
+ # schedules (and the thinkwork-jobs schedule group on first use). Without
434
+ # these permissions the manager Lambda threw silently and every scheduled
435
+ # automation was orphaned with eb_schedule_name = null.
436
+ {
437
+ Effect = "Allow"
438
+ Action = [
439
+ "scheduler:CreateSchedule",
440
+ "scheduler:UpdateSchedule",
441
+ "scheduler:DeleteSchedule",
442
+ "scheduler:GetSchedule",
443
+ "scheduler:ListSchedules",
444
+ "scheduler:CreateScheduleGroup",
445
+ "scheduler:GetScheduleGroup",
446
+ "scheduler:DeleteScheduleGroup",
447
+ "scheduler:TagResource",
448
+ ]
449
+ Resource = "*"
450
+ },
451
+ # Scheduler.CreateSchedule takes a RoleArn for the target; AWS requires
452
+ # the caller to have iam:PassRole on that role. Without this the
453
+ # CreateSchedule call fails with AccessDenied even if the scheduler
454
+ # permissions above are set.
455
+ {
456
+ Effect = "Allow"
457
+ Action = ["iam:PassRole"]
458
+ Resource = var.job_scheduler_role_arn != "" ? var.job_scheduler_role_arn : "*"
459
+ },
460
+ # (was inline policy "api-cross-function-invoke")
461
+ # Allow API handler Lambdas to invoke each other directly. sendMessage
462
+ # dispatches to chat-agent-invoke for instant chat response; the memory
463
+ # resolvers reach knowledge-base-manager and job-schedule-manager for
464
+ # admin-driven operations. The agentcore-invoke statement below covers
465
+ # the Pi runtime Lambda only — this one covers internal api-to-api
466
+ # calls. ARNs are constructed deterministically from the handler naming
467
+ # pattern so we don't create a dependency cycle with the handler
468
+ # resource.
469
+ {
470
+ Effect = "Allow"
471
+ Action = ["lambda:InvokeFunction"]
472
+ Resource = [
473
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-chat-agent-invoke",
474
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-knowledge-base-manager",
475
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-job-schedule-manager",
476
+ # eval-runner: graphql-http's startEvalRun mutation Event-invokes
477
+ # this asynchronously after inserting the eval_runs row.
478
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-eval-runner",
479
+ # wiki-compile: memory-retain Event-invokes this after a successful
480
+ # retainTurn when the tenant's wiki_compile_enabled flag is on.
481
+ # compileWikiNow admin mutation also Event-invokes.
482
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-wiki-compile",
483
+ # knowledge-graph-thread-ingest: graphql-http's
484
+ # startKnowledgeGraphThreadIngest mutation invokes this with
485
+ # RequestResponse after inserting the durable ingest run.
486
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-knowledge-graph-thread-ingest",
487
+ # knowledge-graph-observations-ingest: graphql-http's
488
+ # startKnowledgeGraphObservationsIngest mutation invokes this with
489
+ # RequestResponse; the worker also Event-invokes ITSELF to drain a
490
+ # truncated candidate backlog across successive runs.
491
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-knowledge-graph-observations-ingest",
492
+ # wiki-bootstrap-import: bootstrapJournalImport admin mutation
493
+ # Event-invokes this for the long-running ingest path.
494
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-wiki-bootstrap-import",
495
+ # ontology-scan: startOntologySuggestionScan Event-invokes this
496
+ # after inserting a durable scan job row.
497
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-ontology-scan",
498
+ # ontology-reprocess: approveOntologyChangeSet Event-invokes this
499
+ # after inserting a durable reprocess job row.
500
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-ontology-reprocess",
501
+ # routine-resume: routine-approval-bridge (Phase B U8) invokes
502
+ # this with RequestResponse after a HITL decideInboxItem
503
+ # decision. Calls SendTaskSuccess/SendTaskFailure on the SFN
504
+ # task token; idempotent on already-consumed tokens.
505
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-routine-resume",
506
+ # workspace-files-efs: workspace-files invokes this (RequestResponse)
507
+ # for Computer-target list/get to bypass the computer_tasks queue
508
+ # and read EFS directly. Standalone resource below.
509
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-workspace-files-efs",
510
+ # workspace-renderer: chat-agent-invoke invokes this synchronously
511
+ # before AgentCore so Pi can opt into the rendered
512
+ # per-(agent, Space, user) workspace prefix.
513
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-workspace-renderer",
514
+ # skill-trust-runner: graphql-http's publishSkillDraft mutation
515
+ # invokes this with RequestResponse so SkillSpector completion is a
516
+ # server-side publish gate, not just an operator UI affordance.
517
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-skill-trust-runner",
518
+ ]
519
+ },
520
+ # (was standalone managed policy "workspace_renderer_invoke")
521
+ # Allow API Lambdas to invoke the workspace renderer.
522
+ {
523
+ Effect = "Allow"
524
+ Action = ["lambda:InvokeFunction"]
525
+ Resource = [
526
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-workspace-renderer",
527
+ "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-workspace-renderer:*",
528
+ ]
529
+ },
530
+ # (was standalone managed policy "thread_idle_memory_learning_invoke")
531
+ # Allow API job-trigger Lambda to invoke requester idle memory learning
532
+ # worker (thinkwork-${var.stage}-thread-idle-memory-learning-invoke).
533
+ {
534
+ Effect = "Allow"
535
+ Action = ["lambda:InvokeFunction"]
536
+ Resource = "arn:aws:lambda:${var.region}:${var.account_id}:function:thinkwork-${var.stage}-api-thread-idle-memory-learning"
537
+ },
538
+ # (was inline policy "routines-step-functions"; its code-interpreter
539
+ # statement lives in the ai group and its S3-offload statement in the
540
+ # data-plane group)
541
+ # Step Functions admin operations — for createRoutine /
542
+ # publishRoutineVersion / triggerRoutineRun / updateRoutine resolvers
543
+ # (Phase B U7) and the routine-asl-validator Lambda (Phase A U5).
544
+ # State-machine ARNs follow the naming convention
545
+ # `thinkwork-${stage}-routine-*`; aliases follow the state-machine ARN
546
+ # with a colon-separated alias name.
547
+ {
548
+ Sid = "RoutineStateMachineLifecycle"
549
+ Effect = "Allow"
550
+ Action = [
551
+ "states:CreateStateMachine",
552
+ "states:UpdateStateMachine",
553
+ "states:DeleteStateMachine",
554
+ "states:DescribeStateMachine",
555
+ "states:ListStateMachines",
556
+ "states:TagResource",
557
+ "states:UntagResource",
558
+ "states:PublishStateMachineVersion",
559
+ "states:DeleteStateMachineVersion",
560
+ "states:ListStateMachineVersions",
561
+ "states:CreateStateMachineAlias",
562
+ "states:UpdateStateMachineAlias",
563
+ "states:DeleteStateMachineAlias",
564
+ "states:DescribeStateMachineAlias",
565
+ "states:ListStateMachineAliases",
566
+ "states:DescribeStateMachineForExecution",
567
+ ]
568
+ Resource = "arn:aws:states:${var.region}:${var.account_id}:stateMachine:thinkwork-${var.stage}-routine-*"
569
+ },
570
+ {
571
+ Sid = "RoutineExecution"
572
+ Effect = "Allow"
573
+ Action = [
574
+ "states:StartExecution",
575
+ "states:StartSyncExecution",
576
+ "states:StopExecution",
577
+ "states:DescribeExecution",
578
+ "states:ListExecutions",
579
+ "states:GetExecutionHistory",
580
+ ]
581
+ Resource = [
582
+ "arn:aws:states:${var.region}:${var.account_id}:stateMachine:thinkwork-${var.stage}-routine-*",
583
+ "arn:aws:states:${var.region}:${var.account_id}:execution:thinkwork-${var.stage}-routine-*:*",
584
+ ]
585
+ },
586
+ {
587
+ Sid = "RoutineTaskTokens"
588
+ Effect = "Allow"
589
+ Action = [
590
+ "states:SendTaskSuccess",
591
+ "states:SendTaskFailure",
592
+ "states:SendTaskHeartbeat",
593
+ ]
594
+ Resource = "*"
595
+ },
596
+ {
597
+ Sid = "RoutineValidate"
598
+ Effect = "Allow"
599
+ Action = ["states:ValidateStateMachineDefinition"]
600
+ Resource = "*"
601
+ },
602
+ {
603
+ # PassRole so the createRoutine resolver can hand the routines
604
+ # execution role to a newly-created state machine. Scoped to the
605
+ # specific role created by the routines-stepfunctions module.
606
+ Sid = "RoutinePassExecutionRole"
607
+ Effect = "Allow"
608
+ Action = ["iam:PassRole"]
609
+ Resource = "arn:aws:iam::${var.account_id}:role/thinkwork-${var.stage}-routines-execution-role"
610
+ Condition = {
611
+ StringEquals = {
612
+ "iam:PassedToService" = "states.amazonaws.com"
613
+ }
614
+ }
615
+ },
616
+ # (was standalone managed policy "lambda_deployment_stepfunctions")
617
+ # Allow API Lambdas to start and inspect the deployment orchestrator.
618
+ {
619
+ Sid = "DeploymentExecution"
620
+ Effect = "Allow"
621
+ Action = [
622
+ "states:StartExecution",
623
+ "states:StopExecution",
624
+ "states:DescribeExecution",
625
+ "states:GetExecutionHistory",
626
+ ]
627
+ Resource = [
628
+ "arn:aws:states:${var.region}:${var.account_id}:stateMachine:thinkwork-${var.stage}-deployment-*",
629
+ "arn:aws:states:${var.region}:${var.account_id}:execution:thinkwork-${var.stage}-deployment-*:*",
630
+ ]
631
+ },
632
+ # Settings release-update preflight inspects the frozen customer
633
+ # control-plane runner and detects known live IAM drift before dispatch.
634
+ # This is read-only by design: v1 blocks on IAM gaps and requires a
635
+ # reviewed infrastructure change rather than mutating the runner role
636
+ # from GraphQL.
637
+ {
638
+ Sid = "DeploymentPreflightRead"
639
+ Effect = "Allow"
640
+ Action = [
641
+ "codebuild:BatchGetProjects",
642
+ "iam:GetPolicy",
643
+ "iam:GetPolicyVersion",
644
+ "iam:GetRolePolicy",
645
+ "iam:ListAttachedRolePolicies",
646
+ "iam:ListRolePolicies",
647
+ ]
648
+ Resource = [
649
+ "arn:aws:codebuild:${var.region}:${var.account_id}:project/thinkwork-${var.stage}-deployment-*",
650
+ "arn:aws:iam::${var.account_id}:role/thinkwork-${var.stage}-deployment-*",
651
+ "arn:aws:iam::${var.account_id}:policy/thinkwork-${var.stage}-deployment-*",
652
+ ]
653
+ },
654
+ ],
655
+ # (was inline policy "agentcore-invoke", count-gated on the same flag)
656
+ # Allow API Lambdas to directly invoke the Pi AgentCore Lambda. Used by
657
+ # chat-agent-invoke, wake-up, retry, and skill-run paths via InvokeCommand.
658
+ var.enable_agentcore_pi_invoke_policy ? [
659
+ {
660
+ Effect = "Allow"
661
+ Action = [
662
+ "lambda:InvokeFunction",
663
+ ]
664
+ Resource = compact([
665
+ var.agentcore_pi_function_arn,
666
+ var.agentcore_pi_function_arn != "" ? "${var.agentcore_pi_function_arn}:*" : "",
667
+ ])
668
+ },
669
+ ] : [],
670
+ )
671
+
672
+ # ---------------------------------------------------------------------------
673
+ # Group 3: AI — Bedrock model invocation, Knowledge Bases, AgentCore
674
+ # memory / evaluations / code interpreter.
675
+ # ---------------------------------------------------------------------------
676
+ api_ai_statements = [
677
+ # (was inline policy "bedrock-invoke")
678
+ # Cross-region inference profiles (us.anthropic.claude-*) require
679
+ # `bedrock:InvokeModel` on the *inference-profile* ARN AND on the
680
+ # underlying foundation-model ARN in *every* region the profile can
681
+ # route to (e.g. us-east-2 for us.anthropic.claude-haiku-4-5). The
682
+ # region wildcard below covers all of them. Needed by the eval-runner
683
+ # llm-rubric judge and any handler that calls Converse with a profile ID.
684
+ {
685
+ Effect = "Allow"
686
+ Action = ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"]
687
+ Resource = [
688
+ "arn:aws:bedrock:*::foundation-model/*",
689
+ "arn:aws:bedrock:*:${var.account_id}:inference-profile/*",
690
+ ]
691
+ },
692
+ # (was standalone managed policy "lambda_bedrock_knowledge_base")
693
+ # The knowledge-base-manager Lambda provisions and manages Bedrock
694
+ # Knowledge Bases (control plane: create/sync/rechunk/delete), and
695
+ # graphql-http's testKnowledgeBaseRetrieval query calls Retrieve. Without
696
+ # these the manager fails with "not authorized to perform:
697
+ # bedrock:CreateKnowledgeBase" and every KB is stuck in `failed`.
698
+ # CreateKnowledgeBase / CreateDataSource also take a roleArn that Bedrock
699
+ # assumes, so the caller needs iam:PassRole on the KB service role.
700
+ {
701
+ Effect = "Allow"
702
+ Action = [
703
+ "bedrock:CreateKnowledgeBase",
704
+ "bedrock:GetKnowledgeBase",
705
+ "bedrock:UpdateKnowledgeBase",
706
+ "bedrock:DeleteKnowledgeBase",
707
+ "bedrock:ListKnowledgeBases",
708
+ "bedrock:CreateDataSource",
709
+ "bedrock:GetDataSource",
710
+ "bedrock:UpdateDataSource",
711
+ "bedrock:DeleteDataSource",
712
+ "bedrock:ListDataSources",
713
+ "bedrock:StartIngestionJob",
714
+ "bedrock:GetIngestionJob",
715
+ "bedrock:ListIngestionJobs",
716
+ "bedrock:Retrieve",
717
+ ]
718
+ # CreateKnowledgeBase/CreateDataSource have no resource ARN at create
719
+ # time and don't support resource-level scoping, so a knowledge-base/*
720
+ # ARN makes the grant not match. Control-plane "*" for this internal
721
+ # manager Lambda; PassRole below stays scoped to the KB service role.
722
+ Resource = "*"
723
+ },
724
+ {
725
+ Effect = "Allow"
726
+ Action = ["iam:PassRole"]
727
+ Resource = var.kb_service_role_arn != "" ? var.kb_service_role_arn : "*"
728
+ },
729
+ # (was inline policy "agentcore-memory-rw")
730
+ # AgentCore Memory read access for the GraphQL memory resolvers.
731
+ # memoryRecords / memorySearch call ListMemoryRecordsCommand to fetch
732
+ # records across the tenant's agents.
733
+ {
734
+ Effect = "Allow"
735
+ Action = [
736
+ "bedrock-agentcore:ListMemoryRecords",
737
+ "bedrock-agentcore:RetrieveMemoryRecords",
738
+ "bedrock-agentcore:GetMemoryRecord",
739
+ "bedrock-agentcore:BatchCreateMemoryRecords",
740
+ "bedrock-agentcore:BatchUpdateMemoryRecords",
741
+ "bedrock-agentcore:BatchDeleteMemoryRecords",
742
+ "bedrock-agentcore:DeleteMemoryRecord",
743
+ ]
744
+ Resource = "*"
745
+ },
746
+ # (were the AgentCore statements of inline policy
747
+ # "eval-runner-bedrock-agentcore"; the spans-read statement lives in
748
+ # the observability group and the SSM read in the data-plane group)
749
+ # Eval-runner: invoke the AgentCore Runtime data plane to run an agent
750
+ # under test, and call AgentCore Evaluations.Evaluate to score the
751
+ # resulting spans. Both APIs are on the bedrock-agentcore service.
752
+ {
753
+ Sid = "AgentCoreInvokeRuntime"
754
+ Effect = "Allow"
755
+ Action = ["bedrock-agentcore:InvokeAgentRuntime"]
756
+ Resource = "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:runtime/*"
757
+ },
758
+ {
759
+ Sid = "AgentCoreEvaluate"
760
+ Effect = "Allow"
761
+ Action = [
762
+ "bedrock-agentcore:Evaluate",
763
+ "bedrock-agentcore:GetEvaluator",
764
+ "bedrock-agentcore:ListEvaluators",
765
+ ]
766
+ Resource = "*"
767
+ },
768
+ # (was the RoutineTaskPythonCodeInterpreter statement of inline policy
769
+ # "routines-step-functions")
770
+ # routine-task-python (Phase B U6) wraps the AgentCore code
771
+ # interpreter so SFN can run `python` recipe states. Three calls
772
+ # per Task: Start session, Invoke, Stop. Resource is `*` because
773
+ # interpreter sessions are runtime-scoped, not provisioned.
774
+ {
775
+ Sid = "RoutineTaskPythonCodeInterpreter"
776
+ Effect = "Allow"
777
+ Action = [
778
+ "bedrock-agentcore:StartCodeInterpreterSession",
779
+ "bedrock-agentcore:InvokeCodeInterpreter",
780
+ "bedrock-agentcore:StopCodeInterpreterSession",
781
+ "bedrock-agentcore:GetCodeInterpreterSession",
782
+ ]
783
+ Resource = "*"
784
+ },
785
+ ]
786
+
787
+ # ---------------------------------------------------------------------------
788
+ # Group 4: observability — CloudWatch Logs reads, ECS/ALB health reads.
789
+ # ---------------------------------------------------------------------------
790
+ api_observability_statements = [
791
+ # (was inline policy "cloudwatch-logs-read")
792
+ {
793
+ Effect = "Allow"
794
+ Action = ["logs:FilterLogEvents", "logs:GetLogEvents", "logs:DescribeLogGroups"]
795
+ Resource = [
796
+ local.bedrock_invocation_log_group_arn,
797
+ "${local.bedrock_invocation_log_group_arn}:*",
798
+ ]
799
+ },
800
+ # (was the EvalSpansRead statement of inline policy
801
+ # "eval-runner-bedrock-agentcore")
802
+ # Eval-runner reads spans + log events from CloudWatch Logs (aws/spans is
803
+ # the Transaction Search destination; runtime log groups carry the OTel
804
+ # records that EvaluateCommand requires alongside the spans).
805
+ {
806
+ Sid = "EvalSpansRead"
807
+ Effect = "Allow"
808
+ Action = [
809
+ "logs:FilterLogEvents",
810
+ "logs:GetLogEvents",
811
+ "logs:DescribeLogGroups",
812
+ "logs:DescribeLogStreams",
813
+ ]
814
+ Resource = [
815
+ "arn:aws:logs:${var.region}:${var.account_id}:log-group:aws/spans",
816
+ "arn:aws:logs:${var.region}:${var.account_id}:log-group:aws/spans:*",
817
+ "arn:aws:logs:${var.region}:${var.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*",
818
+ "arn:aws:logs:${var.region}:${var.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*:*",
819
+ ]
820
+ },
821
+ # (was standalone managed policy "lambda_cognee_health_read")
822
+ # graphql-http's Knowledge Graph health check validates the private
823
+ # Cognee service from outside the VPC by reading ECS service steadiness
824
+ # and ALB target health. ELBv2 Describe* actions do not support useful
825
+ # resource scoping.
826
+ {
827
+ Effect = "Allow"
828
+ Action = [
829
+ "ecs:DescribeServices",
830
+ "elasticloadbalancing:DescribeTargetGroups",
831
+ "elasticloadbalancing:DescribeTargetHealth",
832
+ ]
833
+ Resource = "*"
834
+ },
835
+ ]
836
+ }
837
+
838
+ resource "aws_iam_policy" "api_data_plane" {
839
+ name = "thinkwork-${var.stage}-api-data-plane"
840
+ description = "Grouped data-plane grants (RDS Data API, Secrets Manager, S3, DynamoDB, Cognito, SSM, KMS-via-SSM, SQS) for the shared api Lambda role"
841
+
842
+ policy = jsonencode({
843
+ Version = "2012-10-17"
844
+ Statement = local.api_data_plane_statements
845
+ })
846
+ }
847
+
848
+ resource "aws_iam_role_policy_attachment" "api_data_plane" {
849
+ role = aws_iam_role.lambda.name
850
+ policy_arn = aws_iam_policy.api_data_plane.arn
851
+ }
852
+
853
+ resource "aws_iam_policy" "api_orchestration" {
854
+ name = "thinkwork-${var.stage}-api-orchestration"
855
+ description = "Grouped orchestration grants (Lambda invoke, EventBridge Scheduler, Step Functions, SES) for the shared api Lambda role"
856
+
857
+ policy = jsonencode({
858
+ Version = "2012-10-17"
859
+ Statement = local.api_orchestration_statements
860
+ })
861
+ }
862
+
863
+ resource "aws_iam_role_policy_attachment" "api_orchestration" {
864
+ role = aws_iam_role.lambda.name
865
+ policy_arn = aws_iam_policy.api_orchestration.arn
866
+ }
867
+
868
+ resource "aws_iam_policy" "api_ai" {
869
+ name = "thinkwork-${var.stage}-api-ai"
870
+ description = "Grouped AI grants (Bedrock invoke, Knowledge Bases, AgentCore memory/eval/code-interpreter) for the shared api Lambda role"
871
+
872
+ policy = jsonencode({
873
+ Version = "2012-10-17"
874
+ Statement = local.api_ai_statements
875
+ })
876
+ }
877
+
878
+ resource "aws_iam_role_policy_attachment" "api_ai" {
879
+ role = aws_iam_role.lambda.name
880
+ policy_arn = aws_iam_policy.api_ai.arn
881
+ }
882
+
883
+ resource "aws_iam_policy" "api_observability" {
884
+ name = "thinkwork-${var.stage}-api-observability"
885
+ description = "Grouped observability grants (CloudWatch Logs reads, ECS/ALB health reads) for the shared api Lambda role"
886
+
887
+ policy = jsonencode({
888
+ Version = "2012-10-17"
889
+ Statement = local.api_observability_statements
890
+ })
891
+ }
892
+
893
+ resource "aws_iam_role_policy_attachment" "api_observability" {
894
+ role = aws_iam_role.lambda.name
895
+ policy_arn = aws_iam_policy.api_observability.arn
896
+ }
897
+
898
+ # ----------------------------------------------------------------------------
899
+ # Quota-safe cutover from the absorbed standalone managed policies.
900
+ #
901
+ # The role had up to 9 managed-policy attachments before this consolidation;
902
+ # IAM's default quota is 10 per role. Naively, terraform could create the 4
903
+ # grouped attachments before destroying the 7 absorbed ones (creates and
904
+ # destroys of unrelated resources have no ordering), transiently hitting 13
905
+ # and failing the apply with LimitExceeded — in a customer account, that is
906
+ # exactly the #2375-class deploy failure this plan exists to retire.
907
+ #
908
+ # These moved blocks alias 4 of the absorbed attachment addresses to the 4
909
+ # grouped attachments. Changing policy_arn forces a same-address REPLACEMENT,
910
+ # and attachments replace destroy-before-create, so each swap is
911
+ # count-neutral; the remaining absorbed attachments are pure destroys. The
912
+ # attachment count therefore never exceeds its pre-apply value.
913
+ # ----------------------------------------------------------------------------
914
+
915
+ moved {
916
+ from = aws_iam_role_policy_attachment.lambda_model_catalog_import_read
917
+ to = aws_iam_role_policy_attachment.api_data_plane
918
+ }
919
+
920
+ moved {
921
+ from = aws_iam_role_policy_attachment.lambda_thread_idle_memory_learning_invoke
922
+ to = aws_iam_role_policy_attachment.api_orchestration
923
+ }
924
+
925
+ moved {
926
+ from = aws_iam_role_policy_attachment.lambda_bedrock_knowledge_base
927
+ to = aws_iam_role_policy_attachment.api_ai
928
+ }
929
+
930
+ moved {
931
+ from = aws_iam_role_policy_attachment.lambda_cognee_health_read
932
+ to = aws_iam_role_policy_attachment.api_observability
933
+ }