Kanban Maintenance Guide

Drewgent 칸반 보드 정리 표준 절차. cron job과 수동 정리 모두 이 프로토콜을 따름.

문제

칸반 DB에 개발/테스트 중에 쌓인 junk task가 쌓이면:

  • 유의미한 task가 가려짐
  • cron job 결과가 혼잡해짐
  • board 가독성 저하

정리 기준

삭제 대상 (DELETE)

trigger_sourcestatusAction
testANY전부 삭제
verifyANY전부 삭제
manual_testANY전부 삭제
activity_loggercompleted전부 삭제 (cron garbage)

제목 기반 junk pattern

다음 패턴에 매치되면 trigger_source=manual 이어도 삭제:

  • A, B, C (단독 1글자 이름)
  • Test, Test A/B/C
  • Child task, Child2, Parent task
  • Block test, Link Child, Link Bug Child
  • Ready task for dispatcher
  • Default board task, Another default
  • integration test
  • [tool] *, [Discord] Test *, [test] *
  • Notify test (완료 후 방치된 것)

유지 대상 (KEEP)

  • trigger_source=manual + 의미 있는 제목
  • trigger_source=integration_workflow (모두)
  • trigger_source=activity_logger + status != completed
  • status=in_progress (작업 중인 것)

정리 스크립트

#!/usr/bin/env python3
"""Drewgent Kanban Board Cleanup — remove test/dev garbage."""
import sqlite3
from pathlib import Path
 
DB = Path.home() / ".drewgent" / "state" / "drewgent_tasks.db"
conn = sqlite3.connect(str(DB))
conn.execute("PRAGMA foreign_keys = ON")
 
# Phase 1: trigger-based bulk delete
deleted = 0
for trigger in ("test", "verify", "manual_test"):
    d = conn.execute("DELETE FROM tasks WHERE trigger_source=?", (trigger,)).rowcount
    deleted += d
 
d = conn.execute(
    "DELETE FROM tasks WHERE status='completed' AND trigger_source='activity_logger'"
).rowcount
deleted += d
 
# Phase 2: title-based cleanup (manual trigger only)
junk_titles = [
    "A", "B", "C",
    "Test", "Test A", "Test B", "Test C",
    "Child task", "Child2",
    "Block test",
    "Link Child", "Link Bug Child",
    "Ready task for dispatcher",
    "Default board task", "Another default",
    "integration test",
    "[tool] super_tool", "[tool] test_tool",
    "Notify test",
    "Parent task", "Parent2",
    "Link Parent", "Link Bug Parent",
    "[Discord] Test task from Activity Logger",
    "[Discord] p3g integration test",
    "[test] Activity logger test card",
]
placeholders = ",".join(["?"] * len(junk_titles))
d = conn.execute(
    f"DELETE FROM tasks WHERE trigger_source='manual' AND title IN ({placeholders})",
    junk_titles
).rowcount
deleted += d
 
conn.commit()
print(f"Deleted: {deleted}")
 
# Verify remaining
print(f"Remaining: {conn.execute('SELECT COUNT(*) FROM tasks').fetchone()[0]}")
for r in conn.execute("SELECT status, board, title FROM tasks ORDER BY status"):
    print(f"  [{r[0]:12}] {r[1]:12} | {r[2][:50]}")
 
conn.close()

task_links에 남은 parent/child가 실제 tasks 테이블에 존재하지 않으면 정리:

task_ids = {r[0] for r in conn.execute("SELECT id FROM tasks").fetchall()}
orphans = [(p, c) for p, c in conn.execute("SELECT parent_id, child_id FROM task_links")
           if p not in task_ids or c not in task_ids]
for p, c in orphans:
    conn.execute("DELETE FROM task_links WHERE parent_id=? AND child_id=?", (p, c))

cron job 연동

kanban-dispatcher가 매번 실행될 때 정리하는 것이 아니라, 주간 정리 cron job으로 분리:

{
  "name": "kanban-maintenance",
  "schedule": "0 3 * * 0",
  "prompt": "Run kanban cleanup script. Report: deleted=N remaining=N.",
  "deliver": "local"
}

HTML refresh

정리 후 dashboard 자동 갱신:

python3 ~/.drewgent/P4-cortex/scripts/generate_kanban_html.py
python3 ~/.drewgent/P4-cortex/scripts/generate_cron_html.py

완료 기준

정리 후 남은 task:

  • todo/ready: 실제 작업 항목만 (의미 있는 제목)
  • in_progress: 현재 작업 중인 것
  • blocked: 대기 중인 실제 blocking 원인이 있는 것
  • completed: integração workflow 완료 기록만

junk pattern이 보이는 즉시 정리하는 것이 아니라, 주 1회 정리로 운영.