0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

basou import で Claude Code / Codex のセッションを一つの証跡にまとめる

0
Posted at

🔗 この記事は https://blog.tak3.jp/ja/blog/basou-agent-session-trail/ からの転載です(一次情報源)。

Claude Code は、あなたのリポジトリで既に日記をつけている。Codex も同じだ。ただしそれは、読み返されることのないベンダーログの山としてだ — 別々の形式で、別々の場所に、読めず、検証できない形で。

5分後、それが変わる。両方のセッションが、コードの隣の一つの証跡に、同じ形式で並ぶ。ワークフローは何も変えない。過去のセッションも、遡って対象になる。

5分後に手に入るもの

対象リポジトリの隣に .basou/ ができて、中にこれらが入る:

  • 人間が読む handoff.md — どこまで進み、何が起き、どこから再開するか
  • 正本の events.jsonl(セッションごとに .basou/sessions/ 配下)— 追記専用・hash chain で連結されたイベントログ。Claude Code のセッションも Codex のセッションも、ここでは同じ形になる
  • basou verify が「この記録は改竄されていないか」に機械的に答えられる状態

basou 自体の全体像は紹介記事に書いた。一言でいえば AI コーディングエージェントのためのローカルファーストな馬装(ハーネス)— 鞍(宣言的ワークスペース)と手綱(意図を運ぶオリエンテーション)、そしてその足元に置かれた再生可能な記録からなる。今日はその足元、セッションの証跡だけを、手を動かして試す。

前提と Step 1: インストールと init(30秒)

前提は3つ。Node.js 20.10.0 以上、Claude Code か Codex(どちらか一方でいい。両方ならこの記事の全部が試せる)、そしてそれらを使ってきた実リポジトリがあること。

npm install -g @basou/cli
cd path/to/your-repo
basou init

本記事は basou v0.34.0(2026-07-14 時点)を基準にしている。

git に何が入るかを先に言っておく。既定では、basou はノイズの多い側を git の外に置く — 生イベントログ、内部ログ、揮発的な orientation ビュー。追跡対象として残るのは永続的な要約だ: manifest、handoff.mddecisions.md、それに各セッションの session.yaml。つまり PR の diff でレビューできる。ただしこれらの要約には実作業の中身 — セッションのラベル、決定のタイトル、handoff の本文そのもの — が含まれるので、公開リポジトリなどで何ひとつ commit したくなければ basou init --local-only.basou/ 全体を gitignore する側に倒せる。

Step 2: Claude Code の過去分を取り込む — basou import

ここが今日の山場だ。

basou import claude-code --all
Imported sessions: 20 path(s) sanitized
Imported 4 session(s) (101 events)

1コマンドで、このリポジトリで過去に走らせた Claude Code のセッション4つが、101 イベントの証跡として遡って取り込まれた。--all は「見つかった過去分を全部」の明示で、パス指定も設定ファイルも要らない — basou が各ツール固有のログをディスク上から自動検出する。慎重に行きたければ先に --dry-run を付ける — 何も書かずに Dry run: would import … とプレビューだけが返る。

取り込みの細部やつまずきどころは quickstart に譲る。ここで押さえてほしいのは1点だけ — ワークフローを何も変えていないのに、過去分が証跡になった、ということだ。

Step 3: Codex も、同じ証跡へ

タイトルの「一つの証跡にまとめる」はここからだ。同じリポジトリで Codex も使っていたなら、コマンドはこう変わるだけ:

basou import codex --all
Imported sessions: 1 path(s) sanitized
Imported 1 session(s) (01KXFP) (15 events)

これで証跡は 5 セッション・116 イベントになった。取り込まれたものは、次の Step で handoff.md を生成すると、その末尾のセッション一覧でこう見える:

| short_id | status | started_at | label |
|---|---|---|---|
| 01KXFPWTJG | imported | 2026-05-14T23:56:54.061Z | codex 2026-05-14: 13 commands |
| 01KXFPWT97 | imported | 2026-07-06T03:42:36.504Z | claude-code 2026-07-06: 1 command, 0 files |
| 01KXFPWT95 | imported | 2026-05-25T04:19:07.538Z | claude-code 2026-05-25..2026-05-27: 24 commands, 9 files |
| 01KXFPWT8Y | imported | 2026-05-27T13:53:53.125Z | claude-code 2026-05-27..2026-06-10: 12 commands, 4 files |
| 01KXFPWT8S | imported | 2026-06-14T06:10:20.317Z | claude-code 2026-06-14: 23 commands, 3 files |

Sessions: 5 (imported 5). Tasks: 0.

codexclaude-code が同じ表に並んでいる。別々のツールの、別々の時期のセッションが、一つのワークスペースの一つの時系列に入った。ツールごとにログの置き場所と形式を思い出す必要は、もう無い。

Step 4: handoff を生成して読む — そして "replayable" の意味

import が書いたのは記録だ。.basou/sessions/ の下にある、追記専用で hash chain された JSONL。人間が読むビューは、こう頼んで作る:

basou handoff generate
# Handoff

> Generated at 2026-07-14T07:02:06.205Z from ses_01KXFPWT8S..ses_01KXFPWTJG

## 現在の状態

- 最終 session: claude-code 2026-06-14: 23 commands, 3 files (imported) [ses_01KXFPWT8S]

## 直近の判断

- ████████ の AGENTS.md 文書そのもの(散文本文)の言語をどう改定しますか? … -> 本文は日本語のまま維持 [decision_01KXFPWT8P]

(3 decisions total — see decisions.md)

これが .basou/handoff.md の抜粋 — どこまで進み、直近で何が起き、どこから再開するか。チームメイトに渡せる。明日の自分に渡せる。次のエージェントセッションに渡せる。

(見出しが日本語なのは、workspace の manifest でこのリポジトリに language: ja を宣言してあるからだ。生成ビューの見出しなどの定型文は既定では英語。宣言が変えるのはその定型文だけで、ユーザーデータには触れない — あなたが書いたもの・エージェントがやったことは verbatim のまま。)

さて、この節の見出しにある replayable(再生可能)がここで意味を持つ。いま読んだ Markdown は記録ではない — 記録から導出されたビューだ。つまり、使い捨てられる。証明しよう。rm してもいいのだが、あとで diff を取るために脇へ移す:

mv .basou/handoff.md /tmp/before.md
basou handoff generate
diff /tmp/before.md .basou/handoff.md
4c4
< > Generated at 2026-07-14T07:02:06.205Z from ses_01KXFPWT8S..ses_01KXFPWTJG
---
> > Generated at 2026-07-14T07:03:24.276Z from ses_01KXFPWT8S..ses_01KXFPWTJG

動いたのは1行 — 生成タイムスタンプだけ。残りは byte 単位で同一のまま戻ってきたevents.jsonl から、決定論的に、オフラインで、LLM なしで再導出された。同じコマンドが、同じビューを、正本から蘇らせる。

ここでいう replayable はそういう意味だ。ステップ実行のプレイヤーがあるわけではない — いつでも再消費できる正本ログがあり、人間可読のビューはすべてそこから再構築できる、ということ。handoff も、decision log も、orientation も、どれも1つの検証可能なログの安価な投影にすぎない。ビューは手で編集して構わない。正本側の版が欲しくなったら、再生成すればいい。

Step 5: 検証する — "verifiable" の意味

セッションの events.jsonl を覗くと、各イベントが直前のイベントのハッシュを握っているのが見える:

{"schema_version":"0.1.0","id":"evt_01KXFPWT8S…","session_id":"ses_01KXFPWT8S…","occurred_at":"2026-06-14T06:10:20.317Z","source":"claude-code-import","type":"session_started","prev_hash":"cc5b28d0…7118a77"}
{"schema_version":"0.1.0","id":"evt_01KXFPWT8S…","session_id":"ses_01KXFPWT8S…","occurred_at":"2026-06-14T06:10:25.021Z","source":"claude-code-import","type":"command_executed","command":"bash", … ,"prev_hash":"309256a7…148fa84"}

だからこの問いに、機械が答えられる — 「この記録は、書かれたあとに改竄されていないか」。

basou verify
ses_01KXFPWT8S…  verified (34 events)
ses_01KXFPWT8Y…  verified (19 events)
ses_01KXFPWT95…  verified (45 events)
ses_01KXFPWT97…  verified (3 events)
ses_01KXFPWTJG…  verified (15 events)
Sessions: 5 total — 5 verified, 0 unchained, 0 empty, 0 incomplete, 0 in_progress, 0 tampered

Codex のセッション(検証行の最後・15 events)も、Claude Code の4つと同じ鎖の検証を、同じコマンドで通っている。見たいのは、集計行の末尾が 0 tampered で終わる形だ。もし1件でも改竄があれば該当セッションが TAMPERED (...) になり、exit code が 1 になる — つまりスクリプトにも組める。ちなみにこの鎖は、import が書き込んだ瞬間から既に繋がっている。あとから祝福する工程は無い。

「一つの証跡」を支える設計 — adapter とベンダー中立な証跡フォーマット

Step 3 で起きたことを、少しだけ設計側から見ておく。ツールが増えても証跡が一つでいられるのは、役割が2層に分かれているからだ。

adapter は、ベンダー固有ログの reader だ。 Claude Code のトランスクリプトと Codex のセッションログは、形式も置き場所もまったく違う。その差異を知っているのは各 adapter だけで、仕事は「読んで、共通の形に写す」ことに尽きる。

証跡フォーマットは、中立で統一されている。 adapter を通過した先は、どのツール由来でも同じ共通スキーマの events.jsonl に落ちる — 同じフィールド、同じ hash chain。さっきの Step 5 のイベント行と見比べてほしい。Codex 由来のイベントはこうなっている:

{"schema_version":"0.1.0","id":"evt_01KXFPWTJG…","session_id":"ses_01KXFPWTJG…","occurred_at":"2026-05-14T23:56:54.061Z","source":"codex-import","type":"session_started","prev_hash":"3906bbc4…2d59cb1"}

フィールドの形は Claude Code 由来のものと同一で、由来(provenance)は source フィールドがデータ自身として名乗る — この行では codex-import。各セッションの session.yaml には source.external_id としてベンダー側のセッション id も残るので、元ログへ遡ることもできる。

この分離が効いてくるのは下流だ。handoffverify もさっきの diff も、ソースが何だったかを知らないまま、一つの形式だけを相手に動いている。だからツールを足しても、検証や再生の仕組みは1系統のまま増えない。

これからのセッション

ここまでは過去分の話。これからの分は、もっと簡単だ。

朝いちは basou orient — 「どこまでやったっけ」に記録が答える。日々の取り込みとビュー更新は basou refresh の一発 — Claude Code も Codex も、実装済みの adapter をまとめて処理する(ソースログが無いツールは skip される)。設計判断が下りたら basou decision capture、離席前に basou note "次はここから"。セッションを最初からライブで記録したければ、basou run claude-code でプロセスごと包む手もある。

これは何では「ない」か

ダッシュボード SaaS ではない。何もマシンの外に出ない。実行時に LLM を呼ばない。証跡はすべて .basou/ の中に閉じ、やめたくなればそのディレクトリを消すだけでいい。ローカルで眺めたければ basou view(127.0.0.1 のみに束縛)もあるが、それも任意。

結び

5分の内訳はこうだった — install と initimport を2回(Claude Code と Codex)、handoff generateverify。これで2つのツールのセッションがコードの隣の一つの証跡に並び、ビューは消しても正本から戻り、改竄されれば機械が気づく。

続きは quickstart と CLI リファレンスに。0.x で引っかかったら issue をどうぞ — 歓迎する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?