chore: Add workflow economic-circuit-breaker.yml
This commit is contained in:
parent
f6312eb3c4
commit
31fe696e5a
1 changed files with 395 additions and 0 deletions
395
.github/workflows/economic-circuit-breaker.yml
vendored
Normal file
395
.github/workflows/economic-circuit-breaker.yml
vendored
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue