@jaguilar87/gaia-ops 4.4.0 → 4.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +12 -3
  3. package/ARCHITECTURE.md +9 -8
  4. package/CHANGELOG.md +34 -0
  5. package/README.md +43 -11
  6. package/agents/terraform-architect.md +1 -1
  7. package/bin/README.md +2 -2
  8. package/bin/gaia-doctor.js +18 -5
  9. package/bin/gaia-history.js +0 -1
  10. package/bin/gaia-metrics.js +2 -2
  11. package/bin/gaia-scan.py +23 -1
  12. package/bin/gaia-update.js +346 -54
  13. package/bin/pre-publish-validate.js +33 -10
  14. package/commands/gaia.md +37 -0
  15. package/config/README.md +3 -9
  16. package/config/context-contracts.json +47 -15
  17. package/config/surface-routing.json +9 -1
  18. package/dist/gaia-ops/.claude-plugin/plugin.json +22 -0
  19. package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
  20. package/dist/gaia-ops/agents/devops-developer.md +57 -0
  21. package/dist/gaia-ops/agents/gaia-system.md +58 -0
  22. package/dist/gaia-ops/agents/gitops-operator.md +60 -0
  23. package/dist/gaia-ops/agents/speckit-planner.md +71 -0
  24. package/dist/gaia-ops/agents/terraform-architect.md +60 -0
  25. package/dist/gaia-ops/commands/gaia.md +37 -0
  26. package/dist/gaia-ops/config/README.md +58 -0
  27. package/dist/gaia-ops/config/cloud/aws.json +140 -0
  28. package/dist/gaia-ops/config/cloud/gcp.json +145 -0
  29. package/dist/gaia-ops/config/context-contracts.json +131 -0
  30. package/dist/gaia-ops/config/git_standards.json +72 -0
  31. package/dist/gaia-ops/config/surface-routing.json +197 -0
  32. package/dist/gaia-ops/config/universal-rules.json +10 -0
  33. package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
  34. package/dist/gaia-ops/hooks/adapters/base.py +219 -0
  35. package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
  36. package/dist/gaia-ops/hooks/adapters/claude_code.py +1477 -0
  37. package/dist/gaia-ops/hooks/adapters/types.py +194 -0
  38. package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
  39. package/dist/gaia-ops/hooks/hooks.json +126 -0
  40. package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
  41. package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
  42. package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
  43. package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
  44. package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +124 -0
  45. package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
  46. package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
  47. package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
  48. package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
  49. package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
  50. package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
  51. package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
  52. package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +576 -0
  53. package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
  54. package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
  55. package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
  56. package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +215 -0
  57. package/dist/gaia-ops/hooks/modules/context/context_cache.py +129 -0
  58. package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
  59. package/dist/gaia-ops/hooks/modules/context/context_injector.py +427 -0
  60. package/dist/gaia-ops/hooks/modules/context/context_writer.py +518 -0
  61. package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
  62. package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
  63. package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
  64. package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
  65. package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
  66. package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +558 -0
  67. package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
  68. package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
  69. package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
  70. package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
  71. package/dist/gaia-ops/hooks/modules/identity/__init__.py +0 -0
  72. package/dist/gaia-ops/hooks/modules/identity/identity_provider.py +21 -0
  73. package/dist/gaia-ops/hooks/modules/identity/ops_identity.py +34 -0
  74. package/dist/gaia-ops/hooks/modules/identity/security_identity.py +10 -0
  75. package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
  76. package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +227 -0
  77. package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
  78. package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +128 -0
  79. package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
  80. package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
  81. package/dist/gaia-ops/hooks/modules/security/__init__.py +89 -0
  82. package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
  83. package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
  84. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +912 -0
  85. package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
  86. package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +153 -0
  87. package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +584 -0
  88. package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +86 -0
  89. package/dist/gaia-ops/hooks/modules/security/command_semantics.py +130 -0
  90. package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
  91. package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +850 -0
  92. package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
  93. package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
  94. package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
  95. package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
  96. package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +158 -0
  97. package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
  98. package/dist/gaia-ops/hooks/modules/tools/__init__.py +25 -0
  99. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +708 -0
  100. package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +181 -0
  101. package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
  102. package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
  103. package/dist/gaia-ops/hooks/modules/tools/task_validator.py +283 -0
  104. package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
  105. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
  106. package/dist/gaia-ops/hooks/post_compact.py +43 -0
  107. package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
  108. package/dist/gaia-ops/hooks/pre_tool_use.py +383 -0
  109. package/dist/gaia-ops/hooks/session_start.py +69 -0
  110. package/dist/gaia-ops/hooks/stop_hook.py +69 -0
  111. package/dist/gaia-ops/hooks/subagent_start.py +71 -0
  112. package/dist/gaia-ops/hooks/subagent_stop.py +288 -0
  113. package/dist/gaia-ops/hooks/task_completed.py +70 -0
  114. package/dist/gaia-ops/hooks/user_prompt_submit.py +177 -0
  115. package/dist/gaia-ops/settings.json +72 -0
  116. package/dist/gaia-ops/skills/README.md +109 -0
  117. package/dist/gaia-ops/skills/agent-protocol/SKILL.md +105 -0
  118. package/dist/gaia-ops/skills/agent-protocol/examples.md +170 -0
  119. package/dist/gaia-ops/skills/agent-response/SKILL.md +53 -0
  120. package/dist/gaia-ops/skills/approval/SKILL.md +85 -0
  121. package/dist/gaia-ops/skills/approval/examples.md +140 -0
  122. package/dist/gaia-ops/skills/approval/reference.md +57 -0
  123. package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
  124. package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
  125. package/dist/gaia-ops/skills/context-updater/SKILL.md +76 -0
  126. package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
  127. package/dist/gaia-ops/skills/developer-patterns/SKILL.md +93 -0
  128. package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
  129. package/dist/gaia-ops/skills/execution/SKILL.md +66 -0
  130. package/dist/gaia-ops/skills/fast-queries/SKILL.md +47 -0
  131. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +92 -0
  132. package/dist/gaia-ops/skills/gaia-patterns/reference.md +22 -0
  133. package/dist/gaia-ops/skills/git-conventions/SKILL.md +48 -0
  134. package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +73 -0
  135. package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
  136. package/dist/gaia-ops/skills/investigation/SKILL.md +77 -0
  137. package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +64 -0
  138. package/dist/gaia-ops/skills/reference.md +134 -0
  139. package/dist/gaia-ops/skills/security-tiers/SKILL.md +61 -0
  140. package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
  141. package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
  142. package/dist/gaia-ops/skills/skill-creation/SKILL.md +119 -0
  143. package/dist/gaia-ops/skills/specification/SKILL.md +186 -0
  144. package/dist/gaia-ops/skills/speckit-workflow/SKILL.md +165 -0
  145. package/dist/gaia-ops/skills/speckit-workflow/reference.md +117 -0
  146. package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +63 -0
  147. package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
  148. package/dist/gaia-ops/speckit/README.md +516 -0
  149. package/dist/gaia-ops/speckit/scripts/.gitkeep +0 -0
  150. package/dist/gaia-ops/speckit/templates/adr-template.md +118 -0
  151. package/dist/gaia-ops/speckit/templates/agent-file-template.md +23 -0
  152. package/dist/gaia-ops/speckit/templates/plan-template.md +227 -0
  153. package/dist/gaia-ops/speckit/templates/spec-template.md +140 -0
  154. package/dist/gaia-ops/speckit/templates/tasks-template.md +257 -0
  155. package/dist/gaia-ops/tools/context/README.md +132 -0
  156. package/dist/gaia-ops/tools/context/__init__.py +42 -0
  157. package/dist/gaia-ops/tools/context/_paths.py +20 -0
  158. package/dist/gaia-ops/tools/context/context_provider.py +476 -0
  159. package/dist/gaia-ops/tools/context/context_section_reader.py +330 -0
  160. package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
  161. package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
  162. package/dist/gaia-ops/tools/context/surface_router.py +278 -0
  163. package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
  164. package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
  165. package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  166. package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  167. package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  168. package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  169. package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
  170. package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  171. package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
  172. package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
  173. package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
  174. package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
  175. package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
  176. package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
  177. package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +262 -0
  178. package/dist/gaia-ops/tools/memory/README.md +0 -0
  179. package/dist/gaia-ops/tools/memory/__init__.py +20 -0
  180. package/dist/gaia-ops/tools/memory/episodic.py +1196 -0
  181. package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
  182. package/dist/gaia-ops/tools/review/__init__.py +1 -0
  183. package/dist/gaia-ops/tools/review/review_engine.py +157 -0
  184. package/dist/gaia-ops/tools/scan/__init__.py +35 -0
  185. package/dist/gaia-ops/tools/scan/config.py +247 -0
  186. package/dist/gaia-ops/tools/scan/merge.py +212 -0
  187. package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
  188. package/dist/gaia-ops/tools/scan/registry.py +127 -0
  189. package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
  190. package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
  191. package/dist/gaia-ops/tools/scan/scanners/environment.py +324 -0
  192. package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
  193. package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
  194. package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
  195. package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
  196. package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
  197. package/dist/gaia-ops/tools/scan/setup.py +753 -0
  198. package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
  199. package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
  200. package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
  201. package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
  202. package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
  203. package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
  204. package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
  205. package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
  206. package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
  207. package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
  208. package/dist/gaia-ops/tools/scan/ui.py +624 -0
  209. package/dist/gaia-ops/tools/scan/verify.py +266 -0
  210. package/dist/gaia-ops/tools/scan/walk.py +118 -0
  211. package/dist/gaia-ops/tools/scan/workspace.py +85 -0
  212. package/dist/gaia-ops/tools/validation/README.md +244 -0
  213. package/dist/gaia-ops/tools/validation/__init__.py +17 -0
  214. package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
  215. package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
  216. package/dist/gaia-security/.claude-plugin/plugin.json +22 -0
  217. package/dist/gaia-security/config/universal-rules.json +10 -0
  218. package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
  219. package/dist/gaia-security/hooks/adapters/base.py +219 -0
  220. package/dist/gaia-security/hooks/adapters/channel.py +17 -0
  221. package/dist/gaia-security/hooks/adapters/claude_code.py +1477 -0
  222. package/dist/gaia-security/hooks/adapters/types.py +194 -0
  223. package/dist/gaia-security/hooks/adapters/utils.py +25 -0
  224. package/dist/gaia-security/hooks/hooks.json +57 -0
  225. package/dist/gaia-security/hooks/modules/__init__.py +15 -0
  226. package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
  227. package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
  228. package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
  229. package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +124 -0
  230. package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
  231. package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
  232. package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
  233. package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
  234. package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
  235. package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
  236. package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
  237. package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +576 -0
  238. package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
  239. package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
  240. package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
  241. package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +215 -0
  242. package/dist/gaia-security/hooks/modules/context/context_cache.py +129 -0
  243. package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
  244. package/dist/gaia-security/hooks/modules/context/context_injector.py +427 -0
  245. package/dist/gaia-security/hooks/modules/context/context_writer.py +518 -0
  246. package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
  247. package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
  248. package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
  249. package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
  250. package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
  251. package/dist/gaia-security/hooks/modules/core/plugin_setup.py +558 -0
  252. package/dist/gaia-security/hooks/modules/core/state.py +179 -0
  253. package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
  254. package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
  255. package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
  256. package/dist/gaia-security/hooks/modules/identity/__init__.py +0 -0
  257. package/dist/gaia-security/hooks/modules/identity/identity_provider.py +21 -0
  258. package/dist/gaia-security/hooks/modules/identity/ops_identity.py +34 -0
  259. package/dist/gaia-security/hooks/modules/identity/security_identity.py +10 -0
  260. package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
  261. package/dist/gaia-security/hooks/modules/memory/episode_writer.py +227 -0
  262. package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
  263. package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +128 -0
  264. package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
  265. package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
  266. package/dist/gaia-security/hooks/modules/security/__init__.py +89 -0
  267. package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
  268. package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
  269. package/dist/gaia-security/hooks/modules/security/approval_grants.py +912 -0
  270. package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
  271. package/dist/gaia-security/hooks/modules/security/approval_scopes.py +153 -0
  272. package/dist/gaia-security/hooks/modules/security/blocked_commands.py +584 -0
  273. package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +86 -0
  274. package/dist/gaia-security/hooks/modules/security/command_semantics.py +130 -0
  275. package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
  276. package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +850 -0
  277. package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
  278. package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
  279. package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
  280. package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
  281. package/dist/gaia-security/hooks/modules/session/session_event_injector.py +158 -0
  282. package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
  283. package/dist/gaia-security/hooks/modules/tools/__init__.py +25 -0
  284. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +708 -0
  285. package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +181 -0
  286. package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
  287. package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
  288. package/dist/gaia-security/hooks/modules/tools/task_validator.py +283 -0
  289. package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
  290. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
  291. package/dist/gaia-security/hooks/post_tool_use.py +54 -0
  292. package/dist/gaia-security/hooks/pre_tool_use.py +383 -0
  293. package/dist/gaia-security/hooks/session_start.py +69 -0
  294. package/dist/gaia-security/hooks/stop_hook.py +69 -0
  295. package/dist/gaia-security/hooks/user_prompt_submit.py +177 -0
  296. package/dist/gaia-security/settings.json +58 -0
  297. package/git-hooks/commit-msg +41 -0
  298. package/hooks/README.md +8 -6
  299. package/hooks/adapters/channel.py +0 -25
  300. package/hooks/adapters/claude_code.py +364 -125
  301. package/hooks/elicitation_result.py +132 -0
  302. package/hooks/hooks.json +10 -1
  303. package/hooks/modules/README.md +3 -2
  304. package/hooks/modules/agents/contract_validator.py +3 -51
  305. package/hooks/modules/agents/response_contract.py +4 -8
  306. package/hooks/modules/agents/transcript_reader.py +4 -5
  307. package/hooks/modules/audit/__init__.py +4 -6
  308. package/hooks/modules/audit/event_detector.py +0 -2
  309. package/hooks/modules/audit/metrics.py +108 -187
  310. package/hooks/modules/audit/workflow_auditor.py +0 -4
  311. package/hooks/modules/audit/workflow_recorder.py +0 -5
  312. package/hooks/modules/context/compact_context_builder.py +1 -0
  313. package/hooks/modules/context/context_cache.py +129 -0
  314. package/hooks/modules/context/context_injector.py +18 -40
  315. package/hooks/modules/context/context_writer.py +1 -25
  316. package/hooks/modules/context/contracts_loader.py +7 -10
  317. package/hooks/modules/core/hook_entry.py +1 -0
  318. package/hooks/modules/core/paths.py +12 -13
  319. package/hooks/modules/core/plugin_mode.py +74 -4
  320. package/hooks/modules/core/plugin_setup.py +395 -23
  321. package/hooks/modules/events/__init__.py +1 -0
  322. package/hooks/modules/events/event_writer.py +210 -0
  323. package/hooks/modules/identity/ops_identity.py +18 -27
  324. package/hooks/modules/memory/episode_writer.py +1 -6
  325. package/hooks/modules/orchestrator/__init__.py +1 -0
  326. package/hooks/modules/orchestrator/delegate_mode.py +128 -0
  327. package/hooks/modules/security/__init__.py +2 -4
  328. package/hooks/modules/security/approval_constants.py +5 -1
  329. package/hooks/modules/security/approval_grants.py +189 -6
  330. package/hooks/modules/security/approval_messages.py +9 -21
  331. package/hooks/modules/security/blocked_commands.py +98 -34
  332. package/hooks/modules/security/command_semantics.py +0 -4
  333. package/hooks/modules/security/gitops_validator.py +1 -11
  334. package/hooks/modules/security/mutative_verbs.py +179 -38
  335. package/hooks/modules/security/tiers.py +1 -19
  336. package/hooks/modules/session/session_event_injector.py +1 -25
  337. package/hooks/modules/tools/bash_validator.py +310 -94
  338. package/hooks/modules/tools/shell_parser.py +0 -1
  339. package/hooks/modules/tools/task_validator.py +9 -29
  340. package/hooks/post_tool_use.py +0 -72
  341. package/hooks/pre_tool_use.py +42 -102
  342. package/hooks/session_start.py +4 -2
  343. package/hooks/subagent_start.py +6 -2
  344. package/hooks/subagent_stop.py +1 -13
  345. package/hooks/user_prompt_submit.py +119 -37
  346. package/index.js +1 -1
  347. package/package.json +5 -3
  348. package/skills/README.md +3 -5
  349. package/skills/agent-protocol/SKILL.md +17 -16
  350. package/skills/agent-protocol/examples.md +6 -6
  351. package/skills/agent-response/SKILL.md +11 -14
  352. package/skills/approval/SKILL.md +28 -13
  353. package/skills/approval/reference.md +2 -2
  354. package/skills/execution/SKILL.md +1 -1
  355. package/skills/gaia-patterns/SKILL.md +2 -3
  356. package/skills/orchestrator-approval/SKILL.md +22 -50
  357. package/skills/security-tiers/SKILL.md +1 -1
  358. package/templates/README.md +9 -9
  359. package/templates/managed-settings.template.json +43 -0
  360. package/tools/gaia_simulator/runner.py +34 -1
  361. package/tools/scan/orchestrator.py +13 -0
  362. package/tools/scan/scanners/base.py +8 -0
  363. package/tools/scan/scanners/git.py +78 -0
  364. package/tools/scan/scanners/infrastructure.py +65 -0
  365. package/tools/scan/scanners/stack.py +110 -0
  366. package/tools/scan/setup.py +120 -13
  367. package/tools/scan/workspace.py +85 -0
  368. package/config/context-contracts.aws.json +0 -42
  369. package/config/context-contracts.gcp.json +0 -39
  370. package/skills/project-dispatch/SKILL.md +0 -34
  371. package/templates/settings.template.json +0 -226
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ # QuickTriage for Terraform - Optimized version
3
+ # Only shows validation results, not full output
4
+
5
+ set -euo pipefail
6
+
7
+ TARGET_DIR="${1:-.}"
8
+ USE_TERRAGRUNT="${USE_TERRAGRUNT:-false}"
9
+
10
+ # Detect if should use terragrunt based on files present
11
+ if [ "$USE_TERRAGRUNT" != "true" ] && [ -f "$TARGET_DIR/terragrunt.hcl" ]; then
12
+ USE_TERRAGRUNT="true"
13
+ fi
14
+
15
+ TOOL="terraform"
16
+ if [ "$USE_TERRAGRUNT" == "true" ]; then
17
+ TOOL="terragrunt"
18
+ fi
19
+
20
+ echo "=== TERRAFORM CHECK: $TARGET_DIR ($TOOL) ==="
21
+
22
+ # Check if tool exists
23
+ if ! command -v "$TOOL" >/dev/null 2>&1; then
24
+ echo "❌ $TOOL not installed"
25
+ exit 2
26
+ fi
27
+
28
+ cd "$TARGET_DIR" || exit 2
29
+
30
+ # 1. Format check (only show result, not diff)
31
+ if $TOOL fmt -check -diff=false > /dev/null 2>&1; then
32
+ echo "✅ Format OK"
33
+ else
34
+ echo "❌ Format issues (run: $TOOL fmt)"
35
+ fi
36
+
37
+ # 2. Init if needed (silent)
38
+ if [ ! -d ".terraform" ] && [ "$TOOL" == "terraform" ]; then
39
+ terraform init -backend=false -upgrade=false > /dev/null 2>&1 || true
40
+ fi
41
+
42
+ # 3. Validation (only show if fails)
43
+ VALIDATION_OUTPUT=$($TOOL validate 2>&1 || true)
44
+ if echo "$VALIDATION_OUTPUT" | grep -q "Success\|configuration is valid"; then
45
+ echo "✅ Valid configuration"
46
+ elif [ -z "$VALIDATION_OUTPUT" ]; then
47
+ echo "✅ Valid configuration"
48
+ else
49
+ echo "❌ Validation failed:"
50
+ echo "$VALIDATION_OUTPUT" | grep -E "Error:|Warning:" | head -3 | sed 's/^/ /'
51
+ fi
52
+
53
+ # 4. Plan summary (only count changes, don't show full plan)
54
+ if [ "$USE_TERRAGRUNT" == "true" ]; then
55
+ # Terragrunt doesn't support -detailed-exitcode well, just check for drift
56
+ PLAN_OUTPUT=$(terragrunt plan -lock=false 2>&1 | tail -20 || true)
57
+ else
58
+ # Terraform with detailed exit code
59
+ set +e
60
+ terraform plan -lock=false -refresh=false -detailed-exitcode -out=/dev/null > /tmp/tf-plan-$$.txt 2>&1
61
+ PLAN_EXIT=$?
62
+ set -e
63
+
64
+ if [ $PLAN_EXIT -eq 0 ]; then
65
+ echo "✅ No changes needed"
66
+ elif [ $PLAN_EXIT -eq 2 ]; then
67
+ # Changes detected, count them
68
+ PLAN_OUTPUT=$(cat /tmp/tf-plan-$$.txt)
69
+ ADD=$(echo "$PLAN_OUTPUT" | grep -c "will be created" || echo "0")
70
+ UPDATE=$(echo "$PLAN_OUTPUT" | grep -c "will be updated\|will be modified" || echo "0")
71
+ DELETE=$(echo "$PLAN_OUTPUT" | grep -c "will be destroyed" || echo "0")
72
+ echo "⚠️ Changes detected: +$ADD ~$UPDATE -$DELETE"
73
+ else
74
+ echo "❌ Plan failed"
75
+ fi
76
+ rm -f /tmp/tf-plan-$$.txt
77
+ fi
78
+
79
+ # Exit code: 0 if all OK, 1 if issues found
80
+ [ -n "$(echo "$VALIDATION_OUTPUT" | grep -E "Error:")" ] && exit 1 || exit 0
@@ -0,0 +1,33 @@
1
+ """
2
+ Gaia simulator module for gaia-ops hooks.
3
+
4
+ Extracts real hook events from production logs, replays them against the current
5
+ hooks, and detects regressions. Also provides routing simulation and skills mapping.
6
+
7
+ Modules:
8
+ extractor - Log parser: ReplayEvent + LogExtractor
9
+ runner - Hook executor: ReplayResult + HookRunner
10
+ reporter - Results formatter: ReplayReporter
11
+ routing_simulator - Surface routing simulation: RoutingSimulator
12
+ skills_mapper - Agent/skill/surface mapping: SkillsMapper
13
+ cli - Command-line entry point
14
+ """
15
+
16
+ from gaia_simulator.extractor import LogExtractor, ReplayEvent
17
+ from gaia_simulator.runner import HookRunner, ReplayResult
18
+ from gaia_simulator.reporter import ReplayReporter
19
+ from gaia_simulator.routing_simulator import RoutingSimulator, RoutingResult
20
+ from gaia_simulator.skills_mapper import SkillsMapper, SkillMapping, AgentProfile
21
+
22
+ __all__ = [
23
+ "LogExtractor",
24
+ "ReplayEvent",
25
+ "HookRunner",
26
+ "ReplayResult",
27
+ "ReplayReporter",
28
+ "RoutingSimulator",
29
+ "RoutingResult",
30
+ "SkillsMapper",
31
+ "SkillMapping",
32
+ "AgentProfile",
33
+ ]
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CLI entry point for gaia-ops hook replay testing and routing analysis.
4
+
5
+ Usage:
6
+ python3 tools/gaia_simulator/cli.py # replay all logs
7
+ python3 tools/gaia_simulator/cli.py --logs-dir /path/to/logs # custom log dir
8
+ python3 tools/gaia_simulator/cli.py --date 2026-03-11 # specific date
9
+ python3 tools/gaia_simulator/cli.py --hook pre_tool_use # specific hook only
10
+ python3 tools/gaia_simulator/cli.py --regressions-only # show only failures
11
+ python3 tools/gaia_simulator/cli.py --output results.json # save results
12
+ python3 tools/gaia_simulator/cli.py --extract-only # extract without running
13
+ python3 tools/gaia_simulator/cli.py --simulate "prompt" # simulate routing
14
+ python3 tools/gaia_simulator/cli.py --simulate-logs --date D # simulate from logs
15
+ python3 tools/gaia_simulator/cli.py --skills-map # show skills map
16
+ python3 tools/gaia_simulator/cli.py --agent-profiles # show agent profiles
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import argparse
22
+ import json
23
+ import sys
24
+ from pathlib import Path
25
+
26
+ _TOOLS_DIR = Path(__file__).resolve().parent.parent
27
+ if str(_TOOLS_DIR) not in sys.path:
28
+ sys.path.insert(0, str(_TOOLS_DIR))
29
+
30
+
31
+ def _find_defaults() -> tuple[Path, Path, Path]:
32
+ """Find default paths relative to the plugin root.
33
+
34
+ Returns:
35
+ (hooks_dir, logs_dir, plugin_root) tuple.
36
+ """
37
+ # tools/gaia_simulator/cli.py -> tools/gaia_simulator -> tools -> plugin_root
38
+ cli_path = Path(__file__).resolve()
39
+ plugin_root = cli_path.parent.parent.parent
40
+ hooks_dir = plugin_root / "hooks"
41
+ # Default logs location: two levels up from plugin root in .claude/logs
42
+ logs_dir = plugin_root.parent / ".claude" / "logs"
43
+ return hooks_dir, logs_dir, plugin_root
44
+
45
+
46
+ def _handle_simulate(prompt: str, plugin_root: Path) -> int:
47
+ """Handle --simulate command: simulate routing for a prompt."""
48
+ from gaia_simulator.routing_simulator import RoutingSimulator, format_routing_result
49
+
50
+ config_dir = plugin_root / "config"
51
+ agents_dir = plugin_root / "agents"
52
+ simulator = RoutingSimulator(config_dir=config_dir, agents_dir=agents_dir)
53
+ result = simulator.simulate(prompt)
54
+ print(format_routing_result(result))
55
+ return 0
56
+
57
+
58
+ def _handle_simulate_logs(logs_dir: Path, date_filter: str, plugin_root: Path) -> int:
59
+ """Handle --simulate-logs command: simulate routing for log events."""
60
+ from gaia_simulator.extractor import LogExtractor
61
+ from gaia_simulator.routing_simulator import RoutingSimulator, format_routing_result
62
+
63
+ config_dir = plugin_root / "config"
64
+ agents_dir = plugin_root / "agents"
65
+
66
+ extractor = LogExtractor()
67
+ events = extractor.extract_all(logs_dir, date_filter=date_filter)
68
+
69
+ if not events:
70
+ print("No events found matching the criteria.")
71
+ return 0
72
+
73
+ simulator = RoutingSimulator(config_dir=config_dir, agents_dir=agents_dir)
74
+
75
+ # Convert ReplayEvents to dicts for simulate_from_log
76
+ event_dicts = []
77
+ for ev in events:
78
+ tool_input = ev.stdin_payload.get("tool_input", {})
79
+ prompt = ""
80
+ if isinstance(tool_input, dict):
81
+ prompt = tool_input.get("command", tool_input.get("description", ""))
82
+ agent = ""
83
+ if ev.tool_name == "Agent" and isinstance(tool_input, dict):
84
+ agent = tool_input.get("subagent_type", "")
85
+ if prompt:
86
+ event_dicts.append({"prompt": prompt, "agent": agent})
87
+
88
+ results = simulator.simulate_from_log(event_dicts)
89
+ for result in results:
90
+ print(format_routing_result(result))
91
+ print()
92
+
93
+ print("Total events simulated: " + str(len(results)))
94
+ return 0
95
+
96
+
97
+ def _handle_skills_map(plugin_root: Path) -> int:
98
+ """Handle --skills-map command: show skills mapping report."""
99
+ from gaia_simulator.skills_mapper import SkillsMapper
100
+
101
+ mapper = SkillsMapper(
102
+ agents_dir=plugin_root / "agents",
103
+ skills_dir=plugin_root / "skills",
104
+ config_dir=plugin_root / "config",
105
+ )
106
+ print(mapper.format_report())
107
+ return 0
108
+
109
+
110
+ def _handle_agent_profiles(plugin_root: Path) -> int:
111
+ """Handle --agent-profiles command: show agent profiles."""
112
+ from gaia_simulator.skills_mapper import SkillsMapper
113
+
114
+ mapper = SkillsMapper(
115
+ agents_dir=plugin_root / "agents",
116
+ skills_dir=plugin_root / "skills",
117
+ config_dir=plugin_root / "config",
118
+ )
119
+ profiles = mapper.get_agent_profiles()
120
+
121
+ lines = []
122
+ lines.append("=" * 60)
123
+ lines.append("AGENT PROFILES")
124
+ lines.append("=" * 60)
125
+
126
+ for profile in profiles:
127
+ lines.append("")
128
+ lines.append(profile.agent_name + ":")
129
+ lines.append(" Skills: " + (", ".join(profile.skills) or "(none)"))
130
+ lines.append(" Surfaces: " + (", ".join(profile.surfaces) or "(none)"))
131
+ lines.append(" Read: " + (", ".join(profile.read_sections) or "(none)"))
132
+ lines.append(" Write: " + (", ".join(profile.write_sections) or "(none)"))
133
+ lines.append(" Invocations: " + str(profile.invocation_count))
134
+
135
+ lines.append("")
136
+ lines.append("=" * 60)
137
+
138
+ nl = chr(10)
139
+ print(nl.join(lines))
140
+ return 0
141
+
142
+
143
+ def main(argv: list[str] | None = None) -> int:
144
+ """Main entry point for the gaia simulator CLI.
145
+
146
+ Args:
147
+ argv: Command-line arguments (defaults to sys.argv[1:]).
148
+
149
+ Returns:
150
+ Exit code: 0 if all matched, 1 if regressions found, 2 on error.
151
+ """
152
+ hooks_dir_default, logs_dir_default, plugin_root = _find_defaults()
153
+
154
+ parser = argparse.ArgumentParser(
155
+ description="Replay gaia-ops hook events from production logs to detect regressions.",
156
+ formatter_class=argparse.RawDescriptionHelpFormatter,
157
+ )
158
+ parser.add_argument(
159
+ "--logs-dir",
160
+ type=Path,
161
+ default=logs_dir_default,
162
+ help="Directory containing log files (default: " + str(logs_dir_default) + ")",
163
+ )
164
+ parser.add_argument(
165
+ "--hooks-dir",
166
+ type=Path,
167
+ default=hooks_dir_default,
168
+ help="Directory containing hook scripts (default: " + str(hooks_dir_default) + ")",
169
+ )
170
+ parser.add_argument(
171
+ "--date",
172
+ type=str,
173
+ default=None,
174
+ help="Filter by date (YYYY-MM-DD format)",
175
+ )
176
+ parser.add_argument(
177
+ "--hook",
178
+ type=str,
179
+ default=None,
180
+ help="Filter by hook name (e.g. pre_tool_use)",
181
+ )
182
+ parser.add_argument(
183
+ "--regressions-only",
184
+ action="store_true",
185
+ help="Show only regression details",
186
+ )
187
+ parser.add_argument(
188
+ "--full",
189
+ action="store_true",
190
+ help="Show full report with breakdowns",
191
+ )
192
+ parser.add_argument(
193
+ "--output",
194
+ type=Path,
195
+ default=None,
196
+ help="Save results to JSON file",
197
+ )
198
+ parser.add_argument(
199
+ "--extract-only",
200
+ action="store_true",
201
+ help="Extract events from logs without running hooks",
202
+ )
203
+ parser.add_argument(
204
+ "--limit",
205
+ type=int,
206
+ default=0,
207
+ help="Limit number of events to replay (0 = all)",
208
+ )
209
+ parser.add_argument(
210
+ "--report-format",
211
+ choices=("text", "json"),
212
+ default="text",
213
+ help="Emit text for humans or JSON for machines",
214
+ )
215
+ # New routing/skills commands
216
+ parser.add_argument(
217
+ "--simulate",
218
+ type=str,
219
+ default=None,
220
+ metavar="PROMPT",
221
+ help="Simulate surface routing for a prompt",
222
+ )
223
+ parser.add_argument(
224
+ "--simulate-logs",
225
+ action="store_true",
226
+ help="Simulate routing for events extracted from logs",
227
+ )
228
+ parser.add_argument(
229
+ "--skills-map",
230
+ action="store_true",
231
+ help="Show agent/skill/surface mapping report",
232
+ )
233
+ parser.add_argument(
234
+ "--agent-profiles",
235
+ action="store_true",
236
+ help="Show detailed agent profiles",
237
+ )
238
+
239
+ args = parser.parse_args(argv)
240
+
241
+ # Handle routing/skills commands first (they don't need logs/hooks validation)
242
+ if args.simulate is not None:
243
+ return _handle_simulate(args.simulate, plugin_root)
244
+
245
+ if args.simulate_logs:
246
+ if not args.logs_dir.is_dir():
247
+ print("Error: Logs directory not found: " + str(args.logs_dir), file=sys.stderr)
248
+ return 2
249
+ return _handle_simulate_logs(args.logs_dir, args.date, plugin_root)
250
+
251
+ if args.skills_map:
252
+ return _handle_skills_map(plugin_root)
253
+
254
+ if args.agent_profiles:
255
+ return _handle_agent_profiles(plugin_root)
256
+
257
+ def status(message: str = "") -> None:
258
+ target = sys.stderr if args.report_format == "json" else sys.stdout
259
+ print(message, file=target)
260
+
261
+ # Validate paths
262
+ if not args.logs_dir.is_dir():
263
+ print("Error: Logs directory not found: " + str(args.logs_dir), file=sys.stderr)
264
+ return 2
265
+
266
+ if not args.extract_only and not args.hooks_dir.is_dir():
267
+ print("Error: Hooks directory not found: " + str(args.hooks_dir), file=sys.stderr)
268
+ return 2
269
+
270
+ # Lazy module loading to keep CLI fast for --help
271
+ from gaia_simulator.extractor import LogExtractor
272
+ from gaia_simulator.runner import HookRunner
273
+ from gaia_simulator.reporter import ReplayReporter
274
+
275
+ # Step 1: Extract events
276
+ extractor = LogExtractor()
277
+ reporter = ReplayReporter()
278
+
279
+ status("Extracting events from: " + str(args.logs_dir))
280
+ if args.date:
281
+ status("Date filter: " + args.date)
282
+ if args.hook:
283
+ status("Hook filter: " + args.hook)
284
+
285
+ events = extractor.extract_all(
286
+ args.logs_dir,
287
+ date_filter=args.date,
288
+ hook_filter=args.hook,
289
+ )
290
+
291
+ if args.limit > 0:
292
+ events = events[: args.limit]
293
+
294
+ status("Extracted " + str(len(events)) + " events")
295
+
296
+ if not events:
297
+ if args.report_format == "json":
298
+ print("[]")
299
+ else:
300
+ status("No events found matching the criteria.")
301
+ return 0
302
+
303
+ # Extract-only mode
304
+ if args.extract_only:
305
+ if args.report_format == "json":
306
+ print(json.dumps(reporter.events_payload(events), indent=2, default=str))
307
+ else:
308
+ nl = chr(10)
309
+ print(nl + "--- Extracted Events ---")
310
+ for i, ev in enumerate(events, 1):
311
+ tool_input = ev.stdin_payload.get("tool_input", {})
312
+ if ev.tool_name == "Bash":
313
+ detail = tool_input.get("command", "")[:80]
314
+ elif ev.tool_name == "Agent":
315
+ detail = tool_input.get("subagent_type", tool_input.get("description", ""))[:80]
316
+ else:
317
+ detail = str(tool_input)[:80]
318
+ print(" [" + str(i) + "] " + ev.timestamp + " " + ev.hook_name + " " + ev.tool_name +
319
+ " -> " + ev.expected_decision + " (" + ev.expected_tier + ") | " + detail)
320
+ return 0
321
+
322
+ # Step 2: Run hooks
323
+ def progress(current: int, total: int) -> None:
324
+ if total > 10 and current % 10 == 0:
325
+ print(" Replayed " + str(current) + "/" + str(total) + " events...", file=sys.stderr)
326
+
327
+ nl = chr(10)
328
+ status(nl + "Replaying against hooks in: " + str(args.hooks_dir))
329
+ runner = HookRunner(hooks_dir=args.hooks_dir)
330
+ results = runner.run_batch(events, progress_callback=progress)
331
+ status("Replay complete: " + str(len(results)) + " results" + nl)
332
+
333
+ # Step 3: Report
334
+ if args.report_format == "json":
335
+ print(json.dumps(reporter.results_payload(results), indent=2, default=str))
336
+ elif args.regressions_only:
337
+ print(reporter.regressions_only(results))
338
+ elif args.full:
339
+ print(reporter.full_report(results))
340
+ else:
341
+ print(reporter.summary(results))
342
+
343
+ # Save JSON if requested
344
+ if args.output:
345
+ reporter.save_json(results, args.output)
346
+ status(nl + "Results saved to: " + str(args.output))
347
+
348
+ # Return exit code based on regressions
349
+ has_regressions = any(not r.matched for r in results)
350
+ return 1 if has_regressions else 0
351
+
352
+
353
+ if __name__ == "__main__":
354
+ sys.exit(main())