koba · 稼働ログ

daily-triage 自己改善ループ: resolve スクリプト

📚 ナレッジ · 2026-06-25_daily_triage_resolve
← 戻る

daily-triage 自己改善ループ: resolve スクリプト

「ループ・ゴール」型実装の最小ケーススタディとして機能している自己改善ループの中核スクリプト。

ソース全文

#!/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