対象ユーザー: 本記事は、プライバシー責任者、学校区・省庁のITアーキテスター、ダッシュ監視ベンダーOEM、およびEU・米国・湾岸地域・中南米の買い手に対して「ペンが工場に何を報告しているのか」という質問に回答しなければならないB2B輸入業者向けです。GDPRおよびCOPPAを概念レベルで理解していることを前提に、B1/B2/F8/K7/KF1/L5/P2/Q6/Q8/T2/Y6各ペンから送信されるイベントクラス、その匿名化対象、オプトイン対象、そして絶対に送信されないイベントを正確に知りたい方を対象としています。
前四半期、12,000本のペンを発注したスペインの学校組合がコンプライアンスチームに正確な質問をしました。「GDPR第25条に基づき、デバイスから送信されるデータ、デバイス上に保持されるデータ、そして保護者が保証補償を失うことなくオプトアウトできるかどうか」というものです。正直な答えは23ページにも及びます。ここで公開する短い答えは、テレメトリーイベントはEUではデフォルトでオプトアウト、米国ではCOPPAに基づきデフォルトでオプトイン、サウジアラビアではSFDAに基づきデフォルトでオプトイン、OEMセルフホスト環境ではデフォルトで完全に無効化される、というものです。以下がそのポリシーの技術的背景です。
本記事は、デバイス内のリングバッファ、イベントスキーマ、匿名化パイプライン、アップロードスケジュール、GDPR/COPPA/PIPL/LGPD対応方針、ダッシュボードが開示する情報端末メーカーのものであり、47か国にわたる12,000本超のペンでのテレメトリー運用コストについて解説します。
1. デバイス内リングバッファ
すべてのペンには、ユーザーデータパーティション上に512 KBのリングバッファが搭載されています。このバッファは追加書き込み専用で、タイムインデックス化されており、工場出荷時リセット後も保護者が「診断ログを保持」を選択した場合のみ存続します。エンタープライズ展開ではこれがデフォルトで、小売向けではデフォルトで無効となっています。
1.1 モデル別バッファパラメータ
| モデル | パーティション | バッファサイズ | イベントレコード数 | 保持期間(日数) |
|---|---|---|---|---|
| B1 | ユーザー データ NOR | 256 KB | 2,800 | 14 |
| B2 | ユーザー データ NOR | 256 KB | 2,800 | 14 |
| F8 | ユーザー データ NAND | 512 KB | 5,600 | 21 |
| K7 / KF1 | ユーザー データ NAND | 512 KB | 5,600 | 21 |
| L5 | ユーザー データ NAND | 1 MB | 11,200 | 30 |
| P2 | ユーザー データ NOR | 256 KB | 2,800 | 14 |
| Q6 / Q8 | ユーザー データ NAND | 1 MB | 11,200 | 30 |
| T2 / Y6 | ユーザー データ NAND | 2 MB | 22,400 | 45 |
バッファは、最も発生頻度の高いイベント クラス (app.evt) をモデルに応じて 14〜45 日分保持できるサイズです。バッファはリング バッファで、最も古いイベントから順に上書きされます。
1.2 イベント スキーマ
すべてのレコードは固定 96 バイトの構造体で、1 バイトのタイプ、4 バイトのタイムスタンプ、2 バイトのスキーマ バージョン、および 89 バイトのタイプ固有ペイロードで構成されます。
struct telemetry_event_t {
uint8_t type; // 0x01..0x2C
uint32_t timestamp; // 起動からの秒数
uint16_t schema_ver; // 例:0x0007
uint8_t severity; // 0..3(info、warn、error、critical)
uint8_t reserved;
uint8_t payload[80];
uint16_t crc; // CRC-16-CCITT
uint8_t sig_pad[6]; // Ed25519 短署名用に予約
} __attribute__((packed));
ペイロードはタイプ固有です。boot.end イベントには uint32 のブート時間が含まれ、oid.lookup イベントには uint16 のレイテンシと uint16 の辞書ページバケットが含まれ、app.crash イベントには 64 バイトのスタックフィンガープリントハッシュが含まれます。
2. イベントクラス
44 個のイベントクラスを定義します。すべてがアップロードされるわけではありません。分類は LOCAL(アップロードしない)、TELEMETRY(アップロードし anonymised)、または SUPPORT(明示的なユーザー同意がある場合のみアップロード)です。
| クラス | 件数 | デフォルト方針 | 例 |
|---|---|---|---|
| ローカルのみ | 18 | LOCAL | key.press, book.open, app.locale |
| テレメトリー(匿名化) | 19 | TELEMETRY | boot.end, oid.lookup, pwr.drain, fw.update |
| サポート(オプトイン) | 7 | SUPPORT | voice.clip, asr.utterance, dict.override |
18 個の LOCAL イベントはデバイス内に保持され、「中断した場所を再開する」などのアプリ内機能にのみ使用されます。19 個の TELEMETRY イベントは Wi-Fi 経由でバッチアップロードされます。7 個の SUPPORT イベントは、保護者またはフリート管理者が明示的にサポートモードを有効にした場合にのみアップロードされます。
3. 匿名化ルール
すべての TELEMETRY イベントは、アップロード前に 4 段階の匿名化パイプラインを通過します。このパイプラインはデバイス上で実行され、ブートローダーによって強制されるため、侵害されたアプリケーションでもバイパスできません。
- 識別子の削除 — デバイスシリアル番号は、ブートごとにローテーションするソルトに置き換えられます。このソルトは 128 ビットのランダム値で、コールドブートごとに再生成されます。
- 値のバケット化 — レイテンシは最も近い 10 ms 単位に丸められます。バッテリー残量は最も近い 5% 単位に丸められます。辞書検索は CEFR レベルにバケット化されます。
- フィンガープリントのハッシュ化 — スタックトレースはフリートごとのソルトでハッシュ化されます。ソルトは毎月ローテーションされ、アップロードされることはありません。
- ソースでの集約 — 単一のイベントはデバイス上で 15 分単位のウィンドウに集約されます。デバイスは 30 件の個別イベントではなく、ウィンドウごとに 1 件のレコードをアップロードします。
集約レコードには、ウィンドウのタイムスタンプ、フリート ID(OEM サブキーの 32 ビットハッシュ)、モデル、ファームウェアバージョン、地域コード、および 6 つのメトリックカウンターが含まれます。デバイスシリアル、保護者の名前、子供の名前、子供がタップしたコンテンツは一切含まれません。
4. アップロードスケジュールとバッチ処理
アップロードは Wi-Fi 経由でのみ行われ、セルラー経由では行われません(セルラーモデムは搭載していません)。デフォルトのスケジュールは次のとおりです。
| 条件 | 動作 |
|---|---|
| Wi-Fi 接続中かつアイドル >5 分 | 保留中のバッチをアップロード |
| バッテリー残量 <20% | アップロードを延期 |
| バッテリー残量<10% | アップロードをキャンセルし、バッチをローカルに保持 |
| 充電器接続中、バッテリー残量は問わず | 即時にアップロード |
| フリート管理者による強制アップロード | 状態に関わらず今すぐアップロード |
一般的なペンは1日あたり1〜3件のバッチ記録をアップロードし、合計18〜54KBです。12,000本のフリートでは学校週単位で週間アップロード量は1.6〜4.8GBとなり、企業向けブロードバンド回線1本に十分収まります。
5. 各法域(GDPR / COPPA / PIPL / LGPD)への対応方針
テレメトリのデフォルト動作は管轄区域によって異なります。工場は出荷先の規制に基づいてデフォルトを設定します。
| 管轄区域 | デフォルトのテレメトリ | デフォルトのサポート | オプトアウトの仕組み |
|---|---|---|---|
| EU(GDPR) | オプトアウト | オフ | 設定 → プライバシー → テレメトリ |
| 英国(GDPR + DPA) | オプトアウト | オフ | 設定 → プライバシー → テレメトリ |
| 米国(COPPA、13歳未満) | オプトイン | オフ | 初回起動ウィザード |
| 米国(13歳以上、各州法) | オプトアウト | オフ | 設定 → プライバシー → テレメトリ |
| サウジアラビア(SFDA、PTA) | オプトイン | オフ | 初回起動ウィザード + PTAポータル |
| UAE(TDRA) | オプトイン | オフ | 初回起動ウィザード + TDRAポータル |
| 中国(PIPL) | オプトイン | オフ | 初回起動ウィザード + PIPL同意 |
| ブラジル(LGPD) | オプトアウト | オフ | 設定 → プライバシー → テレメトリ |
| メキシコ(LFPDPPP) | オプトアウト | オフ | 設定 → プライバシー → テレメトリ |
| その他のすべての地域 | オプトアウト | オフ | 設定 → プライバシー → テレメトリ |
すべての管轄区域において、保護者またはフリート管理者は、保証範囲、OTAアップデートへのアクセス、サポートへのアクセスを失うことなくテレメトリを無効化できます。オプトアウトによって無効化されるのは、集計テレメトリを必要とするフリートヘルスダッシュボードのみです。
6. フリートヘルス指標ダッシュボード
OEMパートナーおよび大規模フリート事業者向けに、テレメトリダッシュボードはフリートレベルで9つの指標を提供します。いずれの指標も、個別のデバイスシリアルまでドリルダウンすることはできません。
| 指標 | 定義 | 用途 |
|---|---|---|
| 日間アクティブ率 | (24時間以内に1回以上起動したペン) ÷ ( fleet size ) | エンゲージメント |
| クラッシュなしセッション | (未処理例外が発生しなかったセッション) ÷ (セッション) | 安定性 |
| OIDルックアップ p95 | OIDから発音までの95パーセンタイル | パフォーマンス |
| バッテリー健康状態 | 初期容量の80%未満を報告したペン | ハードウェアライフサイクル |
| OTA 採用率 | (最新ファームウェアのペン) ÷ ( fleet size ) | アップデートの速度 |
| 辞書ヒット率 | (キャッシュから提供されたルックアップ) ÷ (ルックアップ) | パフォーマンス |
| 言語パックのロード成功率 | (署名検証に失敗しなかったLPロード) ÷ (ロード) | コンテンツの整合性 |
| 充電イベント率 | (ペン1台あたりの週間充電セッション数) | 利用パターン |
| エラー重大度の構成比 | 重大度0〜3イベントの発生分布 | 健全性 |
ダッシュボードは5,000本以上の fleet では無料です。それ未満の場合は、ペン1本あたり年額$0.04が毎月請求されます。
7. テレメトリーパイプラインとメトリクス構成のSVG可視化
8. コスト
| サービス | コスト | 備考 |
|---|---|---|
| ホスト型テレメトリーダッシュボード(5,000本以上のペン) | OEMポータルに付属 | 無料 |
| ホスト型テレメトリーダッシュボード(5,000本未満のペン) | $0.04/ペン/年 | 月額課金 |
| 自社ホスト型テレメトリーシンク | $1,800/年 | ディストリビューターごと |
| カスタムイベントクラス(タイプ別) | $2,400 一括 + $0.06/ペン/年 | OEMパートナーごと |
| プライバシー影響評価のサポート | $1,200 | 地域ごと |
| データ削除証明書(GDPR Art. 17) | $0 | ポータル経由でセルフサービス |
購入者へのヒント: EU圏で10,000本を超える展開の場合、発注書にサインオフする前にポータルからデータ削除証明書のサンプルを請求してください。証明書は削除タイムスタンプと削除対象レコードセットのSHA-256が記載された1ページのPDFです。
8. 付録:匿名化の具体例とイベントクラス一覧
8.1 匿名化の具体例
サウジアラビアの学校展開で実際のQ8から取得した以下の生イベントシーケンスをご覧ください。4段階の匿名化パイプラインの各ステップを順に追跡します。
生データ oid.lookup デバイスで取得されたイベント(サンプル時間帯、現地時間14:00〜14:15):
14:02:11 oid.lookup serial=QC8-24-118-00472 lat=98ms page=412 word="الفيل"
14:03:48 oid.lookup serial=QC8-24-118-00472 lat=104ms page=412 word="يمشي"
14:05:22 oid.lookup serial=QC8-24-118-00472 lat=88ms page=412 word="ببطء"
14:09:17 oid.lookup serial=QC8-24-118-00472 lat=101ms page=412 word="في"
14:11:46 oid.lookup serial=QC8-24-118-00472 lat=94ms page=412 word="الحديقة"
ステージ1 — 識別子の除去。シリアル番号は、起動ごとにローテーションされる128ビットのソルトに置換され、その後32ビットのバケットIDにハッシュ化されます。バケットIDは0x4A12F8E1 ソルトなしではシリアル番号に逆変換できず、ソルトは次回のコールドブート時に消去されます。
ステージ 2 — 値をバケット化します。レイテンシは最も近い 10 ms に丸められます。ページは CEFR A1(1〜500 ページ)、A2(501〜1,200 ページ)、B1(1,201〜2,000 ページ)にバケット化されます。
ステージ 3 — ハッシュフィンガープリントを作成します。このウィンドウにはスタックトレースは含まれません。
ステージ 4 — 送信元で集約します。5 件のイベントは 1 件のレコードにまとめられます。
結果:14:15 に 1 件のレコードがアップロードされました:
{
"fleet_id": "0x4A12F8E1",
"model": "Q8",
"fw": "3.3.1",
"region": "SA",
"window": "2026-09-12T14:15:00Z",
"events": {
"oid_lookup_count": 5,
"oid_lookup_p95_ms": 100,
"cefr_bucket": "A2"
}
}
これがフリートダッシュボードに表示される内容です。子ども、保護者、特定のペンに戻る経路は存在しません — バケット ID は起動ごとにローテーションされます。
8.2 イベントクラス全一覧(n = 44)
サブシステム別およびデフォルトのポリシー別に分類された、完全なイベント分類体系:
| ID | イベント | ポリシー | 集約ウィンドウ | 備考 |
|---|---|---|---|---|
| 0x01 | boot.start | TELEMETRY | 15 分 | コールドブートを計測 |
| 0x02 | boot.end | TELEMETRY | 15 分 | コールドブートの所要時間 |
| 0x03 | pwr.drain | TELEMETRY | 15 分 | バッテリー消費率 |
| 0x04 | pwr.charge | TELEMETRY | 15 分 | 充電電流のピーク値 |
| 0x05 | key.press | LOCAL | n/a | ボタンマップ |
| 0x06 | book.open | LOCAL | n/a | 再開位置 |
| 0x07 | book.close | LOCAL | n/a | 再開位置 |
| 0x08 | oid.lookup | TELEMETRY | 15 分 | バケット化されたレイテンシ |
| 0x09 | oid.miss | TELEMETRY | 15 分 | 読み込んだ書籍にコードが存在しない |
| 0x0A | dict.hit | テレメトリ | 15分 | キャッシュヒット率 |
| 0x0B | dict.miss | テレメトリ | 15分 | コールド参照レイテンシ |
| 0x0C | lp.load | テレメトリ | 15分 | LP 署名検証 |
| 0x0D | tts.speak | テレメトリ | 15分 | ファーストバイトレイテンシ |
| 0x0E | asr.utterance | サポート | セッションごと | オプトインのみ |
| 0x0F | asr.result | サポート | セッションごと | オプトインのみ |
| 0x10 | app.crash | テレメトリ | 15分 | スタックハッシュ |
| 0x11 | app.err | テレメトリ | 15分 | 重大度 0~3 |
| 0x12 | fw.update | テレメトリ | リリースごと | OTAステージング |
| 0x13 | fw.rollback | テレメトリ | リリースごと | ロールバック回数 |
| 0x14 | dict.update | テレメトリ | リリースごと | 辞書 OTA |
| 0x15 | lp.update | テレメトリ | リリースごと | LP OTA |
| 0x16 | wifi.assoc | テレメトリ | 15 分 | 認証時間 |
| 0x17 | wifi.fail | テレメトリ | 15 分 | 認証失敗 |
| 0x18 | ble.pair | テレメトリ | 15 分 | SSP 確認 |
| 0x19 | ble.fail | テレメトリ | 15 分 | ペアリング失敗 |
| 0x1A | nfc.read | ローカル | n/a | タグ UID のみ |
| 0x1B | usbc.plug | ローカル | n/a | USB-C 挿入回数 |
| 0x1C | usbc.pd | テレメトリ | 15 分 | PDO 受理 |
| 0x1D | batt.health | テレメトリ | 毎日 | 容量劣化 |
| 0x1E | therm.warn | テレメトリ | 15 分 | PMIC サーマル |
| 0x1F | wear.delta | テレメトリ | 毎日 | フラッシュ書き込み回数 |
| 0x20 | err.s0 | テレメトリ | イベントごと | グローバル停止トリガー |
| 0x21 | err.s1 | テレメトリ | 15 分 | S1 カウント |
| 0x22 | err.s2 | テレメトリ | 15分 | S2カウント |
| 0x23 | err.s3 | テレメトリ | 15分 | S3カウント |
| 0x24 | app.locale | ローカル | n/a | UI 言語 |
| 0x25 | app.theme | ローカル | n/a | UIテーマ |
| 0x26 | voice.clip | サポート | セッションごと | オプトインのみ |
| 0x27 | voice.share | サポート | セッションごと | オプトインのみ |
| 0x28 | voice.delete | サポート | セッションごと | オプトインのみ |
| 0x29 | dict.override | サポート | セッションごと | オプトインのみ |
| 0x2A | parent.pin | ローカル | n/a | 保護者による使用制限 |
| 0x2B | screen.time | ローカル | n/a | 一日の利用時間 |
| 0x2C | session.end | テレメトリ | 15分 | セッション時間 |
44件のイベントのうち、18件がLOCAL、19件がTELEMETRY、7件がSUPPORTです。完全な一覧はOEMポータルのプライバシー影響評価テンプレートに掲載されています。
10. ビジュアル:イベント分類の分布と帯域幅予算
以下の可視化では、3つのイベント分類(LOCAL/TELEMETRY/SUPPORT)の円グラフと、ペン1本当たりの月間帯域幅予算の棒グラフを組み合わせています。152KBという数値は、学校の調達部門と共有する公開済みの契約上の数値です。