daily-triage 自己改善ループ: resolve スクリプト
「ループ・ゴール」型実装の最小ケーススタディとして機能している自己改善ループの中核スクリプト。
- 位置:
/Users/ish/Claude/work/clients/BOSS/AI活用/daily-triage/scripts/daily_triage_resolve.sh - 役割: 要確認アイテム(needs_review.json)に対し、人間が判断した resolution を記録して解決済みにマークする
- ループ性: 解決ログが蓄積 → 次回の自動分類精度が上がる構造
ソース全文
#!/usr/bin/env bash
# daily-triage 要確認アイテムを解決済みにマークする
#
# 使い方:
# daily_triage_resolve.sh <item_id> <resolution>
# daily_triage_resolve.sh abc12345 "alias_for: higgsfield"
# daily_triage_resolve.sh abc12345 "削除"
# daily_triage_resolve.sh abc12345 "保留"
#
# resolution が "alias_for: <サービス名>" 形式の場合、
# keyword_aliases.json にも自動で追加される(次回以降は要確認に上がらない)
set -euo pipefail
ITEM_ID="${1:-}"
RESOLUTION="${2:-}"
if [[ -z "$ITEM_ID" || -z "$RESOLUTION" ]]; then
echo "usage: $0 <item_id> <resolution>" >&2
echo " 例: $0 abc12345 \"alias_for: higgsfield\"" >&2
exit 1
fi
DATA_DIR="/Users/ish/Claude/work/clients/BOSS/AI活用/daily-triage/data"
NEEDS_REVIEW="$DATA_DIR/needs_review.json"
ALIASES="$DATA_DIR/keyword_aliases.json"
if [[ ! -f "$NEEDS_REVIEW" ]]; then
echo "needs_review.json が見つかりません: $NEEDS_REVIEW" >&2
exit 1
fi
export DT_NEEDS_REVIEW="$NEEDS_REVIEW"
export DT_ALIASES="$ALIASES"
export DT_ITEM_ID="$ITEM_ID"
export DT_RESOLUTION="$RESOLUTION"
/usr/bin/python3 - <<'PYEOF'
import json
import os
import sys
from datetime import datetime, timedelta, timezone
JST = timezone(timedelta(hours=9))
NEEDS_REVIEW = os.environ["DT_NEEDS_REVIEW"]
ALIASES = os.environ["DT_ALIASES"]
ITEM_ID = os.environ["DT_ITEM_ID"]
RESOLUTION = os.environ["DT_RESOLUTION"]
with open(NEEDS_REVIEW, "r", encoding="utf-8") as f:
data = json.load(f)
target = None
for it in data.get("items", []):
if it.get("id") == ITEM_ID:
target = it
break
if not target:
print(f"item_id {ITEM_ID} は見つかりません", file=sys.stderr)
sys.exit(2)
now = datetime.now(JST).strftime("%Y-%m-%d %H:%M:%S")
target["status"] = "resolved"
target["resolved_at"] = now
target["resolution"] = RESOLUTION
data["_updated_at"] = now[:10]
with open(NEEDS_REVIEW, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"resolved: id={ITEM_ID} keyword={target.get('keyword')}")
if RESOLUTION.startswith("alias_for:"):
alias_target = RESOLUTION.split(":", 1)[1].strip()
alias_target = alias_target.split("(")[0].strip()
try:
with open(ALIASES, "r", encoding="utf-8") as f:
aliases_data = json.load(f)
except FileNotFoundError:
aliases_data = {"aliases": {}}
aliases_data.setdefault("aliases", {})[target["keyword"]] = alias_target
aliases_data["_updated_at"] = now[:10]
with open(ALIASES, "w", encoding="utf-8") as f:
json.dump(aliases_data, f, ensure_ascii=False, indent=2)
print(f"alias added: {target['keyword']} -> {alias_target}")
PYEOF