@jaguilar87/gaia 5.0.0-rc1
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 +33 -0
- package/.claude-plugin/plugin.json +26 -0
- package/ARCHITECTURE.md +335 -0
- package/CHANGELOG.md +1212 -0
- package/CODE_OF_CONDUCT.md +11 -0
- package/CONTRIBUTING.md +146 -0
- package/INSTALL.md +436 -0
- package/LICENSE +21 -0
- package/README.md +222 -0
- package/SECURITY.md +47 -0
- package/agents/README.md +78 -0
- package/agents/cloud-troubleshooter.md +73 -0
- package/agents/developer.md +65 -0
- package/agents/gaia-operator.md +64 -0
- package/agents/gaia-orchestrator.md +237 -0
- package/agents/gaia-planner.md +53 -0
- package/agents/gaia-system.md +70 -0
- package/agents/gitops-operator.md +61 -0
- package/agents/terraform-architect.md +63 -0
- package/bin/README.md +106 -0
- package/bin/cli/__init__.py +1 -0
- package/bin/cli/approvals.py +740 -0
- package/bin/cli/cleanup.py +562 -0
- package/bin/cli/context.py +283 -0
- package/bin/cli/doctor.py +628 -0
- package/bin/cli/history.py +305 -0
- package/bin/cli/memory.py +464 -0
- package/bin/cli/metrics.py +1068 -0
- package/bin/cli/plans.py +515 -0
- package/bin/cli/status.py +302 -0
- package/bin/cli/update.py +382 -0
- package/bin/gaia +112 -0
- package/bin/gaia-cleanup.js +531 -0
- package/bin/gaia-doctor.js +635 -0
- package/bin/gaia-evidence +126 -0
- package/bin/gaia-history.js +251 -0
- package/bin/gaia-metrics.js +1278 -0
- package/bin/gaia-review.js +269 -0
- package/bin/gaia-scan +44 -0
- package/bin/gaia-scan.py +589 -0
- package/bin/gaia-skills-diagnose.js +929 -0
- package/bin/gaia-status.js +278 -0
- package/bin/gaia-uninstall.js +111 -0
- package/bin/gaia-update.js +816 -0
- package/bin/pre-publish-validate.js +610 -0
- package/bin/python-detect.js +60 -0
- package/commands/README.md +64 -0
- package/commands/gaia.md +37 -0
- package/commands/scan-project.md +67 -0
- package/config/README.md +71 -0
- package/config/cloud/aws.json +134 -0
- package/config/cloud/gcp.json +139 -0
- package/config/context-contracts.json +158 -0
- package/config/crons-schema.md +81 -0
- package/config/git_standards.json +72 -0
- package/config/surface-routing.json +421 -0
- package/config/universal-rules.json +102 -0
- package/dist/gaia-ops/.claude-plugin/plugin.json +24 -0
- package/dist/gaia-ops/README.md +80 -0
- package/dist/gaia-ops/agents/cloud-troubleshooter.md +73 -0
- package/dist/gaia-ops/agents/developer.md +65 -0
- package/dist/gaia-ops/agents/gaia-operator.md +64 -0
- package/dist/gaia-ops/agents/gaia-orchestrator.md +237 -0
- package/dist/gaia-ops/agents/gaia-planner.md +53 -0
- package/dist/gaia-ops/agents/gaia-system.md +70 -0
- package/dist/gaia-ops/agents/gitops-operator.md +61 -0
- package/dist/gaia-ops/agents/terraform-architect.md +63 -0
- package/dist/gaia-ops/commands/gaia.md +37 -0
- package/dist/gaia-ops/config/README.md +71 -0
- package/dist/gaia-ops/config/cloud/aws.json +134 -0
- package/dist/gaia-ops/config/cloud/gcp.json +139 -0
- package/dist/gaia-ops/config/context-contracts.json +158 -0
- package/dist/gaia-ops/config/crons-schema.md +81 -0
- package/dist/gaia-ops/config/git_standards.json +72 -0
- package/dist/gaia-ops/config/surface-routing.json +421 -0
- package/dist/gaia-ops/config/universal-rules.json +102 -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 +1890 -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 +163 -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 +120 -0
- package/dist/gaia-ops/hooks/modules/agents/state_tracker.py +267 -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 +611 -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/agentic_loop_detector.py +165 -0
- package/dist/gaia-ops/hooks/modules/context/anchor_tracker.py +317 -0
- package/dist/gaia-ops/hooks/modules/context/compact_context_builder.py +218 -0
- package/dist/gaia-ops/hooks/modules/context/context_freshness.py +145 -0
- package/dist/gaia-ops/hooks/modules/context/context_injector.py +558 -0
- package/dist/gaia-ops/hooks/modules/context/context_writer.py +530 -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 +577 -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/memory/__init__.py +8 -0
- package/dist/gaia-ops/hooks/modules/memory/episode_writer.py +216 -0
- package/dist/gaia-ops/hooks/modules/orchestrator/__init__.py +1 -0
- package/dist/gaia-ops/hooks/modules/orchestrator/delegate_mode.py +122 -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 +120 -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 +1638 -0
- package/dist/gaia-ops/hooks/modules/security/approval_messages.py +71 -0
- package/dist/gaia-ops/hooks/modules/security/approval_scopes.py +222 -0
- package/dist/gaia-ops/hooks/modules/security/blocked_commands.py +595 -0
- package/dist/gaia-ops/hooks/modules/security/blocked_message_formatter.py +87 -0
- package/dist/gaia-ops/hooks/modules/security/command_semantics.py +181 -0
- package/dist/gaia-ops/hooks/modules/security/composition_rules.py +547 -0
- package/dist/gaia-ops/hooks/modules/security/flag_classifiers.py +873 -0
- package/dist/gaia-ops/hooks/modules/security/gitops_validator.py +179 -0
- package/dist/gaia-ops/hooks/modules/security/mutative_verbs.py +1131 -0
- package/dist/gaia-ops/hooks/modules/security/network_hosts.py +481 -0
- package/dist/gaia-ops/hooks/modules/security/prompt_validator.py +40 -0
- package/dist/gaia-ops/hooks/modules/security/shell_unwrapper.py +165 -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/pending_scanner.py +174 -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 +160 -0
- package/dist/gaia-ops/hooks/modules/session/session_manager.py +31 -0
- package/dist/gaia-ops/hooks/modules/session/session_registry.py +232 -0
- package/dist/gaia-ops/hooks/modules/tools/__init__.py +29 -0
- package/dist/gaia-ops/hooks/modules/tools/bash_validator.py +1008 -0
- package/dist/gaia-ops/hooks/modules/tools/cloud_pipe_validator.py +231 -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/stage_decomposer.py +315 -0
- package/dist/gaia-ops/hooks/modules/tools/task_validator.py +294 -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_compact.py +60 -0
- package/dist/gaia-ops/hooks/pre_tool_use.py +413 -0
- package/dist/gaia-ops/hooks/session_start.py +81 -0
- package/dist/gaia-ops/hooks/stop_hook.py +82 -0
- package/dist/gaia-ops/hooks/subagent_start.py +71 -0
- package/dist/gaia-ops/hooks/subagent_stop.py +295 -0
- package/dist/gaia-ops/hooks/task_completed.py +70 -0
- package/dist/gaia-ops/hooks/user_prompt_submit.py +246 -0
- package/dist/gaia-ops/settings.json +72 -0
- package/dist/gaia-ops/skills/README.md +154 -0
- package/dist/gaia-ops/skills/agent-protocol/SKILL.md +93 -0
- package/dist/gaia-ops/skills/agent-protocol/examples.md +223 -0
- package/dist/gaia-ops/skills/agent-response/SKILL.md +69 -0
- package/dist/gaia-ops/skills/agentic-loop/SKILL.md +80 -0
- package/dist/gaia-ops/skills/agentic-loop/reference.md +378 -0
- package/dist/gaia-ops/skills/blog-writing/SKILL.md +98 -0
- package/dist/gaia-ops/skills/blog-writing/reference.md +130 -0
- package/dist/gaia-ops/skills/brief-spec/SKILL.md +182 -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 +87 -0
- package/dist/gaia-ops/skills/context-updater/examples.md +71 -0
- package/dist/gaia-ops/skills/developer-patterns/SKILL.md +50 -0
- package/dist/gaia-ops/skills/developer-patterns/reference.md +112 -0
- package/dist/gaia-ops/skills/execution/SKILL.md +99 -0
- package/dist/gaia-ops/skills/fast-queries/SKILL.md +43 -0
- package/dist/gaia-ops/skills/gaia-compact/SKILL.md +74 -0
- package/dist/gaia-ops/skills/gaia-patterns/SKILL.md +108 -0
- package/dist/gaia-ops/skills/gaia-patterns/reference.md +395 -0
- package/dist/gaia-ops/skills/gaia-planner/SKILL.md +37 -0
- package/dist/gaia-ops/skills/gaia-planner/reference.md +107 -0
- package/dist/gaia-ops/skills/gaia-release/SKILL.md +82 -0
- package/dist/gaia-ops/skills/gaia-release/reference.md +102 -0
- package/dist/gaia-ops/skills/gaia-self-check/SKILL.md +114 -0
- package/dist/gaia-ops/skills/gaia-self-check/reference.md +453 -0
- package/dist/gaia-ops/skills/gaia-verify/SKILL.md +77 -0
- package/dist/gaia-ops/skills/gaia-verify/reference.md +80 -0
- package/dist/gaia-ops/skills/git-conventions/SKILL.md +47 -0
- package/dist/gaia-ops/skills/gitops-patterns/SKILL.md +60 -0
- package/dist/gaia-ops/skills/gitops-patterns/reference.md +183 -0
- package/dist/gaia-ops/skills/gmail-policy/SKILL.md +200 -0
- package/dist/gaia-ops/skills/gmail-policy/reference.md +150 -0
- package/dist/gaia-ops/skills/gmail-triage/SKILL.md +100 -0
- package/dist/gaia-ops/skills/gws-setup/SKILL.md +99 -0
- package/dist/gaia-ops/skills/gws-setup/reference.md +73 -0
- package/dist/gaia-ops/skills/investigation/SKILL.md +100 -0
- package/dist/gaia-ops/skills/memory-curation/SKILL.md +83 -0
- package/dist/gaia-ops/skills/memory-search/SKILL.md +88 -0
- package/dist/gaia-ops/skills/orchestrator-approval/SKILL.md +160 -0
- package/dist/gaia-ops/skills/orchestrator-approval/reference.md +174 -0
- package/dist/gaia-ops/skills/pending-approvals/SKILL.md +72 -0
- package/dist/gaia-ops/skills/pending-approvals/reference.md +214 -0
- package/dist/gaia-ops/skills/readme-writing/SKILL.md +71 -0
- package/dist/gaia-ops/skills/readme-writing/reference.md +188 -0
- package/dist/gaia-ops/skills/reference.md +135 -0
- package/dist/gaia-ops/skills/request-approval/SKILL.md +140 -0
- package/dist/gaia-ops/skills/request-approval/examples.md +140 -0
- package/dist/gaia-ops/skills/request-approval/reference.md +57 -0
- package/dist/gaia-ops/skills/schedule-task/SKILL.md +64 -0
- package/dist/gaia-ops/skills/schedule-task/reference.md +233 -0
- package/dist/gaia-ops/skills/security-tiers/SKILL.md +141 -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 +92 -0
- package/dist/gaia-ops/skills/skill-creation/reference.md +29 -0
- package/dist/gaia-ops/skills/terraform-patterns/SKILL.md +89 -0
- package/dist/gaia-ops/skills/terraform-patterns/reference.md +93 -0
- package/dist/gaia-ops/tools/__init__.py +9 -0
- package/dist/gaia-ops/tools/agentic-loop/decide-status.py +210 -0
- package/dist/gaia-ops/tools/agentic-loop/parse-metric.py +106 -0
- package/dist/gaia-ops/tools/agentic-loop/record-iteration.py +221 -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 +721 -0
- package/dist/gaia-ops/tools/context/context_section_reader.py +342 -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 +264 -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/backfill_fts5.py +107 -0
- package/dist/gaia-ops/tools/memory/conflict_detector.py +295 -0
- package/dist/gaia-ops/tools/memory/episodic.py +1210 -0
- package/dist/gaia-ops/tools/memory/git_invalidator.py +262 -0
- package/dist/gaia-ops/tools/memory/paths.py +102 -0
- package/dist/gaia-ops/tools/memory/scoring.py +193 -0
- package/dist/gaia-ops/tools/memory/search_store.py +360 -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 +349 -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 +686 -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 +270 -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 +24 -0
- package/dist/gaia-security/README.md +90 -0
- package/dist/gaia-security/config/universal-rules.json +102 -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 +1890 -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 +84 -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 +120 -0
- package/dist/gaia-security/hooks/modules/agents/state_tracker.py +267 -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 +611 -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/agentic_loop_detector.py +165 -0
- package/dist/gaia-security/hooks/modules/context/anchor_tracker.py +317 -0
- package/dist/gaia-security/hooks/modules/context/compact_context_builder.py +218 -0
- package/dist/gaia-security/hooks/modules/context/context_freshness.py +145 -0
- package/dist/gaia-security/hooks/modules/context/context_injector.py +558 -0
- package/dist/gaia-security/hooks/modules/context/context_writer.py +530 -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 +577 -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/memory/__init__.py +8 -0
- package/dist/gaia-security/hooks/modules/memory/episode_writer.py +216 -0
- package/dist/gaia-security/hooks/modules/orchestrator/__init__.py +1 -0
- package/dist/gaia-security/hooks/modules/orchestrator/delegate_mode.py +122 -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 +120 -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 +1638 -0
- package/dist/gaia-security/hooks/modules/security/approval_messages.py +71 -0
- package/dist/gaia-security/hooks/modules/security/approval_scopes.py +222 -0
- package/dist/gaia-security/hooks/modules/security/blocked_commands.py +595 -0
- package/dist/gaia-security/hooks/modules/security/blocked_message_formatter.py +87 -0
- package/dist/gaia-security/hooks/modules/security/command_semantics.py +181 -0
- package/dist/gaia-security/hooks/modules/security/composition_rules.py +547 -0
- package/dist/gaia-security/hooks/modules/security/flag_classifiers.py +873 -0
- package/dist/gaia-security/hooks/modules/security/gitops_validator.py +179 -0
- package/dist/gaia-security/hooks/modules/security/mutative_verbs.py +1131 -0
- package/dist/gaia-security/hooks/modules/security/network_hosts.py +481 -0
- package/dist/gaia-security/hooks/modules/security/prompt_validator.py +40 -0
- package/dist/gaia-security/hooks/modules/security/shell_unwrapper.py +165 -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/pending_scanner.py +174 -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 +160 -0
- package/dist/gaia-security/hooks/modules/session/session_manager.py +31 -0
- package/dist/gaia-security/hooks/modules/session/session_registry.py +232 -0
- package/dist/gaia-security/hooks/modules/tools/__init__.py +29 -0
- package/dist/gaia-security/hooks/modules/tools/bash_validator.py +1008 -0
- package/dist/gaia-security/hooks/modules/tools/cloud_pipe_validator.py +231 -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/stage_decomposer.py +315 -0
- package/dist/gaia-security/hooks/modules/tools/task_validator.py +294 -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 +413 -0
- package/dist/gaia-security/hooks/session_start.py +81 -0
- package/dist/gaia-security/hooks/stop_hook.py +82 -0
- package/dist/gaia-security/hooks/user_prompt_submit.py +246 -0
- package/dist/gaia-security/settings.json +58 -0
- package/git-hooks/commit-msg +41 -0
- package/hooks/README.md +100 -0
- package/hooks/adapters/__init__.py +52 -0
- package/hooks/adapters/base.py +219 -0
- package/hooks/adapters/channel.py +17 -0
- package/hooks/adapters/claude_code.py +1890 -0
- package/hooks/adapters/types.py +194 -0
- package/hooks/adapters/utils.py +25 -0
- package/hooks/elicitation_result.py +179 -0
- package/hooks/hooks.json +84 -0
- package/hooks/modules/README.md +189 -0
- package/hooks/modules/__init__.py +15 -0
- package/hooks/modules/agents/__init__.py +29 -0
- package/hooks/modules/agents/contract_validator.py +647 -0
- package/hooks/modules/agents/response_contract.py +496 -0
- package/hooks/modules/agents/skill_injection_verifier.py +120 -0
- package/hooks/modules/agents/state_tracker.py +267 -0
- package/hooks/modules/agents/task_info_builder.py +74 -0
- package/hooks/modules/agents/transcript_analyzer.py +458 -0
- package/hooks/modules/agents/transcript_reader.py +152 -0
- package/hooks/modules/audit/__init__.py +28 -0
- package/hooks/modules/audit/event_detector.py +168 -0
- package/hooks/modules/audit/logger.py +131 -0
- package/hooks/modules/audit/metrics.py +134 -0
- package/hooks/modules/audit/workflow_auditor.py +611 -0
- package/hooks/modules/audit/workflow_recorder.py +296 -0
- package/hooks/modules/context/__init__.py +11 -0
- package/hooks/modules/context/agentic_loop_detector.py +165 -0
- package/hooks/modules/context/anchor_tracker.py +317 -0
- package/hooks/modules/context/compact_context_builder.py +218 -0
- package/hooks/modules/context/context_freshness.py +145 -0
- package/hooks/modules/context/context_injector.py +558 -0
- package/hooks/modules/context/context_writer.py +530 -0
- package/hooks/modules/context/contracts_loader.py +161 -0
- package/hooks/modules/core/__init__.py +40 -0
- package/hooks/modules/core/hook_entry.py +78 -0
- package/hooks/modules/core/paths.py +160 -0
- package/hooks/modules/core/plugin_mode.py +149 -0
- package/hooks/modules/core/plugin_setup.py +577 -0
- package/hooks/modules/core/state.py +179 -0
- package/hooks/modules/core/stdin.py +24 -0
- package/hooks/modules/events/__init__.py +1 -0
- package/hooks/modules/events/event_writer.py +210 -0
- package/hooks/modules/evidence/__init__.py +34 -0
- package/hooks/modules/evidence/assertions.py +137 -0
- package/hooks/modules/evidence/index_writer.py +57 -0
- package/hooks/modules/evidence/loader.py +126 -0
- package/hooks/modules/evidence/runner.py +241 -0
- package/hooks/modules/memory/__init__.py +8 -0
- package/hooks/modules/memory/episode_writer.py +216 -0
- package/hooks/modules/orchestrator/__init__.py +1 -0
- package/hooks/modules/orchestrator/delegate_mode.py +122 -0
- package/hooks/modules/scanning/__init__.py +8 -0
- package/hooks/modules/scanning/scan_trigger.py +84 -0
- package/hooks/modules/security/__init__.py +120 -0
- package/hooks/modules/security/approval_cleanup.py +87 -0
- package/hooks/modules/security/approval_constants.py +23 -0
- package/hooks/modules/security/approval_grants.py +1638 -0
- package/hooks/modules/security/approval_messages.py +71 -0
- package/hooks/modules/security/approval_scopes.py +222 -0
- package/hooks/modules/security/blocked_commands.py +595 -0
- package/hooks/modules/security/blocked_message_formatter.py +87 -0
- package/hooks/modules/security/command_semantics.py +181 -0
- package/hooks/modules/security/composition_rules.py +547 -0
- package/hooks/modules/security/flag_classifiers.py +873 -0
- package/hooks/modules/security/gitops_validator.py +179 -0
- package/hooks/modules/security/mutative_verbs.py +1131 -0
- package/hooks/modules/security/network_hosts.py +481 -0
- package/hooks/modules/security/prompt_validator.py +40 -0
- package/hooks/modules/security/shell_unwrapper.py +165 -0
- package/hooks/modules/security/tiers.py +196 -0
- package/hooks/modules/session/__init__.py +10 -0
- package/hooks/modules/session/pending_scanner.py +174 -0
- package/hooks/modules/session/session_context_writer.py +100 -0
- package/hooks/modules/session/session_event_injector.py +160 -0
- package/hooks/modules/session/session_manager.py +31 -0
- package/hooks/modules/session/session_registry.py +232 -0
- package/hooks/modules/tools/__init__.py +29 -0
- package/hooks/modules/tools/bash_validator.py +1008 -0
- package/hooks/modules/tools/cloud_pipe_validator.py +231 -0
- package/hooks/modules/tools/hook_response.py +55 -0
- package/hooks/modules/tools/shell_parser.py +227 -0
- package/hooks/modules/tools/stage_decomposer.py +315 -0
- package/hooks/modules/tools/task_validator.py +294 -0
- package/hooks/modules/validation/__init__.py +23 -0
- package/hooks/modules/validation/commit_validator.py +380 -0
- package/hooks/post_compact.py +43 -0
- package/hooks/post_tool_use.py +54 -0
- package/hooks/pre_compact.py +60 -0
- package/hooks/pre_tool_use.py +413 -0
- package/hooks/session_start.py +81 -0
- package/hooks/stop_hook.py +82 -0
- package/hooks/subagent_start.py +71 -0
- package/hooks/subagent_stop.py +295 -0
- package/hooks/task_completed.py +70 -0
- package/hooks/user_prompt_submit.py +246 -0
- package/index.js +83 -0
- package/package.json +99 -0
- package/pyproject.toml +32 -0
- package/skills/README.md +154 -0
- package/skills/agent-protocol/SKILL.md +93 -0
- package/skills/agent-protocol/examples.md +223 -0
- package/skills/agent-response/SKILL.md +69 -0
- package/skills/agentic-loop/SKILL.md +80 -0
- package/skills/agentic-loop/reference.md +378 -0
- package/skills/blog-writing/SKILL.md +98 -0
- package/skills/blog-writing/reference.md +130 -0
- package/skills/brief-spec/SKILL.md +182 -0
- package/skills/command-execution/SKILL.md +64 -0
- package/skills/command-execution/reference.md +83 -0
- package/skills/context-updater/SKILL.md +87 -0
- package/skills/context-updater/examples.md +71 -0
- package/skills/developer-patterns/SKILL.md +50 -0
- package/skills/developer-patterns/reference.md +112 -0
- package/skills/execution/SKILL.md +99 -0
- package/skills/fast-queries/SKILL.md +43 -0
- package/skills/gaia-compact/SKILL.md +74 -0
- package/skills/gaia-patterns/SKILL.md +108 -0
- package/skills/gaia-patterns/reference.md +395 -0
- package/skills/gaia-planner/SKILL.md +37 -0
- package/skills/gaia-planner/reference.md +107 -0
- package/skills/gaia-release/SKILL.md +82 -0
- package/skills/gaia-release/reference.md +102 -0
- package/skills/gaia-self-check/SKILL.md +114 -0
- package/skills/gaia-self-check/reference.md +453 -0
- package/skills/gaia-verify/SKILL.md +77 -0
- package/skills/gaia-verify/reference.md +80 -0
- package/skills/git-conventions/SKILL.md +47 -0
- package/skills/gitops-patterns/SKILL.md +60 -0
- package/skills/gitops-patterns/reference.md +183 -0
- package/skills/gmail-policy/SKILL.md +200 -0
- package/skills/gmail-policy/reference.md +150 -0
- package/skills/gmail-triage/SKILL.md +100 -0
- package/skills/gws-setup/SKILL.md +99 -0
- package/skills/gws-setup/reference.md +73 -0
- package/skills/investigation/SKILL.md +100 -0
- package/skills/memory-curation/SKILL.md +83 -0
- package/skills/memory-search/SKILL.md +88 -0
- package/skills/orchestrator-approval/SKILL.md +160 -0
- package/skills/orchestrator-approval/reference.md +174 -0
- package/skills/pending-approvals/SKILL.md +72 -0
- package/skills/pending-approvals/reference.md +214 -0
- package/skills/readme-writing/SKILL.md +71 -0
- package/skills/readme-writing/reference.md +188 -0
- package/skills/reference.md +135 -0
- package/skills/request-approval/SKILL.md +140 -0
- package/skills/request-approval/examples.md +140 -0
- package/skills/request-approval/reference.md +57 -0
- package/skills/schedule-task/SKILL.md +64 -0
- package/skills/schedule-task/reference.md +233 -0
- package/skills/security-tiers/SKILL.md +141 -0
- package/skills/security-tiers/destructive-commands-reference.md +623 -0
- package/skills/security-tiers/reference.md +39 -0
- package/skills/skill-creation/SKILL.md +92 -0
- package/skills/skill-creation/reference.md +29 -0
- package/skills/terraform-patterns/SKILL.md +89 -0
- package/skills/terraform-patterns/reference.md +93 -0
- package/templates/README.md +69 -0
- package/templates/managed-settings.template.json +43 -0
- package/tools/__init__.py +9 -0
- package/tools/agentic-loop/decide-status.py +210 -0
- package/tools/agentic-loop/parse-metric.py +106 -0
- package/tools/agentic-loop/record-iteration.py +221 -0
- package/tools/context/README.md +132 -0
- package/tools/context/__init__.py +42 -0
- package/tools/context/_paths.py +20 -0
- package/tools/context/context_provider.py +721 -0
- package/tools/context/context_section_reader.py +342 -0
- package/tools/context/deep_merge.py +159 -0
- package/tools/context/pending_updates.py +760 -0
- package/tools/context/surface_router.py +278 -0
- package/tools/fast-queries/README.md +65 -0
- package/tools/fast-queries/__init__.py +30 -0
- package/tools/fast-queries/appservices/quicktriage_devops_developer.sh +75 -0
- package/tools/fast-queries/cloud/aws/quicktriage_aws_troubleshooter.sh +32 -0
- package/tools/fast-queries/cloud/gcp/quicktriage_gcp_troubleshooter.sh +88 -0
- package/tools/fast-queries/gitops/quicktriage_gitops_operator.sh +48 -0
- package/tools/fast-queries/run_triage.sh +59 -0
- package/tools/fast-queries/terraform/quicktriage_terraform_architect.sh +80 -0
- package/tools/gaia_simulator/__init__.py +33 -0
- package/tools/gaia_simulator/cli.py +354 -0
- package/tools/gaia_simulator/extractor.py +457 -0
- package/tools/gaia_simulator/reporter.py +258 -0
- package/tools/gaia_simulator/routing_simulator.py +334 -0
- package/tools/gaia_simulator/runner.py +539 -0
- package/tools/gaia_simulator/skills_mapper.py +264 -0
- package/tools/memory/README.md +0 -0
- package/tools/memory/__init__.py +20 -0
- package/tools/memory/backfill_fts5.py +107 -0
- package/tools/memory/conflict_detector.py +295 -0
- package/tools/memory/episodic.py +1210 -0
- package/tools/memory/git_invalidator.py +262 -0
- package/tools/memory/paths.py +102 -0
- package/tools/memory/scoring.py +193 -0
- package/tools/memory/search_store.py +360 -0
- package/tools/persist_transcript_analysis.py +85 -0
- package/tools/review/__init__.py +1 -0
- package/tools/review/review_engine.py +157 -0
- package/tools/scan/__init__.py +35 -0
- package/tools/scan/config.py +247 -0
- package/tools/scan/merge.py +212 -0
- package/tools/scan/orchestrator.py +549 -0
- package/tools/scan/registry.py +127 -0
- package/tools/scan/scanners/__init__.py +18 -0
- package/tools/scan/scanners/base.py +137 -0
- package/tools/scan/scanners/environment.py +349 -0
- package/tools/scan/scanners/git.py +570 -0
- package/tools/scan/scanners/infrastructure.py +875 -0
- package/tools/scan/scanners/orchestration.py +600 -0
- package/tools/scan/scanners/stack.py +1085 -0
- package/tools/scan/scanners/tools.py +260 -0
- package/tools/scan/setup.py +686 -0
- package/tools/scan/tests/__init__.py +1 -0
- package/tools/scan/tests/conftest.py +796 -0
- package/tools/scan/tests/test_environment.py +323 -0
- package/tools/scan/tests/test_git.py +419 -0
- package/tools/scan/tests/test_infrastructure.py +382 -0
- package/tools/scan/tests/test_integration.py +920 -0
- package/tools/scan/tests/test_merge.py +269 -0
- package/tools/scan/tests/test_orchestration.py +304 -0
- package/tools/scan/tests/test_stack.py +604 -0
- package/tools/scan/tests/test_tools.py +349 -0
- package/tools/scan/ui.py +624 -0
- package/tools/scan/verify.py +270 -0
- package/tools/scan/walk.py +118 -0
- package/tools/scan/workspace.py +85 -0
- package/tools/validation/README.md +244 -0
- package/tools/validation/__init__.py +17 -0
- package/tools/validation/approval_gate.py +321 -0
- package/tools/validation/validate_skills.py +189 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-creation
|
|
3
|
+
description: Use when creating a new skill, improving an existing skill, or deciding what a skill should contain and how it should be structured
|
|
4
|
+
metadata:
|
|
5
|
+
user-invocable: false
|
|
6
|
+
type: technique
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Skill Creation
|
|
10
|
+
|
|
11
|
+
## What is a skill?
|
|
12
|
+
|
|
13
|
+
Injected procedural knowledge -- the "how" for agents. The agent brings identity and domain knowledge. The skill brings process and protocol. They never duplicate each other.
|
|
14
|
+
|
|
15
|
+
## Step 1: Choose the type
|
|
16
|
+
|
|
17
|
+
Type determines structure. Choose before writing anything.
|
|
18
|
+
|
|
19
|
+
| Type | Purpose | When it applies |
|
|
20
|
+
|------|---------|-----------------|
|
|
21
|
+
| **Discipline** | Enforces rules the agent will rationalize around under pressure | command-execution, execution |
|
|
22
|
+
| **Technique** | How to think about or approach a class of problem | investigation, approval |
|
|
23
|
+
| **Reference** | Lookup tables, classifications, format specifications | security-tiers, fast-queries, git-conventions |
|
|
24
|
+
| **Domain** | Project-specific patterns for a technical area | terraform-patterns, gitops-patterns |
|
|
25
|
+
| **Protocol** | System operating contract -- state machines, mandatory formats | agent-protocol |
|
|
26
|
+
|
|
27
|
+
## Step 2: Apply the type structure
|
|
28
|
+
|
|
29
|
+
**Discipline:** Iron Law -> Mental Model -> Rules -> Traps -> Anti-patterns. Every trap you leave unnamed is a loophole.
|
|
30
|
+
|
|
31
|
+
**Technique:** Overview (core principle + when to use) -> Process (numbered steps) -> Anti-patterns.
|
|
32
|
+
|
|
33
|
+
**Reference:** Quick-scan table at top -> Examples -> Edge cases / special rules.
|
|
34
|
+
|
|
35
|
+
**Domain:** Conventions (naming, structure) -> Examples/snippets -> Key rules -> links to reference files.
|
|
36
|
+
|
|
37
|
+
**Protocol:** State machine / flow -> Mandatory format -> State transitions -> Error handling.
|
|
38
|
+
|
|
39
|
+
## Step 3: Write for judgment, not compliance
|
|
40
|
+
|
|
41
|
+
A rule without context ("ALWAYS do X") carries almost no weight in the LLM's reasoning -- the model has no reason to prioritize it over competing signals. An explanation with consequences carries enough weight to influence decisions even under pressure. Every line competes for attention; earn each one with reasoning the model can use.
|
|
42
|
+
|
|
43
|
+
The test: for each rule, ask -- if the agent saw enough examples of this going wrong, would it reach the same conclusion? If yes, you are capturing genuine wisdom. If no, it needs more context.
|
|
44
|
+
|
|
45
|
+
For detailed guidance on tone by type (discipline, technique, domain, reference, protocol) and connection to the gaia-patterns design philosophy, see `reference.md`.
|
|
46
|
+
|
|
47
|
+
## Step 4: Write the description field
|
|
48
|
+
|
|
49
|
+
The description determines when the agent reads the skill. It contains **triggering conditions only** -- describing the process causes the agent to follow the description and skip reading the content.
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
# Bad -- summarizes process, agent skips content
|
|
53
|
+
description: Defensive command execution - timeout protection, pipe avoidance, safe shell patterns
|
|
54
|
+
|
|
55
|
+
# Good -- triggering conditions only
|
|
56
|
+
description: Use when executing any bash command, cloud CLI, or shell operation
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Step 5: Respect the line budget
|
|
60
|
+
|
|
61
|
+
| Injection method | Budget | Reason |
|
|
62
|
+
|-----------------|--------|--------|
|
|
63
|
+
| Frontmatter (always loaded) | < 100 lines | Loaded on every agent call |
|
|
64
|
+
| On-demand (read from disk) | < 500 lines | Loaded only when explicitly needed |
|
|
65
|
+
|
|
66
|
+
Heavy reference material -> `reference.md` (on-demand). Concrete examples -> `examples.md`. Executable tools -> `scripts/`.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
skill-name/
|
|
70
|
+
├── SKILL.md <- main content (always loaded)
|
|
71
|
+
├── reference.md <- heavy docs (on-demand)
|
|
72
|
+
├── examples.md <- concrete examples (on-demand)
|
|
73
|
+
└── scripts/ <- executable tools
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## When to create vs update
|
|
77
|
+
|
|
78
|
+
**Create new skill:** Distinct behavioral concern not covered by existing skills. Domain knowledge inline in an agent that applies to multiple agents.
|
|
79
|
+
|
|
80
|
+
**Update existing skill:** Agent ignores a rule the skill already defines -> strengthen with traps. Skill is missing a type-appropriate section.
|
|
81
|
+
|
|
82
|
+
**Put elsewhere:** Project-specific config -> CLAUDE.md or agent inline. Single-agent-only behavior -> keep inline. Knowledge the LLM covers well from training -> not needed.
|
|
83
|
+
|
|
84
|
+
**When creating a new skill:** Also update `skills/README.md` to add the new skill to the index. Load Skill('readme-writing') to do this correctly.
|
|
85
|
+
|
|
86
|
+
## Anti-Patterns
|
|
87
|
+
|
|
88
|
+
- **Description summarizes process** -- agent follows the description and skips reading the skill body.
|
|
89
|
+
- **Discipline without traps** -- agents rationalize around rules; every unnamed loophole gets used.
|
|
90
|
+
- **Too generic** -- "be careful with commands" teaches nothing; skills need specific, concrete rules.
|
|
91
|
+
- **Duplicates agent content** -- two sources of truth both become stale; pick one place.
|
|
92
|
+
- **Single responsibility violated** -- if a skill covers two distinct behaviors, split it.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Skill Creation -- Reference
|
|
2
|
+
|
|
3
|
+
Detailed guidance on writing style, tone by type, and design philosophy. Read on-demand when crafting or reviewing skill content.
|
|
4
|
+
|
|
5
|
+
## Write for Judgment, Not Compliance
|
|
6
|
+
|
|
7
|
+
A skill that says "ALWAYS do X" is a rule. Rules get skipped the moment the agent encounters a situation where X seems unnecessary. A skill that explains *what goes wrong when you skip X* forms judgment. Judgment holds even in situations the skill never anticipated.
|
|
8
|
+
|
|
9
|
+
The test: for each rule or step you write, ask -- if the agent saw enough real examples of this going wrong, would it reach the same conclusion on its own? If yes, you're capturing genuine wisdom. If no, it's probably an arbitrary preference that needs more context before it can guide decisions.
|
|
10
|
+
|
|
11
|
+
This is why the investigation skill doesn't say "INVESTIGATE FIRST. ALWAYS. NO EXCEPTIONS." It says: *"Every codebase is a record of accumulated decisions... The first 2-3 files you read define whether your solution fits or fights the project."* The agent understands the stakes. The behavior follows.
|
|
12
|
+
|
|
13
|
+
Every line in a skill competes for weight in the LLM's reasoning. A rule without context carries almost no weight -- the model has no reason to prioritize it over competing signals. An explanation with consequences carries enough weight to influence decisions even under pressure. This is why conciseness matters: a verbose skill dilutes its own weight. Every line should earn its place by adding reasoning the model can use.
|
|
14
|
+
|
|
15
|
+
## Tone by Type
|
|
16
|
+
|
|
17
|
+
**Discipline** works best when the Iron Law is blunt and a reasoned paragraph follows explaining what breaks when you violate it. Command-execution's mental model ("When you reach for a pipe, you have not looked for the flag yet") does more work than a dozen capitalized warnings because it reframes the decision point itself.
|
|
18
|
+
|
|
19
|
+
**Technique** should read like a mentor sharing experience. Not "do step 1, step 2, step 3" but "when you encounter X, the thing that matters most is Y, because Z." The agent needs to internalize the priority, not memorize the sequence.
|
|
20
|
+
|
|
21
|
+
**Domain** skills guide discovery of the project's conventions, not dictate a generic structure. The codebase is the source of truth; the skill is a reference that helps the agent find and interpret what's already there.
|
|
22
|
+
|
|
23
|
+
**Reference** is where tone matters least and accuracy matters most. Tables, classifications, format specs. Get the content right.
|
|
24
|
+
|
|
25
|
+
**Protocol** needs precision in its state machines and formats, but transitions should explain why they exist. An agent that understands why REVIEW precedes IN_PROGRESS for T3 operations will handle edge cases the protocol didn't enumerate.
|
|
26
|
+
|
|
27
|
+
## Connection to Design Philosophy
|
|
28
|
+
|
|
29
|
+
The gaia-patterns Workflow Design Philosophy captures this directly: *"Be positive -- describe what to do, not what to avoid"* and *"Allow discovery -- agent reaches conclusions empirically."* These principles apply directly to skill writing. A skill full of prohibitions ("never do X", "do NOT do Y") trains avoidance, not understanding. A skill that describes the better path and explains why it's better trains judgment that generalizes.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terraform-patterns
|
|
3
|
+
description: Use when creating, modifying, or reviewing Terraform or Terragrunt configuration files
|
|
4
|
+
metadata:
|
|
5
|
+
user-invocable: false
|
|
6
|
+
type: domain
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Terraform Patterns
|
|
10
|
+
|
|
11
|
+
Project-specific conventions. Use values from your injected project-context — never hardcode project IDs, regions, or account identifiers.
|
|
12
|
+
|
|
13
|
+
For HCL examples (remote state, component structure, labels, outputs), read `reference.md` in this directory.
|
|
14
|
+
|
|
15
|
+
## Discover the Project's Organization
|
|
16
|
+
|
|
17
|
+
Every project organizes Terraform differently. Before creating any
|
|
18
|
+
file, discover how THIS project does it.
|
|
19
|
+
|
|
20
|
+
1. **Find the modules directory.** Look for `tf_modules/`, `modules/`,
|
|
21
|
+
`terraform/`, or similar. The name varies — what matters is whether
|
|
22
|
+
reusable modules exist and where they live.
|
|
23
|
+
2. **Read 2-3 existing terragrunt.hcl files.** Look at the `source =`
|
|
24
|
+
lines. Do they reference local modules? Registry modules? A mix?
|
|
25
|
+
3. **Follow the majority pattern.** If 8 out of 10 components use
|
|
26
|
+
local module references, yours should too. Consistency with the
|
|
27
|
+
project matters more than what you'd choose on a greenfield.
|
|
28
|
+
|
|
29
|
+
### Module vs Inline
|
|
30
|
+
|
|
31
|
+
If the project has reusable modules for similar resource compositions
|
|
32
|
+
(e.g., a cloud-sql module that composes instance + database + user +
|
|
33
|
+
secrets), and your new resource follows a similar composition pattern,
|
|
34
|
+
create a reusable module. If it's truly one-off glue with no reuse
|
|
35
|
+
potential, inline is acceptable — but check first, because most
|
|
36
|
+
projects lean one way.
|
|
37
|
+
|
|
38
|
+
## Directory Structure (Reference)
|
|
39
|
+
|
|
40
|
+
The structure below is a common starting point, not a prescription.
|
|
41
|
+
If the codebase uses a different layout, follow the codebase.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
terraform/
|
|
45
|
+
└── [module-name]/
|
|
46
|
+
├── main.tf # Resource definitions
|
|
47
|
+
├── variables.tf # Input variables
|
|
48
|
+
├── outputs.tf # Output values (snake_case, with descriptions)
|
|
49
|
+
└── provider.tf # Provider config (if module-level)
|
|
50
|
+
|
|
51
|
+
features/infra/[env]/
|
|
52
|
+
├── terragrunt.hcl # Root: remote state config
|
|
53
|
+
└── [component]/
|
|
54
|
+
└── terragrunt.hcl # Component: inputs + dependency references
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Naming Convention
|
|
58
|
+
|
|
59
|
+
| Resource | Pattern | Notes |
|
|
60
|
+
|----------|---------|-------|
|
|
61
|
+
| Network/VPC | `{app}-{env}-vpc` | From context: project + env |
|
|
62
|
+
| Cluster | `{app}-{env}-cluster-{n}` | Match context cluster_name |
|
|
63
|
+
| Database | `{app}-{env}-{engine}-instance` | Engine: postgres, mysql |
|
|
64
|
+
| Secret | `{service}-secret` | Matches app service name |
|
|
65
|
+
| Service Account | `{resource}-sa` | Scope: resource it serves |
|
|
66
|
+
|
|
67
|
+
## Module Sourcing
|
|
68
|
+
|
|
69
|
+
- **Local modules** (preferred for GCP): `../../../../../terraform//{module-name}`
|
|
70
|
+
- **Registry modules** (preferred for AWS): `tfr:///terraform-aws-modules/{module}/aws?version=x.y.z`
|
|
71
|
+
- **Always pin exact versions** — never `latest`, never unpinned
|
|
72
|
+
|
|
73
|
+
## Key Rules
|
|
74
|
+
|
|
75
|
+
1. **Prefer Terragrunt** — prefer `terragrunt` commands for all environment operations; raw `terraform` is acceptable for module development and testing only
|
|
76
|
+
2. **Dependencies via blocks** — never hardcode IDs, always `dependency.x.outputs.y`
|
|
77
|
+
3. **Version pinning** — exact versions for modules, `~>` for providers
|
|
78
|
+
4. **Tags on everything** — all resources get the standard label block
|
|
79
|
+
5. **snake_case outputs** — descriptive names with `description` field
|
|
80
|
+
6. **mock_outputs on dependencies** — required for `validate` and `plan` to work offline
|
|
81
|
+
|
|
82
|
+
## Reference Docs
|
|
83
|
+
|
|
84
|
+
Use `WebFetch` when a resource or attribute is unknown or ambiguous. Do not use WebFetch to discover patterns — the codebase always wins over external docs.
|
|
85
|
+
|
|
86
|
+
| Need | URL |
|
|
87
|
+
|------|-----|
|
|
88
|
+
| Google provider resources | `https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/{resource}` |
|
|
89
|
+
| Terragrunt config blocks | `https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes` |
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Terraform Patterns — HCL Reference
|
|
2
|
+
|
|
3
|
+
Structural patterns for Terraform and Terragrunt. Cloud-agnostic — use values from project-context, never hardcode.
|
|
4
|
+
|
|
5
|
+
For cloud-specific resource examples (VPCs, clusters, databases), discover patterns from the existing codebase using the `investigation` skill.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Remote State (root terragrunt.hcl)
|
|
10
|
+
|
|
11
|
+
```hcl
|
|
12
|
+
remote_state {
|
|
13
|
+
backend = "gcs" # gcs | s3 | azurerm — from cloud_provider in context
|
|
14
|
+
config = {
|
|
15
|
+
bucket = "{project_id}-terraform-state"
|
|
16
|
+
prefix = "${path_relative_to_include()}/terraform.tfstate"
|
|
17
|
+
project = "{project_id}" # from project-context
|
|
18
|
+
location = "{primary_region}" # from project-context
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Component (terragrunt.hcl)
|
|
24
|
+
|
|
25
|
+
```hcl
|
|
26
|
+
include "root" { path = find_in_parent_folders() }
|
|
27
|
+
terraform { source = "../../../../../terraform//{module-name}" }
|
|
28
|
+
|
|
29
|
+
dependency "vpc" {
|
|
30
|
+
config_path = "../vpc"
|
|
31
|
+
mock_outputs = { network_id = "mock-network" }
|
|
32
|
+
mock_outputs_allowed_terraform_commands = ["validate", "plan"]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
inputs = {
|
|
36
|
+
project_id = "{project_id}" # from project-context
|
|
37
|
+
region = "{primary_region}" # from project-context
|
|
38
|
+
network_id = dependency.vpc.outputs.network_id
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Required Labels
|
|
43
|
+
|
|
44
|
+
Every resource must include:
|
|
45
|
+
|
|
46
|
+
```hcl
|
|
47
|
+
labels = {
|
|
48
|
+
environment = "{env}" # from project-context
|
|
49
|
+
managed_by = "terraform"
|
|
50
|
+
project = "{project_id}" # from project-context
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Outputs Pattern
|
|
55
|
+
|
|
56
|
+
```hcl
|
|
57
|
+
output "resource_id" {
|
|
58
|
+
description = "Description of what this output represents"
|
|
59
|
+
value = resource_type.name.id
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Always: snake_case name, non-empty description, no sensitive values unless `sensitive = true`.
|
|
64
|
+
|
|
65
|
+
## Module Sourcing
|
|
66
|
+
|
|
67
|
+
```hcl
|
|
68
|
+
# Local module (GCP preferred)
|
|
69
|
+
terraform { source = "../../../../../terraform//{module-name}" }
|
|
70
|
+
|
|
71
|
+
# Registry module (AWS preferred)
|
|
72
|
+
terraform { source = "tfr:///terraform-aws-modules/{module}/aws?version=x.y.z" }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Always pin exact versions — never `latest`, never unpinned.
|
|
76
|
+
|
|
77
|
+
## State Operations
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
terragrunt state list
|
|
81
|
+
terragrunt state show {resource_type}.{name}
|
|
82
|
+
terragrunt import {resource_type}.{name} {live_id}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Troubleshooting
|
|
86
|
+
|
|
87
|
+
| Issue | Solution |
|
|
88
|
+
|-------|----------|
|
|
89
|
+
| State lock | Check state backend lock table, wait or force-unlock with caution |
|
|
90
|
+
| Module not found | Run `terragrunt init` |
|
|
91
|
+
| Dependency cycle | Review dependency `config_path` declarations |
|
|
92
|
+
| Mock outputs mismatch | Update `mock_outputs` to match actual output types |
|
|
93
|
+
| Plan shows unexpected destroy | Check for naming drift between code and live state |
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Templates
|
|
2
|
+
|
|
3
|
+
Templates are the reference files that Gaia uses to generate per-project configuration. They are not consumed by the Claude Code runtime — they are consumed by the install scripts in `bin/` and by organization administrators deploying managed policies. Think of this directory as the catalog of files that exist as skeletons, ready to be filled in during installation or deployed verbatim as a policy.
|
|
4
|
+
|
|
5
|
+
There are two audiences for this directory, and they do not overlap. The first is the individual developer installing Gaia into their project — their scanner reads templates during `npx gaia-scan` and generates the files their project needs. The second is the enterprise administrator — they take `managed-settings.template.json` and deploy it as a managed policy via the Claude.ai Admin Console or by placing it at `/etc/claude-code/managed-settings.json` on managed workstations.
|
|
6
|
+
|
|
7
|
+
Keeping these files here, rather than embedding them in `bin/gaia-scan.py`, means policies and skeletons can be audited and customized without touching executable code. An admin can diff `managed-settings.template.json` against a previous version. A developer can read `governance.template.md` (when present) before letting the scanner interpolate it.
|
|
8
|
+
|
|
9
|
+
## Cuándo se activa
|
|
10
|
+
|
|
11
|
+
This component does not activate in the runtime Claude Code pipeline. Templates are consumed only by install-time tooling and by administrators deploying policies out-of-band.
|
|
12
|
+
|
|
13
|
+
**When each template is consumed:**
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Individual developer runs: npx gaia-scan
|
|
17
|
+
|
|
|
18
|
+
bin/gaia-scan.py reads templates/ directory
|
|
19
|
+
|
|
|
20
|
+
For each template:
|
|
21
|
+
managed-settings.template.json -> NOT consumed by gaia-scan (enterprise only)
|
|
22
|
+
governance.template.md -> interpolated with project-context.json values
|
|
23
|
+
(any other *.template.* files) -> interpolated or copied per install logic
|
|
24
|
+
|
|
|
25
|
+
Generated files written to project .claude/ or project root
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Enterprise admin deploys managed policy
|
|
30
|
+
|
|
|
31
|
+
Admin copies templates/managed-settings.template.json
|
|
32
|
+
|
|
|
33
|
+
Deploys to Claude.ai Admin Console
|
|
34
|
+
OR writes to /etc/claude-code/managed-settings.json (Linux managed workstations)
|
|
35
|
+
|
|
|
36
|
+
Managed settings take highest precedence — cannot be overridden by user or project
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Qué hay aquí
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
templates/
|
|
43
|
+
├── managed-settings.template.json # Enterprise reference — deployed by admin, not gaia-scan
|
|
44
|
+
└── README.md
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Currently only `managed-settings.template.json` ships in this directory. A `governance.template.md` is referenced by some Gaia docs as generated during `gaia-scan` setup, but the file is not present here in source — it may live in a future location or be inlined in the scanner script.
|
|
48
|
+
|
|
49
|
+
## Convenciones
|
|
50
|
+
|
|
51
|
+
**Audience per file:**
|
|
52
|
+
|
|
53
|
+
| File | Audience | Consumed by | Trigger |
|
|
54
|
+
|------|----------|-------------|---------|
|
|
55
|
+
| `managed-settings.template.json` | Enterprise administrator | Claude.ai Admin Console or `/etc/claude-code/managed-settings.json` | Admin action — out of band, not automated |
|
|
56
|
+
| `governance.template.md` (if present) | Individual developer | `bin/gaia-scan.py` | `npx gaia-scan` on first install |
|
|
57
|
+
|
|
58
|
+
**Managed settings precedence:** `managed-settings.template.json` contains wildcard deny rules that cannot be overridden by user or project settings. It also sets `disableBypassPermissionsMode: true` to prevent `--dangerously-skip-permissions`. Deploy this only when you want organization-wide enforcement.
|
|
59
|
+
|
|
60
|
+
**No CLAUDE.md generated:** Orchestrator identity is no longer generated from a template. It lives in `agents/gaia-orchestrator.md` and is activated via `settings.json: { "agent": "gaia-orchestrator" }`. Surface routing is injected by the `UserPromptSubmit` hook, not by a template.
|
|
61
|
+
|
|
62
|
+
**Template naming:** Files intended for interpolation use the `.template.<ext>` suffix (e.g., `governance.template.md`, `managed-settings.template.json`). Files without that suffix should not be here.
|
|
63
|
+
|
|
64
|
+
## Ver también
|
|
65
|
+
|
|
66
|
+
- [`bin/gaia-scan.py`](../bin/gaia-scan.py) — consumes interpolation templates at install time
|
|
67
|
+
- [`bin/gaia-update.js`](../bin/gaia-update.js) — updates settings.local.json (merges, does not use templates here)
|
|
68
|
+
- [`agents/gaia-orchestrator.md`](../agents/gaia-orchestrator.md) — orchestrator identity (replaces old CLAUDE.md template path)
|
|
69
|
+
- [`build/gaia-ops.manifest.json`](../build/gaia-ops.manifest.json) — plugin-level permission defaults (distinct from managed-settings)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": [
|
|
3
|
+
"Managed settings template for enterprise/organization deployment.",
|
|
4
|
+
"Deploy to: /etc/claude-code/managed-settings.json (Linux/WSL)",
|
|
5
|
+
" /Library/Application Support/ClaudeCode/managed-settings.json (macOS)",
|
|
6
|
+
" Or via Claude.ai Admin > Claude Code > Managed Settings",
|
|
7
|
+
"",
|
|
8
|
+
"These rules have the HIGHEST precedence and CANNOT be overridden by",
|
|
9
|
+
"user, project, or local settings. They are the ultimate security gate."
|
|
10
|
+
],
|
|
11
|
+
"permissions": {
|
|
12
|
+
"deny": [
|
|
13
|
+
"Bash(aws * delete-*:*)",
|
|
14
|
+
"Bash(aws * terminate-*:*)",
|
|
15
|
+
"Bash(az * delete:*)",
|
|
16
|
+
"Bash(gcloud * delete:*)",
|
|
17
|
+
"Bash(gsutil rb:*)",
|
|
18
|
+
"Bash(gsutil rm:*)",
|
|
19
|
+
"Bash(gcloud storage rm:*)",
|
|
20
|
+
"Bash(kubectl delete:*)",
|
|
21
|
+
"Bash(kubectl drain:*)",
|
|
22
|
+
"Bash(terraform destroy:*)",
|
|
23
|
+
"Bash(terragrunt destroy:*)",
|
|
24
|
+
"Bash(terragrunt run-all destroy:*)",
|
|
25
|
+
"Bash(helm uninstall:*)",
|
|
26
|
+
"Bash(helm delete:*)",
|
|
27
|
+
"Bash(flux uninstall:*)",
|
|
28
|
+
"Bash(docker system prune:*)",
|
|
29
|
+
"Bash(docker volume prune:*)",
|
|
30
|
+
"Bash(git push --force:*)",
|
|
31
|
+
"Bash(git push -f:*)",
|
|
32
|
+
"Bash(git reset --hard:*)",
|
|
33
|
+
"Bash(gh repo delete:*)",
|
|
34
|
+
"Bash(glab project delete:*)",
|
|
35
|
+
"Bash(dd:*)",
|
|
36
|
+
"Bash(fdisk:*)",
|
|
37
|
+
"Bash(mkfs:*)",
|
|
38
|
+
"Bash(mkfs.*:*)"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"disableBypassPermissionsMode": "disable",
|
|
42
|
+
"allowManagedHooksOnly": false
|
|
43
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""gaia-ops tools namespace package.
|
|
2
|
+
|
|
3
|
+
Marking ``tools`` as a regular package ensures pytest's rootdir discovery
|
|
4
|
+
resolves to the repo root for both ``tests/`` and ``tools/scan/tests/``
|
|
5
|
+
during full-suite collection. Without this file, pytest walks up from
|
|
6
|
+
``tools/scan/tests/__init__.py`` to ``tools/`` (no ``__init__.py``) and
|
|
7
|
+
uses that as the package root, which makes ``from tools.scan...`` imports
|
|
8
|
+
fail at collection time.
|
|
9
|
+
"""
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
decide-status.py
|
|
4
|
+
|
|
5
|
+
Mechanically decide what to do based on numbers alone. No LLM judgment.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python3 decide-status.py \
|
|
9
|
+
--current 94.5 \
|
|
10
|
+
--best 92.0 \
|
|
11
|
+
--threshold 98 \
|
|
12
|
+
--direction higher \
|
|
13
|
+
--consecutive-discards 2 \
|
|
14
|
+
--pivot-count 1
|
|
15
|
+
|
|
16
|
+
Output JSON:
|
|
17
|
+
{
|
|
18
|
+
"decision": "keep",
|
|
19
|
+
"reason": "Metric improved from 92.0 to 94.5",
|
|
20
|
+
"improved": true,
|
|
21
|
+
"gap_remaining": 3.5
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Decision precedence (evaluated top-to-bottom, first match wins):
|
|
25
|
+
1. pivot_count >= 3 → stop
|
|
26
|
+
2. consecutive_discards >= 5 → pivot (also a discard)
|
|
27
|
+
3. consecutive_discards >= 3 → refine (also a discard)
|
|
28
|
+
4. current meets or passes threshold → threshold_reached
|
|
29
|
+
5. current improved vs best (per direction) → keep
|
|
30
|
+
6. current same or worse → discard
|
|
31
|
+
|
|
32
|
+
Exit codes:
|
|
33
|
+
0 success (decision emitted as JSON)
|
|
34
|
+
1 invalid input
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
import argparse
|
|
38
|
+
import json
|
|
39
|
+
import sys
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
Decision = str # type alias for readability
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _is_improved(current: float, best: float, direction: str) -> bool:
|
|
46
|
+
"""Return True if *current* is strictly better than *best* per direction."""
|
|
47
|
+
if direction == "higher":
|
|
48
|
+
return current > best
|
|
49
|
+
return current < best # lower is better
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _threshold_reached(current: float, threshold: float, direction: str) -> bool:
|
|
53
|
+
"""Return True if *current* has met or surpassed *threshold*."""
|
|
54
|
+
if direction == "higher":
|
|
55
|
+
return current >= threshold
|
|
56
|
+
return current <= threshold
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _gap_remaining(current: float, threshold: float, direction: str) -> float:
|
|
60
|
+
"""Absolute gap between current value and threshold."""
|
|
61
|
+
if direction == "higher":
|
|
62
|
+
return max(0.0, threshold - current)
|
|
63
|
+
return max(0.0, current - threshold)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def decide(
|
|
67
|
+
current: float,
|
|
68
|
+
best: float,
|
|
69
|
+
threshold: float,
|
|
70
|
+
direction: str,
|
|
71
|
+
consecutive_discards: int,
|
|
72
|
+
pivot_count: int,
|
|
73
|
+
) -> dict:
|
|
74
|
+
"""Pure function: return decision dict from numeric inputs."""
|
|
75
|
+
|
|
76
|
+
gap = _gap_remaining(current, threshold, direction)
|
|
77
|
+
improved = _is_improved(current, best, direction)
|
|
78
|
+
|
|
79
|
+
# --- Precedence 1: hard stop on too many pivots ---
|
|
80
|
+
if pivot_count >= 3:
|
|
81
|
+
return {
|
|
82
|
+
"decision": "stop",
|
|
83
|
+
"reason": f"pivot_count={pivot_count} has reached the maximum of 3; halting loop",
|
|
84
|
+
"improved": improved,
|
|
85
|
+
"gap_remaining": gap,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# --- Precedence 2 & 3: discard streak escalations ---
|
|
89
|
+
# Evaluated before threshold/keep so an ongoing failing streak is flagged
|
|
90
|
+
# even if the current run happens to reach the threshold.
|
|
91
|
+
if consecutive_discards >= 5:
|
|
92
|
+
return {
|
|
93
|
+
"decision": "pivot",
|
|
94
|
+
"reason": (
|
|
95
|
+
f"consecutive_discards={consecutive_discards} >= 5; "
|
|
96
|
+
"strategy is not working, force a pivot"
|
|
97
|
+
),
|
|
98
|
+
"improved": improved,
|
|
99
|
+
"gap_remaining": gap,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if consecutive_discards >= 3:
|
|
103
|
+
return {
|
|
104
|
+
"decision": "refine",
|
|
105
|
+
"reason": (
|
|
106
|
+
f"consecutive_discards={consecutive_discards} >= 3; "
|
|
107
|
+
"current approach needs refinement before continuing"
|
|
108
|
+
),
|
|
109
|
+
"improved": improved,
|
|
110
|
+
"gap_remaining": gap,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# --- Precedence 4: threshold reached ---
|
|
114
|
+
if _threshold_reached(current, threshold, direction):
|
|
115
|
+
return {
|
|
116
|
+
"decision": "threshold_reached",
|
|
117
|
+
"reason": (
|
|
118
|
+
f"current={current} {'≥' if direction == 'higher' else '≤'} "
|
|
119
|
+
f"threshold={threshold}; goal achieved"
|
|
120
|
+
),
|
|
121
|
+
"improved": improved,
|
|
122
|
+
"gap_remaining": 0.0,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# --- Precedence 5 & 6: standard keep/discard ---
|
|
126
|
+
if improved:
|
|
127
|
+
return {
|
|
128
|
+
"decision": "keep",
|
|
129
|
+
"reason": f"Metric improved from {best} to {current}",
|
|
130
|
+
"improved": True,
|
|
131
|
+
"gap_remaining": gap,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
"decision": "discard",
|
|
136
|
+
"reason": f"Metric did not improve (current={current}, best={best})",
|
|
137
|
+
"improved": False,
|
|
138
|
+
"gap_remaining": gap,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def main() -> None:
|
|
143
|
+
parser = argparse.ArgumentParser(
|
|
144
|
+
description="Compute the next agentic-loop decision from metric numbers only.",
|
|
145
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
146
|
+
epilog="""
|
|
147
|
+
Decisions:
|
|
148
|
+
keep current improved vs best
|
|
149
|
+
discard current same or worse
|
|
150
|
+
refine 3+ consecutive discards (improvement needed in approach)
|
|
151
|
+
pivot 5+ consecutive discards (strategy change required)
|
|
152
|
+
stop 3+ pivots already attempted
|
|
153
|
+
threshold_reached current meets or surpasses the goal threshold
|
|
154
|
+
|
|
155
|
+
Direction values:
|
|
156
|
+
higher larger numbers are better (e.g. accuracy, passing tests)
|
|
157
|
+
lower smaller numbers are better (e.g. error rate, latency ms)
|
|
158
|
+
""",
|
|
159
|
+
)
|
|
160
|
+
parser.add_argument("--current", required=True, type=float, help="Metric value for the current run")
|
|
161
|
+
parser.add_argument("--best", required=True, type=float, help="Best metric seen so far (from state.json)")
|
|
162
|
+
parser.add_argument("--threshold", required=True, type=float, help="Target threshold to reach")
|
|
163
|
+
parser.add_argument(
|
|
164
|
+
"--direction",
|
|
165
|
+
required=True,
|
|
166
|
+
choices=["higher", "lower"],
|
|
167
|
+
help="Whether higher or lower values are better",
|
|
168
|
+
)
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
"--consecutive-discards",
|
|
171
|
+
required=True,
|
|
172
|
+
type=int,
|
|
173
|
+
metavar="N",
|
|
174
|
+
help="Number of consecutive discard outcomes so far (from state.json)",
|
|
175
|
+
)
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"--pivot-count",
|
|
178
|
+
required=True,
|
|
179
|
+
type=int,
|
|
180
|
+
metavar="N",
|
|
181
|
+
help="Number of pivots executed so far (from state.json)",
|
|
182
|
+
)
|
|
183
|
+
args = parser.parse_args()
|
|
184
|
+
|
|
185
|
+
# --- Input validation ---
|
|
186
|
+
errors = []
|
|
187
|
+
if args.consecutive_discards < 0:
|
|
188
|
+
errors.append("--consecutive-discards must be >= 0")
|
|
189
|
+
if args.pivot_count < 0:
|
|
190
|
+
errors.append("--pivot-count must be >= 0")
|
|
191
|
+
|
|
192
|
+
if errors:
|
|
193
|
+
for err in errors:
|
|
194
|
+
print(f"error: {err}", file=sys.stderr)
|
|
195
|
+
sys.exit(1)
|
|
196
|
+
|
|
197
|
+
result = decide(
|
|
198
|
+
current=args.current,
|
|
199
|
+
best=args.best,
|
|
200
|
+
threshold=args.threshold,
|
|
201
|
+
direction=args.direction,
|
|
202
|
+
consecutive_discards=args.consecutive_discards,
|
|
203
|
+
pivot_count=args.pivot_count,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
print(json.dumps(result, indent=2))
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
if __name__ == "__main__":
|
|
210
|
+
main()
|