archive-crawler について
archive-crawler は、個人アーカイブを調べ、価値のある内容を選んで brain に取り込むためのスキルです。明示的なパス許可リストを必須とし、マニフェストで進捗を管理しながら、ノイズや機微な文書を除外します。
主な機能
- 01スキャン対象パスの許可リストを必須化
- 02アーカイブの内容を一覧化・分類
- 03マニフェストで確認と取り込みを管理
- 04提示前に内容をフィルタリング
- 05選択した項目を brain ページに取り込み
活用シーン
- 01ローカルアーカイブの文章や通信を確認
- 02.mbox などのメールエクスポートを整理
- 03許可された Dropbox や Backblaze のアーカイブを調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill archive-crawlerインストール後、Claude Code で/archive-crawlerを入力して読み込まれたか確認します。
同梱ファイルrouting-eval.jsonl
詳細
archive-crawler — 万能アーキビスト
規約: 引用ルール、ユーザーの反応を記録する際の正確な表現の要件、バックリンクの適用については、conventions/quality.md を参照してください。
規約: _brain-filing-rules.md を参照してください。このスキルはスキーマに依存しません。特定の時代やアーカイブのレイアウトをハードコードするのではなく、ルール JSON からユーザーのファイリングルールを読み取ります。
安全ゲート(必須、例外なし)
archive-crawler は、gbrain.yml に archive-crawler.scan_paths: が明示的に設定されていない限り、実行を拒否します。これは、エージェントがスキャンの範囲を広げすぎて機密コンテンツ(税務 PDF、医療記録、認証情報)を取り込むことを防ぐための、意図的な安全措置です。
# gbrain.yml — the allow-list is mandatory
archive-crawler:
scan_paths:
- ~/Documents/writing/
- ~/Dropbox/Archive/
- /mnt/backup/old-letters/
# Optional deny-list inside the allow-list:
# deny_paths:
# - ~/Documents/finances/
# - ~/Documents/medical/
scan_paths が空または未設定の場合、スキルは次のメッセージを出力して終了します。
archive-crawler: refusing to run. No `archive-crawler.scan_paths:` allow-list
in gbrain.yml. Add explicit paths the agent is permitted to scan, then re-run.
This is a safety fence — the agent will not infer what's safe to read.
この契約は src/core/storage-config.ts によって適用されます(v0.22.11 のストレージ階層化における db_tracked / db_only の許可リストパターンを反映しています)。
これは何か
明示的な許可リスト内にある、あらゆる個人コンテンツのツリーを探索する汎用エンジンです。ローカルマウント、Dropbox API の対象、Backblaze B2、Gmail のエクスポートデータ(.mbox)など、類似のアーカイブで動作します。「価値あるもの」(ユーザー自身の文章、アイデア、人間関係)をフィルタリングし、レビュー用に対話形式で提示します。ノイズ(システムファイル、設定、バイナリデータ)はスキップします。
概念
ソース
ソースとは、探索対象となるファイルのツリーです。ソースには以下が含まれます。
- type:
local|dropbox|backblaze|gmail-takeout|mbox|pst - root:ファイルシステムのパス、Dropbox のパス、B2 のプレフィックス、mbox のパス
- manifest:進捗を記録するブレインページ。場所は
projects/<archive-slug>/STATUS.md
マニフェスト
アーカイブを探索するたびに、進捗を記録するマニフェスト用のブレインページが作成されます。記録する内容は次のとおりです。
- ツリーのインベントリ — フォルダー/ファイル/サイズ/種類
- トリアージ状況 — 各項目:
⬜ 未確認/👀 レビュー済み/✅ 取り込み済み/⏭️ スキップ/🔥 重要度高 - ユーザーの反応 — 反応があった場合は正確な引用(conventions/quality.md の正確な表現に関するルールに準拠)
- 優先キュー — 次に探索する対象とその優先順位
- セッションログ — 各セッションで提示した内容のタイムスタンプ付き記録
価値あるもののフィルター
ユーザーに何かを提示する前に、価値あるもののフィルターを適用します。
| 残す(提示する) | スキップする(存在のみ記録し、提示しない) |
|---|---|
| 個人的な文章(日記、手紙、振り返り、エッセイ) | システムファイル、設定、package.json、node_modules |
| 会話(メッセージログ、内容のあるメールスレッド) | バイナリデータ(画像/動画) |
| アイデア、テーゼ、フレームワーク | 領収書、請求書、税務書類 |
| 人間関係に関する資料(大切な人とのやり取りや、その人に宛てた手紙) | スパム、ニュースレター、メーリングリストの大量配信 |
| 創作物(詩、物語、魂のこもったコード) | 破損ファイル/空ファイル |
| 重要なものへと発展した事柄の始まり(初期バージョン) | |
| 感情を含む内容(怒り、愛、悲しみ、発見) |
プロトコル
フェーズ 1:インベントリ
新しいソースを指定された場合:
- scan_paths が設定されていることを確認する(安全ゲート)。未設定の場合は終了します。
- ツリーをマッピングする — フォルダーとファイル、サイズ、日付範囲を一覧表示します。
- フォルダーを分類する — 内容の種類(文章、メール、コード、写真、文書、システムなど)ごとにグループ化します。
- マニフェストを作成する — 全インベントリを
projects/<archive-slug>/STATUS.mdに記録します。 - 優先キューを提案する — 価値あるものが多く含まれていそうな順にフォルダーを並べます。
- ユーザーに提示する — マップと提案する順序を示します。ユーザーが変更できるようにします。
フェーズ 2:クロール
優先順位に従ってフォルダーを確認します。
- 表示する前に読む — 候補ファイルをそれぞれ開き、ゴールドフィルターを適用して、ノイズを除外します。
- 1 件ずつ表示する — ゴールド項目を個別に提示してレビューしてもらいます。
- 正確な反応を記録する — ユーザーの反応を、本人の正確な言葉でマニフェストに記録します(
conventions/quality.mdの規約に従います)。 - 保存する価値があれば取り込む — すぐにブレインページを作成します。
- マニフェストを更新する — やり取りのたびに項目のステータスを更新します。
- 再表示しない — 何かを提示する前に、マニフェストを確認します。
フェーズ 3:取り込み
項目を保存する価値がある場合は、_brain-filing-rules.md に従い、主要な主題に基づいて格納します。
- ユーザー自身の文章/アイデア/オリジンストーリーに関するコンテンツ →
originals/<slug>.md - 内省/個人的な生活に関するコンテンツ →
personal/<slug>.md - 製品/ビジネスのアイデア →
ideas/<slug>.md - 特定の人物に関する手紙やスレッド →
people/<person>/timelineへのバックリンクと、personal/<slug>.mdまたはoriginals/<slug>.mdに手紙を格納
このスキルのスキーマは汎用的です。 特定の時代別フォルダー構造(例:2003 年以前は originals/archive/、2019 年以降は originals/yc-era/ など)を組み込んでいません。ユーザーの格納ルールは実行時に _brain-filing-rules.json から読み込み、エージェントが許可されたディレクトリ内でページごとに格納先を決定します。
ブレインページの形式:
---
title: "[Title or first line]"
type: original
source_type: "[local|dropbox|backblaze|gmail-takeout|mbox|pst]"
source_path: "[path within the allow-listed scan_paths]"
date: "YYYY-MM-DD" # date from the file metadata or content
people: ["person-1", "person-2"]
tags: ["tag-1", "tag-2"]
---
# [Title]
[Summary: what it is, when it's from, why it matters]
**User's reaction:** [exact quote, no paraphrasing]
## Context
[Cross-links to people, concepts, projects.]
---
[Raw source material below the line — full text]
ファイル形式別の処理
プレーンテキスト/HTML/Markdown
直接読み取ります。表示する際は HTML タグを取り除きます。
.mbox(メールアーカイブ)
import mailbox
mbox = mailbox.mbox('/path/to/file.mbox')
for msg in mbox:
body = ''
if msg.is_multipart():
for part in msg.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True).decode('utf-8', errors='replace')
break
else:
body = msg.get_payload(decode=True).decode('utf-8', errors='replace')
# Apply gold filter
.doc/.docx
# .docx (modern)
python3 -c "
import zipfile, xml.etree.ElementTree as ET
with zipfile.ZipFile('/path/to/file.docx') as z:
tree = ET.parse(z.open('word/document.xml'))
print(''.join(t.text or '' for t in tree.iter('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t')))
"
# .doc (legacy, requires antiword or catdoc)
antiword /path/to/file.doc 2>/dev/null || catdoc /path/to/file.doc 2>/dev/null
.pst(Outlook アーカイブ)
# Validate first; many PSTs are null bytes
python3 -c "
with open('/path/to/file.pst', 'rb') as f:
print('Valid PST' if f.read(4) == b'!BDN' else 'CORRUPT/NULL')
"
# If valid:
readpst -o /tmp/pst-output /path/to/file.pst
.zip/.tar/.tar.gz
一時ディレクトリに展開してから、展開したツリーを再帰的に処理します。
画像
存在することとメタデータ(ファイル名、サイズ、日付)を記録します。ユーザーから求められない限り表示しません。スキャン画像やポートレートは、個人的な内容である可能性があると記録します。
マニフェストのテンプレート
---
title: "[Archive Name] — Ingestion Status"
type: project
created: YYYY-MM-DD
updated: YYYY-MM-DD
source_type: "[local|dropbox|...]"
scan_paths: ["paths from gbrain.yml"]
---
# [Archive Name] — Ingestion Status
## Source
- **Type:** [local|dropbox|...]
- **Allow-listed paths:** [from gbrain.yml]
- **Total files:** [N]
- **Total size:** [X GB]
- **Date range:** [earliest] — [latest]
## Inventory
### [Folder 1]
| Item | Type | Size | Status | Reaction |
|------|------|------|--------|----------|
| file1.txt | text | 2KB | ✅ ingested | 🔥 "exact quote" |
| file2.doc | doc | 15KB | ⏭️ skip | — |
| file3.html | html | 4KB | ⬜ unseen | — |
### [Folder 2]
...
## Priority Queue
1. [Highest priority — why]
2. [Next — why]
...
## Session Log
### YYYY-MM-DD — [Session topic]
- Reviewed: [list]
- Reactions: [exact quotes]
- Ingested: [brain pages created]
- Next: [what's queued]
失敗した場合
gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックが発生した場合は、エージェント運用者プロトコルに従います。このスキル固有の対応は次のとおりです。
archive-crawler.scan_paths:の許可リストがない場合:これはスキル独自の厳格な拒否です。スキャンを許可するディレクトリをユーザーに尋ねます。拒否を回避するために、自分の判断でリストを拡張してはいけません。- アーカイブのマウント、テイクアウト、またはバケットが読み取れない場合(権限、期限切れのトークン):失敗した正確なパスを報告し、そのソースの処理を停止します。親ディレクトリのスキャンに切り替えてはいけません。
- 検索結果の格納で
write_pending(終了コード 10)またはrevision_conflictが返された場合:前者ではgbrain write-request <request_id>をポーリングします。後者ではページを再読み込みしてマージします。新しいスラッグで再度格納してはいけません。
アンチパターン
- ❌
archive-crawler.scan_paths:を設定せずに実行する。厳格な拒否です。 これは安全性を守るための契約です。決して回避してはいけません。 - ❌ 時代固有の格納パス(例:
originals/archive/、originals/yc-era/)をハードコードする。代わりに、実行時に格納ルールを読み込みます。 - ❌ マニフェストに記録済みの項目を再表示する。ユーザーの時間は最も貴重なリソースです。
- ❌ 反応を言い換える。正確な言葉のみを記録します。
- ❌ 見つかったコンテンツを教訓や要点としてまとめる。ストーリーそのものを尊重します。
- ❌ コンテンツがブレインページのある人物/企業に言及しているのに、バックリンクを省略する。
conventions/quality.mdに定められた鉄則です。
関連スキル
skills/voice-note-ingest/SKILL.md— 音声の記録に同じ正確な表現のパターンを使用skills/idea-ingest/SKILL.md— 主要な主題に基づく同じ格納ルールを使用する、単一リンクまたは記事の取り込みskills/conventions/quality.md— 引用、バックリンク、文体
契約
このスキルでは、次のことを保証します。
- ルーティングがフロントマターの正規トリガーに一致します。
- (該当する場合)
writes_to:に記載されたディレクトリ配下に出力を書き込みます。 - 参照されている規約(
quality.md、brain-first.md、_brain-filing-rules.md)に従います。 - プライバシー契約を維持します。実名、フォーク固有のファイルシステムパスを示すリテラル、上流フォークへの言及は含めません。
動作契約の全文は上記の本文セクションに記載されています。このセクションは適合性テスト用に設けられています。
出力形式
スキルの出力形式は、本文セクション内に記載されています(「Output」、「Brain page format」または同等の項目を参照)。ここにある見出しは、適合性テスト(test/skills-conformance.test.ts)用のものです。