Repository navigation
Conversation
Pico ~2Mbps 600秒連続受信(154MB)でメモリ計測。合計WSは送信中ピーク~685MB →停止で46.5MBへ解放(プロセス7→1)。保持リークの兆候なし。ただしピークは WebView2フロントの一過性描画バッファが主で、154MB受信に対し大きい(footprint 課題、リークではない)。10分/~2Mbps/1サイクルであり、正式60分ゲートと 複数サイクルのベースライン漸増チェック、真の12Mbps(FT2232H)は残課題。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
- CHANGELOG.md を新規作成(Keep a Changelog、0.1.0 の機能を記載) - T2-1/T2-2 ペアワイズ E2E 回帰: AI Bridge/MCP/ガイド追加後の 7 行全 PASS。 プロセス生存オラクルが PowerShell の実行コンテキスト依存の文字列比較の癖 (連続ハイフンを含む名 serial-monitor-essential に -Name/-eq/-match が偽を返す) で「app process died」を誤検出していたため、UIA メインウィンドウ存在での liveness 判定に変更(旧プロセス名 + -ErrorAction Stop の誤検出も解消) - T2-3 ミューテーション差分: mcp_stdio.rs は missed 0(完全被覆)。bridge.rs は test_size_constants / test_is_ok_reflects_outcome とat_msアサーション強化で 6 件を kill、残 2(port_handle/is_timeout の IO 層)は単体では等価とコメント明記 - docs/23 テスト数更新(bridge 30, 計227)、docs/24 §6.5 に T2-1/2/3 結果を記録 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
再測定で missed は port_handle→None の 1 件のみ(IO層・単体等価)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
- 重大な訂正: 先の「mcp_stdio 0 missed / bridge 1 missed」は cargo-mutants の 逐次書き込み outcomes.json を途中で誤読した誤り。完走値は 232 mutants = caught 159 / missed 57 / unviable 15 / timeout 1(≈74%。bridge 27・mcp_stdio 30)。 - mcp_stdio.rs にテスト追加(from_env の port>0/token フィルタ、is_valid_utf8 の 切断境界、serial_send の全 line_ending、dispatch の null-id 通知扱い)。 bridge.rs は既追加テストで 27→21。 - 残存ミュータントは大半が IO 層・コマンド配線・stdio 主ローカル(実ソケット結合と E2E で担保、ミュータント粒度は未アサート)→ DEBT-7 を両ファイルに拡大。 - T2-4 メモリソークは静穏条件の 60 分計測が正式値: WS ~410MB で定常、 +1.3MB/30分(リークなし)。10 分版の 685MB ピークは計測中 UI 操作の 一過性アーティファクトと判明。 - docs/23 テスト数更新(mcp_stdio 34 / bridge 30 / 計 231)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
完走サマリ行で完走を確認したうえでの確定値。追加テストで 11 kill (bridge 27→22 / mcp_stdio 30→24)。残 46 は IO 層・コマンド配線・stdio 主ループ が中心で DEBT-7 として管理。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
12 Mbps (1.5 MB/s) 級の受信中でも AI エージェントのトークン消費が デバイスのスループットに比例しない API を設計。帯域ではなく 「AI が読める量」が制約であるという分析から出発する。 - 統括原則「アプリは問いに答える。干し草の山を送りつけない」と 5 原則 - 既存機構を正として流用できない理由をコードで検証して明記 (aggregator の GUI ライフサイクル依存、plotter の非 epoch 時刻、 PlotterParser のゴミチャンネル、LF のみの line_index) - ブリッジ所有の insight モジュールを新設する構成と応答エンベロープ - 新規 6 ツール (digest/watch/find/patterns/sample/channels)、 既存 7 ツールは削除せず有界化。PROTOCOL_VERSION 1 -> 2 - 誤誘導防止を受入基準として規範化 (正確な件数、稀少イベントの床、 重大度は常に全バイト走査、極値には必ずオフセット、裸の err=0 禁止) - 効果/労力順の 6 段階実装計画と、受け入れたリスクの明示 あわせて既存実装の実バグを 1 件記録: serial_wait_for の クライアント側ポーリングは 65536 B / 500 ms = 実効 131 KB/s で、 1.5 MB/s に対し約 11 倍の読み負けとなり返信を取りこぼす。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
docs/26 §5.1 で発見した実バグの暫定修正。 問題: 待機ループは tail 窓を固定 64 KiB で WAIT_POLL_MS(500ms) ごとに 読んでいた = 実効 131 KB/s。約 1 Mbps を超えるとポーリング間にデータが 窓から流れ出て chunk_offset > cursor が毎回成立し、累積バッファが 置換される(gap)。12 Mbps(1.5 MB/s)では約 11 倍の読み負けとなり、 デバイスの返信は着弾から約 43ms 以内にポーリングが落ちたときしか 観測できなかった。 修正: - 窓を適応的にした。要求量 = 前回判明した未読分 + 64 KiB を MAX_READ_LENGTH(1 MiB)で頭打ち。到着レートに応じて自動的に広がり、 約 16 Mbps まで読み負けない。 - 窓を広げると蓄積が毎秒 MB 単位で伸びるため、走査済み接頭辞を解放し WAIT_RETAIN_BYTES(64 KiB)の重なりだけ残す。acc_start を同量進めるので 報告するオフセットは絶対値のまま狂わない。データを捨てていないので gap は立てない。 - bytes_scanned が切り詰めで減らないよう累計を別管理にした (usize -> u64)。 - Node 参照実装にも同じ変更を適用(DEBT-6 の同期義務)。Node 版はロッシー UTF-8 文字列上でマッチするため、切り出し位置を UTF-8 先頭バイトへ 寄せて既知のオフセットずれを悪化させないようにした。 テスト: 窓が未読分に応じて広がり MAX_READ_LENGTH で頭打ちになること、 切り詰めてもオフセットが絶対値のままで bytes_scanned が累計であり gap が立たないことを固定。cargo test 233/233、mcp/smoke.mjs 全 PASS、 mcp_stdio_smoke.py 全 PASS。 残る限界は DEBT-8 として記録(64 KiB 超の単一マッチ、16 Mbps 超、 ポーリングと base64 往復の構造)。恒久対策は待機のサーバ側化 (docs/26 §7 段階 4)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
高レート受信でも AI のトークンがスループットに比例しないようにする
設計の第 1 段階。アーキ変更なし、新スレッド・新状態なし。
問題: looks_like_text が false になった瞬間、既定 4096 バイトの
serial_read_tail が hex ダンプ約 20 KB (6〜8k トークン) を返していた。
serial_status は 4 行と同じ内容を raw: {全 JSON} で繰り返しており、
情報ゼロのままトークンを倍にしていた。
変更:
- render_chunk に max_chars (既定 4000、範囲 500〜200000) を導入。
設計では「後段適用」としていたが、描画前にバイト単位で切り出す方式に
変えた。文字列を切ると出したバイト範囲を絶対オフセットで言えず、
「ペイロードではなくハンドル」の原則を満たせないため。
- 切り詰めたらヘッダに shown=<start>..<end> を付け、落とした範囲を
serial_read_range(...) 呼び出しとしてフッタで正確に示す。前後どちらにも
落ちる場合は両方。フッタは本文より優先して残す。
- 切り詰める側は用途に合わせる。tail は末尾(最新)、range は先頭(この位置
から)を残す。
- format (auto|text|hex|lines) と collapse_repeats を追加。
- serial_status の raw: {全 JSON} を廃止。
- 予算は文字数で課す。バイト概算だと CJK ログで予算の 1/3 しか使えない
ため、lossy UTF-8 の文字数を Utf8Error::error_len() の規則どおり
数えて逆算する。
- Node 参照実装にも同じ変更 (DEBT-6 の同期義務)。
max_chars の下限を 500 とした。ヘッダ+フッタ用に 240 文字を確保しており、
封筒すら入らない予算を許すと本文が空でも上限を超える。これは
プロパティ試験が実際に検出した (budget 200 で 201 文字)。
実測: 4096 バイトのバイナリが 20,223 -> 3,902 文字。
テスト: 受入基準「どんな入力・書式・予算でも max_chars を超えない」を
Rust 側でプロパティ試験、Node 側で smoke に固定。cargo test 244/244、
clippy -D warnings クリーン、mcp/smoke.mjs 全 PASS、
mcp_stdio_smoke.py 全 PASS。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
「1 MiB 引いてエージェント側で grep」(約 25 万トークン、しかも 1 MiB を 超えると届かない) を「サーバ側で数えて件数と少数のハンドルを返す」 (約 350 トークン) に置き換える。応答コストはキャプチャ長に依存しない。 追加: - src-tauri/src/insight/ を新設。走査ロジックは find.rs に純粋関数として 置き、ByteSource トレイトで実ストアから切り離した。試験は Vec<u8> 裏の 実装で欠落と時間切れを再現する。DEBT-7 が示した「IO ループから純関数を 抽出して細粒度検証」を新規コードで最初から守る形。 - ブリッジに find メソッド。help にも載せたので生 TCP のエージェントも 自己発見できる。 - MCP ツール serial_find (pattern / from / to / max_hits / count_only / max_chars)。ツール数 7 -> 8。 走査の正確性: - 256 KiB 窓 + 4096 B 重なり。窓の末尾で終わるマッチは打ち切られている 可能性があるためその窓では採らず、次の窓が重なりごと読み直して拾う。 重複計上は報告済みオフセットで抑える。窓境界ちょうどのマッチが 1 回だけ 数えられることを試験で固定した。 - bytes_scanned は重なりの二重読みを差し引いた実効値 (カバレッジ率が 100% を超えないため)。 - 欠落 (DEBT-5) は窓ごと飛ばして gap_bytes に積む。飛ばしたら exact は 必ず false。 - 3 秒で打ち切り complete=false を返す。クライアントの 5 秒タイムアウトで 無言で失敗させ「見つからなかった」と誤解させないため。打ち切り時は 再開用の from= を必ず添える。 出力の規範 (受入基準として試験に固定): - 件数は exact か AT LEAST — <理由> のどちらか。丸めない。 - 裸のゼロを出さない。matches: 0 には必ず走査バイト数・カバレッジ率・ 欠落・所要時間が付く。「見つからなかった」と「見に行けなかった」を 区別できるようにする。 - ヒットを打ち切ったら showing N of M hits と明示する。 返答に base64 が混ざらないこと、応答サイズがキャプチャ長に依らないことを ブリッジ側の試験で固定 (find の存在意義そのもの)。tools/list のスキーマ 常駐コストが 9000 文字を超えないことも押さえた。 Node 参照実装・アプリ内 Setup Guide・mcp/README も同期 (DEBT-6)。 テスト: cargo test 263/263、clippy -D warnings クリーン、vitest 173/173、 tsc/eslint クリーン、mcp/smoke.mjs 全 PASS、mcp_stdio_smoke.py 全 PASS。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkrgSKpH4VPzKKXX1FEs4h
12 Mbps 級の受信中でも、AI エージェントのトークン消費がデバイスの スループットに比例しない経路を作る。実測は digest 901 文字(約 250 tok)/ watch 394 文字(約 110 tok)で、3,042 行でも 20,000 行でも同じ桁に収まる。 新規 `src-tauri/src/insight/`: - mask.rs 行 -> テンプレート、重大度の全バイト走査(純粋) - window.rs ウィンドウ解決、カーソルの生成/解釈(純粋) - render.rs セクション優先順位と文字数予算(純粋。予算はここ 1 箇所) - index.rs 有界テンプレート表、チェックポイント差分、世代 - thread.rs DataStore を読む唯一の追加リーダ 索引は BridgeState が所有し、bridge_set(true) で起動・(false) で停止する。 GUI の窓の開閉に影響されないので、人間がプロット窓を閉じても AI の答えが 遡って変わらない。PROTOCOL_VERSION 1 -> 2。 設計から意図的に変えた点(docs/26 §7.3 に理由つきで記録): - 表の追い出しは LRU。最も稀なものを追い出すと「稀少イベントの床」と矛盾する - 差分では first / min / max を出さない。窓の外を指しうる値は書かない - 写しとカーソルは同じロックで取る。ずれると行がどちらの応答にも載らない - watch のロングポールは 3000ms 上限(MCP クライアントの 5s タイムアウト手前) - 時系列バケットは素材にしたチェックポイントの範囲を必ず明記する 達成できなかった点も記録した: MCP スキーマの常駐コストは 7.1k -> 9.0k 文字に 増え、docs/26 の「約 1.0k トークン」目標には届いていない(既存 8 ツールの 時点で約 1.9k トークンあった)。12 Mbps での索引の追随性能は未実測(DEBT-9)。 試験: 単体 + プロパティ(P-10〜P-13)、SM-7 の状態遷移(0-switch 6 / 1-switch 36)、 実ソケット + 実索引スレッドの一気通し、Node smoke、MCP stdio E2E(10 ツール)。 cargo test 326 passed / vitest 173 passed。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xXghguLZV3q5aVg4R3xve
導出情報では足りず「実際の行そのもの」が要る場面のための、上限付き・ 重複畳み込み付きの窓と、テンプレート 1 件の詳細を追加した。 - insight/sample.rs(純粋): 完全な行だけの抜き取り、重複畳み込み、等間隔位置 - ブリッジ `sample` / MCP `serial_sample` (tail | head | around | stratified | by_template) - `serial_digest(template="t12")`: そのテンプレートの全項目の範囲を 発生オフセット付きで、実際の行つきで返す `serial_patterns` は別ツールにしなかった。中身を分解すると 3 つのうち 2 つは 既にある(ヒストグラム = digest、compare_to = watch)ので、残る「詳細」だけの ために tools/list の常駐コストを全リクエストに乗せる価値がない。設計自身の 原則「機能はパラメータに畳む」に従って digest のパラメータにした (docs/26 §7.4 に記録)。増えたツールは serial_sample の 1 つだけ。 正確さのための判断: - 読み出し窓の端で切れた行は捨てる。0 行になったら理由と次の手を必ず出す - 索引はテンプレートごとに直近 4 件の「オフセットだけ」を覚える(8 KB)。 行本文は持たず、必要になった時点で読み直す。4 件しか無いことは明記する - stratified は範囲が狭ければ短くする(同じ位置を n 回読んで水増ししない) - [xN] の N は丸めない cargo test 338 passed / vitest 173 passed / MCP stdio E2E 11 ツール。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xXghguLZV3q5aVg4R3xve
`serial_wait_for` の走査をブリッジへ移し(`bridge::method_wait_for`)、 `serial_send` / `serial_send_hex` に `expect` を足した。 消えた失敗モード(DEBT-8 の 3 点すべて): - 窓が無い。ストアを from から末尾までそのまま前方走査するので読み負けない (旧: 固定 64 KiB / 500ms = 実効 131 KB/s、約 1 Mbps で返信を取りこぼす) - 蓄積が無い。WAIT_RETAIN_BYTES(64 KiB) を超える単一マッチの取り逃がしが 再開の重なり 4 KiB 超だけに縮んだ - base64 の往復が無い。ワイヤに乗るのはマッチ 1 件の情報だけ さらに `send` が書き込み直前の total_bytes を返すようにした。 `serial_send(expect=...)` はその位置から走査するので、「返信が最初の ポーリングより早いと観測できない」競合が構造的に消える(時間ではなく 位置で決まる)。Node スモークに `a reply that lands before the first scan is not missed` として固定した。 設計から変えた点(docs/26 §7.5): - 1 リクエストで待ち切らない。クライアントの 1 リクエストタイムアウトは 5000ms で、ブロック中のソケット読み出しは中断できず cancelled に 反応できなくなる。サーバ側 1 回の待機を 1000ms で切り、next_from で 呼び直す。キャンセル検知の遅延は最大 500ms -> 1000ms に悪化する - 重なりの計算はブリッジに 1 箇所だけ(next_from)。Rust 版と Node 版で 境界の扱いがずれない - match_text をブリッジが返すことで、Node 版の lossy UTF-8 由来の オフセットずれ(DEBT-6 の既知の非対称 2)も解消した 残る限界: 再開の重なり 4 KiB を超える単一マッチは境界で取り逃がし得る。 cargo test 350 passed / vitest 173 passed / Node smoke / MCP stdio E2E。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xXghguLZV3q5aVg4R3xve
索引が取り込んだ制御バイトの割合を数え、行指向でなさそうなときは serial_digest の固定枠(INDEX セクション)で明言する。バイナリに対して 「402,331 行」と文字化けテンプレートを並べるのは、docs/26 が禁じている 「自信満々に嘘をつく」そのものだった。 判定は「タブ / CR / LF / 表示可能 ASCII / 0x80 以上のいずれでもない バイト」が 5% 超。0x80 以上を可とするのは CJK ログをバイナリと誤認 しないため(この向きの誤検知の方が害が大きい)。一様乱数のバイナリは この定義で約 11% になる。256 バイト未満では判定しない。 段階 5 の残り(serial_channels / binary.rs のフレーム要約)は **やらないことを選んだ**。理由は docs/26 §7.6 に記録: - serial_channels の中身は既に digest(template=) / watch / buckets にある。 テンプレート単位の統計はラベル推定を必要としない分だけ誤りにくい - フレーム境界の推定を外すと、今度はフレーム単位で嘘をつく。 「テンプレートを信じるな」と言えている以上、当てにならない推定より serial_find と read_range(format="hex") へ誘導する方が正直 cargo test 355 passed / vitest 173 passed / Node smoke / MCP stdio E2E。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xXghguLZV3q5aVg4R3xve
FT232H(D0-D1 ジャンパ)で実ボーレートの UART を初めて測定した。 - test_tools/ft232h/: pyserial 単体のトランスポート基準(loopback_baseline.py)、 AI Bridge 経由のアプリ受信試験(app_loopback.py)、一括実行(run_app_loopback.ps1) - ui.ps1: toggle に -State(永続化された設定を冪等に揃える)、click-text に -Path による ControlType 絞り込み(ボーレートの Text と ListItem の名前衝突) 結果(docs/24 §6.5 T2-5b): - ボーレートは実際に効く(115200〜6M で理論値の 93〜98%) - フロー制御なしではトランスポート単体でも 6M 以上・60 秒で欠落(破損 0) - アプリ経路では送信長に比例して欠落が悪化(16 KiB 送信で 60%)。 送信がポート Mutex を握ったまま write_all し受信ワーカーを止めるため。 DEBT-10 として docs/22 に記録(対策方針は決定待ち) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ADR-14: ポート I/O を受信ワーカーが単独所有し、送信・DTR・RTS はキュー経由で 1 ms 分ずつ読みと交互に書く(外部レビューの提言を serialport 4.9 の実装で裏付けて採用)。 スライスしてロックを手放す案、try_clone、オーバーラップ I/O を退けた理由と、 実装時に足す不変条件 INV-14〜17・検証と合格条件を記録。実装は未着手 - docs/21: 「12 Mbps」= 12 Mbaud(8N1 でペイロード 1.2 MB/s)とオーナー決定を明記。 SYS-NF-101 の測定は RTS/CTS ありで行う - docs/24 T2-5b: RTS/CTS ありだとトランスポート単体は 12 Mbaud・60 秒・65 MB で欠落 0。 アプリは 4 KiB 送信で欠落 0 だが停滞し、16 KiB 送信は自己デッドロックで WriteZero - ft232h: baseline に --rtscts、ランナーに -FlowControl、失敗時も必ずアプリを終了、 送信エラーの報告。ui.ps1 の select-combo は値が同じ複数のコンボを順に試す Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
送信がポートの Mutex を握ったまま write_all していたため、書き込み中は受信が 止まりドライバのバッファから溢れていた(FT232H 12 Mbaud で 16 KiB 送信時に 60% 欠落、 RTS/CTS 下では自己デッドロックで WriteZero)。 - serial/tx.rs(新規): OpenPort / PortCommand / TxEngine / PortIo。送信・DTR・RTS は キューでワーカーへ渡し、ワーカーが read と 1 ms 分のスライス書き込みを交互に行う - タイムアウト 2 段: スライス単位の OS タイムアウト(書けなかった分は再開)と 無進捗タイムアウト 3 s。総時間の期限はフロー制御下で偽タイムアウトを出したので置かない - 呼び出し側は期限なしで待つ(キュー待ちの要求を Err にして二重送信を招かない)。 終了経路はすべて返信を破棄するので必ず戻る - Clear では進行中の送信を状態ごと退避して次のワーカーが続ける - ブリッジ send の offset_before はワーカーが取り出した時点の公開済み位置。 status.connected は切断で false - Windows ではワーカー稼働中だけ timeBeginPeriod(1)(COMMTIMEOUTS の待ちが 15.6 ms 粒度に丸められ 1 スライスが最大 19 ms 止まっていた) - write_data / write_dtr / write_rts を async + spawn_blocking に - ワーカーの 5 秒ステータスログに受信停止の最大時間(read/tx/other)を追加 - テスト: 偽ポートでエンジンとワーカーループを駆動(INV-14〜17、停止→再開、 無進捗、Clear の引き継ぎ、致命エラー、ブリッジ send の成功経路)。Rust 376 件 PASS 設計は別エージェント 4 人で順にレビュー(提言 → 必須指摘 2 件 → 承認 → 実測後の 無進捗タイムアウト化を承認)。送信キュー残量でのゲートは効果が無く採用しなかった。 受入(docs/24 §6.5 T2-5c): 12 Mbaud・RTS/CTS・AI Bridge ON・64 KiB 送信・60 秒 ×2 で 65 MB 欠落 0・SHA-256 一致(線速度の 91〜92%)、索引の遅れ 0。SYS-NF-101 受入、 DEBT-9 (4) 解消。フロー制御なしでも 0.012%(修正前 60%)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
自動再接続(SYS-F-807 新設 / SYS-F-803 を手動の Connect に限定) - 「Auto Connect」の飾りのチェックボックスを Auto Reconnect として実装。 切断したデバイスと同じデバイスパスが戻ったら reopen_port で開き直し、 同じ DataStore に追記を続ける(オフセット連続・ブリッジに reset なし・ 切断前のログを保持)。手動の Connect は従来どおり新しいセッション - 待機中は alert を出さず「Waiting for …」と Cancel を表示、ポート選択を 保持(一覧から消えたポートは "(not present)" で残す)。設定は localStorage - ブリッジ status に reconnecting、MCP serial_status にも反映(Rust / Node) - 既存バグ修正: 致命エラー経路で最後のチャンクの行位置を索引していなかった - 設計は Fable のレビュー(OK with changes)の指摘をすべて反映 表示名と言語(SYS-NF-305 新設) - 設定トグルの表示名 AI Bridge → MCP Server(識別子・環境変数は据え置き) - 外部へ出す文字列を英語のみに(UI の残り・MCP エラーの日英併記を廃止) 公開準備 - README を書き直し(比較表の誤りと Auto Connect の記述を削除、実測性能・ Linux の MCP 登録・セキュリティの説明を追加)、スクリーンショットを撮り直し - coverage/ と agents/ を追跡から外す 未確認事項リスト(docs/27 新設) - 実機の抜き差し(OV-1)など未確認の 9 件を 1 か所で管理し、docs/24・25 から参照。 確認用に test_tools/ft232h/reconnect_check.py を追加 検証: cargo test 383 / vitest 179 / Node smoke / clippy / fmt / tsc / eslint / prettier、UIA E2E(run_bridge_e2e.ps1)と mcp_stdio_smoke.py をリリースバイナリで PASS。 自動再接続の実機抜き差しは未確認(docs/27 OV-1)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…認に分割 プロッタ(ADR-15 / SYS-F-513・515・517) - 画面評価(docs/27 §3 PF-1)で、既定の LTTB モードが 1 サンプルのスパイクを バケット平均で潰すことを確認(400 → 10 秒窓で約 41、300 秒窓で約 9。 6.0 のスパイクは 300 秒窓で消失) - 表示モードを Peak に置換: 絶対時刻グリッドのセルごとに最小・最大サンプルを 実時刻で時間順に描く。LIVE / 静的範囲で同じ処理。LTTB は実装・テスト・ 設定名とも削除(三角形面積の選択では極値が残る保証がないため) - 取り込み時の 10 件平均(bucket_size 10)とレベルアップでの倍増を廃止。 バケットに ts_min / ts_max と結合的な同値規則を追加。凡例の最新値は別保持 - テスト: 性質テスト prop_peak_mode_keeps_extremes_and_real_samples、 遅いデータが平均されず描画済みの点が変わらないこと、Peak 包絡線の単体 6 件。 同じ信号でアプリを再撮影し、外れ値・スパイクが元の値で描かれることを確認 - 設計は Fable のレビュー(OK with changes)の指摘を反映 V&V - docs/27 を検証(OV)と妥当性確認(VA)に分割。妥当性確認の記録は 0 件と明記、 プロッタの画面評価の所見 PF-1〜5 を追加。E-17 / E-19 を実施 - Auto Reconnect と US-02 は利用者が切り替えられるので衝突しない(オーナー判断) 既知の未対応: 上限到達後の再集約で表示が周期的に粗くなる問題(ADR-16 で対応予定) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
上限 1 万件での全履歴の再集約(ウィンドウ相対)は、Peak 化で恒常的に走るように なり、既定の 10 秒窓でも 100 Hz なら 50 秒ごとに粗くなって右から埋まり直す 「呼吸」を起こしていた(Fable の定量評価)。 - 線チャンネルごとに段を持つ。段 k は 2^k ms のセルの絶対時刻グリッド。新しい サンプルは段 0(1 ms セル)へ、古くなったセルは隣同士をまとめて次の段へ。 セルは粗くなる方向にしか変わらず境界は動かない。どの段も約 2048 セルで、 メモリは受信レートに依存しない - 表示グリッドを 2 の冪に(SYS-F-512)。LIVE 窓(1〜300 秒、最大 4000 px)は 窓内の生サンプルだけで描かれる(性質テスト P-14 を追加、段を早く畳みすぎる 変異で落ちることを確認)。バッチ等価性 P-7 は全領域で強形に - 平均は合計で保持。Average の静的範囲もウィンドウ相対をやめ絶対グリッドへ統一 - level_up / aggregate_buckets_preserving / bucket_size / max_points を削除し、 設定は tier0_span_ms に。凡例の pts は受信サンプル数 - アプリで 100 Hz・3 分を確認: 旧方式で粗くなり始めた 100 秒を過ぎても 10 秒窓は 細かいまま、スパイクも元の値 - ズームでいつでも 1 ms 解像度を見る要求(R1)はディスク保存で別コミット予定 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
画面側は右端を実時間ぶん進め、取得時は Math.ceil(右端) を送る。バックエンドは それを end_ms として返し、画面は「返った値が右端より先なら合わせる」ので、毎回の 切り上げの端数が積もって戻らなかった。100 Hz で 160 秒後に 3 秒、10 秒窓では 約 10 分でデータが画面から消える。段階化の確認中に発見した、前からある欠陥。 右端を合わせるのは初回(範囲を指定しない要求)の応答だけにした。再現テストを追加 (修正前は失敗)し、アプリで 3 分後もデータが右端まで届くことを確認。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
段階化(ADR-16)でメモリの段は古いほど粗くなる。オーナー要求「ズームすれば細かい データをいつでも見られること」に対応する。 - 段 0 から押し出される 1 ms セルを、書き込み専用スレッドがチャンネルごとのファイルへ 書き足す(1 / 64 / 4096 ms の 3 レベル、48 バイト固定長、疎な索引)。アグリゲータの ロック内では I/O をしない - 静的範囲でメモリの段が表示セルより粗いときだけ、同期してからディスクを読む (表示セルあたり最大約 64 件)。LIVE はディスクを読まない - 世代ごとのディレクトリ(Clear で切替、読み手がいなくなったら削除)。上限 4 GiB - 受信データの再パース案は、パーサの状態とタイムスタンプの再現が要るため不採用 - テスト: 性質テスト P-16(静的範囲は生サンプルの包絡線と一致)、1 時間分を入れて 50 分前を拡大すると全サンプルが出る、LIVE はディスクを読まない、世代の切替。 ディスクを読む経路を無効にする変異で落ちることを確認 - 設計は Fable のレビューを反映 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
状態チャンネルはメモリに直近 10,000 件だけを持ち、それより古い変化は捨てていた (120 ms で切り替わる弁なら約 21 分で消える)。まれな異常状態を後から遡れるよう、 捨てる分を数値と同じ保存スレッドでファイルへ書き出し(24 バイト固定長、状態名は id)、 静的範囲でメモリより古い時刻を要求されたら読み戻す(1 回最大 50,000 件)。 LIVE はディスクを読まない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
動いているデバイスにつなぐと最初の行はほぼ必ず途中から始まり、前の途中の行と つながって消えない偽のチャンネルを作っていた(画面評価で 2 回観測)。 - データストアに受信の開始・再開位置(segment_starts)を記録(start_reception で、 ワーカー起動より前に登録) - パーサに begin_untrusted_segment を追加: 前の途中の行を捨て、次の 1 行はヘッダー 検出にだけ使いデータ点にしない(DTR リセットで起動する基板のヘッダーは残る)。 CR / LF / CRLF と、改行が読み出しの切れ目で割れる場合にも対応 - プロッタのスレッドは読んだデータを区切り位置で分けてパース。読み飛ばし後も同様 - AI 向けの索引(insight)も再開位置で途中の行を捨てる - テスト 11 件(観測ケースの再現を含む)。区切りを伝えない変異で落ちることを確認 - 設計は Fable のレビュー(OK with changes)を反映 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…S-F-808) - 新しいセッション(手動 Connect / Clear)のストアにつながるたびに時間の原点を戻す。 自動再接続は同じストアなので戻さない - ポートを閉じた状態の Clear でストアが外れたら、その時点でプロッタを空にする。 Disconnect → Clear → Connect で旧セッションのチャンネルが残って混ざる欠陥 (PF-7、SYS-F-802 違反)を解消 - アグリゲータに世代番号を追加し、バージョン照会とペイロードで画面へ渡す。画面は データが流れ続けていても世代の変化で表示を作り直し、Inspect 中なら LIVE に戻る (原点だけ戻すと古い時間軸の窓を要求し続けて固まるため。Fable の指摘) - データが窓に満たない間は [0, W] を表示して負の時刻を描かない - テスト: バックエンド 3 件、フロント 3 件。世代の検知を外す変異で落ちることを確認 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
文字列ハッシュの色相では E01/E02/E03 がほぼ同じ色になり、FAULT_OVERTEMP_LATCHED が 正常の ON と同じ緑、正常な STOPPED と ERROR がほぼ同じ赤だった(Fable が計算で確認)。 - 異常(FAULT/ERR/ALARM/FAIL/TRIP など)は赤・橙系、警告は琥珀、稼働は緑、停止・待機は 灰色。それ以外は、これらの色を使わないパレットから登場順に割り当て、セッション中は固定 - 異常の区間は最低 4 px で、隣の区間に塗りつぶされないよう後から描く - テスト 7 件(計算で衝突が確認された組を含む) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- バージョンを 0.1.0-beta.1 に(tauri.conf.json / Cargo.toml / package.json と lock) - β を定義(docs/25 §1.1): 妥当性確認(VA)をするために出すプレリリース。検証(OV)は 必須、VA と Linux 実機(OV-7)は免除。GitHub では Pre-release、winget には出さない - release.yml: タグに '-' があれば prerelease として作り、Windows は NSIS のみ。 MSI(WiX)は英字のプレリリース識別子を受け付けないことを手元のビルドで確認した - README / CHANGELOG を β 向けに更新 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI(dtolnay/rust-toolchain@stable = 1.98)は手元(1.92)より新しい clippy で、 11/3 のコミットから失敗していた。 - bridge.rs: 不要な format!(useless_format) - mcp_stdio.rs: ゼロ除算の手動チェックを checked_div に(manual_checked_ops) - plotter/spill.rs: 定数サイズの chunks_exact を as_chunks に(chunks_exact_to_as_chunks) Windows ジョブの Prettier 失敗(AiGuideWindow の 2 ファイル)は 70ccbae で整形済み。 WSL(Rust 1.98)で CI の ubuntu ジョブと同じ手順(fmt / clippy / cargo test / バイナリのビルド / MCP stdio smoke)がすべて通ることを確認した。 docs/27: OV-1(自動再接続の実機抜き差し)は β では未確認のまま公開する(オーナー判断)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
SummaryRelease candidate for the first beta of the Tauri/Rust version, 0.1.0-beta.1 (pre-release). Plotter
Serial / MCP
Release / CI
Verification
🤖 Generated with Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.