@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,168 @@
1
+ """
2
+ Critical event detection.
3
+
4
+ Detects events that warrant context updates:
5
+ - Git commits
6
+ - Git pushes
7
+ - File modifications
8
+ """
9
+
10
+ import re
11
+ import logging
12
+ from enum import Enum
13
+ from typing import Dict, Any, Optional, List
14
+ from dataclasses import dataclass
15
+ from datetime import datetime
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class EventType(str, Enum):
21
+ """Types of critical events."""
22
+ GIT_COMMIT = "git_commit"
23
+ GIT_PUSH = "git_push"
24
+ FILE_MODIFICATIONS = "file_modifications"
25
+
26
+
27
+ @dataclass
28
+ class CriticalEvent:
29
+ """A detected critical event."""
30
+ event_type: EventType
31
+ data: Dict[str, Any]
32
+ timestamp: str = ""
33
+
34
+ def __post_init__(self):
35
+ if not self.timestamp:
36
+ self.timestamp = datetime.now().isoformat()
37
+
38
+ def to_dict(self) -> Dict[str, Any]:
39
+ return {
40
+ "event_type": self.event_type.value,
41
+ "timestamp": self.timestamp,
42
+ **self.data,
43
+ }
44
+
45
+
46
+ class CriticalEventDetector:
47
+ """Detect critical events that warrant context updates."""
48
+
49
+ def detect_git_commit(
50
+ self,
51
+ tool_name: str,
52
+ parameters: Dict[str, Any],
53
+ result: Any,
54
+ success: bool
55
+ ) -> Optional[CriticalEvent]:
56
+ """Detect successful git commit."""
57
+ if not success or tool_name.lower() != "bash":
58
+ return None
59
+
60
+ command = parameters.get("command", "")
61
+ if "git commit" not in command or not result:
62
+ return None
63
+
64
+ result_str = str(result)
65
+
66
+ # Extract commit hash
67
+ commit_hash = ""
68
+ match = re.search(r'\[[\w\-/]+ ([a-f0-9]{7,})\]', result_str)
69
+ if match:
70
+ commit_hash = match.group(1)
71
+
72
+ # Extract commit message
73
+ commit_message = ""
74
+ if commit_hash:
75
+ msg_match = re.search(
76
+ r'\[[\w\-/]+ [a-f0-9]{7,}\]\s*(.+)',
77
+ result_str,
78
+ re.MULTILINE
79
+ )
80
+ if msg_match:
81
+ commit_message = msg_match.group(1).strip().split('\n')[0]
82
+
83
+ return CriticalEvent(
84
+ event_type=EventType.GIT_COMMIT,
85
+ data={
86
+ "commit_hash": commit_hash,
87
+ "commit_message": commit_message,
88
+ "command": command,
89
+ }
90
+ )
91
+
92
+ def detect_git_push(
93
+ self,
94
+ tool_name: str,
95
+ parameters: Dict[str, Any],
96
+ result: Any,
97
+ success: bool
98
+ ) -> Optional[CriticalEvent]:
99
+ """Detect successful git push."""
100
+ if not success or tool_name.lower() != "bash":
101
+ return None
102
+
103
+ command = parameters.get("command", "")
104
+ if "git push" not in command or not result:
105
+ return None
106
+
107
+ result_str = str(result)
108
+
109
+ # Extract branch info
110
+ branch = ""
111
+ match = re.search(
112
+ r'To .+\n\s+[a-f0-9]+\.\.[a-f0-9]+\s+([\w\-/]+)\s+->',
113
+ result_str
114
+ )
115
+ if match:
116
+ branch = match.group(1)
117
+
118
+ return CriticalEvent(
119
+ event_type=EventType.GIT_PUSH,
120
+ data={
121
+ "branch": branch,
122
+ "command": command,
123
+ }
124
+ )
125
+
126
+ def detect_all(
127
+ self,
128
+ tool_name: str,
129
+ parameters: Dict[str, Any],
130
+ result: Any = None,
131
+ success: bool = True
132
+ ) -> List[CriticalEvent]:
133
+ """Run all detectors and return found events."""
134
+ events = []
135
+
136
+ # Git commit
137
+ event = self.detect_git_commit(tool_name, parameters, result, success)
138
+ if event:
139
+ events.append(event)
140
+
141
+ # Git push
142
+ event = self.detect_git_push(tool_name, parameters, result, success)
143
+ if event:
144
+ events.append(event)
145
+
146
+ return events
147
+
148
+
149
+ # Singleton detector
150
+ _detector: Optional[CriticalEventDetector] = None
151
+
152
+
153
+ def get_detector() -> CriticalEventDetector:
154
+ """Get singleton event detector."""
155
+ global _detector
156
+ if _detector is None:
157
+ _detector = CriticalEventDetector()
158
+ return _detector
159
+
160
+
161
+ def detect_critical_event(
162
+ tool_name: str,
163
+ parameters: Dict[str, Any],
164
+ result: Any = None,
165
+ success: bool = True
166
+ ) -> List[CriticalEvent]:
167
+ """Detect critical events (convenience function)."""
168
+ return get_detector().detect_all(tool_name, parameters, result, success)
@@ -0,0 +1,131 @@
1
+ """
2
+ Audit logger for tool executions.
3
+
4
+ Logs all tool executions to daily audit log files.
5
+ Note: session-<id>.jsonl was removed — it duplicated the daily audit log
6
+ with no additional value (session_id was always "default").
7
+ """
8
+
9
+ import os
10
+ import json
11
+ import logging
12
+ from pathlib import Path
13
+ from datetime import datetime
14
+ from typing import Dict, Any, Optional
15
+
16
+ from ..core.paths import get_logs_dir
17
+ from ..core.state import get_session_id
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+
22
+ class AuditLogger:
23
+ """Audit logger for tracking all tool executions."""
24
+
25
+ def __init__(self, log_dir: Optional[Path] = None):
26
+ """
27
+ Initialize audit logger.
28
+
29
+ Args:
30
+ log_dir: Override log directory (for testing)
31
+ """
32
+ if log_dir is not None:
33
+ self.log_dir = Path(log_dir) if isinstance(log_dir, str) else log_dir
34
+ else:
35
+ self.log_dir = get_logs_dir()
36
+ self.log_dir.mkdir(parents=True, exist_ok=True)
37
+ self.session_id = get_session_id()
38
+
39
+ def log_execution(
40
+ self,
41
+ tool_name: str,
42
+ parameters: Dict[str, Any],
43
+ result: Any,
44
+ duration: float,
45
+ exit_code: int = 0,
46
+ tier: str = "unknown"
47
+ ) -> None:
48
+ """
49
+ Log tool execution details.
50
+
51
+ Args:
52
+ tool_name: Name of the tool
53
+ parameters: Tool parameters
54
+ result: Execution result
55
+ duration: Duration in seconds
56
+ exit_code: Exit code (0 = success)
57
+ tier: Security tier
58
+ """
59
+ timestamp = datetime.now().isoformat()
60
+
61
+ # Extract command for bash tools
62
+ command = ""
63
+ if tool_name.lower() == "bash":
64
+ command = parameters.get("command", "")
65
+
66
+ # Create audit record
67
+ audit_record = {
68
+ "timestamp": timestamp,
69
+ "session_id": self.session_id,
70
+ "tool_name": tool_name,
71
+ "command": command,
72
+ "parameters": self._sanitize_params(parameters),
73
+ "duration_ms": round(duration * 1000, 2),
74
+ "exit_code": exit_code,
75
+ "tier": tier,
76
+ }
77
+
78
+ # Write to daily audit log (session log removed — was always "session-default.jsonl")
79
+ daily_log_file = self.log_dir / f"audit-{datetime.now().strftime('%Y-%m-%d')}.jsonl"
80
+ self._write_record(daily_log_file, audit_record)
81
+
82
+ logger.debug(f"Logged execution: {tool_name} - {command[:50]} - {duration:.2f}s")
83
+
84
+ def _sanitize_params(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
85
+ """Remove sensitive data from parameters."""
86
+ sanitized = {}
87
+ sensitive_keys = ["password", "secret", "token", "key", "credential"]
88
+
89
+ for key, value in parameters.items():
90
+ if any(s in key.lower() for s in sensitive_keys):
91
+ sanitized[key] = "[REDACTED]"
92
+ elif isinstance(value, str) and len(value) > 500:
93
+ sanitized[key] = value[:500] + "...[truncated]"
94
+ else:
95
+ sanitized[key] = value
96
+
97
+ return sanitized
98
+
99
+ def _write_record(self, file_path: Path, record: Dict) -> None:
100
+ """Write record to JSONL file."""
101
+ try:
102
+ with open(file_path, "a") as f:
103
+ f.write(json.dumps(record) + "\n")
104
+ except Exception as e:
105
+ logger.error(f"Error writing audit record to {file_path}: {e}")
106
+
107
+
108
+ # Singleton logger
109
+ _audit_logger: Optional[AuditLogger] = None
110
+
111
+
112
+ def get_audit_logger() -> AuditLogger:
113
+ """Get singleton audit logger."""
114
+ global _audit_logger
115
+ if _audit_logger is None:
116
+ _audit_logger = AuditLogger()
117
+ return _audit_logger
118
+
119
+
120
+ def log_execution(
121
+ tool_name: str,
122
+ parameters: Dict[str, Any],
123
+ result: Any,
124
+ duration: float,
125
+ exit_code: int = 0,
126
+ tier: str = "unknown"
127
+ ) -> None:
128
+ """Log tool execution (convenience function)."""
129
+ get_audit_logger().log_execution(
130
+ tool_name, parameters, result, duration, exit_code, tier
131
+ )
@@ -0,0 +1,134 @@
1
+ """
2
+ Metrics aggregation from audit logs.
3
+
4
+ Reads audit-*.jsonl files (the single source of truth for execution data)
5
+ and produces aggregated summaries. No write path — audit/logger.py owns writes.
6
+ """
7
+
8
+ import json
9
+ import logging
10
+ from pathlib import Path
11
+ from datetime import datetime, timedelta
12
+ from typing import Dict, Any, List, Optional
13
+ from collections import defaultdict
14
+
15
+ from ..core.paths import get_logs_dir
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ def _classify_command(command: str) -> str:
21
+ """Classify command type for metrics aggregation."""
22
+ command_lower = command.lower()
23
+ classifiers = [
24
+ ("terraform", "terraform"),
25
+ ("kubectl", "kubernetes"),
26
+ ("helm", "helm"),
27
+ ("gcloud", "gcp"),
28
+ ("aws", "aws"),
29
+ ("flux", "flux"),
30
+ ("docker", "docker"),
31
+ ("git", "git"),
32
+ ]
33
+ for keyword, classification in classifiers:
34
+ if keyword in command_lower:
35
+ return classification
36
+ return "general"
37
+
38
+
39
+ def _load_audit_records_since(
40
+ logs_dir: Path, cutoff_date: datetime
41
+ ) -> List[Dict]:
42
+ """Load audit records from audit-*.jsonl files since cutoff date."""
43
+ records = []
44
+
45
+ try:
46
+ audit_files = list(logs_dir.glob("audit-*.jsonl"))
47
+ except Exception as e:
48
+ logger.error(f"Error listing audit files: {e}")
49
+ return records
50
+
51
+ for audit_file in audit_files:
52
+ try:
53
+ with open(audit_file, "r") as f:
54
+ for line in f:
55
+ line = line.strip()
56
+ if not line:
57
+ continue
58
+ try:
59
+ record = json.loads(line)
60
+ record_time = datetime.fromisoformat(
61
+ record.get("timestamp", "")
62
+ )
63
+ if record_time >= cutoff_date:
64
+ records.append(record)
65
+ except (json.JSONDecodeError, ValueError):
66
+ continue
67
+ except Exception as e:
68
+ logger.debug(f"Error reading {audit_file}: {e}")
69
+
70
+ return records
71
+
72
+
73
+ def generate_summary(
74
+ days: int = 7, logs_dir: Optional[Path] = None
75
+ ) -> Dict[str, Any]:
76
+ """
77
+ Generate metrics summary from audit logs for the last N days.
78
+
79
+ Args:
80
+ days: Number of days to include
81
+ logs_dir: Override logs directory (for testing)
82
+
83
+ Returns:
84
+ Dictionary with aggregated metrics:
85
+ - period_days, total_executions, avg_duration_ms
86
+ - top_commands (by classified command_type)
87
+ - tier_distribution, command_type_distribution
88
+ """
89
+ if logs_dir is None:
90
+ logs_dir = get_logs_dir()
91
+
92
+ cutoff_date = datetime.now() - timedelta(days=days)
93
+ records = _load_audit_records_since(logs_dir, cutoff_date)
94
+
95
+ if not records:
96
+ return {
97
+ "period_days": days,
98
+ "total_executions": 0,
99
+ "avg_duration_ms": 0.0,
100
+ "top_commands": [],
101
+ "tier_distribution": {},
102
+ "command_type_distribution": {},
103
+ }
104
+
105
+ total = len(records)
106
+ total_duration = sum(r.get("duration_ms", 0) for r in records)
107
+
108
+ # Classify commands from audit log 'command' field
109
+ command_types = defaultdict(int)
110
+ for r in records:
111
+ cmd = r.get("command", "")
112
+ command_types[_classify_command(cmd)] += 1
113
+
114
+ # Count by tier
115
+ tiers = defaultdict(int)
116
+ for r in records:
117
+ tiers[r.get("tier", "unknown")] += 1
118
+
119
+ # Top command types
120
+ top_commands = sorted(
121
+ command_types.items(),
122
+ key=lambda x: x[1],
123
+ reverse=True,
124
+ )[:10]
125
+
126
+ return {
127
+ "period_days": days,
128
+ "total_executions": total,
129
+ "avg_duration_ms": round(total_duration / total, 2) if total > 0 else 0.0,
130
+ "top_commands": [{"type": t, "count": c} for t, c in top_commands],
131
+ "tier_distribution": dict(tiers),
132
+ "command_type_distribution": dict(command_types),
133
+ "generated_at": datetime.now().isoformat(),
134
+ }