ctx-bucket
WIP(現在進行中)
Work In Progress
このプロジェクトで現在進行中の作業と、過去のスナップショットを記録する。
現在の状況
(2026-10-04 23:11 更新)
どこまで進んだか: 収集・蓄積・活用の3層がひととおり動いている。CtxCapture は6タブ(TODO / カレンダー / 麻雀 / Message / その他=メディア・キャプチャ)構成で実機(iPhone 14)稼働中。今セッションで麻雀タブを追加し、mahjong-lab のサーバー worker が作る麻雀の振り返りレポート(mahjong/)を読めるようにした。麻雀タブの+から NAGA のレポート URL を送ると、digest が daily に記録し、worker がレポートを作って通知する(通し動作は未確認)。
次にやること:
- キャプチャ画面の保存失敗を成功扱いする件を直す(別タスクとして切り出し済み)
- アプリ削除→再インストールで保身の記録が iCloud から戻るかのテスト(
~/ichirokisanuki/ctxcapture-backup/にバックアップ済み) - 既存7件の保身の記録に評価を後付けする
- 朝昼夜のブリーフィング cron を多目的サーバー1に設置(積み残し)
未決事項: digest が新ルールどおり NAGA の URL を daily にそのまま記録するかは、最初の本番で確認する。キャプチャが「その他」の中に移って2タップになったので、使いにくければ配置を見直す。実機の iCloud サインイン状態はまだ目視していない。capture-ios/.devnotes/ の二重管理も未整理。
過去のWIPアーカイブ
(新しい「現在の状況」を書く前に、古いものをここに追記でアーカイブする。新しいものが上)
2026-09-23 02:29 時点のスナップショット
どこまで進んだか: 収集・蓄積・活用の3層がひととおり動いている。仕分けサーバーが投入から約1分で自動 digest し、CtxCapture は5タブ(TODO / カレンダー / メディア / Message / キャプチャ)構成で実機(iPhone 14)稼働中。通知ゲートウェイ経由の APNs プッシュと Gmail 監視も動いている。今セッションでは CtxCapture の起動タブを TODO にし、保身の記録に3段階評価(Good / Normal / Bad)と iCloud キー値ストアによる削除耐性を入れて、実機へ削除なしで上書き済み(既存の記録7件は無事)。
次にやること:
- アプリ削除→再インストールで保身の記録が iCloud から戻るかのテスト(
~/ichirokisanuki/ctxcapture-backup/にバックアップ済みなので安全に試せる) - 既存7件の保身の記録に評価を後付けする
- 朝昼夜のブリーフィング cron(朝7:30 計画 / 昼12:30 ナッジ / 夜21:30 振り返り)を多目的サーバー1に設置(積み残し)
未決事項: 実機の iCloud サインイン状態を設定画面でまだ目視していない(「未サインイン」ならミラーは効かない)。capture-ios/.devnotes/ がルートの .devnotes/ と二重管理になっていて、中身は 2026-08-08 で止まっている。
2026-08-17 16:25 時点のスナップショット
どこまで進んだか: 仕分けサーバーが本番稼働中(投入から約1分で自動 digest)。加えて iOS キャプチャアプリ CtxCapture を旧 ctx-bucket-capture-ios リポジトリから capture-ios/ に履歴ごと吸収し、収集・蓄積が1リポジトリに一本化された。旧 GitHub リポジトリとローカルディレクトリは削除済み。
次にやること:
- 朝昼夜のブリーフィング cron(朝7:30 計画 / 昼12:30 ナッジ / 夜21:30 振り返り)を同じサーバーに設置
- APNs + 自前 iOS アプリ v1(プッシュ受信+今日ビュー)
- アプリに capture 入力を統合(v1.5)、TODO チェックオフ(v2)
- 新しい場所(
capture-ios/)で Xcode ビルドが通ることを次のアプリ作業時に確認
未決事項: 通知3枠→5枠への拡張タイミング、ブリーフィングの文面設計、APNs まわりの具体(証明書、配布は TestFlight 想定)。
2026-08-17 16:13 時点のスナップショット
どこまで進んだか: 仕分けサーバーが本番稼働。多目的サーバー1の毎分 cron が inbox への push を検知し、約1分で自動 digest(正規化→daily/todo 振り分け→commit & push)される。手動 /digest は日常では不要になった。end-to-end テスト済み(c19a9bc)。
次にやること:
- 朝昼夜のブリーフィング cron(朝7:30 計画 / 昼12:30 ナッジ / 夜21:30 振り返り)を同じサーバーに設置
- APNs + 自前 iOS アプリ v1(プッシュ受信+今日ビュー)
- アプリに capture 入力を統合(v1.5)、TODO チェックオフ(v2)
未決事項: 通知3枠→5枠への拡張タイミング、ブリーフィングの文面設計、APNs まわりの具体(証明書、配布は TestFlight 想定)。
ROADMAP(計画)
ロードマップ
今週
- 朝昼夜のブリーフィング cron(朝7:30 計画 / 昼12:30 ナッジ / 夜21:30 振り返り+digest 済み確認)を多目的サーバー1に設置
- アプリ削除→再インストールで保身の記録が iCloud から復元されるかテスト
- キャプチャ画面で、保存に失敗したら入力を残してエラーを出す(今は成功表示になる)
今月
- 自前 iOS アプリ v1: APNs プッシュ受信+今日ビュー(ブリーフィング履歴・tomorrow.md 表示)
- 仕分け完了時の「仕分けたよ」即時プッシュ(capture 習慣維持のための応答ループ)
今四半期
- アプリに capture 入力を統合(GitHub API で inbox/ へ push、v1.5)
いつか
- TODO チェックオフのアプリ書き戻し(v2)
- 毎分 cron を GitHub webhook(push 即仕分け)に格上げ
- 通知を3枠→5枠に拡張(15:30 / 18:30 など)
- 音声文字起こし対応(必要になったら OpenAI 文字起こし API で)
DECISIONS(意思決定)
意思決定記録
このプロジェクトで下した重要な意思決定を記録する。 最新が上に来る。
2026-10-04: digest は NAGA のレポート URL を読みに行かず、daily にそのまま記録する
背景: 麻雀タブ(またはキャプチャ)から NAGA のレポート URL が inbox に入るようになった。NAGA のレポート画面は JavaScript で描くため、WebFetch しても本文が取れず、中身のない reading/ が溜まる。
決定: NAGA のレポート URL(https://naga.dmv.nico/htmls/...)は例外として WebFetch せず、reading/ も作らず、daily に 麻雀: NAGA レポート <URL>(タグ #log)として URL をそのまま残す。
理由: URL を拾ってレポートを作るのは mahjong-lab のサーバー worker の仕事で、digest は記録だけすればよい。タグは既存の最小セット(#log)に収め、新タグは増やさない。
2026-10-04: ctx-bucket に mahjong/(mahjong-lab の生成物)を置く
背景: CtxCapture の麻雀タブで、mahjong-lab が作る HTML レポートを読みたい。アプリの GitHub トークン(PAT)は ctx-bucket にしか触れない設定。
決定: mahjong-lab が mahjong/index.json と mahjong/<id>.html を ctx-bucket に公開し、アプリはそれを読む。mahjong/ は手で編集せず、公開は mahjong-lab の tools/publish.py が公開専用のクローン経由で行う(普段の作業コピーやサーバーの digest 作業コピーには触らない)。
理由: You の選択。PAT の対象に mahjong-lab を足す案もあったが、設定変更なしで済むこちらを選んだ。ctx-bucket は「蓄積」の場所だが、活用層のアプリが読むデータの置き場として割り切る。
2026-10-04: タブを6つにして、メディアとキャプチャを「その他」へ移す
背景: 麻雀タブを足すとタブが6つになり、iPhone では下に並ぶのが4つで、残りは「その他」に入る。2026-09-23 の決定では「キャプチャは右端タブとして残し、1タップで到達」としていた。
決定: 並びを TODO / カレンダー / 麻雀 / Message / その他(メディア・キャプチャ)にする。キャプチャは2タップになる。
理由: You の選択。麻雀タブからも NAGA の URL は直接送れる。キャプチャが遠くて使いにくければ、配置を見直す。
2026-09-23: 保身の記録の削除耐性は iCloud キー値ストアのミラーで持たせる
背景: 保身の記録は端末内の hoshin.json にしか存在せず、アプリを削除すると失われる状態だった。一方で「この記録は ctx-bucket(GitHub)には出さない」という既存方針は維持したい。
決定: 端末内 JSON を正としたまま、同じ内容のスナップショットを iCloud キー値ストア(NSUbiquitousKeyValueStore、キー hoshin.snapshot.v1)へミラーする。CloudKit も ctx-bucket への同期も採らない。
理由: 利用者は自分ひとりで記録1件は数十バイトのため、1MB 上限のキー値ストアで当面十分足りる。CloudKit はスキーマとコンテナの運用が重く、この規模には過剰。ctx-bucket に出すと既存方針を崩す。キー値ストアはアプリ削除後も同じ Apple ID 側に残るので、再インストールの初回起動で戻せる。上限を超えたらミラーを止めて設定画面に警告を出す。
2026-09-23: 起動時のデフォルトタブを キャプチャ → TODO に変更
背景: MVP 当初は「起動即入力の1画面」が鉄則で、起動時はキャプチャタブだった。その後アプリは5タブ(TODO / カレンダー / メディア / Message / キャプチャ)に育ち、起動して最初に見たいものが変わった。
決定: 起動時の初期タブを TODO にする。キャプチャは右端タブとして残し、1タップで到達できる状態を維持する。
理由: 投入はサーバー側の自動 digest が約1分で処理するようになり、アプリを開く動機が「入力」から「今日やることの確認」に移った。キャプチャは1タップで届くので投入の摩擦はほとんど増えない。
2026-08-17: キャプチャアプリは独立リポジトリをやめ ctx-bucket に同居(モノレポ化)
背景: iOS キャプチャアプリを別リポジトリ(ctx-bucket-capture-ios)で始めたが、収集レイヤーだけ管理が分散し、文脈把握もリポジトリをまたぐ必要があった。
決定: git subtree で履歴ごと capture-ios/ に吸収し、旧 GitHub リポジトリと旧ローカルディレクトリは削除。以後キャプチャアプリの開発は ctx-bucket 内で行う。
理由: 利用者は自分ひとりで、3層パイプラインの収集・蓄積を1つのリポジトリで扱えるほうが見通しがよい。subtree なら旧履歴も残るため、リポジトリ削除による損失がない。将来の活用層アプリ(APNs 通知)も同居させる余地ができる。
2026-08-17: 活用層の媒体は自前 iOS アプリ・通知は1日3〜5回
背景: バケツに入れても何も返ってこないと capture 習慣が消える(実際に1週間投入ゼロが発生)。プッシュ型の「つながる媒体」が必要だった。
決定: 通知の受け口は自前 iOS アプリ(APNs)にする。ntfy・Google カレンダー通知・Claude cloud routine は不採用。通知は1日3〜5回(朝昼夜の3枠から開始)、v1 は読み取り専用でチェックオフ等の書き戻しは v2 以降。
理由: 将来の capture 入力・TODO ビューとアプリに統合でき、3層パイプラインが1つの器に収まる。通知頻度が多いため時間帯ごとに役割を変えて通知疲れを避ける設計とする。
2026-08-17: 仕分けは多目的サーバー1の毎分 cron + headless claude
背景: インテーク Mac は常時稼働ではないと判明し、サーバー側での自動仕分けが必要になった。実行エンジンは codex exec 案もあった。
決定: 多目的サーバー1(Lightsail 512MB)の毎分 cron で、リモート HEAD の変化を検知したときだけ pull し、inbox に中身があるときだけ headless claude -p "/digest" を実行する。
理由: digest の手順書が Claude Code スキルとして完成済みで、claude -p ならスキル・WebFetch・画像読解をそのまま再利用できる(codex だと AGENTS.md への移植=二重管理になる)。サブスク OAuth トークンで従量課金も不要。毎分の空振りは ls-remote 1リクエストのみでコストは実質ゼロ。
2026-08-17: 音声文字起こしは仕分け対象外
背景: mlx_whisper は Apple Silicon 専用で Lightsail (x86) では動かず、代替は API 課金か低精度な CPU 版 whisper だった。
決定: 音声文字起こし機能は載せない。音声ファイルが来たらスキップして inbox に残す(スキルの既存フォールバック)。
理由: 現状の capture はテキスト・画像・URL が主で、音声の必要性が薄い。必要になったら OpenAI 文字起こし API の追加で対応可能。
DEVLOG(作業ログ)
開発日誌
このプロジェクトでの作業を時系列で記録する。 最新のエントリが上に来る。
2026-10-04
23:11 - CtxCapture に麻雀タブを追加、mahjong-lab の自動レポートとつないだ
やったこと
- CtxCapture に麻雀タブを追加(
Views/MahjongView.swift/Services/MahjongStore.swift/Models/MahjongGame.swift)mahjong/index.json(一覧)とmahjong/<id>.html(レポート)を GitHub Contents API で読み、WKWebView で表示。中のリンク(NAGA・天鳳)は Safari で開く- HTML は中身の SHA-1(先頭12桁)を一覧の
hashと照合してからキャッシュ(Caches/mahjong/)。一覧の取得は端末の HTTP キャッシュを使わない - 右上の+から NAGA のレポート URL を送信(
CaptureQueueで inbox/ へ)。一覧に出るまで「作成中」を表示(UserDefaults に report_id と送信時刻)。天鳳の牌譜 URL など NAGA のレポート以外は送る前に弾く - 通知の
kindが「麻雀」なら、タップで麻雀タブを開く(PushService.openMahjongTab)
- タブが6つになったため、メディアとキャプチャを「その他」へ移した(TODO / カレンダー / 麻雀 / Message / その他)
- 通知タップでのタブ切り替えを
onChange(initial: true)にし、通知からの初回起動でも取りこぼさないようにした(Message タブも同様) CaptureQueue.enqueueが端末への保存の成否(Bool)を返すようにした。GitHubClient.getFileにignoreCacheを追加PasteButtonのクロージャを@Sendableにした(Swift 6 で MainActor を継承すると実行時検査で落ちる既知の問題)- digest に「NAGA のレポート URL は WebFetch せず、daily に
麻雀: NAGA レポート <URL>としてそのまま記録する」ルールを追加 mahjong/を新設し、最初のレポート(2026-10-04 一般東風)を mahjong-lab の公開スクリプト経由で置いた- 実機(iPhone 14)へ削除せず上書きインストール(USB 経由)。保身の記録・メディア・送信履歴が残っていることを確認。サーバーからの試し通知で麻雀タブが開くことを確認
- コミット前に Codex(GPT)にレビューを3回頼み、指摘(通知からの初回起動、キャッシュの整合、URL 判定、PasteButton など)を反映
決めたこと
- タブを6つにして、メディアとキャプチャを「その他」へ(DECISIONS.md 参照)
- ctx-bucket に
mahjong/(mahjong-lab の生成物)を置く(DECISIONS.md 参照) - digest は NAGA のレポート URL を読みに行かず、daily に記録するだけにする(DECISIONS.md 参照)
気づき
devicectlはネットワーク経由だと途中で「利用不可」になることがある。USB でつなぐと確実- シミュレータで麻雀タブを確かめるときは、環境変数
MAHJONG_LOCAL_DIRに mahjong-lab のreports/を渡すと GitHub を使わずに読める(DEBUG のシミュレータだけ) - Codex のレビューで、キャプチャ画面にも「保存に失敗しても入力を消して成功表示する」既存の問題が見つかった(今回の変更とは無関係なので別タスクに切り出した)
次回やること
- キャプチャ画面の保存失敗を成功扱いする件を直す
- 麻雀の通し動作(NAGA の URL を送る → digest → サーバー worker → 麻雀タブ・通知)を、次の半荘で確認する(mahjong-lab 側の作業)
2026-09-23
02:29 - 保身の記録の3段階評価と iCloud バックアップ、起動タブ変更
やったこと
- CtxCapture の起動時デフォルトタブを「キャプチャ」から「TODO」に変更
- 保身の記録に3段階評価(Good / Normal / Bad)を追加。良いほど濃いオレンジで月・年ビューを塗る (同じ日に複数あればその日の最も良い評価を採用)
- 評価より前の記録は
gradeを nil のまま「未登録」として扱い、色は Normal と同じ。 編集シートから後付けできる(選ばなければ未登録のまま) hoshin.jsonをスナップショット形式(updatedAt/records/deletedIDs)に変更し、 旧形式(記録の配列だけ)から自動移行するようにした- 同じ内容を iCloud キー値ストア(キー
hoshin.snapshot.v1)へミラー。 取り込みは id の和集合、削除は墓標(deletedIDs)で伝播、同じ id はupdatedAtが新しい側を採用 - 設定画面に「保身の記録のバックアップ(iCloud)」を追加 (サインイン状態 / 件数 / 最終同期 / 今すぐ同期)
- entitlements に
com.apple.developer.ubiquity-kvstore-identifierを追加 (project.ymlと実ファイルの両方) - シミュレータに旧形式 JSON を置いて、自動移行・未登録表示・Good/Bad の濃淡を目視確認
- 実機(iPhone 14)へ削除せず上書きインストール。記録7件がそのまま残ることを、 インストール後にコンテナから読み直して確認。アプリの起動とクラッシュなしも確認
決めたこと
- 保身の記録の削除耐性は iCloud キー値ストアのミラーで持たせる(DECISIONS.md 参照)
- 起動時のデフォルトタブを TODO にする(DECISIONS.md 参照)
気づき
devicectl device info filesは--username、devicectl device copy fromは--userと オプション名が揃っていない。開発用署名のアプリならコンテナのファイルを Mac 側へ吸い出せるので、 実機を触る前のバックアップ手段として使える- 端末に
Library/SyncedPreferences/com.apple.kvs/ChangeTokens/…が出来ていれば、 キー値ストアが実際に同期機構に載っている確認になる
次回やること
- アプリ削除→再インストールで iCloud から実際に復元されるかのテスト
(
~/ichirokisanuki/ctxcapture-backup/にバックアップ済みなので安全に試せる) - 既存7件の保身の記録に評価を後付けする
2026-08-17
16:25 - キャプチャアプリのリポジトリ吸収(モノレポ化)
やったこと
ctx-bucket-capture-ios(iOS キャプチャアプリ CtxCapture)をgit subtreeで このリポジトリのcapture-ios/に履歴ごと吸収(旧3コミットもgit logで辿れる)- 旧リポジトリに残っていた未コミット分(アプリアイコン PNG / Contents.json / exportOptions.plist)も取り込み
- ルート CLAUDE.md(ディレクトリ構成・位置づけ)と
capture-ios/CLAUDE.md(冒頭)を新構成に更新 - 旧 GitHub リポジトリ
ichirokisanuki/ctx-bucket-capture-iosを削除、 旧ローカルディレクトリ~/cdev/ctx-bucket-capture-iosも削除(110MB 解放) - capture アプリ側の開発メモは
capture-ios/.devnotes/としてそのまま保持
決めたこと
- キャプチャアプリは独立リポジトリをやめ ctx-bucket に同居させる(DECISIONS.md 参照)
次回やること
- 新しい場所(
capture-ios/)で Xcode ビルドが通ることを次のアプリ作業時に確認
16:13 - 活用層(媒体)の設計相談と仕分けサーバー構築
やったこと
- 「ctx-bucket と自分がつながる媒体」の設計相談。プッシュ型を先行させる段階論で合意 (ブリーフィング通知 → 自前アプリ、TODOアプリは摩擦を感じてから)
- 多目的サーバー1に毎分 cron の仕分け worker を構築(
/usr/local/bin/ctx-bucket-digest.sh)git ls-remoteでリモート HEAD 変化を監視、inbox/に中身があるときだけ headlessclaude -p "/digest"を実行。LLM 起動は capture 時のみ- deploy key(write 権限)
~/.ssh/id_ed25519_ctx_bucket、clone 先/home/ubuntu/apps/ctx-bucket/ - 認証はサブスク OAuth トークン(
~/.config/ctx-bucket-digest.env) - RAM 512MB のためスワップ 2GB 前提(既設)。Claude CLI・libheif を新規インストール
- digest スキルを Linux 対応に微修正(heif-convert、inbox 不存在時の扱い)
- end-to-end テスト成功: capture push 16:00:43 → 検知 16:01:06 → 仕分け完了 16:01:44。 投入から約1分で自動仕分けされる蓄積層が完成
- 両リポジトリ(ctx-bucket / multi-purpose-lightsail-server1)のドキュメント更新
決めたこと
- 媒体は自前 iOS アプリ・通知は1日3〜5回(DECISIONS.md 参照)
- 仕分けエンジンは codex exec でなく headless claude(DECISIONS.md 参照)
- 音声文字起こしは対象外(DECISIONS.md 参照)
気づき
- 8/10〜8/17 の1週間 capture がゼロだった。「返ってこないと入れる習慣が消える」の実証。 プッシュ型の媒体と「仕分けたよ」即時応答が習慣維持の鍵になりそう
次回やること
- 朝昼夜のブリーフィング cron(朝7:30 計画 / 昼12:30 ナッジ / 夜21:30 振り返り)
- その後 APNs + 自前アプリ v1(プッシュ受信+今日ビュー)
最近のコミット
- 2ec5284 麻雀レポートを更新 2026/10/5
- 00a8e47 digest: 2026-10-05 12:29 2026/10/5
- 3e2121a capture: 2026-10-05-122801-dde.md 2026/10/5
- 11e8a9d 麻雀レポートを更新 2026/10/5
- fa17712 CtxCaptureの日付表示を西暦・日本語に固定(端末が和暦でも「Reiwa 8」と出ないように) 2026/10/5
- 081136a 麻雀レポートを更新 2026/10/5
- 98b8038 digest: 2026-10-05 10:46 2026/10/5
- 4abc2d6 capture: 2026-10-05-104552-cpw.md 2026/10/5
- 2ada50f gmail-watch: 両アドレスに届く同じ内容の写しを1件として扱い、二重通知を防ぐ 2026/10/5
- c638de1 gmail-watch: 朝7時台の初回実行で夜間分(8.5h)を拾うようにし、Notta週次レポートを無視に追加 2026/10/5
README
ctx-bucket
自分の生活コンテキストをとにかく突っ込むバケツ。
テキスト・音声・画像・URLを inbox/ に放り込み、Claude Codeの /digest がテキストに正規化して日次ログに積む。
データベースでもナレッジベースでもなく、バケツ。入力時にスキーマも分類も要求しない。
セットアップ
- このディレクトリを
~/cdev/ctx-bucket/に置く - プライベートリポジトリを作ってpush
cd ~/cdev/ctx-bucket git init && git add -A && git commit -m "init" gh repo create ctx-bucket --private --source=. --push - 音声の文字起こし用にwhisperを入れる(音声を使わないなら省略可)
uv tool install mlx-whisper # Apple Silicon推奨 claudeを起動して/digestと打てば準備完了の確認になる (動作確認用のサンプルがinbox/に入っている)
使い方
- 思いついたら・撮ったら・録ったら、ファイルを
inbox/に放り込む - 1日1回(またはinboxが気になったら)Claude Codeで
/digest daily/に日次ログ、todo/にやることリストが育っていく
設計原則
- 入力ゼロ判断: 突っ込むハードルを上げるものはすべて敵
- 出口で構造化: 分類・整形・振り分けはdigestの仕事
- プレーンテキスト+Git: AIに食わせる前提。grepとClaude Codeで後からいくらでも掘れる
- 元データ不滅: 処理後も
attachments/に原本を残す
ロードマップ
- iOSキャプチャアプリ(テキスト・録音・共有シート → GitHub API経由でinboxへpush)
- TODOビューアプリ(
todo/を読み書きする別ビュー。完了項目は「やったこと」としてdailyへ還流) - 定期実行(自宅Macでdigestを自動化)
- 再浮上・活用レイヤーとの接続