@jaguilar87/gaia 5.0.0-rc.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 (621) hide show
  1. package/.claude-plugin/marketplace.json +33 -0
  2. package/.claude-plugin/plugin.json +26 -0
  3. package/ARCHITECTURE.md +335 -0
  4. package/CHANGELOG.md +1298 -0
  5. package/CODE_OF_CONDUCT.md +11 -0
  6. package/CONTRIBUTING.md +146 -0
  7. package/INSTALL.md +436 -0
  8. package/LICENSE +21 -0
  9. package/README.md +222 -0
  10. package/SECURITY.md +47 -0
  11. package/agents/README.md +78 -0
  12. package/agents/cloud-troubleshooter.md +73 -0
  13. package/agents/developer.md +65 -0
  14. package/agents/gaia-operator.md +64 -0
  15. package/agents/gaia-orchestrator.md +111 -0
  16. package/agents/gaia-planner.md +53 -0
  17. package/agents/gaia-system.md +71 -0
  18. package/agents/gitops-operator.md +61 -0
  19. package/agents/terraform-architect.md +63 -0
  20. package/bin/README.md +106 -0
  21. package/bin/cli/__init__.py +1 -0
  22. package/bin/cli/approvals.py +740 -0
  23. package/bin/cli/cleanup.py +562 -0
  24. package/bin/cli/context.py +283 -0
  25. package/bin/cli/doctor.py +651 -0
  26. package/bin/cli/history.py +305 -0
  27. package/bin/cli/memory.py +483 -0
  28. package/bin/cli/metrics.py +1068 -0
  29. package/bin/cli/plans.py +515 -0
  30. package/bin/cli/status.py +302 -0
  31. package/bin/cli/update.py +382 -0
  32. package/bin/gaia +112 -0
  33. package/bin/gaia-cleanup.js +531 -0
  34. package/bin/gaia-doctor.js +635 -0
  35. package/bin/gaia-evidence +126 -0
  36. package/bin/gaia-history.js +251 -0
  37. package/bin/gaia-metrics.js +1278 -0
  38. package/bin/gaia-review.js +269 -0
  39. package/bin/gaia-scan +44 -0
  40. package/bin/gaia-scan.py +589 -0
  41. package/bin/gaia-skills-diagnose.js +929 -0
  42. package/bin/gaia-status.js +278 -0
  43. package/bin/gaia-uninstall.js +111 -0
  44. package/bin/gaia-update.js +919 -0
  45. package/bin/pre-publish-validate.js +610 -0
  46. package/bin/python-detect.js +60 -0
  47. package/bin/validate-sandbox.sh +601 -0
  48. package/commands/README.md +64 -0
  49. package/commands/gaia.md +37 -0
  50. package/commands/scan-project.md +67 -0
  51. package/config/README.md +71 -0
  52. package/config/cloud/aws.json +134 -0
  53. package/config/cloud/gcp.json +139 -0
  54. package/config/context-contracts.json +158 -0
  55. package/config/crons-schema.md +81 -0
  56. package/config/git_standards.json +72 -0
  57. package/config/surface-routing.json +417 -0
  58. package/config/universal-rules.json +102 -0
  59. package/dist/gaia-ops/.claude-plugin/plugin.json +24 -0
  60. package/dist/gaia-ops/README.md +80 -0
  61. package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
  62. package/dist/gaia-ops/agents/developer.md +65 -0
  63. package/dist/gaia-ops/agents/gaia-operator.md +64 -0
  64. package/dist/gaia-ops/agents/gaia-orchestrator.md +111 -0
  65. package/dist/gaia-ops/agents/gaia-planner.md +53 -0
  66. package/dist/gaia-ops/agents/gaia-system.md +71 -0
  67. package/dist/gaia-ops/agents/gitops-operator.md +61 -0
  68. package/dist/gaia-ops/agents/terraform-architect.md +63 -0
  69. package/dist/gaia-ops/commands/gaia.md +37 -0
  70. package/dist/gaia-ops/config/README.md +71 -0
  71. package/dist/gaia-ops/config/cloud/aws.json +134 -0
  72. package/dist/gaia-ops/config/cloud/gcp.json +139 -0
  73. package/dist/gaia-ops/config/context-contracts.json +158 -0
  74. package/dist/gaia-ops/config/crons-schema.md +81 -0
  75. package/dist/gaia-ops/config/git_standards.json +72 -0
  76. package/dist/gaia-ops/config/surface-routing.json +417 -0
  77. package/dist/gaia-ops/config/universal-rules.json +102 -0
  78. package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
  79. package/dist/gaia-ops/hooks/adapters/base.py +219 -0
  80. package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
  81. package/dist/gaia-ops/hooks/adapters/claude_code.py +1890 -0
  82. package/dist/gaia-ops/hooks/adapters/types.py +194 -0
  83. package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
  84. package/dist/gaia-ops/hooks/hooks.json +192 -0
  85. package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
  86. package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
  87. package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
  88. package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
  89. package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +120 -0
  90. package/dist/gaia-ops/hooks/modules/agents/state_tracker.py +267 -0
  91. package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
  92. package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
  93. package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
  94. package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
  95. package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
  96. package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
  97. package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
  98. package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +611 -0
  99. package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
  100. package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
  101. package/dist/gaia-ops/hooks/modules/context/agentic_loop_detector.py +165 -0
  102. package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
  103. package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +218 -0
  104. package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
  105. package/dist/gaia-ops/hooks/modules/context/context_injector.py +558 -0
  106. package/dist/gaia-ops/hooks/modules/context/context_writer.py +530 -0
  107. package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
  108. package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
  109. package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
  110. package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
  111. package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
  112. package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +577 -0
  113. package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
  114. package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
  115. package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
  116. package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
  117. package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
  118. package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +216 -0
  119. package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
  120. package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +122 -0
  121. package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
  122. package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
  123. package/dist/gaia-ops/hooks/modules/security/__init__.py +120 -0
  124. package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
  125. package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
  126. package/dist/gaia-ops/hooks/modules/security/approval_grants.py +1638 -0
  127. package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
  128. package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +222 -0
  129. package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +595 -0
  130. package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +87 -0
  131. package/dist/gaia-ops/hooks/modules/security/command_semantics.py +181 -0
  132. package/dist/gaia-ops/hooks/modules/security/composition_rules.py +547 -0
  133. package/dist/gaia-ops/hooks/modules/security/flag_classifiers.py +873 -0
  134. package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
  135. package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +1131 -0
  136. package/dist/gaia-ops/hooks/modules/security/network_hosts.py +481 -0
  137. package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
  138. package/dist/gaia-ops/hooks/modules/security/shell_unwrapper.py +165 -0
  139. package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
  140. package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
  141. package/dist/gaia-ops/hooks/modules/session/pending_scanner.py +174 -0
  142. package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
  143. package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +160 -0
  144. package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
  145. package/dist/gaia-ops/hooks/modules/session/session_registry.py +333 -0
  146. package/dist/gaia-ops/hooks/modules/tools/__init__.py +29 -0
  147. package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +1008 -0
  148. package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  149. package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
  150. package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
  151. package/dist/gaia-ops/hooks/modules/tools/stage_decomposer.py +315 -0
  152. package/dist/gaia-ops/hooks/modules/tools/task_validator.py +294 -0
  153. package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
  154. package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
  155. package/dist/gaia-ops/hooks/post_compact.py +43 -0
  156. package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
  157. package/dist/gaia-ops/hooks/pre_compact.py +60 -0
  158. package/dist/gaia-ops/hooks/pre_tool_use.py +413 -0
  159. package/dist/gaia-ops/hooks/session_end_hook.py +77 -0
  160. package/dist/gaia-ops/hooks/session_start.py +81 -0
  161. package/dist/gaia-ops/hooks/stop_hook.py +70 -0
  162. package/dist/gaia-ops/hooks/subagent_start.py +71 -0
  163. package/dist/gaia-ops/hooks/subagent_stop.py +295 -0
  164. package/dist/gaia-ops/hooks/task_completed.py +70 -0
  165. package/dist/gaia-ops/hooks/user_prompt_submit.py +246 -0
  166. package/dist/gaia-ops/settings.json +72 -0
  167. package/dist/gaia-ops/skills/README.md +158 -0
  168. package/dist/gaia-ops/skills/agent-creation/SKILL.md +87 -0
  169. package/dist/gaia-ops/skills/agent-creation/examples.md +170 -0
  170. package/dist/gaia-ops/skills/agent-creation/reference.md +191 -0
  171. package/dist/gaia-ops/skills/agent-protocol/SKILL.md +93 -0
  172. package/dist/gaia-ops/skills/agent-protocol/examples.md +223 -0
  173. package/dist/gaia-ops/skills/agent-response/SKILL.md +69 -0
  174. package/dist/gaia-ops/skills/agentic-loop/SKILL.md +80 -0
  175. package/dist/gaia-ops/skills/agentic-loop/reference.md +378 -0
  176. package/dist/gaia-ops/skills/blog-writing/SKILL.md +98 -0
  177. package/dist/gaia-ops/skills/blog-writing/reference.md +130 -0
  178. package/dist/gaia-ops/skills/brief-spec/SKILL.md +185 -0
  179. package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
  180. package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
  181. package/dist/gaia-ops/skills/context-updater/SKILL.md +87 -0
  182. package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
  183. package/dist/gaia-ops/skills/developer-patterns/SKILL.md +50 -0
  184. package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
  185. package/dist/gaia-ops/skills/execution/SKILL.md +99 -0
  186. package/dist/gaia-ops/skills/fast-queries/SKILL.md +43 -0
  187. package/dist/gaia-ops/skills/gaia-compact/SKILL.md +74 -0
  188. package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +108 -0
  189. package/dist/gaia-ops/skills/gaia-patterns/reference.md +395 -0
  190. package/dist/gaia-ops/skills/gaia-planner/SKILL.md +37 -0
  191. package/dist/gaia-ops/skills/gaia-planner/reference.md +107 -0
  192. package/dist/gaia-ops/skills/gaia-release/SKILL.md +85 -0
  193. package/dist/gaia-ops/skills/gaia-release/reference.md +92 -0
  194. package/dist/gaia-ops/skills/gaia-self-check/SKILL.md +114 -0
  195. package/dist/gaia-ops/skills/gaia-self-check/reference.md +453 -0
  196. package/dist/gaia-ops/skills/gaia-verify/SKILL.md +77 -0
  197. package/dist/gaia-ops/skills/gaia-verify/reference.md +80 -0
  198. package/dist/gaia-ops/skills/git-conventions/SKILL.md +47 -0
  199. package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +60 -0
  200. package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
  201. package/dist/gaia-ops/skills/gmail-policy/SKILL.md +200 -0
  202. package/dist/gaia-ops/skills/gmail-policy/reference.md +150 -0
  203. package/dist/gaia-ops/skills/gmail-triage/SKILL.md +100 -0
  204. package/dist/gaia-ops/skills/gws-setup/SKILL.md +99 -0
  205. package/dist/gaia-ops/skills/gws-setup/reference.md +73 -0
  206. package/dist/gaia-ops/skills/investigation/SKILL.md +100 -0
  207. package/dist/gaia-ops/skills/memory-curation/SKILL.md +83 -0
  208. package/dist/gaia-ops/skills/memory-search/SKILL.md +88 -0
  209. package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +160 -0
  210. package/dist/gaia-ops/skills/orchestrator-approval/reference.md +174 -0
  211. package/dist/gaia-ops/skills/pending-approvals/SKILL.md +72 -0
  212. package/dist/gaia-ops/skills/pending-approvals/reference.md +214 -0
  213. package/dist/gaia-ops/skills/readme-writing/SKILL.md +71 -0
  214. package/dist/gaia-ops/skills/readme-writing/reference.md +188 -0
  215. package/dist/gaia-ops/skills/reference.md +135 -0
  216. package/dist/gaia-ops/skills/request-approval/SKILL.md +140 -0
  217. package/dist/gaia-ops/skills/request-approval/examples.md +140 -0
  218. package/dist/gaia-ops/skills/request-approval/reference.md +57 -0
  219. package/dist/gaia-ops/skills/schedule-task/SKILL.md +64 -0
  220. package/dist/gaia-ops/skills/schedule-task/reference.md +233 -0
  221. package/dist/gaia-ops/skills/security-tiers/SKILL.md +141 -0
  222. package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
  223. package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
  224. package/dist/gaia-ops/skills/session-reflection/SKILL.md +69 -0
  225. package/dist/gaia-ops/skills/skill-creation/SKILL.md +92 -0
  226. package/dist/gaia-ops/skills/skill-creation/reference.md +29 -0
  227. package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +89 -0
  228. package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
  229. package/dist/gaia-ops/tools/__init__.py +9 -0
  230. package/dist/gaia-ops/tools/agentic-loop/decide-status.py +210 -0
  231. package/dist/gaia-ops/tools/agentic-loop/parse-metric.py +106 -0
  232. package/dist/gaia-ops/tools/agentic-loop/record-iteration.py +221 -0
  233. package/dist/gaia-ops/tools/context/README.md +132 -0
  234. package/dist/gaia-ops/tools/context/__init__.py +42 -0
  235. package/dist/gaia-ops/tools/context/_paths.py +20 -0
  236. package/dist/gaia-ops/tools/context/context_provider.py +721 -0
  237. package/dist/gaia-ops/tools/context/context_section_reader.py +342 -0
  238. package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
  239. package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
  240. package/dist/gaia-ops/tools/context/surface_router.py +278 -0
  241. package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
  242. package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
  243. package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  244. package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  245. package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  246. package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  247. package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
  248. package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  249. package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
  250. package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
  251. package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
  252. package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
  253. package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
  254. package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
  255. package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +264 -0
  256. package/dist/gaia-ops/tools/memory/README.md +0 -0
  257. package/dist/gaia-ops/tools/memory/__init__.py +20 -0
  258. package/dist/gaia-ops/tools/memory/backfill_fts5.py +107 -0
  259. package/dist/gaia-ops/tools/memory/conflict_detector.py +295 -0
  260. package/dist/gaia-ops/tools/memory/episodic.py +1210 -0
  261. package/dist/gaia-ops/tools/memory/git_invalidator.py +262 -0
  262. package/dist/gaia-ops/tools/memory/paths.py +102 -0
  263. package/dist/gaia-ops/tools/memory/scoring.py +193 -0
  264. package/dist/gaia-ops/tools/memory/search_store.py +375 -0
  265. package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
  266. package/dist/gaia-ops/tools/review/__init__.py +1 -0
  267. package/dist/gaia-ops/tools/review/review_engine.py +157 -0
  268. package/dist/gaia-ops/tools/scan/__init__.py +35 -0
  269. package/dist/gaia-ops/tools/scan/config.py +247 -0
  270. package/dist/gaia-ops/tools/scan/merge.py +212 -0
  271. package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
  272. package/dist/gaia-ops/tools/scan/registry.py +127 -0
  273. package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
  274. package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
  275. package/dist/gaia-ops/tools/scan/scanners/environment.py +349 -0
  276. package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
  277. package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
  278. package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
  279. package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
  280. package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
  281. package/dist/gaia-ops/tools/scan/setup.py +686 -0
  282. package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
  283. package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
  284. package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
  285. package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
  286. package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
  287. package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
  288. package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
  289. package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
  290. package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
  291. package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
  292. package/dist/gaia-ops/tools/scan/ui.py +624 -0
  293. package/dist/gaia-ops/tools/scan/verify.py +270 -0
  294. package/dist/gaia-ops/tools/scan/walk.py +118 -0
  295. package/dist/gaia-ops/tools/scan/workspace.py +85 -0
  296. package/dist/gaia-ops/tools/validation/README.md +244 -0
  297. package/dist/gaia-ops/tools/validation/__init__.py +17 -0
  298. package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
  299. package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
  300. package/dist/gaia-security/.claude-plugin/plugin.json +24 -0
  301. package/dist/gaia-security/README.md +90 -0
  302. package/dist/gaia-security/config/universal-rules.json +102 -0
  303. package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
  304. package/dist/gaia-security/hooks/adapters/base.py +219 -0
  305. package/dist/gaia-security/hooks/adapters/channel.py +17 -0
  306. package/dist/gaia-security/hooks/adapters/claude_code.py +1890 -0
  307. package/dist/gaia-security/hooks/adapters/types.py +194 -0
  308. package/dist/gaia-security/hooks/adapters/utils.py +25 -0
  309. package/dist/gaia-security/hooks/hooks.json +113 -0
  310. package/dist/gaia-security/hooks/modules/__init__.py +15 -0
  311. package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
  312. package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
  313. package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
  314. package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +120 -0
  315. package/dist/gaia-security/hooks/modules/agents/state_tracker.py +267 -0
  316. package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
  317. package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
  318. package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
  319. package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
  320. package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
  321. package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
  322. package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
  323. package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +611 -0
  324. package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
  325. package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
  326. package/dist/gaia-security/hooks/modules/context/agentic_loop_detector.py +165 -0
  327. package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
  328. package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +218 -0
  329. package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
  330. package/dist/gaia-security/hooks/modules/context/context_injector.py +558 -0
  331. package/dist/gaia-security/hooks/modules/context/context_writer.py +530 -0
  332. package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
  333. package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
  334. package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
  335. package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
  336. package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
  337. package/dist/gaia-security/hooks/modules/core/plugin_setup.py +577 -0
  338. package/dist/gaia-security/hooks/modules/core/state.py +179 -0
  339. package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
  340. package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
  341. package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
  342. package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
  343. package/dist/gaia-security/hooks/modules/memory/episode_writer.py +216 -0
  344. package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
  345. package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +122 -0
  346. package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
  347. package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
  348. package/dist/gaia-security/hooks/modules/security/__init__.py +120 -0
  349. package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
  350. package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
  351. package/dist/gaia-security/hooks/modules/security/approval_grants.py +1638 -0
  352. package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
  353. package/dist/gaia-security/hooks/modules/security/approval_scopes.py +222 -0
  354. package/dist/gaia-security/hooks/modules/security/blocked_commands.py +595 -0
  355. package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +87 -0
  356. package/dist/gaia-security/hooks/modules/security/command_semantics.py +181 -0
  357. package/dist/gaia-security/hooks/modules/security/composition_rules.py +547 -0
  358. package/dist/gaia-security/hooks/modules/security/flag_classifiers.py +873 -0
  359. package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
  360. package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +1131 -0
  361. package/dist/gaia-security/hooks/modules/security/network_hosts.py +481 -0
  362. package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
  363. package/dist/gaia-security/hooks/modules/security/shell_unwrapper.py +165 -0
  364. package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
  365. package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
  366. package/dist/gaia-security/hooks/modules/session/pending_scanner.py +174 -0
  367. package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
  368. package/dist/gaia-security/hooks/modules/session/session_event_injector.py +160 -0
  369. package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
  370. package/dist/gaia-security/hooks/modules/session/session_registry.py +333 -0
  371. package/dist/gaia-security/hooks/modules/tools/__init__.py +29 -0
  372. package/dist/gaia-security/hooks/modules/tools/bash_validator.py +1008 -0
  373. package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  374. package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
  375. package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
  376. package/dist/gaia-security/hooks/modules/tools/stage_decomposer.py +315 -0
  377. package/dist/gaia-security/hooks/modules/tools/task_validator.py +294 -0
  378. package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
  379. package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
  380. package/dist/gaia-security/hooks/post_tool_use.py +54 -0
  381. package/dist/gaia-security/hooks/pre_tool_use.py +413 -0
  382. package/dist/gaia-security/hooks/session_end_hook.py +77 -0
  383. package/dist/gaia-security/hooks/session_start.py +81 -0
  384. package/dist/gaia-security/hooks/stop_hook.py +70 -0
  385. package/dist/gaia-security/hooks/user_prompt_submit.py +246 -0
  386. package/dist/gaia-security/settings.json +58 -0
  387. package/git-hooks/commit-msg +41 -0
  388. package/hooks/README.md +100 -0
  389. package/hooks/adapters/__init__.py +52 -0
  390. package/hooks/adapters/base.py +219 -0
  391. package/hooks/adapters/channel.py +17 -0
  392. package/hooks/adapters/claude_code.py +1890 -0
  393. package/hooks/adapters/types.py +194 -0
  394. package/hooks/adapters/utils.py +25 -0
  395. package/hooks/elicitation_result.py +179 -0
  396. package/hooks/hooks.json +84 -0
  397. package/hooks/modules/README.md +189 -0
  398. package/hooks/modules/__init__.py +15 -0
  399. package/hooks/modules/agents/__init__.py +29 -0
  400. package/hooks/modules/agents/contract_validator.py +647 -0
  401. package/hooks/modules/agents/response_contract.py +496 -0
  402. package/hooks/modules/agents/skill_injection_verifier.py +120 -0
  403. package/hooks/modules/agents/state_tracker.py +267 -0
  404. package/hooks/modules/agents/task_info_builder.py +74 -0
  405. package/hooks/modules/agents/transcript_analyzer.py +458 -0
  406. package/hooks/modules/agents/transcript_reader.py +152 -0
  407. package/hooks/modules/audit/__init__.py +28 -0
  408. package/hooks/modules/audit/event_detector.py +168 -0
  409. package/hooks/modules/audit/logger.py +131 -0
  410. package/hooks/modules/audit/metrics.py +134 -0
  411. package/hooks/modules/audit/workflow_auditor.py +611 -0
  412. package/hooks/modules/audit/workflow_recorder.py +296 -0
  413. package/hooks/modules/context/__init__.py +11 -0
  414. package/hooks/modules/context/agentic_loop_detector.py +165 -0
  415. package/hooks/modules/context/anchor_tracker.py +317 -0
  416. package/hooks/modules/context/compact_context_builder.py +218 -0
  417. package/hooks/modules/context/context_freshness.py +145 -0
  418. package/hooks/modules/context/context_injector.py +558 -0
  419. package/hooks/modules/context/context_writer.py +530 -0
  420. package/hooks/modules/context/contracts_loader.py +161 -0
  421. package/hooks/modules/core/__init__.py +40 -0
  422. package/hooks/modules/core/hook_entry.py +78 -0
  423. package/hooks/modules/core/paths.py +160 -0
  424. package/hooks/modules/core/plugin_mode.py +149 -0
  425. package/hooks/modules/core/plugin_setup.py +577 -0
  426. package/hooks/modules/core/state.py +179 -0
  427. package/hooks/modules/core/stdin.py +24 -0
  428. package/hooks/modules/events/__init__.py +1 -0
  429. package/hooks/modules/events/event_writer.py +210 -0
  430. package/hooks/modules/evidence/__init__.py +34 -0
  431. package/hooks/modules/evidence/assertions.py +137 -0
  432. package/hooks/modules/evidence/index_writer.py +57 -0
  433. package/hooks/modules/evidence/loader.py +126 -0
  434. package/hooks/modules/evidence/runner.py +241 -0
  435. package/hooks/modules/memory/__init__.py +8 -0
  436. package/hooks/modules/memory/episode_writer.py +216 -0
  437. package/hooks/modules/orchestrator/__init__.py +1 -0
  438. package/hooks/modules/orchestrator/delegate_mode.py +122 -0
  439. package/hooks/modules/scanning/__init__.py +8 -0
  440. package/hooks/modules/scanning/scan_trigger.py +84 -0
  441. package/hooks/modules/security/__init__.py +120 -0
  442. package/hooks/modules/security/approval_cleanup.py +87 -0
  443. package/hooks/modules/security/approval_constants.py +23 -0
  444. package/hooks/modules/security/approval_grants.py +1638 -0
  445. package/hooks/modules/security/approval_messages.py +71 -0
  446. package/hooks/modules/security/approval_scopes.py +222 -0
  447. package/hooks/modules/security/blocked_commands.py +595 -0
  448. package/hooks/modules/security/blocked_message_formatter.py +87 -0
  449. package/hooks/modules/security/command_semantics.py +181 -0
  450. package/hooks/modules/security/composition_rules.py +547 -0
  451. package/hooks/modules/security/flag_classifiers.py +873 -0
  452. package/hooks/modules/security/gitops_validator.py +179 -0
  453. package/hooks/modules/security/mutative_verbs.py +1131 -0
  454. package/hooks/modules/security/network_hosts.py +481 -0
  455. package/hooks/modules/security/prompt_validator.py +40 -0
  456. package/hooks/modules/security/shell_unwrapper.py +165 -0
  457. package/hooks/modules/security/tiers.py +196 -0
  458. package/hooks/modules/session/__init__.py +10 -0
  459. package/hooks/modules/session/pending_scanner.py +174 -0
  460. package/hooks/modules/session/session_context_writer.py +100 -0
  461. package/hooks/modules/session/session_event_injector.py +160 -0
  462. package/hooks/modules/session/session_manager.py +31 -0
  463. package/hooks/modules/session/session_registry.py +333 -0
  464. package/hooks/modules/tools/__init__.py +29 -0
  465. package/hooks/modules/tools/bash_validator.py +1008 -0
  466. package/hooks/modules/tools/cloud_pipe_validator.py +231 -0
  467. package/hooks/modules/tools/hook_response.py +55 -0
  468. package/hooks/modules/tools/shell_parser.py +227 -0
  469. package/hooks/modules/tools/stage_decomposer.py +315 -0
  470. package/hooks/modules/tools/task_validator.py +294 -0
  471. package/hooks/modules/validation/__init__.py +23 -0
  472. package/hooks/modules/validation/commit_validator.py +380 -0
  473. package/hooks/post_compact.py +43 -0
  474. package/hooks/post_tool_use.py +54 -0
  475. package/hooks/pre_compact.py +60 -0
  476. package/hooks/pre_tool_use.py +413 -0
  477. package/hooks/session_end_hook.py +77 -0
  478. package/hooks/session_start.py +81 -0
  479. package/hooks/stop_hook.py +70 -0
  480. package/hooks/subagent_start.py +71 -0
  481. package/hooks/subagent_stop.py +295 -0
  482. package/hooks/task_completed.py +70 -0
  483. package/hooks/user_prompt_submit.py +246 -0
  484. package/index.js +83 -0
  485. package/package.json +103 -0
  486. package/pyproject.toml +32 -0
  487. package/skills/README.md +158 -0
  488. package/skills/agent-creation/SKILL.md +87 -0
  489. package/skills/agent-creation/examples.md +170 -0
  490. package/skills/agent-creation/reference.md +191 -0
  491. package/skills/agent-protocol/SKILL.md +93 -0
  492. package/skills/agent-protocol/examples.md +223 -0
  493. package/skills/agent-response/SKILL.md +69 -0
  494. package/skills/agentic-loop/SKILL.md +80 -0
  495. package/skills/agentic-loop/reference.md +378 -0
  496. package/skills/blog-writing/SKILL.md +98 -0
  497. package/skills/blog-writing/reference.md +130 -0
  498. package/skills/brief-spec/SKILL.md +185 -0
  499. package/skills/command-execution/SKILL.md +64 -0
  500. package/skills/command-execution/reference.md +83 -0
  501. package/skills/context-updater/SKILL.md +87 -0
  502. package/skills/context-updater/examples.md +71 -0
  503. package/skills/developer-patterns/SKILL.md +50 -0
  504. package/skills/developer-patterns/reference.md +112 -0
  505. package/skills/execution/SKILL.md +99 -0
  506. package/skills/fast-queries/SKILL.md +43 -0
  507. package/skills/gaia-compact/SKILL.md +74 -0
  508. package/skills/gaia-patterns/SKILL.md +108 -0
  509. package/skills/gaia-patterns/reference.md +395 -0
  510. package/skills/gaia-planner/SKILL.md +37 -0
  511. package/skills/gaia-planner/reference.md +107 -0
  512. package/skills/gaia-release/SKILL.md +85 -0
  513. package/skills/gaia-release/reference.md +92 -0
  514. package/skills/gaia-self-check/SKILL.md +114 -0
  515. package/skills/gaia-self-check/reference.md +453 -0
  516. package/skills/gaia-verify/SKILL.md +77 -0
  517. package/skills/gaia-verify/reference.md +80 -0
  518. package/skills/git-conventions/SKILL.md +47 -0
  519. package/skills/gitops-patterns/SKILL.md +60 -0
  520. package/skills/gitops-patterns/reference.md +183 -0
  521. package/skills/gmail-policy/SKILL.md +200 -0
  522. package/skills/gmail-policy/reference.md +150 -0
  523. package/skills/gmail-triage/SKILL.md +100 -0
  524. package/skills/gws-setup/SKILL.md +99 -0
  525. package/skills/gws-setup/reference.md +73 -0
  526. package/skills/investigation/SKILL.md +100 -0
  527. package/skills/memory-curation/SKILL.md +83 -0
  528. package/skills/memory-search/SKILL.md +88 -0
  529. package/skills/orchestrator-approval/SKILL.md +160 -0
  530. package/skills/orchestrator-approval/reference.md +174 -0
  531. package/skills/pending-approvals/SKILL.md +72 -0
  532. package/skills/pending-approvals/reference.md +214 -0
  533. package/skills/readme-writing/SKILL.md +71 -0
  534. package/skills/readme-writing/reference.md +188 -0
  535. package/skills/reference.md +135 -0
  536. package/skills/request-approval/SKILL.md +140 -0
  537. package/skills/request-approval/examples.md +140 -0
  538. package/skills/request-approval/reference.md +57 -0
  539. package/skills/schedule-task/SKILL.md +64 -0
  540. package/skills/schedule-task/reference.md +233 -0
  541. package/skills/security-tiers/SKILL.md +141 -0
  542. package/skills/security-tiers/destructive-commands-reference.md +623 -0
  543. package/skills/security-tiers/reference.md +39 -0
  544. package/skills/session-reflection/SKILL.md +69 -0
  545. package/skills/skill-creation/SKILL.md +92 -0
  546. package/skills/skill-creation/reference.md +29 -0
  547. package/skills/terraform-patterns/SKILL.md +89 -0
  548. package/skills/terraform-patterns/reference.md +93 -0
  549. package/templates/README.md +69 -0
  550. package/templates/managed-settings.template.json +43 -0
  551. package/tools/__init__.py +9 -0
  552. package/tools/agentic-loop/decide-status.py +210 -0
  553. package/tools/agentic-loop/parse-metric.py +106 -0
  554. package/tools/agentic-loop/record-iteration.py +221 -0
  555. package/tools/context/README.md +132 -0
  556. package/tools/context/__init__.py +42 -0
  557. package/tools/context/_paths.py +20 -0
  558. package/tools/context/context_provider.py +721 -0
  559. package/tools/context/context_section_reader.py +342 -0
  560. package/tools/context/deep_merge.py +159 -0
  561. package/tools/context/pending_updates.py +760 -0
  562. package/tools/context/surface_router.py +278 -0
  563. package/tools/fast-queries/README.md +65 -0
  564. package/tools/fast-queries/__init__.py +30 -0
  565. package/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
  566. package/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
  567. package/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
  568. package/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
  569. package/tools/fast-queries/run_triage.sh +59 -0
  570. package/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
  571. package/tools/gaia_simulator/__init__.py +33 -0
  572. package/tools/gaia_simulator/cli.py +354 -0
  573. package/tools/gaia_simulator/extractor.py +457 -0
  574. package/tools/gaia_simulator/reporter.py +258 -0
  575. package/tools/gaia_simulator/routing_simulator.py +334 -0
  576. package/tools/gaia_simulator/runner.py +539 -0
  577. package/tools/gaia_simulator/skills_mapper.py +264 -0
  578. package/tools/memory/README.md +0 -0
  579. package/tools/memory/__init__.py +20 -0
  580. package/tools/memory/backfill_fts5.py +107 -0
  581. package/tools/memory/conflict_detector.py +295 -0
  582. package/tools/memory/episodic.py +1210 -0
  583. package/tools/memory/git_invalidator.py +262 -0
  584. package/tools/memory/paths.py +102 -0
  585. package/tools/memory/scoring.py +193 -0
  586. package/tools/memory/search_store.py +375 -0
  587. package/tools/persist_transcript_analysis.py +85 -0
  588. package/tools/review/__init__.py +1 -0
  589. package/tools/review/review_engine.py +157 -0
  590. package/tools/scan/__init__.py +35 -0
  591. package/tools/scan/config.py +247 -0
  592. package/tools/scan/merge.py +212 -0
  593. package/tools/scan/orchestrator.py +549 -0
  594. package/tools/scan/registry.py +127 -0
  595. package/tools/scan/scanners/__init__.py +18 -0
  596. package/tools/scan/scanners/base.py +137 -0
  597. package/tools/scan/scanners/environment.py +349 -0
  598. package/tools/scan/scanners/git.py +570 -0
  599. package/tools/scan/scanners/infrastructure.py +875 -0
  600. package/tools/scan/scanners/orchestration.py +600 -0
  601. package/tools/scan/scanners/stack.py +1085 -0
  602. package/tools/scan/scanners/tools.py +260 -0
  603. package/tools/scan/setup.py +686 -0
  604. package/tools/scan/tests/__init__.py +1 -0
  605. package/tools/scan/tests/conftest.py +796 -0
  606. package/tools/scan/tests/test_environment.py +323 -0
  607. package/tools/scan/tests/test_git.py +419 -0
  608. package/tools/scan/tests/test_infrastructure.py +382 -0
  609. package/tools/scan/tests/test_integration.py +920 -0
  610. package/tools/scan/tests/test_merge.py +269 -0
  611. package/tools/scan/tests/test_orchestration.py +304 -0
  612. package/tools/scan/tests/test_stack.py +604 -0
  613. package/tools/scan/tests/test_tools.py +349 -0
  614. package/tools/scan/ui.py +624 -0
  615. package/tools/scan/verify.py +270 -0
  616. package/tools/scan/walk.py +118 -0
  617. package/tools/scan/workspace.py +85 -0
  618. package/tools/validation/README.md +244 -0
  619. package/tools/validation/__init__.py +17 -0
  620. package/tools/validation/approval_gate.py +321 -0
  621. package/tools/validation/validate_skills.py +189 -0
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env python3
2
+ import os
3
+ import re
4
+ import yaml
5
+ from pathlib import Path
6
+ from collections import defaultdict
7
+
8
+ def find_skills(base_dirs):
9
+ """Encuentra todas las skills en los directorios base."""
10
+ skills = {}
11
+ for base_dir in base_dirs:
12
+ path = Path(base_dir)
13
+ if not path.exists():
14
+ continue
15
+ for skill_file in path.rglob("SKILL.md"):
16
+ skill_name = skill_file.parent.name
17
+ skills[skill_name] = {
18
+ "path": str(skill_file),
19
+ "content": skill_file.read_text(encoding="utf-8", errors="ignore")
20
+ }
21
+ return skills
22
+
23
+ def validate_skill_format(skills):
24
+ """Valida el formato de cada skill."""
25
+ validation_results = {}
26
+ for name, data in skills.items():
27
+ content = data["content"]
28
+ has_title = bool(re.search(r'^#\s+.+', content, re.MULTILINE))
29
+ validation_results[name] = {
30
+ "has_title": has_title,
31
+ "is_empty": len(content.strip()) == 0,
32
+ "path": data["path"]
33
+ }
34
+ return validation_results
35
+
36
+ def find_agents(base_dirs):
37
+ """Encuentra las definiciones de los agentes."""
38
+ agents = {}
39
+ for base_dir in base_dirs:
40
+ path = Path(base_dir)
41
+ if not path.exists():
42
+ continue
43
+ for agent_file in path.rglob("*.md"):
44
+ if agent_file.name == "README.md":
45
+ continue
46
+ content = agent_file.read_text(encoding="utf-8", errors="ignore")
47
+ # Extraer frontmatter YAML
48
+ match = re.match(r'^---\s*\n(.*?)\n---\s*\n(.*)', content, re.DOTALL)
49
+ if match:
50
+ try:
51
+ frontmatter = yaml.safe_load(match.group(1))
52
+ if isinstance(frontmatter, dict) and "name" in frontmatter:
53
+ agents[frontmatter["name"]] = {
54
+ "path": str(agent_file),
55
+ "skills_declared": frontmatter.get("skills", []),
56
+ "body": match.group(2)
57
+ }
58
+ except yaml.YAMLError:
59
+ pass
60
+ return agents
61
+
62
+ def analyze_injection():
63
+ """Analiza cómo se inyectan las skills (revisando pre_tool_use.py)."""
64
+ hook_path = Path("gaia-ops/hooks/pre_tool_use.py")
65
+ if not hook_path.exists():
66
+ return "No se encontró gaia-ops/hooks/pre_tool_use.py"
67
+
68
+ content = hook_path.read_text(encoding="utf-8", errors="ignore")
69
+ if "skills are injected natively by Claude Code" in content:
70
+ return "Las skills se inyectan de forma nativa por Claude Code a través del campo 'skills:' en el frontmatter del agente (según pre_tool_use.py)."
71
+ return "Mecanismo de inyección en pre_tool_use.py analizado, pero no se encontró la nota estándar sobre inyección nativa."
72
+
73
+ def generate_report(skills, validation, agents, injection_info):
74
+ """Genera el reporte en formato Markdown."""
75
+ report = ["# Reporte de Validación de Skills\n"]
76
+
77
+ report.append("## 1. Análisis de Inyección")
78
+ report.append(f"{injection_info}\n")
79
+
80
+ report.append(f"## 2. Skills Encontradas ({len(skills)})")
81
+ for name, val in validation.items():
82
+ status = "✅ OK" if val["has_title"] and not val["is_empty"] else "❌ PROBLEMA"
83
+ issues = []
84
+ if not val["has_title"]: issues.append("Falta título (# Título)")
85
+ if val["is_empty"]: issues.append("Archivo vacío")
86
+ issue_str = f" - Detalles: {', '.join(issues)}" if issues else ""
87
+ report.append(f"- **{name}** ({val['path']}): {status}{issue_str}")
88
+ report.append("")
89
+
90
+ # Analizar uso de skills
91
+ used_skills = defaultdict(list)
92
+ missing_skills = defaultdict(list)
93
+ body_mentions = defaultdict(list)
94
+
95
+ for agent_name, agent_data in agents.items():
96
+ declared = agent_data["skills_declared"] or []
97
+ body = agent_data["body"]
98
+ for skill in declared:
99
+ if skill in skills:
100
+ used_skills[skill].append(agent_name)
101
+ else:
102
+ missing_skills[agent_name].append(skill)
103
+
104
+ # Check for skills mentioned in the body but not declared
105
+ for skill in skills:
106
+ if skill not in declared and skill in body:
107
+ body_mentions[agent_name].append(skill)
108
+
109
+ report.append("## 3. Uso de Skills por Agentes")
110
+ if not agents:
111
+ report.append("No se encontraron definiciones de agentes con frontmatter YAML válido.\n")
112
+ else:
113
+ for agent_name, agent_data in agents.items():
114
+ declared = agent_data["skills_declared"] or []
115
+ mentions = body_mentions[agent_name]
116
+ mention_str = f" (Menciona en texto sin declarar: {', '.join(mentions)})" if mentions else ""
117
+ report.append(f"- **{agent_name}**: {len(declared)} skills declaradas.{mention_str}")
118
+ report.append("")
119
+
120
+ report.append("## 4. Gaps Identificados")
121
+
122
+ # Skills no utilizadas
123
+ # Consideramos una skill como utilizada si está declarada o si se menciona explícitamente en el cuerpo
124
+ all_used_skills = set(used_skills.keys())
125
+ for mentions in body_mentions.values():
126
+ all_used_skills.update(mentions)
127
+
128
+ unused_skills = set(skills.keys()) - all_used_skills
129
+ if unused_skills:
130
+ report.append("### Skills no utilizadas (Huérfanas)")
131
+ for skill in sorted(unused_skills):
132
+ report.append(f"- {skill}")
133
+ else:
134
+ report.append("### Skills no utilizadas (Huérfanas)")
135
+ report.append("- Ninguna. Todas las skills encontradas están asignadas a al menos un agente.")
136
+ report.append("")
137
+
138
+ # Skills declaradas pero inexistentes
139
+ if missing_skills:
140
+ report.append("### Skills declaradas pero no encontradas (Faltantes)")
141
+ for agent, missing in missing_skills.items():
142
+ for m in missing:
143
+ report.append(f"- El agente **{agent}** declara la skill '{m}', pero no se encontró el archivo SKILL.md correspondiente.")
144
+ else:
145
+ report.append("### Skills declaradas pero no encontradas (Faltantes)")
146
+ report.append("- Ninguna. Todas las skills declaradas por los agentes existen.")
147
+ report.append("")
148
+
149
+ # Skills mencionadas en el texto pero no inyectadas formalmente
150
+ report.append("### Skills mencionadas en el texto pero NO declaradas en 'skills:'")
151
+ if body_mentions:
152
+ for agent, mentions in body_mentions.items():
153
+ for m in mentions:
154
+ report.append(f"- **{agent}** menciona '{m}' en su cuerpo pero no está en la lista de inyección.")
155
+ else:
156
+ report.append("- Ninguna.")
157
+ report.append("")
158
+
159
+ return "\n".join(report)
160
+
161
+ def main():
162
+ skill_dirs = ["gaia-ops/skills", ".claude/skills", "conductor-orchestrator/skills"]
163
+ agent_dirs = ["gaia-ops/agents", ".claude/agents", "conductor-orchestrator/agents"]
164
+
165
+ print("Buscando skills...")
166
+ skills = find_skills(skill_dirs)
167
+
168
+ print("Validando formato...")
169
+ validation = validate_skill_format(skills)
170
+
171
+ print("Buscando agentes...")
172
+ agents = find_agents(agent_dirs)
173
+
174
+ print("Analizando inyección...")
175
+ injection_info = analyze_injection()
176
+
177
+ print("Generando reporte...")
178
+ report = generate_report(skills, validation, agents, injection_info)
179
+
180
+ report_path = Path("gaia-ops/tools/validation/skills_report.md")
181
+ report_path.write_text(report, encoding="utf-8")
182
+ print(f"Reporte generado en {report_path}")
183
+
184
+ # Imprimir el reporte en la salida estándar para que el agente lo pueda devolver
185
+ print("\n" + "="*50 + "\n")
186
+ print(report)
187
+
188
+ if __name__ == "__main__":
189
+ main()
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "gaia-security",
3
+ "version": "5.0.0-rc.2",
4
+ "description": "Keeps you in the loop only when it matters. Gaia Security analyzes every command and classifies it into risk tiers: read-only queries run freely, simulations and validations pass through, and state-changing operations (create, delete, apply, push) pause for your explicit approval before executing. Irreversible commands like dropping databases or deleting cloud infrastructure are permanently blocked.",
5
+ "author": {
6
+ "name": "jaguilar87",
7
+ "email": "jorge.aguilar87@gmail.com"
8
+ },
9
+ "homepage": "https://github.com/metraton/gaia-ops#gaia-security",
10
+ "repository": "https://github.com/metraton/gaia-ops",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "security",
14
+ "devops"
15
+ ],
16
+ "engines": {
17
+ "claude-code": ">=2.1.0"
18
+ },
19
+ "categories": [
20
+ "devops",
21
+ "security",
22
+ "orchestration"
23
+ ]
24
+ }
@@ -0,0 +1,90 @@
1
+ # gaia-security
2
+
3
+ Keeps you in the loop only when it matters. Gaia Security analyzes every Bash command and classifies it into four risk tiers: read-only runs freely, validation and simulation pass through, state-changing operations (create, delete, apply, push) pause for explicit approval, and irreversible commands (database drops, cluster deletes, `git push --force`, `mkfs`, `dd`) are permanently blocked.
4
+
5
+ Install this plugin when you want Gaia's security pipeline without the agent roster, skills, or orchestrator. It is the stripped-down path — hooks, modules, and the deny list. If you want the full Gaia experience with eight specialist agents and a planner, install `gaia-ops` instead.
6
+
7
+ ## Install
8
+
9
+ **Via Claude Code marketplace:**
10
+
11
+ ```
12
+ /plugin marketplace add metraton/gaia
13
+ /plugin install gaia-security
14
+ ```
15
+
16
+ **Via npm (standalone dist):**
17
+
18
+ ```bash
19
+ npm install @jaguilar87/gaia
20
+ # Then point Claude Code at dist/gaia-security/ in your settings.
21
+ ```
22
+
23
+ ## Quick start
24
+
25
+ Once installed, the hooks activate automatically on session start. Try any of these to see the pipeline in action:
26
+
27
+ ```bash
28
+ # Safe (T0) — runs directly
29
+ ls -la
30
+
31
+ # Validation (T1) — runs directly
32
+ terraform validate
33
+
34
+ # Simulation (T2) — runs directly
35
+ terraform plan
36
+
37
+ # Mutative (T3) — prompts for approval
38
+ terraform apply
39
+
40
+ # Blocked — permanently denied, no prompt
41
+ gcloud sql instances delete my-prod-db
42
+ ```
43
+
44
+ To manage approvals during a session:
45
+
46
+ ```
47
+ # Inside Claude Code
48
+ aprobar # show pending approvals
49
+ approve P-<id> # grant a pending request
50
+ reject P-<id> # deny a pending request
51
+ ```
52
+
53
+ ## What ships with this plugin
54
+
55
+ **Hooks** (5 lifecycle events): `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `SessionStart`, `Stop`. All wired to the same security pipeline that powers the full gaia-ops plugin.
56
+
57
+ **Hook modules** (under `hooks/modules/`):
58
+
59
+ - `core/` — classification logic, tier assignment
60
+ - `security/` — blocked commands, mutative verb detection, nonce issuance
61
+ - `audit/` — session registry, approval persistence
62
+ - `tools/` — Bash, Edit, Write adapters
63
+ - `validation/` — schema checks, permission validation
64
+ - `identity/`, `context/`, `scanning/`, `session/`, `memory/`, `orchestrator/`, `events/` — supporting concerns
65
+ - `adapters/claude_code.py` — bridges Gaia classification to CC native permission model
66
+
67
+ **No agents. No skills. No commands.** This plugin is hooks + deny list by design.
68
+
69
+ **Config**: `config/universal-rules.json` — shared rule set that governs tier classification.
70
+
71
+ ## Permissions
72
+
73
+ - `Bash(*)` allowed — the pre-tool-use hook is the real security gate.
74
+ - `Read`, `Glob`, `Grep`, `BashOutput`, `KillShell` allowed for inspection.
75
+ - 45 irreversible commands permanently denied in `settings.json` (AWS VPC/RDS/S3 deletes, GCP project/cluster/SQL deletes, Kubernetes namespace/node/PV deletes, `git push --force`, `dd`, `mkfs`).
76
+
77
+ Writes to `.claude/hooks/` and `.claude/settings*.json` are hook-protected — approval required even in `bypassPermissions` mode.
78
+
79
+ ## Troubleshooting
80
+
81
+ - **Hook not firing**: confirm `hooks/hooks.json` is present and every `entries` file resolves on disk. Missing files are silently skipped.
82
+ - **Approval flow stuck**: check `~/.claude/logs/` for hook traces; `aprobar` lists pending requests.
83
+ - **Want the full system**: install `gaia-ops` — same hook pipeline, plus eight agents, skills, and the orchestrator.
84
+
85
+ ## Links
86
+
87
+ - Documentation: [github.com/metraton/gaia#gaia-security](https://github.com/metraton/gaia#gaia-security)
88
+ - Security policy: [SECURITY.md](https://github.com/metraton/gaia/blob/main/SECURITY.md)
89
+ - Issues: [github.com/metraton/gaia/issues](https://github.com/metraton/gaia/issues)
90
+ - License: MIT
@@ -0,0 +1,102 @@
1
+ {
2
+ "rules": {
3
+ "universal": [
4
+ {
5
+ "rule": "Your prompt includes a Project Context section with confirmed project knowledge. Extract relevant data from it BEFORE executing commands."
6
+ },
7
+ {
8
+ "rule": "context_map: The Project Context section is organized into named sections (e.g. project_identity, stack, git, infrastructure). Each section contains data scanned from the project. Reading the wrong section wastes tokens and produces stale assumptions; reading none at all causes commands built on defaults to fail in ways that are hard to trace back to the root cause."
9
+ }
10
+ ],
11
+ "agent_specific": {
12
+ "cloud-troubleshooter": {
13
+ "rules": [
14
+ {
15
+ "rule": "monitoring_observability and cluster_details are the primary diagnostic surfaces. A diagnosis that skips these sections will miss the live state of the cluster and produce recommendations that contradict what is already deployed."
16
+ },
17
+ {
18
+ "rule": "infrastructure_topology describes how services are connected across regions and availability zones. Ignoring it when investigating connectivity or latency issues leads to remediation steps that address symptoms rather than the structural cause."
19
+ },
20
+ {
21
+ "rule": "operational_guidelines encodes team conventions for runbooks, escalation paths, and SLOs. Bypassing it risks proposing changes that violate on-call agreements or SLA boundaries."
22
+ }
23
+ ]
24
+ },
25
+ "gitops-operator": {
26
+ "rules": [
27
+ {
28
+ "rule": "gitops_configuration holds the source-of-truth for Flux/ArgoCD sync targets, kustomize overlays, and reconciliation intervals. Writing manifests without reading this section produces changes that the GitOps controller will override or reject on the next sync cycle."
29
+ },
30
+ {
31
+ "rule": "cluster_details defines the Kubernetes version, node pools, and namespacing conventions. A manifest targeting the wrong API version or namespace will apply cleanly and then fail at runtime, making the error hard to attribute."
32
+ },
33
+ {
34
+ "rule": "operational_guidelines specifies change-window and approval policies. Bypassing it risks triggering a sync during a protected window and causing a production incident."
35
+ }
36
+ ]
37
+ },
38
+ "terraform-architect": {
39
+ "rules": [
40
+ {
41
+ "rule": "terraform_infrastructure contains existing module versions, backend configuration, and remote state references. Planning without this data generates a diff that replaces instead of updates, and can destroy live resources that were not in scope."
42
+ },
43
+ {
44
+ "rule": "infrastructure_topology maps provider accounts, VPCs, and cross-account trust relationships. Missing this context leads to resource definitions that introduce duplicate CIDR blocks or broken IAM trust chains."
45
+ },
46
+ {
47
+ "rule": "operational_guidelines captures cost-center tagging requirements and provider version constraints. Ignoring them produces plans that pass validation but are rejected at code review or fail cost attribution."
48
+ }
49
+ ]
50
+ },
51
+ "developer": {
52
+ "rules": [
53
+ {
54
+ "rule": "stack defines the languages, frameworks, and build tools in use. Writing code against a different stack version or framework than what is declared here produces changes that pass local tests and break in CI."
55
+ },
56
+ {
57
+ "rule": "application_services describes service boundaries, ports, and inter-service contracts. Changing a service's interface without consulting this section breaks consumers that are not under active development and not visible in the immediate file context."
58
+ },
59
+ {
60
+ "rule": "operational_guidelines specifies coding standards, test coverage thresholds, and linting rules. Code that meets the functional requirement but ignores these standards will be rejected at the review gate, requiring a rework cycle."
61
+ }
62
+ ]
63
+ },
64
+ "gaia-planner": {
65
+ "rules": [
66
+ {
67
+ "rule": "architecture_overview describes the current system design and known constraints. A plan that ignores these constraints will produce tasks that are technically coherent but architecturally incompatible with the existing system, requiring replanning after the first implementation attempt."
68
+ },
69
+ {
70
+ "rule": "application_services lists live services and their owners. Omitting this context leads to plans that assume capabilities are missing when they already exist, or that schedule work in the wrong order relative to service dependencies."
71
+ },
72
+ {
73
+ "rule": "operational_guidelines records process constraints such as deployment windows and team capacity limits. A plan that ignores them will hit blockers during execution that were predictable at planning time."
74
+ }
75
+ ]
76
+ },
77
+ "gaia-operator": {
78
+ "rules": [
79
+ {
80
+ "rule": "workspace_repos is this agent's primary surface: it lists every repository in the workspace with its path, platform, and role. Operating on a repo that is absent from this list risks working in the wrong directory or missing the canonical remote URL, causing pushes to fail or go to the wrong origin."
81
+ },
82
+ {
83
+ "rule": "git describes the platform, default branch, and branching strategy. Ignoring it produces branch names or merge strategies that conflict with the project's CI configuration and require manual cleanup."
84
+ }
85
+ ]
86
+ },
87
+ "gaia-system": {
88
+ "rules": [
89
+ {
90
+ "rule": "architecture_overview is the write target for system-level changes: updates made without first reading the current state overwrite accurate data with stale assumptions, corrupting the context that all other agents depend on."
91
+ },
92
+ {
93
+ "rule": "operational_guidelines captures team-agreed constraints on the Gaia system itself. Proposing architectural changes that contradict these guidelines produces recommendations that will be rejected and mislead agents that read the context between now and the rejection."
94
+ },
95
+ {
96
+ "rule": "infrastructure provides the deployment environment for Gaia components. Missing this section leads to skill or hook designs that assume capabilities (e.g. network access, file system layout) that do not exist in the actual runtime environment."
97
+ }
98
+ ]
99
+ }
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,52 @@
1
+ """
2
+ Adapter Layer for Gaia-Ops Hooks.
3
+
4
+ Provides CLI-agnostic normalized types and the abstract HookAdapter interface.
5
+ Business logic modules consume and produce these types; concrete adapters
6
+ translate between these types and CLI-specific JSON protocols.
7
+
8
+ Modules:
9
+ - types: Frozen dataclasses and enums for all hook event/response data
10
+ - base: Abstract HookAdapter interface
11
+ """
12
+
13
+ from .types import (
14
+ HookEventType,
15
+ PermissionDecision,
16
+ DistributionChannel,
17
+ HookEvent,
18
+ ValidationRequest,
19
+ ValidationResult,
20
+ ToolResult,
21
+ AgentCompletion,
22
+ CompletionResult,
23
+ ContextResult,
24
+ BootstrapResult,
25
+ QualityResult,
26
+ VerificationResult,
27
+ HookResponse,
28
+ )
29
+ from .base import HookAdapter
30
+ from .claude_code import ClaudeCodeAdapter
31
+ from .utils import has_stdin_data, warn_if_dual_channel
32
+
33
+ __all__ = [
34
+ "HookEventType",
35
+ "PermissionDecision",
36
+ "DistributionChannel",
37
+ "HookEvent",
38
+ "ValidationRequest",
39
+ "ValidationResult",
40
+ "ToolResult",
41
+ "AgentCompletion",
42
+ "CompletionResult",
43
+ "ContextResult",
44
+ "BootstrapResult",
45
+ "QualityResult",
46
+ "VerificationResult",
47
+ "HookResponse",
48
+ "HookAdapter",
49
+ "ClaudeCodeAdapter",
50
+ "has_stdin_data",
51
+ "warn_if_dual_channel",
52
+ ]
@@ -0,0 +1,219 @@
1
+ """
2
+ Abstract base class defining the adapter contract.
3
+
4
+ Each CLI backend (Claude Code, future CLIs) provides a concrete implementation
5
+ of HookAdapter. Business logic modules interact only with the normalized types;
6
+ they never see raw CLI JSON.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from abc import ABC, abstractmethod
12
+
13
+ from .types import (
14
+ AgentCompletion,
15
+ BootstrapResult,
16
+ CompletionResult,
17
+ ContextResult,
18
+ DistributionChannel,
19
+ HookEvent,
20
+ HookResponse,
21
+ QualityResult,
22
+ ValidationResult,
23
+ VerificationResult,
24
+ )
25
+
26
+
27
+ class HookAdapter(ABC):
28
+ """Abstract adapter between CLI-specific JSON and normalized types.
29
+
30
+ Invariants (from adapter-interface contract):
31
+ 1. Business logic modules NEVER see HookResponse.
32
+ 2. The adapter NEVER modifies business logic results -- only translates format.
33
+ 3. Adding a new hook event requires ONLY a new adapter method.
34
+ """
35
+
36
+ @abstractmethod
37
+ def parse_event(self, stdin_data: str) -> HookEvent:
38
+ """Parse raw stdin JSON into a normalized HookEvent.
39
+
40
+ Preconditions:
41
+ - stdin_data is a valid JSON string
42
+ - JSON contains at minimum: hook_event_name, session_id
43
+
44
+ Postconditions:
45
+ - Returns HookEvent with event_type set to a valid HookEventType
46
+ - Returns HookEvent with session_id populated
47
+ - payload contains the full raw event data
48
+
49
+ Raises:
50
+ ValueError: If JSON is invalid or event type is unknown.
51
+ """
52
+ ...
53
+
54
+ @abstractmethod
55
+ def format_validation_response(self, result: ValidationResult) -> HookResponse:
56
+ """Format a ValidationResult for CLI consumption.
57
+
58
+ Preconditions:
59
+ - result.allowed is a valid boolean
60
+ - result.reason is a non-empty string
61
+
62
+ Postconditions:
63
+ - HookResponse.output is a valid JSON-serializable dict
64
+ - HookResponse.exit_code is 0 (corrective deny) or 2 (permanent block)
65
+ - If result.allowed is True, output contains permissionDecision: allow
66
+ - If result.allowed is False, output contains permissionDecision: deny
67
+ - If result.modified_input is set, output contains updatedInput
68
+ """
69
+ ...
70
+
71
+ @abstractmethod
72
+ def format_completion_response(self, result: CompletionResult) -> HookResponse:
73
+ """Format a CompletionResult for CLI consumption.
74
+
75
+ Postconditions:
76
+ - HookResponse.output contains contract_valid, anomalies_detected
77
+ - HookResponse.exit_code is always 0
78
+ """
79
+ ...
80
+
81
+ @abstractmethod
82
+ def format_context_response(self, result: ContextResult) -> HookResponse:
83
+ """Format a ContextResult for CLI consumption."""
84
+ ...
85
+
86
+ @abstractmethod
87
+ def format_bootstrap_response(self, result: BootstrapResult) -> HookResponse:
88
+ """Format a BootstrapResult for CLI consumption.
89
+
90
+ Returns session bootstrap status for SessionStart events.
91
+ """
92
+ ...
93
+
94
+ @abstractmethod
95
+ def adapt_session_start(self, raw: dict) -> BootstrapResult:
96
+ """Parse SessionStart event and return bootstrap actions.
97
+
98
+ Preconditions:
99
+ - raw is the HookEvent.payload dict for a SessionStart event
100
+
101
+ Postconditions:
102
+ - Returns BootstrapResult with should_scan and should_refresh set
103
+ based on session_type
104
+ """
105
+ ...
106
+
107
+ # ------------------------------------------------------------------ #
108
+ # P2 event adapters
109
+ # ------------------------------------------------------------------ #
110
+
111
+ @abstractmethod
112
+ def adapt_stop(self, raw: dict) -> QualityResult:
113
+ """Parse Stop event and assess response quality.
114
+
115
+ Preconditions:
116
+ - raw is the HookEvent.payload dict for a Stop event
117
+
118
+ Postconditions:
119
+ - Returns QualityResult with quality assessment
120
+ """
121
+ ...
122
+
123
+ @abstractmethod
124
+ def adapt_task_completed(self, raw: dict) -> VerificationResult:
125
+ """Parse TaskCompleted event and verify completion criteria.
126
+
127
+ Preconditions:
128
+ - raw is the HookEvent.payload dict for a TaskCompleted event
129
+
130
+ Postconditions:
131
+ - Returns VerificationResult with criteria assessment
132
+ """
133
+ ...
134
+
135
+ @abstractmethod
136
+ def adapt_subagent_start(self, raw: dict) -> ContextResult:
137
+ """Parse SubagentStart event and prepare agent context.
138
+
139
+ Preconditions:
140
+ - raw is the HookEvent.payload dict for a SubagentStart event
141
+
142
+ Postconditions:
143
+ - Returns ContextResult with agent-specific context
144
+ """
145
+ ...
146
+
147
+ # ------------------------------------------------------------------ #
148
+ # P2 formatters
149
+ # ------------------------------------------------------------------ #
150
+
151
+ @abstractmethod
152
+ def format_quality_response(self, result: QualityResult) -> HookResponse:
153
+ """Format a QualityResult for CLI consumption."""
154
+ ...
155
+
156
+ @abstractmethod
157
+ def format_verification_response(self, result: VerificationResult) -> HookResponse:
158
+ """Format a VerificationResult for CLI consumption."""
159
+ ...
160
+
161
+ @abstractmethod
162
+ def detect_channel(self) -> DistributionChannel:
163
+ """Detect the distribution channel (NPM or PLUGIN).
164
+
165
+ Checks environment variables and filesystem layout to determine
166
+ how gaia-ops was installed.
167
+ """
168
+ ...
169
+
170
+ # ------------------------------------------------------------------ #
171
+ # Full hook lifecycle adapters (thin-gate pattern)
172
+ # ------------------------------------------------------------------ #
173
+
174
+ @abstractmethod
175
+ def adapt_pre_tool_use(self, event: HookEvent) -> HookResponse:
176
+ """Run all pre-tool-use business logic and return a formatted response.
177
+
178
+ Orchestrates: routing (bash vs task), validation, state management,
179
+ context injection, approval handling, and response formatting.
180
+
181
+ Preconditions:
182
+ - event is a parsed HookEvent with event_type PRE_TOOL_USE
183
+
184
+ Postconditions:
185
+ - Returns HookResponse ready for stdout + sys.exit()
186
+ """
187
+ ...
188
+
189
+ @abstractmethod
190
+ def adapt_post_tool_use(self, event: HookEvent) -> HookResponse:
191
+ """Run all post-tool-use business logic and return a formatted response.
192
+
193
+ Orchestrates: state retrieval, duration computation, audit logging,
194
+ T3 grant confirmation, critical event detection, session context
195
+ writing, and state cleanup.
196
+
197
+ Preconditions:
198
+ - event is a parsed HookEvent with event_type POST_TOOL_USE
199
+
200
+ Postconditions:
201
+ - Returns HookResponse (always exit 0, post-hook never blocks)
202
+ """
203
+ ...
204
+
205
+ @abstractmethod
206
+ def adapt_subagent_stop(self, event: HookEvent) -> HookResponse:
207
+ """Run all subagent-stop business logic and return a formatted response.
208
+
209
+ Orchestrates: contract parsing and validation, approval cleanup,
210
+ context updates, workflow recording, response contract validation,
211
+ anomaly detection, episodic memory, and result assembly.
212
+
213
+ Preconditions:
214
+ - event is a parsed HookEvent with event_type SUBAGENT_STOP
215
+
216
+ Postconditions:
217
+ - Returns HookResponse (exit 0 for success, exit 2 for contract rejection)
218
+ """
219
+ ...