@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +12 -3
- package/ARCHITECTURE.md +9 -8
- package/CHANGELOG.md +34 -0
- package/README.md +43 -11
- package/agents/terraform-architect.md +1 -1
- package/bin/README.md +2 -2
- package/bin/gaia-doctor.js +18 -5
- package/bin/gaia-history.js +0 -1
- package/bin/gaia-metrics.js +2 -2
- package/bin/gaia-scan.py +23 -1
- package/bin/gaia-update.js +346 -54
- package/bin/pre-publish-validate.js +33 -10
- package/commands/gaia.md +37 -0
- package/config/README.md +3 -9
- package/config/context-contracts.json +47 -15
- package/config/surface-routing.json +9 -1
- package/dist/gaia-ops/.claude-plugin/plugin.json +22 -0
- package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
- package/dist/gaia-ops/agents/devops-developer.md +57 -0
- package/dist/gaia-ops/agents/gaia-system.md +58 -0
- package/dist/gaia-ops/agents/gitops-operator.md +60 -0
- package/dist/gaia-ops/agents/speckit-planner.md +71 -0
- package/dist/gaia-ops/agents/terraform-architect.md +60 -0
- package/dist/gaia-ops/commands/gaia.md +37 -0
- package/dist/gaia-ops/config/README.md +58 -0
- package/dist/gaia-ops/config/cloud/aws.json +140 -0
- package/dist/gaia-ops/config/cloud/gcp.json +145 -0
- package/dist/gaia-ops/config/context-contracts.json +131 -0
- package/dist/gaia-ops/config/git_standards.json +72 -0
- package/dist/gaia-ops/config/surface-routing.json +197 -0
- package/dist/gaia-ops/config/universal-rules.json +10 -0
- package/dist/gaia-ops/hooks/adapters/__init__.py +52 -0
- package/dist/gaia-ops/hooks/adapters/base.py +219 -0
- package/dist/gaia-ops/hooks/adapters/channel.py +17 -0
- package/dist/gaia-ops/hooks/adapters/claude_code.py +1477 -0
- package/dist/gaia-ops/hooks/adapters/types.py +194 -0
- package/dist/gaia-ops/hooks/adapters/utils.py +25 -0
- package/dist/gaia-ops/hooks/hooks.json +126 -0
- package/dist/gaia-ops/hooks/modules/__init__.py +15 -0
- package/dist/gaia-ops/hooks/modules/agents/__init__.py +29 -0
- package/dist/gaia-ops/hooks/modules/agents/contract_validator.py +647 -0
- package/dist/gaia-ops/hooks/modules/agents/response_contract.py +496 -0
- package/dist/gaia-ops/hooks/modules/agents/skill_injection_verifier.py +124 -0
- package/dist/gaia-ops/hooks/modules/agents/task_info_builder.py +74 -0
- package/dist/gaia-ops/hooks/modules/agents/transcript_analyzer.py +458 -0
- package/dist/gaia-ops/hooks/modules/agents/transcript_reader.py +152 -0
- package/dist/gaia-ops/hooks/modules/audit/__init__.py +28 -0
- package/dist/gaia-ops/hooks/modules/audit/event_detector.py +168 -0
- package/dist/gaia-ops/hooks/modules/audit/logger.py +131 -0
- package/dist/gaia-ops/hooks/modules/audit/metrics.py +134 -0
- package/dist/gaia-ops/hooks/modules/audit/workflow_auditor.py +576 -0
- package/dist/gaia-ops/hooks/modules/audit/workflow_recorder.py +296 -0
- package/dist/gaia-ops/hooks/modules/context/__init__.py +11 -0
- package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
- package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +215 -0
- package/dist/gaia-ops/hooks/modules/context/context_cache.py +129 -0
- package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
- package/dist/gaia-ops/hooks/modules/context/context_injector.py +427 -0
- package/dist/gaia-ops/hooks/modules/context/context_writer.py +518 -0
- package/dist/gaia-ops/hooks/modules/context/contracts_loader.py +161 -0
- package/dist/gaia-ops/hooks/modules/core/__init__.py +40 -0
- package/dist/gaia-ops/hooks/modules/core/hook_entry.py +78 -0
- package/dist/gaia-ops/hooks/modules/core/paths.py +160 -0
- package/dist/gaia-ops/hooks/modules/core/plugin_mode.py +149 -0
- package/dist/gaia-ops/hooks/modules/core/plugin_setup.py +558 -0
- package/dist/gaia-ops/hooks/modules/core/state.py +179 -0
- package/dist/gaia-ops/hooks/modules/core/stdin.py +24 -0
- package/dist/gaia-ops/hooks/modules/events/__init__.py +1 -0
- package/dist/gaia-ops/hooks/modules/events/event_writer.py +210 -0
- package/dist/gaia-ops/hooks/modules/identity/__init__.py +0 -0
- package/dist/gaia-ops/hooks/modules/identity/identity_provider.py +21 -0
- package/dist/gaia-ops/hooks/modules/identity/ops_identity.py +34 -0
- package/dist/gaia-ops/hooks/modules/identity/security_identity.py +10 -0
- package/dist/gaia-ops/hooks/modules/memory/__init__.py +8 -0
- package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +227 -0
- package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
- package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +128 -0
- package/dist/gaia-ops/hooks/modules/scanning/__init__.py +8 -0
- package/dist/gaia-ops/hooks/modules/scanning/scan_trigger.py +84 -0
- package/dist/gaia-ops/hooks/modules/security/__init__.py +89 -0
- package/dist/gaia-ops/hooks/modules/security/approval_cleanup.py +87 -0
- package/dist/gaia-ops/hooks/modules/security/approval_constants.py +23 -0
- package/dist/gaia-ops/hooks/modules/security/approval_grants.py +912 -0
- package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
- package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +153 -0
- package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +584 -0
- package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +86 -0
- package/dist/gaia-ops/hooks/modules/security/command_semantics.py +130 -0
- package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
- package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +850 -0
- package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
- package/dist/gaia-ops/hooks/modules/security/tiers.py +196 -0
- package/dist/gaia-ops/hooks/modules/session/__init__.py +10 -0
- package/dist/gaia-ops/hooks/modules/session/session_context_writer.py +100 -0
- package/dist/gaia-ops/hooks/modules/session/session_event_injector.py +158 -0
- package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
- package/dist/gaia-ops/hooks/modules/tools/__init__.py +25 -0
- package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +708 -0
- package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +181 -0
- package/dist/gaia-ops/hooks/modules/tools/hook_response.py +55 -0
- package/dist/gaia-ops/hooks/modules/tools/shell_parser.py +227 -0
- package/dist/gaia-ops/hooks/modules/tools/task_validator.py +283 -0
- package/dist/gaia-ops/hooks/modules/validation/__init__.py +23 -0
- package/dist/gaia-ops/hooks/modules/validation/commit_validator.py +380 -0
- package/dist/gaia-ops/hooks/post_compact.py +43 -0
- package/dist/gaia-ops/hooks/post_tool_use.py +54 -0
- package/dist/gaia-ops/hooks/pre_tool_use.py +383 -0
- package/dist/gaia-ops/hooks/session_start.py +69 -0
- package/dist/gaia-ops/hooks/stop_hook.py +69 -0
- package/dist/gaia-ops/hooks/subagent_start.py +71 -0
- package/dist/gaia-ops/hooks/subagent_stop.py +288 -0
- package/dist/gaia-ops/hooks/task_completed.py +70 -0
- package/dist/gaia-ops/hooks/user_prompt_submit.py +177 -0
- package/dist/gaia-ops/settings.json +72 -0
- package/dist/gaia-ops/skills/README.md +109 -0
- package/dist/gaia-ops/skills/agent-protocol/SKILL.md +105 -0
- package/dist/gaia-ops/skills/agent-protocol/examples.md +170 -0
- package/dist/gaia-ops/skills/agent-response/SKILL.md +53 -0
- package/dist/gaia-ops/skills/approval/SKILL.md +85 -0
- package/dist/gaia-ops/skills/approval/examples.md +140 -0
- package/dist/gaia-ops/skills/approval/reference.md +57 -0
- package/dist/gaia-ops/skills/command-execution/SKILL.md +64 -0
- package/dist/gaia-ops/skills/command-execution/reference.md +83 -0
- package/dist/gaia-ops/skills/context-updater/SKILL.md +76 -0
- package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
- package/dist/gaia-ops/skills/developer-patterns/SKILL.md +93 -0
- package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
- package/dist/gaia-ops/skills/execution/SKILL.md +66 -0
- package/dist/gaia-ops/skills/fast-queries/SKILL.md +47 -0
- package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +92 -0
- package/dist/gaia-ops/skills/gaia-patterns/reference.md +22 -0
- package/dist/gaia-ops/skills/git-conventions/SKILL.md +48 -0
- package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +73 -0
- package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
- package/dist/gaia-ops/skills/investigation/SKILL.md +77 -0
- package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +64 -0
- package/dist/gaia-ops/skills/reference.md +134 -0
- package/dist/gaia-ops/skills/security-tiers/SKILL.md +61 -0
- package/dist/gaia-ops/skills/security-tiers/destructive-commands-reference.md +623 -0
- package/dist/gaia-ops/skills/security-tiers/reference.md +39 -0
- package/dist/gaia-ops/skills/skill-creation/SKILL.md +119 -0
- package/dist/gaia-ops/skills/specification/SKILL.md +186 -0
- package/dist/gaia-ops/skills/speckit-workflow/SKILL.md +165 -0
- package/dist/gaia-ops/skills/speckit-workflow/reference.md +117 -0
- package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +63 -0
- package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
- package/dist/gaia-ops/speckit/README.md +516 -0
- package/dist/gaia-ops/speckit/scripts/.gitkeep +0 -0
- package/dist/gaia-ops/speckit/templates/adr-template.md +118 -0
- package/dist/gaia-ops/speckit/templates/agent-file-template.md +23 -0
- package/dist/gaia-ops/speckit/templates/plan-template.md +227 -0
- package/dist/gaia-ops/speckit/templates/spec-template.md +140 -0
- package/dist/gaia-ops/speckit/templates/tasks-template.md +257 -0
- package/dist/gaia-ops/tools/context/README.md +132 -0
- package/dist/gaia-ops/tools/context/__init__.py +42 -0
- package/dist/gaia-ops/tools/context/_paths.py +20 -0
- package/dist/gaia-ops/tools/context/context_provider.py +476 -0
- package/dist/gaia-ops/tools/context/context_section_reader.py +330 -0
- package/dist/gaia-ops/tools/context/deep_merge.py +159 -0
- package/dist/gaia-ops/tools/context/pending_updates.py +760 -0
- package/dist/gaia-ops/tools/context/surface_router.py +278 -0
- package/dist/gaia-ops/tools/fast-queries/README.md +65 -0
- package/dist/gaia-ops/tools/fast-queries/__init__.py +30 -0
- package/dist/gaia-ops/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
- package/dist/gaia-ops/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
- package/dist/gaia-ops/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
- package/dist/gaia-ops/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
- package/dist/gaia-ops/tools/fast-queries/run_triage.sh +59 -0
- package/dist/gaia-ops/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
- package/dist/gaia-ops/tools/gaia_simulator/__init__.py +33 -0
- package/dist/gaia-ops/tools/gaia_simulator/cli.py +354 -0
- package/dist/gaia-ops/tools/gaia_simulator/extractor.py +457 -0
- package/dist/gaia-ops/tools/gaia_simulator/reporter.py +258 -0
- package/dist/gaia-ops/tools/gaia_simulator/routing_simulator.py +334 -0
- package/dist/gaia-ops/tools/gaia_simulator/runner.py +539 -0
- package/dist/gaia-ops/tools/gaia_simulator/skills_mapper.py +262 -0
- package/dist/gaia-ops/tools/memory/README.md +0 -0
- package/dist/gaia-ops/tools/memory/__init__.py +20 -0
- package/dist/gaia-ops/tools/memory/episodic.py +1196 -0
- package/dist/gaia-ops/tools/persist_transcript_analysis.py +85 -0
- package/dist/gaia-ops/tools/review/__init__.py +1 -0
- package/dist/gaia-ops/tools/review/review_engine.py +157 -0
- package/dist/gaia-ops/tools/scan/__init__.py +35 -0
- package/dist/gaia-ops/tools/scan/config.py +247 -0
- package/dist/gaia-ops/tools/scan/merge.py +212 -0
- package/dist/gaia-ops/tools/scan/orchestrator.py +549 -0
- package/dist/gaia-ops/tools/scan/registry.py +127 -0
- package/dist/gaia-ops/tools/scan/scanners/__init__.py +18 -0
- package/dist/gaia-ops/tools/scan/scanners/base.py +137 -0
- package/dist/gaia-ops/tools/scan/scanners/environment.py +324 -0
- package/dist/gaia-ops/tools/scan/scanners/git.py +570 -0
- package/dist/gaia-ops/tools/scan/scanners/infrastructure.py +875 -0
- package/dist/gaia-ops/tools/scan/scanners/orchestration.py +600 -0
- package/dist/gaia-ops/tools/scan/scanners/stack.py +1085 -0
- package/dist/gaia-ops/tools/scan/scanners/tools.py +260 -0
- package/dist/gaia-ops/tools/scan/setup.py +753 -0
- package/dist/gaia-ops/tools/scan/tests/__init__.py +1 -0
- package/dist/gaia-ops/tools/scan/tests/conftest.py +796 -0
- package/dist/gaia-ops/tools/scan/tests/test_environment.py +323 -0
- package/dist/gaia-ops/tools/scan/tests/test_git.py +419 -0
- package/dist/gaia-ops/tools/scan/tests/test_infrastructure.py +382 -0
- package/dist/gaia-ops/tools/scan/tests/test_integration.py +920 -0
- package/dist/gaia-ops/tools/scan/tests/test_merge.py +269 -0
- package/dist/gaia-ops/tools/scan/tests/test_orchestration.py +304 -0
- package/dist/gaia-ops/tools/scan/tests/test_stack.py +604 -0
- package/dist/gaia-ops/tools/scan/tests/test_tools.py +349 -0
- package/dist/gaia-ops/tools/scan/ui.py +624 -0
- package/dist/gaia-ops/tools/scan/verify.py +266 -0
- package/dist/gaia-ops/tools/scan/walk.py +118 -0
- package/dist/gaia-ops/tools/scan/workspace.py +85 -0
- package/dist/gaia-ops/tools/validation/README.md +244 -0
- package/dist/gaia-ops/tools/validation/__init__.py +17 -0
- package/dist/gaia-ops/tools/validation/approval_gate.py +321 -0
- package/dist/gaia-ops/tools/validation/validate_skills.py +189 -0
- package/dist/gaia-security/.claude-plugin/plugin.json +22 -0
- package/dist/gaia-security/config/universal-rules.json +10 -0
- package/dist/gaia-security/hooks/adapters/__init__.py +52 -0
- package/dist/gaia-security/hooks/adapters/base.py +219 -0
- package/dist/gaia-security/hooks/adapters/channel.py +17 -0
- package/dist/gaia-security/hooks/adapters/claude_code.py +1477 -0
- package/dist/gaia-security/hooks/adapters/types.py +194 -0
- package/dist/gaia-security/hooks/adapters/utils.py +25 -0
- package/dist/gaia-security/hooks/hooks.json +57 -0
- package/dist/gaia-security/hooks/modules/__init__.py +15 -0
- package/dist/gaia-security/hooks/modules/agents/__init__.py +29 -0
- package/dist/gaia-security/hooks/modules/agents/contract_validator.py +647 -0
- package/dist/gaia-security/hooks/modules/agents/response_contract.py +496 -0
- package/dist/gaia-security/hooks/modules/agents/skill_injection_verifier.py +124 -0
- package/dist/gaia-security/hooks/modules/agents/task_info_builder.py +74 -0
- package/dist/gaia-security/hooks/modules/agents/transcript_analyzer.py +458 -0
- package/dist/gaia-security/hooks/modules/agents/transcript_reader.py +152 -0
- package/dist/gaia-security/hooks/modules/audit/__init__.py +28 -0
- package/dist/gaia-security/hooks/modules/audit/event_detector.py +168 -0
- package/dist/gaia-security/hooks/modules/audit/logger.py +131 -0
- package/dist/gaia-security/hooks/modules/audit/metrics.py +134 -0
- package/dist/gaia-security/hooks/modules/audit/workflow_auditor.py +576 -0
- package/dist/gaia-security/hooks/modules/audit/workflow_recorder.py +296 -0
- package/dist/gaia-security/hooks/modules/context/__init__.py +11 -0
- package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
- package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +215 -0
- package/dist/gaia-security/hooks/modules/context/context_cache.py +129 -0
- package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
- package/dist/gaia-security/hooks/modules/context/context_injector.py +427 -0
- package/dist/gaia-security/hooks/modules/context/context_writer.py +518 -0
- package/dist/gaia-security/hooks/modules/context/contracts_loader.py +161 -0
- package/dist/gaia-security/hooks/modules/core/__init__.py +40 -0
- package/dist/gaia-security/hooks/modules/core/hook_entry.py +78 -0
- package/dist/gaia-security/hooks/modules/core/paths.py +160 -0
- package/dist/gaia-security/hooks/modules/core/plugin_mode.py +149 -0
- package/dist/gaia-security/hooks/modules/core/plugin_setup.py +558 -0
- package/dist/gaia-security/hooks/modules/core/state.py +179 -0
- package/dist/gaia-security/hooks/modules/core/stdin.py +24 -0
- package/dist/gaia-security/hooks/modules/events/__init__.py +1 -0
- package/dist/gaia-security/hooks/modules/events/event_writer.py +210 -0
- package/dist/gaia-security/hooks/modules/identity/__init__.py +0 -0
- package/dist/gaia-security/hooks/modules/identity/identity_provider.py +21 -0
- package/dist/gaia-security/hooks/modules/identity/ops_identity.py +34 -0
- package/dist/gaia-security/hooks/modules/identity/security_identity.py +10 -0
- package/dist/gaia-security/hooks/modules/memory/__init__.py +8 -0
- package/dist/gaia-security/hooks/modules/memory/episode_writer.py +227 -0
- package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
- package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +128 -0
- package/dist/gaia-security/hooks/modules/scanning/__init__.py +8 -0
- package/dist/gaia-security/hooks/modules/scanning/scan_trigger.py +84 -0
- package/dist/gaia-security/hooks/modules/security/__init__.py +89 -0
- package/dist/gaia-security/hooks/modules/security/approval_cleanup.py +87 -0
- package/dist/gaia-security/hooks/modules/security/approval_constants.py +23 -0
- package/dist/gaia-security/hooks/modules/security/approval_grants.py +912 -0
- package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
- package/dist/gaia-security/hooks/modules/security/approval_scopes.py +153 -0
- package/dist/gaia-security/hooks/modules/security/blocked_commands.py +584 -0
- package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +86 -0
- package/dist/gaia-security/hooks/modules/security/command_semantics.py +130 -0
- package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
- package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +850 -0
- package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
- package/dist/gaia-security/hooks/modules/security/tiers.py +196 -0
- package/dist/gaia-security/hooks/modules/session/__init__.py +10 -0
- package/dist/gaia-security/hooks/modules/session/session_context_writer.py +100 -0
- package/dist/gaia-security/hooks/modules/session/session_event_injector.py +158 -0
- package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
- package/dist/gaia-security/hooks/modules/tools/__init__.py +25 -0
- package/dist/gaia-security/hooks/modules/tools/bash_validator.py +708 -0
- package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +181 -0
- package/dist/gaia-security/hooks/modules/tools/hook_response.py +55 -0
- package/dist/gaia-security/hooks/modules/tools/shell_parser.py +227 -0
- package/dist/gaia-security/hooks/modules/tools/task_validator.py +283 -0
- package/dist/gaia-security/hooks/modules/validation/__init__.py +23 -0
- package/dist/gaia-security/hooks/modules/validation/commit_validator.py +380 -0
- package/dist/gaia-security/hooks/post_tool_use.py +54 -0
- package/dist/gaia-security/hooks/pre_tool_use.py +383 -0
- package/dist/gaia-security/hooks/session_start.py +69 -0
- package/dist/gaia-security/hooks/stop_hook.py +69 -0
- package/dist/gaia-security/hooks/user_prompt_submit.py +177 -0
- package/dist/gaia-security/settings.json +58 -0
- package/git-hooks/commit-msg +41 -0
- package/hooks/README.md +8 -6
- package/hooks/adapters/channel.py +0 -25
- package/hooks/adapters/claude_code.py +364 -125
- package/hooks/elicitation_result.py +132 -0
- package/hooks/hooks.json +10 -1
- package/hooks/modules/README.md +3 -2
- package/hooks/modules/agents/contract_validator.py +3 -51
- package/hooks/modules/agents/response_contract.py +4 -8
- package/hooks/modules/agents/transcript_reader.py +4 -5
- package/hooks/modules/audit/__init__.py +4 -6
- package/hooks/modules/audit/event_detector.py +0 -2
- package/hooks/modules/audit/metrics.py +108 -187
- package/hooks/modules/audit/workflow_auditor.py +0 -4
- package/hooks/modules/audit/workflow_recorder.py +0 -5
- package/hooks/modules/context/compact_context_builder.py +1 -0
- package/hooks/modules/context/context_cache.py +129 -0
- package/hooks/modules/context/context_injector.py +18 -40
- package/hooks/modules/context/context_writer.py +1 -25
- package/hooks/modules/context/contracts_loader.py +7 -10
- package/hooks/modules/core/hook_entry.py +1 -0
- package/hooks/modules/core/paths.py +12 -13
- package/hooks/modules/core/plugin_mode.py +74 -4
- package/hooks/modules/core/plugin_setup.py +395 -23
- package/hooks/modules/events/__init__.py +1 -0
- package/hooks/modules/events/event_writer.py +210 -0
- package/hooks/modules/identity/ops_identity.py +18 -27
- package/hooks/modules/memory/episode_writer.py +1 -6
- package/hooks/modules/orchestrator/__init__.py +1 -0
- package/hooks/modules/orchestrator/delegate_mode.py +128 -0
- package/hooks/modules/security/__init__.py +2 -4
- package/hooks/modules/security/approval_constants.py +5 -1
- package/hooks/modules/security/approval_grants.py +189 -6
- package/hooks/modules/security/approval_messages.py +9 -21
- package/hooks/modules/security/blocked_commands.py +98 -34
- package/hooks/modules/security/command_semantics.py +0 -4
- package/hooks/modules/security/gitops_validator.py +1 -11
- package/hooks/modules/security/mutative_verbs.py +179 -38
- package/hooks/modules/security/tiers.py +1 -19
- package/hooks/modules/session/session_event_injector.py +1 -25
- package/hooks/modules/tools/bash_validator.py +310 -94
- package/hooks/modules/tools/shell_parser.py +0 -1
- package/hooks/modules/tools/task_validator.py +9 -29
- package/hooks/post_tool_use.py +0 -72
- package/hooks/pre_tool_use.py +42 -102
- package/hooks/session_start.py +4 -2
- package/hooks/subagent_start.py +6 -2
- package/hooks/subagent_stop.py +1 -13
- package/hooks/user_prompt_submit.py +119 -37
- package/index.js +1 -1
- package/package.json +5 -3
- package/skills/README.md +3 -5
- package/skills/agent-protocol/SKILL.md +17 -16
- package/skills/agent-protocol/examples.md +6 -6
- package/skills/agent-response/SKILL.md +11 -14
- package/skills/approval/SKILL.md +28 -13
- package/skills/approval/reference.md +2 -2
- package/skills/execution/SKILL.md +1 -1
- package/skills/gaia-patterns/SKILL.md +2 -3
- package/skills/orchestrator-approval/SKILL.md +22 -50
- package/skills/security-tiers/SKILL.md +1 -1
- package/templates/README.md +9 -9
- package/templates/managed-settings.template.json +43 -0
- package/tools/gaia_simulator/runner.py +34 -1
- package/tools/scan/orchestrator.py +13 -0
- package/tools/scan/scanners/base.py +8 -0
- package/tools/scan/scanners/git.py +78 -0
- package/tools/scan/scanners/infrastructure.py +65 -0
- package/tools/scan/scanners/stack.py +110 -0
- package/tools/scan/setup.py +120 -13
- package/tools/scan/workspace.py +85 -0
- package/config/context-contracts.aws.json +0 -42
- package/config/context-contracts.gcp.json +0 -39
- package/skills/project-dispatch/SKILL.md +0 -34
- package/templates/settings.template.json +0 -226
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""Event writer and reader for the GAIA Event Context system.
|
|
2
|
+
|
|
3
|
+
Provides:
|
|
4
|
+
- EventWriter: append-only JSONL writer with file locking
|
|
5
|
+
- read_events(): read events from last N hours with optional filtering
|
|
6
|
+
- cleanup_old_events(): remove events older than N days
|
|
7
|
+
- Event type constants
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import fcntl
|
|
11
|
+
import json
|
|
12
|
+
import logging
|
|
13
|
+
import os
|
|
14
|
+
from datetime import datetime, timedelta, timezone
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any, Dict, List, Optional
|
|
17
|
+
|
|
18
|
+
from ..core.paths import get_events_dir
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
# Event type constants
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
AGENT_DISPATCH = "agent.dispatch"
|
|
27
|
+
AGENT_COMPLETE = "agent.complete"
|
|
28
|
+
COMMAND_EXECUTED = "command.executed"
|
|
29
|
+
SESSION_END = "session.end"
|
|
30
|
+
TRIGGER_SCHEDULED = "trigger.scheduled"
|
|
31
|
+
HEARTBEAT = "heartbeat"
|
|
32
|
+
USER_NOTE = "user.note"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class EventWriter:
|
|
36
|
+
"""Append-only JSONL event writer with file locking.
|
|
37
|
+
|
|
38
|
+
All writes are wrapped in try/except -- events are non-critical and
|
|
39
|
+
must never block the hook pipeline.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, events_dir: Optional[Path] = None):
|
|
43
|
+
self.events_dir = events_dir or get_events_dir()
|
|
44
|
+
self.events_file = self.events_dir / "events.jsonl"
|
|
45
|
+
self.lock_file = self.events_dir / "events.jsonl.lock"
|
|
46
|
+
|
|
47
|
+
def write_event(
|
|
48
|
+
self,
|
|
49
|
+
event_type: str,
|
|
50
|
+
source: str,
|
|
51
|
+
agent: str,
|
|
52
|
+
result: str,
|
|
53
|
+
severity: str = "info",
|
|
54
|
+
meta: Optional[Dict[str, Any]] = None,
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Append a single event to the JSONL log.
|
|
57
|
+
|
|
58
|
+
Thread-safe via exclusive file lock. Fails silently on any error
|
|
59
|
+
to avoid disrupting the hook pipeline.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
event_type: Dotted event category (e.g. "agent.dispatch").
|
|
63
|
+
source: Who wrote the event (e.g. "hook").
|
|
64
|
+
agent: Agent involved, or empty string for non-agent events.
|
|
65
|
+
result: Outcome summary string.
|
|
66
|
+
severity: info | warning | error.
|
|
67
|
+
meta: Optional type-specific structured data.
|
|
68
|
+
"""
|
|
69
|
+
try:
|
|
70
|
+
self.events_dir.mkdir(parents=True, exist_ok=True)
|
|
71
|
+
|
|
72
|
+
record: Dict[str, Any] = {
|
|
73
|
+
"ts": datetime.now(timezone.utc).isoformat(),
|
|
74
|
+
"type": event_type,
|
|
75
|
+
"source": source,
|
|
76
|
+
"agent": agent,
|
|
77
|
+
"result": result,
|
|
78
|
+
"severity": severity,
|
|
79
|
+
}
|
|
80
|
+
if meta:
|
|
81
|
+
record["meta"] = meta
|
|
82
|
+
|
|
83
|
+
with open(self.lock_file, "w") as lf:
|
|
84
|
+
fcntl.flock(lf.fileno(), fcntl.LOCK_EX)
|
|
85
|
+
try:
|
|
86
|
+
with open(self.events_file, "a") as f:
|
|
87
|
+
f.write(json.dumps(record, separators=(",", ":")) + "\n")
|
|
88
|
+
finally:
|
|
89
|
+
fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
|
|
90
|
+
|
|
91
|
+
except Exception as exc:
|
|
92
|
+
logger.debug("Event write failed (non-fatal): %s", exc)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def read_events(
|
|
96
|
+
hours: int = 24,
|
|
97
|
+
event_type: Optional[str] = None,
|
|
98
|
+
limit: int = 50,
|
|
99
|
+
events_dir: Optional[Path] = None,
|
|
100
|
+
) -> List[Dict[str, Any]]:
|
|
101
|
+
"""Read recent events from the JSONL log.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
hours: How far back to look (default 24h).
|
|
105
|
+
event_type: Optional filter by event type (exact match).
|
|
106
|
+
limit: Maximum number of events to return.
|
|
107
|
+
events_dir: Override events directory (for testing).
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
List of event dicts, most recent last, capped at *limit*.
|
|
111
|
+
"""
|
|
112
|
+
try:
|
|
113
|
+
edir = events_dir or get_events_dir()
|
|
114
|
+
events_file = edir / "events.jsonl"
|
|
115
|
+
if not events_file.exists():
|
|
116
|
+
return []
|
|
117
|
+
|
|
118
|
+
cutoff = datetime.now(timezone.utc) - timedelta(hours=hours)
|
|
119
|
+
results: List[Dict[str, Any]] = []
|
|
120
|
+
|
|
121
|
+
with open(events_file, "r") as f:
|
|
122
|
+
for line in f:
|
|
123
|
+
line = line.strip()
|
|
124
|
+
if not line:
|
|
125
|
+
continue
|
|
126
|
+
try:
|
|
127
|
+
evt = json.loads(line)
|
|
128
|
+
except json.JSONDecodeError:
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
# Time filter
|
|
132
|
+
try:
|
|
133
|
+
ts = datetime.fromisoformat(evt.get("ts", ""))
|
|
134
|
+
if ts < cutoff:
|
|
135
|
+
continue
|
|
136
|
+
except (ValueError, TypeError):
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
# Type filter
|
|
140
|
+
if event_type and evt.get("type") != event_type:
|
|
141
|
+
continue
|
|
142
|
+
|
|
143
|
+
results.append(evt)
|
|
144
|
+
|
|
145
|
+
# Return the most recent events, capped at limit
|
|
146
|
+
return results[-limit:]
|
|
147
|
+
|
|
148
|
+
except Exception as exc:
|
|
149
|
+
logger.debug("Event read failed (non-fatal): %s", exc)
|
|
150
|
+
return []
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def cleanup_old_events(
|
|
154
|
+
days: int = 7,
|
|
155
|
+
events_dir: Optional[Path] = None,
|
|
156
|
+
) -> int:
|
|
157
|
+
"""Remove events older than *days* from the JSONL log.
|
|
158
|
+
|
|
159
|
+
Uses file locking to avoid conflicts with concurrent writers.
|
|
160
|
+
Retains lines that cannot be parsed (conservative).
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
days: Retention window in days (default 7).
|
|
164
|
+
events_dir: Override events directory (for testing).
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Number of events removed.
|
|
168
|
+
"""
|
|
169
|
+
try:
|
|
170
|
+
edir = events_dir or get_events_dir()
|
|
171
|
+
events_file = edir / "events.jsonl"
|
|
172
|
+
lock_file = edir / "events.jsonl.lock"
|
|
173
|
+
|
|
174
|
+
if not events_file.exists():
|
|
175
|
+
return 0
|
|
176
|
+
|
|
177
|
+
retention_days = int(os.environ.get("GAIA_EVENT_RETENTION_DAYS", str(days)))
|
|
178
|
+
cutoff = datetime.now(timezone.utc) - timedelta(days=retention_days)
|
|
179
|
+
kept: List[str] = []
|
|
180
|
+
removed = 0
|
|
181
|
+
|
|
182
|
+
with open(lock_file, "w") as lf:
|
|
183
|
+
fcntl.flock(lf.fileno(), fcntl.LOCK_EX)
|
|
184
|
+
try:
|
|
185
|
+
with open(events_file, "r") as f:
|
|
186
|
+
for line in f:
|
|
187
|
+
line = line.strip()
|
|
188
|
+
if not line:
|
|
189
|
+
continue
|
|
190
|
+
try:
|
|
191
|
+
evt = json.loads(line)
|
|
192
|
+
ts = datetime.fromisoformat(evt["ts"])
|
|
193
|
+
if ts < cutoff:
|
|
194
|
+
removed += 1
|
|
195
|
+
continue
|
|
196
|
+
except (json.JSONDecodeError, KeyError, ValueError):
|
|
197
|
+
pass # Keep unparseable lines
|
|
198
|
+
kept.append(line)
|
|
199
|
+
|
|
200
|
+
with open(events_file, "w") as f:
|
|
201
|
+
for line in kept:
|
|
202
|
+
f.write(line + "\n")
|
|
203
|
+
finally:
|
|
204
|
+
fcntl.flock(lf.fileno(), fcntl.LOCK_UN)
|
|
205
|
+
|
|
206
|
+
return removed
|
|
207
|
+
|
|
208
|
+
except Exception as exc:
|
|
209
|
+
logger.debug("Event cleanup failed (non-fatal): %s", exc)
|
|
210
|
+
return 0
|
|
@@ -2,42 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def build_ops_identity() -> str:
|
|
5
|
-
"""Build identity context for ops mode (full orchestrator).
|
|
6
|
-
|
|
7
|
-
Lightweight identity that delegates details to on-demand skills.
|
|
8
|
-
Always dispatches — never searches or executes directly.
|
|
9
|
-
"""
|
|
10
5
|
return """# Identity: Gaia Ops Orchestrator
|
|
11
6
|
|
|
12
|
-
You are a dispatcher. Users bring requests; you
|
|
13
|
-
specialist agent
|
|
7
|
+
You are a dispatcher. Users bring requests; you route to the right
|
|
8
|
+
specialist agent. You never investigate or execute yourself.
|
|
14
9
|
|
|
15
10
|
## Your tools
|
|
16
|
-
- **Agent** — dispatch
|
|
17
|
-
- **SendMessage** — resume a previously spawned agent
|
|
18
|
-
- **AskUserQuestion** — get clarification or approval
|
|
19
|
-
- **Skill** — load on-demand procedures
|
|
11
|
+
- **Agent** — dispatch to specialist agents
|
|
12
|
+
- **SendMessage** — resume a previously spawned agent
|
|
13
|
+
- **AskUserQuestion** — get clarification or approval
|
|
14
|
+
- **Skill** — load on-demand procedures (agent-response, orchestrator-approval)
|
|
20
15
|
|
|
21
16
|
## Routing
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
Each user message includes a routing recommendation. Follow it:
|
|
19
|
+
- confidence >= 0.5 — dispatch the recommended agent(s) using the dispatch_mode
|
|
20
|
+
- confidence < 0.5 — ask the user to clarify
|
|
21
|
+
- no recommendation — respond directly (general question)
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
agent
|
|
30
|
-
and present results to the user.
|
|
23
|
+
Your prompt to the agent = user's objective + info agent cannot derive.
|
|
24
|
+
Resume an active agent with SendMessage instead of creating a new one.
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
answer from loaded context, respond directly.
|
|
26
|
+
## Response Handling
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- When you see AWAITING_APPROVAL, load the orchestrator-approval skill
|
|
38
|
-
- Never synthesize nonces — they are hex tokens from the hook
|
|
28
|
+
When an agent returns a json:contract, load agent-response skill.
|
|
29
|
+
When an agent returns REVIEW with approval_id, load orchestrator-approval skill.
|
|
39
30
|
|
|
40
31
|
## Failures
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
32
|
+
- Hook blocks a command — relay message verbatim, no alternatives
|
|
33
|
+
- Routing unclear — ask the user
|
|
34
|
+
- Agents contradict — present both sides, user decides"""
|
|
@@ -6,7 +6,6 @@ session_state.py directly into this module.
|
|
|
6
6
|
|
|
7
7
|
Provides:
|
|
8
8
|
- write(): Store workflow as episodic memory
|
|
9
|
-
- capture_episodic_memory(): Backward-compatible alias for write()
|
|
10
9
|
- get_session_events(): Read context.json, categorize events
|
|
11
10
|
"""
|
|
12
11
|
|
|
@@ -170,7 +169,7 @@ def write(
|
|
|
170
169
|
outcome = "failed"
|
|
171
170
|
success = False
|
|
172
171
|
else:
|
|
173
|
-
# IN_PROGRESS, REVIEW,
|
|
172
|
+
# IN_PROGRESS, REVIEW, NEEDS_INPUT -> partial
|
|
174
173
|
outcome = "partial"
|
|
175
174
|
success = None
|
|
176
175
|
elif exit_code == 0:
|
|
@@ -226,7 +225,3 @@ def write(
|
|
|
226
225
|
except Exception as e:
|
|
227
226
|
logger.debug(f"Failed to capture episodic memory: {e}")
|
|
228
227
|
return None
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
# Backward-compatible alias
|
|
232
|
-
capture_episodic_memory = write
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Orchestrator enforcement modules.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Orchestrator delegate mode enforcement.
|
|
2
|
+
|
|
3
|
+
When GAIA is installed, delegate mode is always active. The orchestrator
|
|
4
|
+
(main session) is restricted to dispatch-only tools. Direct investigation
|
|
5
|
+
tools (Bash, Read, Edit, etc.) are blocked so the orchestrator must
|
|
6
|
+
delegate to specialist agents.
|
|
7
|
+
|
|
8
|
+
Detection: Claude Code includes ``agent_id`` and ``agent_type`` in the
|
|
9
|
+
PreToolUse payload ONLY when the hook fires inside a subagent. Their absence
|
|
10
|
+
means the call originates from the main session (orchestrator).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from typing import Any, Dict, Optional
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
# Tools the orchestrator is allowed to use in delegate mode.
|
|
22
|
+
# Everything NOT in this set is blocked for the main session.
|
|
23
|
+
ORCHESTRATOR_ALLOWED_TOOLS = frozenset({
|
|
24
|
+
# Dispatch and communication
|
|
25
|
+
"agent",
|
|
26
|
+
"task",
|
|
27
|
+
"sendmessage",
|
|
28
|
+
|
|
29
|
+
# On-demand skills / procedures
|
|
30
|
+
"skill",
|
|
31
|
+
|
|
32
|
+
# Agent teams task management
|
|
33
|
+
"taskcreate",
|
|
34
|
+
"taskupdate",
|
|
35
|
+
"tasklist",
|
|
36
|
+
"taskget",
|
|
37
|
+
|
|
38
|
+
# Tool discovery
|
|
39
|
+
"toolsearch",
|
|
40
|
+
|
|
41
|
+
# Web research (read-only, T0)
|
|
42
|
+
"websearch",
|
|
43
|
+
"webfetch",
|
|
44
|
+
|
|
45
|
+
# User interaction (built-in, may not always trigger hooks)
|
|
46
|
+
"askuserquestion",
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass(frozen=True)
|
|
51
|
+
class DelegateModeResult:
|
|
52
|
+
"""Result of delegate mode check."""
|
|
53
|
+
|
|
54
|
+
blocked: bool
|
|
55
|
+
reason: Optional[str] = None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def is_orchestrator_context(hook_payload: Dict[str, Any]) -> bool:
|
|
59
|
+
"""Determine if the hook is firing in the main session (orchestrator).
|
|
60
|
+
|
|
61
|
+
Claude Code includes ``agent_id`` in the PreToolUse payload only when
|
|
62
|
+
the tool call originates from a subagent. Its absence means the call
|
|
63
|
+
is from the main session.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
hook_payload: The full stdin JSON dict from Claude Code.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
True if this is the orchestrator (main session), False if subagent.
|
|
70
|
+
"""
|
|
71
|
+
agent_id = hook_payload.get("agent_id")
|
|
72
|
+
# agent_id is absent or empty string for the main session
|
|
73
|
+
return not agent_id
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def check_delegate_mode(
|
|
77
|
+
tool_name: str, hook_payload: Dict[str, Any]
|
|
78
|
+
) -> DelegateModeResult:
|
|
79
|
+
"""Check whether a tool call should be blocked by delegate mode.
|
|
80
|
+
|
|
81
|
+
This is the single entry point. Call it early in the PreToolUse flow.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
tool_name: The tool being invoked (e.g., "Bash", "Read", "Edit").
|
|
85
|
+
hook_payload: The full stdin JSON dict from Claude Code.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
DelegateModeResult with blocked=True and a reason if the call
|
|
89
|
+
should be denied, or blocked=False if it should proceed.
|
|
90
|
+
"""
|
|
91
|
+
is_orchestrator = is_orchestrator_context(hook_payload)
|
|
92
|
+
if not is_orchestrator:
|
|
93
|
+
# Subagents have full tool access -- delegate mode does not apply
|
|
94
|
+
agent_id = hook_payload.get("agent_id", "<none>")
|
|
95
|
+
logger.debug(
|
|
96
|
+
"delegate_mode check: SKIP (subagent %s) tool=%s",
|
|
97
|
+
agent_id,
|
|
98
|
+
tool_name,
|
|
99
|
+
)
|
|
100
|
+
return DelegateModeResult(blocked=False)
|
|
101
|
+
|
|
102
|
+
normalized = tool_name.lower().strip()
|
|
103
|
+
if normalized in ORCHESTRATOR_ALLOWED_TOOLS:
|
|
104
|
+
logger.debug(
|
|
105
|
+
"delegate_mode check: ALLOW (orchestrator allowed tool) tool=%s",
|
|
106
|
+
tool_name,
|
|
107
|
+
)
|
|
108
|
+
return DelegateModeResult(blocked=False)
|
|
109
|
+
|
|
110
|
+
logger.warning(
|
|
111
|
+
"DELEGATE_MODE blocked tool '%s' for orchestrator (main session)",
|
|
112
|
+
tool_name,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
return DelegateModeResult(
|
|
116
|
+
blocked=True,
|
|
117
|
+
reason=(
|
|
118
|
+
f"[DELEGATE MODE] Tool '{tool_name}' is not available to the orchestrator.\n\n"
|
|
119
|
+
f"As the orchestrator, you must delegate work to specialist agents.\n"
|
|
120
|
+
f"Use the Agent tool to dispatch to the appropriate agent, or use\n"
|
|
121
|
+
f"SendMessage to resume an existing agent.\n\n"
|
|
122
|
+
f"Allowed orchestrator tools: Agent, SendMessage, Skill, TaskCreate, "
|
|
123
|
+
f"TaskUpdate, TaskList, TaskGet, ToolSearch, WebSearch, WebFetch, "
|
|
124
|
+
f"AskUserQuestion.\n\n"
|
|
125
|
+
f"Do NOT attempt to use {tool_name} directly. Identify the right\n"
|
|
126
|
+
f"specialist agent and delegate the work."
|
|
127
|
+
),
|
|
128
|
+
)
|
|
@@ -4,9 +4,9 @@ Security module - Security tiers, blocked patterns, mutative verb detection.
|
|
|
4
4
|
Provides:
|
|
5
5
|
- tiers: SecurityTier enum and classification
|
|
6
6
|
- blocked_commands: Permanently blocked pattern matching
|
|
7
|
-
- mutative_verbs: Mutative verb detection (
|
|
7
|
+
- mutative_verbs: Mutative verb detection (user approval workflow)
|
|
8
8
|
- gitops_validator: kubectl/helm/flux validation
|
|
9
|
-
- approval_constants:
|
|
9
|
+
- approval_constants: Approval token patterns (legacy APPROVE: and ElicitationResult)
|
|
10
10
|
- approval_grants: Time-limited T3 command passthrough after user approval
|
|
11
11
|
"""
|
|
12
12
|
|
|
@@ -32,7 +32,6 @@ from .approval_messages import (
|
|
|
32
32
|
CANONICAL_APPROVAL_TOKEN_GUIDANCE,
|
|
33
33
|
CANONICAL_APPROVAL_FORMAT_GUIDANCE,
|
|
34
34
|
LATEST_BLOCKED_COMMAND_PHRASE,
|
|
35
|
-
AWAITING_APPROVAL_STATUS,
|
|
36
35
|
)
|
|
37
36
|
from .approval_scopes import (
|
|
38
37
|
ApprovalSignature,
|
|
@@ -76,7 +75,6 @@ __all__ = [
|
|
|
76
75
|
"CANONICAL_APPROVAL_TOKEN_GUIDANCE",
|
|
77
76
|
"CANONICAL_APPROVAL_FORMAT_GUIDANCE",
|
|
78
77
|
"LATEST_BLOCKED_COMMAND_PHRASE",
|
|
79
|
-
"AWAITING_APPROVAL_STATUS",
|
|
80
78
|
"ApprovalSignature",
|
|
81
79
|
"SCOPE_EXACT_COMMAND",
|
|
82
80
|
"SCOPE_SEMANTIC_SIGNATURE",
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Approval token patterns and deprecated approval phrases for T3 operation resumes.
|
|
2
|
+
|
|
3
|
+
The APPROVE: prefix is a legacy path (SendMessage-based nonce relay). The primary
|
|
4
|
+
approval flow now uses ElicitationResult (AskUserQuestion -> user clicks Approve).
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
import re
|
|
4
8
|
|