"Todoist登録の入口。期限付き登録の前にGoogle Calendarと突合(✅可能/⚠️タイト/🚫無理)→作業ブロック案→承認分だけtd.py add+カレンダー登録。突合を飛ばすとhookがdeny。他スキルの期限付き登録も本手順。Triggers: タスク登録して/Todoistに入れて/タスクにしといて。NOT: 逆算→gyakusan、棚卸し→task-audit"
Resources
7Install
npx skillscat add thiguchi125-debug/claude-config/task-add Install via the SkillsCat registry.
対象外(2026-09-05〜): 市役所対応の市民要望案件(相談者がいて担当課へ照会→回答→報告)は Todoist でなく市民要望管理台帳(
~/.claude/scripts/yobo/yobo.py add)へ。本スキルは草川自身の議会・政策・イベント・選挙タスクだけ扱う。迷ったら判定1問「終わったら誰かに報告するか?」→はい=台帳(本スキル対象外)/いいえ=Todoist。親PJは8本固定(Inbox/🏛議員活動/📝議会(会期別)/🎪地域・イベント/🗳選挙2026/📣発信/🏡家族・プライベート/🗂構想バックログ)=空の案件箱を新設しない。詳細=OPERATIONS.md【B】例外節
task-add — カレンダー突合つきタスク登録
目的: 「実施できない日を期限に設定してしまい、期限切れタスクが積み上がる」を構造的に潰す。提案止まりが既定。承認なしにTodoistへ書き込まない。
設計の正本は同ディレクトリの DESIGN.md。本ファイルと矛盾したら DESIGN.md が優先。
Step 1: タスクの整理
登録候補を「内容・登録先プロジェクト案・期限案」の3点に整理する。
- 期限案の既定は今日+3日([[feedback_task_deadline_3days]]・あくまで推奨案であって確定値ではない)
python3 ~/.claude/scripts/todoist/td.py projectsで実在するプロジェクト名を確認してから--projectを決める(「📋 政策・一般質問」は実在しない)- 相手のボール待ち=
@結果待ち、やる方向だが要検討=@保留 - 期限を付けない登録(@アイデア等)はここで終了。Step 2以降は不要で、hookも素通しする
Step 2: 想定所要の見積り
タスク内容から下表で推定する。所要は時間の合計ではなく「30分コマ」の数で数える(1セッション=1時間=2コマ)。30分粒度にしているのは、電話1本のような30分タスクを1時間単位で切り捨てると「30分空いている日」が0と数えられ、実施可能なのに🚫になるため。
| 種別 | 判定語 | 想定所要 | 必要コマ | 最低所要日数 |
|---|---|---|---|---|
| 連絡・電話・アポ取り | 電話/連絡/アポ/確認する | 15分 | 1コマ | 1日 |
| メール・DM返信 | 返信/メール/返事 | 30分 | 1コマ | 1日 |
| 挨拶原稿 | 挨拶/祝辞 | 30分 | 1コマ | 1日 |
| 資料読み込み | 読む/目を通す/資料確認 | 1h | 2コマ | 1日 |
| ブログ・SNS | ブログ/投稿/発信 | 1h | 2コマ | 1日 |
| 訪問・現地確認 | 訪問/現地/視察 | 1h | 2コマ | 1日 |
| 議案分析・調査 | 分析/調査/リサーチ | 3h | 6コマ | 2日 |
| 一般質問・議案質疑原稿 | 一般質問/質疑/通告 | 4h | 8コマ | 2日 |
| スライド・報告会資料 | スライド/資料作成/報告会 | 4h | 8コマ | 2日 |
| 印刷物制作・入稿 | チラシ/ポスター/リーフレット/入稿 | 8h | 16コマ | 4日 |
- 表に該当が無ければ内容から推定し、根拠を1行添える
- 推定値は提案時に必ず表示する。草川が「これ30分」と訂正したら再計算する
- 最低所要日数 =
ceil(必要コマ ÷ 4)(1日に同一タスクへ割けるのは最大2セッション=4コマのため)
Step 3: カレンダー取得
mcp__claude_ai_Google_Calendar__list_events を1回だけ呼ぶ。
calendarId =
kusakawa.taku@gmail.com(kusagawaは誤り)期間 = 今日 〜 期限候補日+14日(+14日は代替期限案を出すための余白)
複数タスクをまとめて登録する場合も、最も遠い期限候補日+14日までを1回で取る。タスクごとに呼ばない
草川のカレンダーは予定が密で、2週間分でも応答が7万字を超えてそのままではコンテキストに載らない。載らなかった場合はツール結果が自動でファイルに保存されるので、そのパスをそのまま Step 4 のスクリプトに渡す(中身を読み下す必要はない)。インラインで返ってきた場合はスクラッチパッドにJSONとして書き出してからパスを渡す
nextPageTokenを必ず確認する(2026-08-06 実運用で発覚)。pageSizeの上限は250件で、草川のカレンダーは約4週間で250件に達する。トークンが返っていたらページが切れており、取れなかった予定が「空き時間」に見える。そのまま割り付けると実在の予定の上に作業ブロックを重ねる。対処は「窓を4週間以内に狭めて取り直す」(pageTokenで継ぎ足すと2ページ目がコンテキストに載ってしまい、ファイル1本にまとまらない)取得結果のヘッダに
nextPageTokenが無ければ完全。あれば窓を狭めて取り直す
gyakusan から呼ばれた場合など、呼び出し元が既にカレンダーを取得済みならそれを受け取り、再取得しない。
Step 4: 空き枠の算出と判定(スクリプトで行う)
区間のマージ・隙間の足切り・1日上限を手計算すると必ず間違えるので、同ディレクトリの sessions.py を使う。手で数えない。
python3 ~/.claude/skills/task-add/sessions.py <events.json> \
--from <今日 YYYY-MM-DD> --due <期限候補日 YYYY-MM-DD> --need <必要コマ数> \
[--now HH:MM] --plan --plan-json <plan_1.json> --plan-title "<タスク内容>"出力に日別コマ数・判定・着手推奨日・代替案がそのまま出る。タスクごとに --due と --need を変えて呼ぶ(カレンダーの取得は1回のまま)。
--plan は既定で必ず付ける。 これが「いつやるか」を実際の時間帯に割り付けた作業ブロック案で、Step 10 でカレンダーに書き戻す材料になる。付け忘れると従来通り「期限日という終日の点」しか残らず、スケジュールに時間が反映されない。--plan-json の出力先はスクラッチパッド配下にタスクごと別名で置く。
ブロック配置の規則(判定コマ数の計算とは別レイヤ・plan_blocks()):
- 1ブロック = 最大60分(1セッション)。1つの空き区間には1ブロックしか置かず、日をまたいで散らす
- 1日あたり ✅可能なら2コマ(1時間)まで/⚠️・🚫なら4コマまで。余裕がある案件を1日に詰め込まない
- 昼 12:00–13:00 には置かない(配置専用の規則。コマ数の算出では昼を引いていないので判定は変わらない)
- 15:00–18:30 は挨拶回り優先枠なので置かない([[feedback_greeting_rounds_time_reserve]]・2026-08-07指示)。例外は草川が「今日はこの時間に作業を入れられる」と明示した日だけで、そのとき
reserve_greeting=Falseで開ける。この枠を空けると実働容量が約1/4減り、役所への照会に使えるのは実質「平日午前」と「13:15–14:45」だけになる - 期限までに置き切れない分は
⚠️ 未割付 Nコマとして出る。これが出たら判定は 🚫 側なので代替期限案とセットで出す
スクリプトが実装している規則:
- 稼働帯 9:00–21:00(全曜日・土日祝も同じ)。当日は
--now以降 - 予定の重なりはマージする。30分未満の隙間は使えないものとして捨てる
- その日のコマ数 =
min(4, 使える空きの30分単位)。1日に同一タスクへ割けるのは最大2セッション=4コマ - 終日予定は原則ブロックしない。 草川のカレンダーでは終日予定の大半が目印(グラウンドゴルフ・憩いの場・地域行事等)で、実際の拘束は時間指定予定として入っている。一律に作業不可日にするとほぼ全日が0コマになる。「議会/視察/出張/研修/入院/旅行/終日」を含む終日予定だけを**作業不可日(0コマ)**とする
【参考】で始まる予定は完全に無視する(他人の行事等の参考情報であり草川を拘束しない)- 移動時間は考慮しない
Step 5: 3値判定(スクリプト出力の読み方)
| 判定 | 条件 | 提案に書くこと |
|---|---|---|
| ✅ 可能 | 確保可能 ≧ 必要コマ × 1.5 | 着手推奨日を併記 |
| ⚠️ タイト | 必要 ≦ 確保可能 < 必要 × 1.5 | 逼迫の理由(終日拘束日・予定過密日)と着手推奨日を併記 |
| 🚫 無理 | 確保可能 < 必要コマ、または残り日数 < 最低所要日数 | 代替期限日を2案(最短で足りる日/余裕×1.5を満たす日) |
残り日数が最低所要日数を下回る場合は、空き状況を見るまでもなく 🚫 になる(例: 入稿16コマ=最低4日を3日後の期限で登録しようとした場合)。
着手推奨日 = 「その日から期限日までに確保できるコマ数が必要数以上になる」日のうち最も遅い日。これ以上先延ばすと間に合わなくなる境界日。
Step 6: 提案
python3 ~/.claude/scripts/todoist/td.py week で同期間に期限が来る既存タスクの件数を取り、ヘッダに併記する(所要を推定して空き時間から差し引くことはしない)。
期限だけでなく作業ブロック案も同じ画面に出す。 確認は1回に束ねる([[feedback_ask_bundling_and_upfront_reflection]])ので、「登録していいか」と「この時間帯でいいか」を別々に聞かない。
📋 タスク登録の確認(カレンダー突合済み 8/3〜8/12・同期間の既存タスク7件)
1. 川合町報告会のスライド作成
PJ: 🏛 議員活動 / 期限案: 8/12(火) / 想定: 4h(8コマ・最低2日)
確保可能 19コマ → ✅ 可能(着手推奨 8/10)
🗓 作業ブロック案: 8/5(火)14:30-15:30 / 8/6(水)9:00-10:00 / 8/8(金)9:00-10:00 / 8/9(土)9:00-10:00
2. ◯◯さんへ回答メール
PJ: 🏛 議員活動 / 期限案: 8/6(木) / 想定: 30分(1コマ)
確保可能 1コマ → ⚠️ タイト(8/4は視察で終日・8/5も予定過密)
🗓 作業ブロック案: 8/6(木)9:00-9:30
3. リーフレット入稿
PJ: 🗳 選挙2026 / 期限案: 8/5(水) / 想定: 8h(16コマ・最低4日)
🚫 残り3日 < 最低4日(確保9コマ < 必要16コマ)
代替案 a) 8/8(土) 累計19コマ b) 8/10(月) 累計27コマ ●推奨
※ブロック案は期限日を決めてから出し直します
→ 「1と2」「3はaで」「全部」「見送り」等でお答えください
→ 時間帯を変えたいものは「1は午後で」「2は要らない」等もどうぞ- ブロック案はタスクごとに出す。🚫のタスクは期限日が動くので、代替案を選んでもらってから出し直す
- 「ブロックは要らない・期限だけでいい」と言われたらカレンダー登録はスキップし、Step 9 だけ実行する
Step 7: 承認取得
草川の返答を待つ。返答が無いもの・見送られたものは登録しない。 既定値で勝手に確定登録しない([[feedback_ask_destination_and_deadline_before_register]])。
Step 8: 突合記録の書込
承認された分だけを ~/.claude/skills/task-add/_verified.json に書く。この記録が無いと次のStep 9が hook に deny される。
python3 -c "
import json, os
from datetime import datetime
p = os.path.expanduser('~/.claude/skills/task-add/_verified.json')
json.dump({
'generated_at': datetime.now().isoformat(timespec='seconds'),
'ttl_minutes': 30,
'calendar_ok': True,
'approved': [
{'content': '<td.py add に渡すのと同じ文字列>', 'due': 'YYYY-MM-DD',
'slots': <必要コマ数>, 'verdict': 'ok'},
],
}, open(p, 'w'), ensure_ascii=False)
"contentはtd.py addに渡す文字列と同じものを書く(hookは絵文字・空白・記号を無視して照合するので多少の揺れは吸収されるが、揃えておく)dueは--dueに渡すYYYY-MM-DDと完全一致させるverdictはok/tight/unverified- TTLは30分。承認から時間が空いたら書き直す
Step 9: 登録
承認分のみ td.py add を実行する。
python3 ~/.claude/scripts/todoist/td.py add "<内容>" --due YYYY-MM-DD --project "<実在PJ名>" [--priority 1-4] [--label 結果待ち] [--desc "<判定根拠1行>"]--desc に「想定4h(8コマ)・確保19コマ・着手推奨8/10」のような判定根拠を1行入れておくと、後で見返したときに期限の由来が分かる。
登録後、_verified.json は放置してよい(30分で失効する)。
Step 10: 作業ブロックをカレンダーへ登録
Todoistの期限は「いつまでに」しか表さない。「いつやるか」はカレンダー側に置く。 承認された作業ブロックを mcp__claude_ai_Google_Calendar__create_event で1ブロック=1予定として作成する。
calendarId : kusakawa.taku@gmail.com
summary : 【作業】<タスク内容>
startTime : 2026-08-06T09:00:00+09:00 (plan.json の date + start)
endTime : 2026-08-06T10:00:00+09:00 (plan.json の date + end)
timeZone : Asia/Tokyo
description : task-add 自動生成/Todoist期限 2026-08-12/想定4h(8コマ)の1/4
colorId : 8 (グレー系。既存の実予定と見分けるため全ブロック共通で固定)
availability: AVAILABILITY_BUSY- タイトルは必ず
【作業】で始める。 実際の予定(会議・訪問)と区別でき、後から一括削除もできる eventType: FOCUS_TIMEは使わない。フォーカスタイムは設定次第で招待を自動辞退するため、副作用が読めない- ブロックは時間指定予定として入るので、次回以降の
sessions.pyが自動的にこれを埋まった時間として扱う。二重に予定を入れない自己修復が効く - 作成後、実際に入った日時をチャットに1行でまとめて報告する
ブロックの後始末
- タスクを前倒しで終えた/不要になった場合、残った
【作業】予定は自動では消えない。td.py doneはカレンダーを触らない - 「作業ブロック消して」と言われたら
search_eventsで【作業】を引き、対象をdelete_eventする - 期限を動かした場合も同様に、古いブロックを消してから貼り直す
一括モード(既存タスクへまとめて作業ブロックを入れる)
「今のTodoistのタスクを全部スケジュールして」のように既存タスク群を対象にするときは、Step 1〜9(新規登録)を飛ばす。Todoistには何も書かないので _verified.json も hook も関係しない。
手順は「案を作る → 見せる → 直す → 登録」の4段。登録は最後
⚠️ 範囲の合意は登録の許可ではない。「今週分だけ」のようなスコープの返事をもらっただけで書き込んではいけない。ブロック案そのものを全件見せ、少なくとも1回は調整のやり取りを経てから登録する(2026-08-06 草川指摘「事前に提案して調整を試みてから入力する手法に変えてください」)。
| 段 | やること | 出力 |
|---|---|---|
| ① 案を作る | estimate.py → bulk_plan.py。カレンダーには一切書かない |
bulk_plan.json |
| ② 見せる | 日別に全ブロックを提示+除外・置けなかった分も必ず提示。自分が自信のない分類を名指しで挙げる | チャット |
| ③ 直す | 迷った点を1件1問の選択式で聞き、回答を tasks.json に反映 → ①へ戻る。草川が「これでいい」と言うまで登録しない |
修正版 |
| ④ 登録 | 承認された分だけ Step 10 で create_event |
カレンダー |
# ① タスク一覧をJSON化(td.py を import して projects_map / all_tasks を使う)
# ② 想定所要を機械的に付与
python3 ~/.claude/skills/task-add/estimate.py tasks.json
# ③ 現実性フィルタ込みで累積割り付け(提案止まり)
python3 ~/.claude/skills/task-add/bulk_plan.py <events.json> tasks.json <今日> <HH:MM> <窓の終端>現実性フィルタ(task_windows.py)
空き時間があるかより先に「相手がいる時間か」「自分の手番か」を見る。 2026-08-06 の初回実行では、空いているという理由だけで日曜に市役所照会を8件・18時以降に7件置き、「連絡待ち」のタスクにまでブロックを作った。カレンダーは埋まったが1件も実行できない。
| 種別 | 判定語の例 | 置ける曜日・時間 | 理由 |
|---|---|---|---|
| 除外 | @結果待ち @保留 ラベル/件名に「〜待ち」 |
置かない | 自分の手番ではない |
| 役所・関係機関 | 照会/担当課/県/警察/消防/教委/アポ/要望書 | 平日 9:00–17:00 | 窓口が開いていない |
| 現地確認 | 現地/下見/視察/写真記録/点検 | 全曜日 9:00–18:00 | 暗いと状況が見えない |
| 住民・関係者連絡 | 連絡/電話/返信/経過報告/◯◯さんへ/訪問 | 全曜日 9:00–20:00 | 夜遅く個人宅にかけない |
| 机上作業 | 上記以外 | 全曜日 5:00–7:00 と 9:00–21:00 | 相手がいない |
早朝5:00–7:00は机上作業だけ([[feedback_early_morning_desk_band]]・2026-08-07指示)。役所・連絡・現地は早朝に置かない=電話を早朝にかけない。Kind.band() が容量の数え方から分けているので、役所タスクの実施可能性が早朝で水増しされることはない。街頭活動6:30・あまね朝準備7:00がある日は自動的に短くなる(実測: 平日2〜3コマ/土日4コマ)。
配置側の規則(判定コマ数は変えない):
- 前後の予定と15分のバッファ(
BUFFER)。予定が終わった瞬間に次を始められない。結果として予定に挟まれた30分の隙間は使わない - 1日の総ブロック上限は平日4件・土日2件(
CAP_WEEKDAY/CAP_WEEKEND) - 昼 12:00–13:00 は置かない
分類は正規表現なので必ず外れが出る。外れを草川に直してもらうのが②③の工程で、ここを飛ばすと同じ失敗を繰り返す。
③の聞き方=1件1問の選択式([[feedback_ask_one_by_one_choices]])
「以下の4点を直してください」と箇条書きで並べて自由記述の返信を求めない。 草川に文章を組み立てさせるのがコストになる(2026-08-06 指摘)。AskUserQuestion で1件1問・タップで答えられる形にする。
- 1回につき最大4問。5件以上あるときは影響の大きい順に4問出し、残りは次のラウンドへ
- 選択肢は推奨案を先頭に置き「(推奨)」を付ける
- 典型的な設問=「この件の種別は役所/現地/連絡/机上のどれか」「所要は30分か1時間か」「分割せず1回で終わるか」
- 迷いが無い項目は聞かない。自分で判断がつかないものだけを設問にする
既存の【作業】ブロックとの整合(2026-08-06 草川指摘)
再提案の前に、既にカレンダーへ入れた 【作業】 を必ず消してから空きを数える。 消さずに計算すると、自分が置いた仮ブロックを「埋まっている」と誤認する。初回はこれで今週の空きがゼロになり、提示した候補時刻が全部すでに埋まっている枠だった。
# 再提案の第一手:既存ブロックの棚卸し
# list_events(fullText="【作業】") → 全件 delete_event → その後に list_events で取り直す- カレンダーの
【作業】を消してもTodoistのタスクは消えない。 消えるのは「いつやるか」の枠だけで、「やること」は残る。草川に確認されたら必ずこう説明する(td.py は一切呼ばない) - 「作業」を含む実在の予定(例:「けんろう折込チラシ作業」「奉仕作業」)を巻き込まない。先頭が
【作業】のものだけを対象にする - 1件の時刻を直すと他のブロックが押し出される。 累積割り付けなので、1件確定するたびに残り全部を再計算し、動いた分を差分として見せる。見せずに黙って動かすと、答えたはずの内容と結果がずれる
一括モードで必ず守ること
- 期限切れタスクは割り付け対象外。 今日より前の期限には置く先が無い。一覧を出して草川の判断を仰ぐ(期限の付け替えは hook のゲート対象で、勝手に動かさない)
- 入り切らない分を黙って捨てない。 「置けなかった N件」「除外 N件」を必ず一覧で出す。全部入ったように見せるのが最悪
- 量を先に見せる。 生成ブロック数と日別件数を提示してから作る
- 実績値(2026-08-06): アクティブ178件・期限あり164件で想定所要は合計415コマ=207.5時間。タスク量が容量を超えているというシグナル自体が成果物なので、詰め込んで隠さない
カレンダーが取れないとき
Google Calendar MCP が応答しない場合は突合を諦めて止まるのではなく、次のように進める。
- 提案に 「⚠️ カレンダー未確認」 と明示する(判定は出さない)
- 草川の承認を得る
_verified.jsonをcalendar_ok: false・各エントリのverdict: 'unverified'で書く- 登録する(Step 10 の作業ブロックは作らない。空きが分からないまま予定を入れると実在の予定と衝突する。「カレンダーが復旧したらブロックを入れ直しますか」と1行添える)
hook は calendar_ok の値で分岐しないので、記録さえあれば通る。黙って未確認のまま登録しないことが要件。
📌 恒久ガードルール
- 提案止まりが既定。承認なしのTodoist書込は禁止([[feedback_ask_destination_and_deadline_before_register]])
- 期限案の「今日+3日」は推奨案であって確定値ではない([[feedback_task_deadline_3days]] は上記に上書きされている)
- 想定所要は必ず提示する。 黙って見積もって黙って判定しない。訂正されたら再計算する
- カレンダーIDは
kusakawa.taku@gmail.com(kusagawaは誤り・CLAUDE.md正本) td.py projectsで実在PJ名を確認してから--projectを指定する- 1日に同一タスクへ割けるのは最大2セッション(4コマ)。空きが8時間ある日でも1タスクには4コマしか計上しない
- **空き枠の算出は必ず
sessions.pyに任せる。**区間のマージ・30分未満の足切り・1日上限を手計算すると間違える - **
sessions.pyは--plan付きで呼ぶ。**期限日(終日の点)だけ登録して「いつやるか」をカレンダーに書き戻さないと、突合で空きを計算した意味が消える(2026-08-05 草川指摘「日付の終日で登録されているだけで時間を細かくスケジュールに反映できていない」) - **作業ブロックの時間帯も承認事項。**期限の承認とまとめて1回で聞き、承認された時間帯だけカレンダーに入れる
- 範囲の合意を登録の許可と取り違えない。「今週分だけ」等のスコープ回答は入口の合意にすぎない。ブロック案を全件見せて調整を1回は回してから登録する(2026-08-06 草川指摘)
- **空き時間があることを「やれる」と読み替えない。**役所は平日9-17時、現地確認は明るいうち、
@結果待ちは自分の手番ではない。判定はtask_windows.py - **作業ブロックのタイトルは
【作業】始まり固定。**実予定と混ざると後始末ができなくなる - **カレンダー未確認のときは作業ブロックを作らない。**空きが分からないまま入れると実在の予定と衝突する
- **終日予定を一律に作業不可日としない。**草川のカレンダーでは終日予定の大半が目印であり、一律ブロックするとほぼ全日が0コマになる(2026-08-03 実データで確認)
- 既存タスクは件数のみ併記。所要を推定して空き時間から差し引かない(裏付けのない数字で判定を歪めない)
list_eventsは1回だけ。タスクごとに呼ばない- まず「記録で足りるか、タスク化が要るか」を振り分ける。方針・状況は記録に残すだけでタスクにしない
- 単発で完結しないタスクは CLAUDE.md「タスク登録時のプロジェクト化判定」基準A〜Eでプロジェクト化要否を問いかける