name: 🔴 Economic Circuit Breaker # AGENTS.md v5.0 - Economic Governance Protocol準拠 # Reference: ai-course-content-generator economic-circuit-breaker.yml on: schedule: - cron: '0 * * * *' # 1時間ごとにコスト監視 workflow_dispatch: inputs: force_check: description: '強制チェック実行' required: false default: 'false' permissions: issues: write actions: write contents: read jobs: monitor-cloud-costs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' - name: Install yq for YAML parsing run: | sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 sudo chmod +x /usr/local/bin/yq - name: Load BUDGET.yml configuration id: budget run: | BUDGET=$(yq '.monthly_budget_usd' BUDGET.yml) WARNING_THRESHOLD=$(yq '.thresholds.warning' BUDGET.yml) EMERGENCY_THRESHOLD=$(yq '.thresholds.emergency' BUDGET.yml) echo "monthly_budget=$BUDGET" >> $GITHUB_OUTPUT echo "warning_threshold=$WARNING_THRESHOLD" >> $GITHUB_OUTPUT echo "emergency_threshold=$EMERGENCY_THRESHOLD" >> $GITHUB_OUTPUT echo "📊 Budget Configuration:" echo " Monthly Budget: \$$BUDGET USD" echo " Warning Threshold: ${WARNING_THRESHOLD} ($(echo "$BUDGET * $WARNING_THRESHOLD" | bc)% = \$$(echo "$BUDGET * $WARNING_THRESHOLD" | bc) USD)" echo " Emergency Threshold: ${EMERGENCY_THRESHOLD} ($(echo "$EMERGENCY_THRESHOLD * 100" | bc)% = \$$(echo "$BUDGET * $EMERGENCY_THRESHOLD" | bc) USD)" - name: Check Anthropic API Usage id: anthropic_cost env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | # 現在の月の開始日を計算 MONTH_START=$(date -u +"%Y-%m-01T00:00:00Z") CURRENT_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") echo "📅 Billing Period: $MONTH_START ~ $CURRENT_DATE" # Anthropic API usage check # Note: Anthropic doesn't provide direct billing API yet, so we estimate from usage # In production, integrate with actual billing endpoint when available # Placeholder: 実際のAPI使用状況をチェック # TODO: Anthropic Billing APIが利用可能になったら統合 ANTHROPIC_COST_USD=0 # Fallback: GitHub Actionsのログから推定 (開発時) if [ "${{ github.event.inputs.force_check }}" == "true" ]; then # デモ用: テストコスト ANTHROPIC_COST_USD=45.23 fi echo "anthropic_cost=$ANTHROPIC_COST_USD" >> $GITHUB_OUTPUT echo "🤖 Anthropic API Cost: \$$ANTHROPIC_COST_USD USD" - name: Check Firebase Costs id: firebase_cost env: GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }} GOOGLE_APPLICATION_CREDENTIALS_JSON: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_JSON }} run: | # Firebase/GCP billing check via Cloud Billing API # Note: Requires Cloud Billing API enabled and service account with billing.accounts.get permission FIREBASE_COST_USD=0 # Placeholder: 実際のFirebase使用状況をチェック # TODO: Cloud Billing API統合 if [ "${{ github.event.inputs.force_check }}" == "true" ]; then # デモ用: テストコスト FIREBASE_COST_USD=12.50 fi echo "firebase_cost=$FIREBASE_COST_USD" >> $GITHUB_OUTPUT echo "🔥 Firebase Cost: \$$FIREBASE_COST_USD USD" - name: Check GitHub Actions Usage id: github_cost env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # GitHub Actions分は無料枠内の想定 (3000分/月) # 念のため使用量を確認 OWNER=$(echo "${{ github.repository }}" | cut -d'/' -f1) REPO=$(echo "${{ github.repository }}" | cut -d'/' -f2) # 当月のActions使用時間を取得 MONTH_START_UNIX=$(date -d "$(date +%Y-%m-01)" +%s) CURRENT_UNIX=$(date +%s) # GitHub API: Workflow runs (last 30 days) TOTAL_MINUTES=$(gh api \ -H "Accept: application/vnd.github+json" \ "/repos/$OWNER/$REPO/actions/runs?per_page=100" \ --jq '[.workflow_runs[] | select(.created_at >= "'$(date -d "@$MONTH_START_UNIX" -u +%Y-%m-%dT%H:%M:%SZ)'") | .run_duration_ms // 0] | add // 0' \ | awk '{print int($1/60000)}') echo "github_minutes=$TOTAL_MINUTES" >> $GITHUB_OUTPUT echo "⚙️ GitHub Actions Usage: ${TOTAL_MINUTES} minutes this month" # 無料枠3000分を超えたら警告 if [ "$TOTAL_MINUTES" -gt 3000 ]; then echo "github_over_quota=true" >> $GITHUB_OUTPUT echo "⚠️ WARNING: GitHub Actions over free tier quota!" else echo "github_over_quota=false" >> $GITHUB_OUTPUT fi - name: Calculate Total Cost and Consumption Rate id: calculate run: | BUDGET=${{ steps.budget.outputs.monthly_budget }} WARNING=${{ steps.budget.outputs.warning_threshold }} EMERGENCY=${{ steps.budget.outputs.emergency_threshold }} ANTHROPIC=${{ steps.anthropic_cost.outputs.anthropic_cost }} FIREBASE=${{ steps.firebase_cost.outputs.firebase_cost }} # 合計コスト計算 TOTAL_COST=$(echo "$ANTHROPIC + $FIREBASE" | bc) # 消費率計算 CONSUMPTION_RATE=$(echo "scale=4; $TOTAL_COST / $BUDGET" | bc) CONSUMPTION_PERCENT=$(echo "scale=2; $CONSUMPTION_RATE * 100" | bc) # しきい値判定 WARNING_AMOUNT=$(echo "$BUDGET * $WARNING" | bc) EMERGENCY_AMOUNT=$(echo "$BUDGET * $EMERGENCY" | bc) echo "total_cost=$TOTAL_COST" >> $GITHUB_OUTPUT echo "consumption_rate=$CONSUMPTION_RATE" >> $GITHUB_OUTPUT echo "consumption_percent=$CONSUMPTION_PERCENT" >> $GITHUB_OUTPUT echo "" echo "═══════════════════════════════════════" echo "📊 ECONOMIC GOVERNANCE PROTOCOL STATUS" echo "═══════════════════════════════════════" echo "💰 Total Cost: \$$TOTAL_COST USD / \$$BUDGET USD" echo "📈 Consumption Rate: ${CONSUMPTION_PERCENT}%" echo "⚠️ Warning Level: \$$WARNING_AMOUNT USD (${WARNING})" echo "🔴 Emergency Level: \$$EMERGENCY_AMOUNT USD (${EMERGENCY})" echo "═══════════════════════════════════════" echo "" # しきい値チェック if (( $(echo "$TOTAL_COST >= $EMERGENCY_AMOUNT" | bc -l) )); then echo "status=EMERGENCY" >> $GITHUB_OUTPUT echo "🚨 STATUS: EMERGENCY - Circuit Breaker will activate!" elif (( $(echo "$TOTAL_COST >= $WARNING_AMOUNT" | bc -l) )); then echo "status=WARNING" >> $GITHUB_OUTPUT echo "⚠️ STATUS: WARNING - Approaching budget limit" else echo "status=OK" >> $GITHUB_OUTPUT echo "✅ STATUS: OK - Within budget" fi - name: Store Cost Metrics run: | # メトリクスディレクトリ作成 mkdir -p .ai/metrics/cost-history # 現在の日時 TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") DATE=$(date -u +"%Y-%m-%d") # メトリクスをJSONで保存 cat > ".ai/metrics/cost-history/${DATE}_$(date +%s).json" << EOF { "timestamp": "$TIMESTAMP", "budget": { "monthly_usd": ${{ steps.budget.outputs.monthly_budget }}, "warning_threshold": ${{ steps.budget.outputs.warning_threshold }}, "emergency_threshold": ${{ steps.budget.outputs.emergency_threshold }} }, "costs": { "anthropic_usd": ${{ steps.anthropic_cost.outputs.anthropic_cost }}, "firebase_usd": ${{ steps.firebase_cost.outputs.firebase_cost }}, "total_usd": ${{ steps.calculate.outputs.total_cost }} }, "consumption": { "rate": ${{ steps.calculate.outputs.consumption_rate }}, "percent": ${{ steps.calculate.outputs.consumption_percent }} }, "github_actions": { "minutes_used": ${{ steps.github_cost.outputs.github_minutes }}, "over_quota": ${{ steps.github_cost.outputs.github_over_quota }} }, "status": "${{ steps.calculate.outputs.status }}" } EOF echo "📝 Cost metrics saved to .ai/metrics/cost-history/" - name: 🔴 EMERGENCY - Trigger Circuit Breaker if: steps.calculate.outputs.status == 'EMERGENCY' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "🚨🚨🚨 ECONOMIC CIRCUIT BREAKER ACTIVATED 🚨🚨🚨" echo "" echo "Consumption rate has exceeded emergency threshold." echo "Initiating automatic workflow disablement..." echo "" # BUDGET.ymlから停止対象ワークフローを読み込み WORKFLOWS_TO_DISABLE=$(yq '.emergency_actions.disable_workflows[]' BUDGET.yml) # 各ワークフローを無効化 for workflow in $WORKFLOWS_TO_DISABLE; do echo "🛑 Disabling workflow: $workflow" gh api \ --method PUT \ -H "Accept: application/vnd.github+json" \ "/repos/${{ github.repository }}/actions/workflows/$workflow/disable" \ && echo "✅ Disabled: $workflow" \ || echo "⚠️ Failed to disable: $workflow (may not exist)" done echo "" echo "✅ Circuit Breaker activation complete" echo "🤖 Creating emergency issue for Guardian intervention..." - name: 🚨 Create Emergency Issue if: steps.calculate.outputs.status == 'EMERGENCY' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Guardianへの通知Issue作成 gh issue create \ --title "🔴🚨 ECONOMIC CIRCUIT BREAKER ACTIVATED - Guardian Intervention Required" \ --label "🔥Sev.1-Critical,🤖AI-システム,💰経済-緊急停止" \ --assignee "${{ github.repository_owner }}" \ --body "$(cat <<'EOF' ## 🚨 ECONOMIC CIRCUIT BREAKER ACTIVATED **AGENTS.md v5.0 - Economic Governance Protocol** に基づき、経済的サーキットブレーカーが作動しました。 ### 📊 Cost Summary - **Total Cost**: \$${{ steps.calculate.outputs.total_cost }} USD - **Monthly Budget**: \$${{ steps.budget.outputs.monthly_budget }} USD - **Consumption Rate**: ${{ steps.calculate.outputs.consumption_percent }}% - **Emergency Threshold**: ${{ steps.budget.outputs.emergency_threshold }} (150%) ### 💰 Cost Breakdown | Service | Cost (USD) | Budget (USD) | |---------|-----------|--------------| | Anthropic API | \$${{ steps.anthropic_cost.outputs.anthropic_cost }} | \$400 | | Firebase | \$${{ steps.firebase_cost.outputs.firebase_cost }} | \$100 | | **Total** | **\$${{ steps.calculate.outputs.total_cost }}** | **\$${{ steps.budget.outputs.monthly_budget }}** | ### 🛑 Actions Taken The following workflows have been **automatically disabled**: $(yq '.emergency_actions.disable_workflows[]' BUDGET.yml | sed 's/^/- ❌ /') ### 🤖 Guardian Intervention Required **我々の自律性は経済的限界に達した。** **AGENTS.md v5.0 - § 4.7.6: Recovery Protocol** に従い、Guardian (@${{ github.repository_owner }}) の承認を要請する。 #### ✅ Recovery Checklist Guardian は以下を確認し、承認してください: - [ ] **根本原因特定完了**: なぜ予算を超過したか? - [ ] 異常なAPI使用パターンの有無 - [ ] バグによる無限ループの有無 - [ ] 想定外のワークフロー実行の有無 - [ ] **BUDGET.yml更新完了**: 月次予算の見直しは必要か? - [ ] 新しい予算額の決定 - [ ] しきい値の再調整 - [ ] **不要リソース削除完了**: コスト削減措置の実施 - [ ] 不要なワークフロー実行の停止 - [ ] キャッシュのクリーンアップ - [ ] リソースの最適化 - [ ] **月次予算見直し完了**: 来月以降の予算計画 #### 🔄 Workflow Re-enablement Guardian承認後、以下のコマンドでワークフローを再開: \`\`\`bash # 各ワークフローを手動で再有効化 gh api --method PUT /repos/${{ github.repository }}/actions/workflows/agent-runner.yml/enable gh api --method PUT /repos/${{ github.repository }}/actions/workflows/continuous-improvement.yml/enable gh api --method PUT /repos/${{ github.repository }}/actions/workflows/agent-onboarding.yml/enable \`\`\` ### 📈 Historical Cost Data 過去のコストメトリクスは `.ai/metrics/cost-history/` に保存されています。 --- **Generated by**: Economic Circuit Breaker Workflow **Timestamp**: $(date -u +"%Y-%m-%d %H:%M:%S UTC") **Workflow Run**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} EOF )" echo "✅ Emergency issue created successfully" - name: ⚠️ Post Warning Comment if: steps.calculate.outputs.status == 'WARNING' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # 既存の警告Issueを検索 EXISTING_ISSUE=$(gh issue list \ --label "💰経済-警告" \ --state open \ --json number \ --jq '.[0].number') if [ -z "$EXISTING_ISSUE" ]; then # 警告Issueが存在しない場合は作成 gh issue create \ --title "⚠️ Economic Warning - Approaching Budget Limit (${{ steps.calculate.outputs.consumption_percent }}%)" \ --label "⚠️重要度-高,🤖AI-システム,💰経済-警告" \ --body "$(cat <<'EOF' ## ⚠️ Economic Warning 現在のコスト消費率が警告しきい値に達しました。 ### 📊 Current Status - **Consumption Rate**: ${{ steps.calculate.outputs.consumption_percent }}% - **Total Cost**: \$${{ steps.calculate.outputs.total_cost }} USD / \$${{ steps.budget.outputs.monthly_budget }} USD - **Warning Threshold**: ${{ steps.budget.outputs.warning_threshold }} (80%) - **Emergency Threshold**: ${{ steps.budget.outputs.emergency_threshold }} (150%) ### 🎯 Recommended Actions 1. Review recent workflow executions 2. Check for any unusual API usage patterns 3. Consider optimizing agent prompts to reduce token usage 4. Monitor cost progression closely --- **Note**: この警告Issueは経済的緊急事態に達するまで更新され続けます。 EOF )" else # 既存のIssueにコメント追加 gh issue comment "$EXISTING_ISSUE" --body "$(cat <<'EOF' ## 📊 Cost Update - $(date -u +"%Y-%m-%d %H:%M UTC") - **Consumption Rate**: ${{ steps.calculate.outputs.consumption_percent }}% - **Total Cost**: \$${{ steps.calculate.outputs.total_cost }} USD 現在も警告レベルを超えています。コスト監視を継続中... EOF )" fi - name: ✅ Post Success Status if: steps.calculate.outputs.status == 'OK' run: | echo "✅ System operating within budget" echo "📊 Consumption: ${{ steps.calculate.outputs.consumption_percent }}%" echo "💚 All systems normal"