# Phase 1 仕様書 — Lv2 Jarvis常駐デーモン（呼名検出型）

> 中期目標「アイアンマンJarvis本物化＝能力の延長線」のPhase 1。
> 暦との会議にJarvisを参加させたかったが叶わなかった経験（2026-05-05）が動機。
> 仕様確定：2026-05-05・暦と方針合意済の流れで設計確定。

---

## 🔴 ゴール

「**ずっとそこにいて、ずっと話を聞いてるけど、呼ばれた時だけ反応する**」  
= 映画のJ.A.R.V.I.S と同じ振る舞いを実現する。

具体的には：
- Whisperで会議音声を常時テキスト化
- 「ジャービス」と呼ばれた時だけ Claude Code が起動して回答生成
- 回答は dashboard カードに書き込み（音声出力はPhase 2で）
- 誤発火しても気にしない・誤発火を学習素材にしてどんどん精度上げる

---

## 🔴 トリガー方式

### 採用：案A（呼名+指示文・自然・誤発火許容）

```
発火条件 = 「ジャービス」検出 AND 後続に指示文/疑問文がある
誤発火期待値：許容（むしろ学習素材として歓迎）
```

### 呼名のバリエーション（揺れ吸収）
- 「ジャービス」「Jarvis」「ジャーヴィス」（Whisper表記揺れ）
- 「ねぇジャービス」「おいジャービス」「Jarvis、〜」も検出
- 厳密一致じゃなく部分一致+前後文脈

### 初期NGパターン（誤発火即弾き・5個）
- 「ジャービス**って**〜」（話題提起）
- 「ジャービス**は**〜」（説明)
- 「ジャービス**みたい**〜」（比喩）
- 「ジャービス**について**〜」（話題）
- 「ジャービス**ってさ**〜」（カジュアル話題提起）

→ これらは即発火しない。`ng_patterns.md` に書き出して動的に読み込む。

---

## 🔴 誤発火学習ループ（最重要・Lv5自律化の核心）

> ユーザー方針（2026-05-05・直接引用）：
> 「弱点で間違えて出てきちゃった場合を保存してそれを学習し、そういうことが起きないようにする。どんどん成長させていく」

### フロー

```
[案A: 呼名+指示文で発火]（自然・誤発火許容）
        ↓
誤発火（「ジャービスってさ〜」で反応しちゃった）
        ↓
ユーザーが一言「ジャービス誤反応」「違う」「呼んでない」など
        ↓
誤発火ログに記録：false_positives.jsonl
- 直前の音声テキスト
- どのルールでマッチしたか
- 文脈（前後10秒）
        ↓
5件溜まったらJarvisが自動でパターン抽出
- 「〜ってさ」「〜について」「〜みたいな」が後続なら呼びかけじゃない
- ng_patterns.md に自動追加（🛡付き）
        ↓
DNA学習ログに🛡で追記（self_recovery準拠）
        ↓
次回から該当パターンは事前フィルタで弾く
```

### 既存機構との接続

| 既存機構 | 役割 |
|---|---|
| `action_log.jsonl` | 誤発火含む全アクションを1行記録 |
| `self_recovery.md` 4段階 | 検出→影響範囲→ロールバック→学習 |
| `🛡学習反映ルール` | 誤発火パターンをDNAに昇格 |
| `clone_updater.md meta_knowledge` | 🛡行を最優先で次回プロンプトに混入 |
| `self_check.md` 不一致ルール | しきい値5回でDNA昇格 |

### しきい値
- 同種誤発火 **5回** で `ng_patterns.md` 自動追加
- self_check の3回ルールから緩和（誤発火は許容前提のため）

### 「違う」検出キーワード（ゆるくマッチ）
雰囲気の言葉なら何でも検出：
- 「ジャービス誤反応」「ジャービス違う」「呼んでない」
- 「黙ってて」「いや今のじゃない」
- 部分一致+前後文脈で判定

---

## 🔴 実装方式：Claude Code 経由（API直叩きしない）

### 採用：subprocess で `claude -p "プロンプト"` を呼ぶ

理由：
- ✅ Claude Max 20xプラン枠で動く（追加課金ゼロ）
- ✅ 過去のJarvis稼働と完全に同じ枠
- ✅ 父への追加交渉不要・Anthropic Console確認不要
- 弱点：起動オーバーヘッド数秒（許容範囲）

### 疑似コード

```python
# jarvis_daemon.py
while True:
    transcript = read_latest_whisper_output()
    if detect_wake_word(transcript) and not is_ng_pattern(transcript):
        prompt = build_prompt(transcript)  # DNA核心100行+直近会話400字+Jarvis履歴
        result = subprocess.run(
            ["claude", "-p", prompt],
            capture_output=True
        )
        write_to_dashboard(result.stdout)
        log_action(transcript, result, "fired")
    time.sleep(2)
```

### 1fire の見積

| 項目 | tokens |
|---|---|
| 入力：DNA核心100行 | 約1,500 |
| 入力：直近会話400字 | 約500 |
| 入力：Jarvis過去発言20件 | 約1,000 |
| 入力：システムプロンプト | 約500 |
| 出力：回答（短め前提） | 約1,000〜2,000 |
| **1fire合計** | **約4.5〜5.5k tok** |

→ 目標通り 5k tok/fire 以下。Max 20x枠の5〜10%消費で1日まわる。

---

## 🔴 モード別トークン上限

> ユーザー方針（2026-05-05）：「会議とかするときにそのモードを上げるの忘れちゃいそうだから通知も欲しい」

| モード | 用途 | 1日上限 | 1fire上限 |
|---|---|---|---|
| 🟢 待機モード | 普段の作業中（デフォルト） | 30k tok | 8k tok |
| 🟡 会議モード | 暦との会議など、呼ぶ頻度高 | 200k tok | 8k tok |
| 🔴 学習モード | 誤発火収集期間 | 500k tok | 8k tok |

### モード切替

- ユーザーが起動時に明示（「ジャービス会議モード」と発話で検出）
- dashboard のボタンでも切替可能
- **3時間で自動的に🟢待機モードに戻る**（モード解除し忘れ対策）

### 通知ルール（切替忘れ対策）

| トリガー | 通知内容 | 通知先 |
|---|---|---|
| モード切替忘れ検出 | 1時間に呼名5回超=会議の可能性 → 「会議モードに切替？」 | dashboard上部バナー |
| モード自動降格直前 | 会議モード残り10分 → 「終了します・継続なら呼んで」 | dashboard通知 |
| 誤発火多発検出 | 30分で誤発火3回 → 「学習モードに切替？」 | dashboard通知 |
| トークン上限80%到達 | 残量警告 → 「あと20%」 | dashboard通知 |
| トークン上限到達 | 全停止 → 「Jarvis停止・手動再起動必要」 | dashboard + iMessage |

---

## 🔴 構成図

```
┌─────────────────────────────────────────────────┐
│ Whisper常駐 (chunk 30秒・余裕持たせて事故回避)    │
│   ↓ transcript.jsonl 全録音                       │
└─────────────────────────────────────────────────┘
                  ↓
┌─────────────────────────────────────────────────┐
│ jarvis_daemon.py (監視デーモン・独立プロセス)     │
│   ・呼名検出: 「ジャービス」+ 指示文              │
│   ・初期NGフィルタ: 5パターン即弾き               │
│   ・累積NGフィルタ: ng_patterns.md 動的読込       │
│   ・誤発火検出: 「ジャービス誤反応」系発話で記録  │
│   ・モード判定: 🟢/🟡/🔴 を読み上限管理           │
└─────────────────────────────────────────────────┘
                  ↓ 発火判定
┌─────────────────────────────────────────────────┐
│ 安全装置レイヤー                                  │
│   ・モード別1日上限で自動停止                     │
│   ・1fire 8k tok超で警告                          │
│   ・dry-runモードで実発火前にテスト可             │
│   ・whisper-cliプロセス数監視（過去事故再発防止） │
└─────────────────────────────────────────────────┘
                  ↓ OK
┌─────────────────────────────────────────────────┐
│ Claude Code 経由 (subprocess `claude -p`)         │
│   入力: DNA核心100行 + 直近会話400字 + Jarvis履歴 │
│   目標: 1fire 5k tok以下                          │
└─────────────────────────────────────────────────┘
                  ↓
┌─────────────────────────────────────────────────┐
│ 出力: dashboard カード (live_meeting_YYYY-MM-DD)  │
│   ・既存自動リフレッシュで会議中もリアルタイム    │
│   ・誤発火マーク機能（撤回ログ可視）              │
└─────────────────────────────────────────────────┘
                  ↓
┌─────────────────────────────────────────────────┐
│ 学習パイプライン                                  │
│   ・action_log.jsonl: 全発火・誤発火を記録       │
│   ・false_positives.jsonl: 誤発火だけ抽出        │
│   ・5回ルール: 同種5回で ng_patterns.md 自動追記 │
│   ・週次: weekly_reports/YYYY-WNN_report.md 生成 │
│   ・🛡: DNA学習ログへ昇格 → 全Jarvisに伝播       │
└─────────────────────────────────────────────────┘
```

---

## 🔴 ファイル配置

```
clone-jarvis/jarvis/live_session/
├── SPEC.md                           # この仕様書
├── daemon/
│   ├── jarvis_daemon.py              # 監視デーモン本体
│   ├── wake_word_detector.py         # 呼名+NGパターン検出
│   ├── code_runner.py                # claude -p subprocess呼び出し
│   ├── safety_guard.py               # モード別上限・dry-run
│   └── notifier.py                   # dashboard通知 + iMessage
├── transcripts/
│   └── YYYY-MM-DD.jsonl              # Whisper出力
├── wake_word_learning/
│   ├── ng_patterns.md                # 自動成長するNGリスト（🛡付き）
│   ├── false_positives.jsonl         # 誤発火履歴
│   └── weekly_reports/
│       └── YYYY-WNN_report.md        # 週次精度レポート
├── tokens.jsonl                      # 1日消費追跡
└── action_log.jsonl                  # 全Jarvis共通アクションログ
```

---

## 🔴 実装ステップ

### Step 1：仕様書作成 ✅（このファイル・2026-05-05完了）

### Step 2：MVP実装（次セッション or 暦会議直前）
1. ディレクトリ構造作成（live_session/配下）
2. `ng_patterns.md` に初期NG5パターン仕込み
3. `wake_word_detector.py`：呼名検出+NGフィルタ
4. `safety_guard.py`：モード別上限+ dry-run
5. `code_runner.py`：`claude -p` subprocess
6. `notifier.py`：dashboard書き込み+iMessage
7. `jarvis_daemon.py`：上記を束ねるメインループ
8. dashboard 新規カード（live_meeting_YYYY-MM-DD.md 表示）

### Step 3：dry-run試運転
- 数時間〜半日、自分の作業中に動かす
- 誤発火パターン収集
- 安全装置動作確認（モード切替・上限到達）

### Step 4：暦会議で実戦投入
- 🟡会議モード起動
- 呼名で動作確認
- 誤発火出ても気にしない（学習素材として歓迎）

---

## 🔴 確定事項サマリ（合意済）

| 項目 | 確定値 |
|---|---|
| トリガー方式 | 案A（呼名+指示文・誤発火許容） |
| 誤発火学習 | 既存self_recovery+action_logパイプ |
| NGパターン昇格しきい値 | 5回 |
| 学習レポート | 週次 |
| API消費上限 | モード別（🟢30k/🟡200k/🔴500k）/日 |
| 切替忘れ対策 | dashboard通知 + iMessage警告 |
| 実装方式 | Claude Code経由（`claude -p` subprocess） |
| トークン現実性 | ✅ Max 20x枠の5〜10%消費 |
| 「違う」検出 | ゆるくマッチ（雰囲気の言葉なら何でも） |
| 初期NGパターン | 5個（って/は/みたい/について/ってさ） |
| 自動降格 | 3時間で🟢待機モードに戻る |
| 出力先 | dashboard カード（live_meeting_YYYY-MM-DD） |

---

## 🔴 関連DNA・memory

- DNA：clone_dna.md 第5サイクル学習ログ（製品化撤回・能力延長線確定）
- memory：feedback_no_loop.md（/loop禁止の根拠）
- memory：feedback_loop_outside_claude_code.md（常駐ループ実装方針・**API直叩き案は本SPECで Claude Code経由に変更**）
- memory：feedback_parallel_survival_design.md（並列生存設計）
- memory：feedback_50pct_pretrip_stop.md（実行前停止ルール）
- self_check.md / self_recovery.md / action_log_rules.md（誤発火学習の接続先）

---

*作成：2026-05-05 ／ 仕様確定：2026-05-05（暦と方針合意済の流れで）*
*次のステップ：Step 2 MVP実装*
