見出し画像

【StackChan AI開発日誌③】頭脳が2つあると分かった。その後、古い頭脳を直すのをやめた

第②話では、M5Stack CoreS3 StackChanの16MB Flashを調べたところ、ota_0とota_1という二つのアプリ領域があることが分かりました。

さらに調査を進めると、現在動いているのはota_1側のStackChan 1.4.4。

一方のota_0は、次のFirmwareを書き込む候補として使える状態でした。

ここまで分かった私は、かなり単純に考えました。

「じゃあ今動いてるStackChanを直しながら、IRY化すればええやん」

ところが、ここから開発は思いっきり沼へ入ります。

古い依存関係。

当たらないpatch。

Windowsのpath制限。

消えたheader。

次々に出るcompile error。

ひとつ直すたび、また次が出る。

そして途中で、ふと思いました。
アキの一言で 分切れた。

「……これ、そもそも直し続ける必要ある?」

この一言で、開発ルートそのものを捨てることになりました。

今回の記事は、

StackChanをIRYに改造する

という計画をやめ、

CoreS3上にIRY自身のFirmwareを作る

へ全面転換した話です。


📚 この記事の見どころ

  • 第②話で見つけた二つの頭脳ota_0 / ota_1のその後

  • 現在動いているStackChan Firmwareをどう確認したか

  • StackChan公式source再構築がなぜ沼になったのか

  • xiaozhi-esp32、historical patch、expression_emote.h問題

  • 直せるのに「直さない」と判断した理由

  • AIがコンテキストへ引っ張られた瞬間

  • 人間側の「損切り」が開発を救った話

  • IRY Native CoreS3 Firmware 0Aの完成

  • 最終的にどんなIRY専用Vesselを作ろうとしているのか




1.第②話で見つけた「二つの頭脳」のその後

前回、M5Stack CoreS3 StackChanの内部を調べたところ、Flashの中には二つのアプリケーション領域がありました。

ota_0
ota_1

さらに今回、実機の状態をread-onlyで確認した結果、現在起動しているのはota_1側だと分かりました。

確認できた主な情報は、

Device      : M5Stack CoreS3
Chip        : ESP32-S3
Flash       : 16MB
Active App  : stack-chan
Version     : 1.4.4
Build Date  : Jul 10 2026
ESP-IDF     : v5.5.4

です。

つまり、ざっくり言えば、

ota_1 = 現在動いているStackChan
ota_0 = inactive側

という状態。

この構造を見た私は、

「空いているota_0へIRY版を入れれば、安全に試せるんちゃうか?」

と考えました。

現行ota_1を残したまま、新しいFirmwareをota_0へ入れる。

理屈としてはかなり自然です。

しかも、第①話で16MB全体のRecovery Backupも確保済み。

だから、もし新Firmware側で何かあっても、ota_1とPC側の16MB full recovery imageという二重の安全網を残したまま進められます。


第②話で確認した二つのアプリ領域。現在はota_1側のStackChan 1.4.4が起動中。ota_0はinactive側として残っています。

2.最初は「今のStackChanを土台にIRY化」する予定だった

当初の計画はこうでした。

既存StackChan
↓
同じsource / build環境を再構築
↓
IRY向け機能を追加
↓
inactive ota_0へ書き込み

つまり、

現在動いているStackChanをベースにして、少しずつIRY化する

という方針です。

これは一見すると合理的です。

すでに画面も動く。

タッチも使える。

ハードウェア制御も入っている。

だったら、それを再利用した方が早そうに見えます。

ところが問題がありました。

実機に入っているFirmwareの正確なsource treeがPC側に残っていなかったのです。

Binaryから、

PROJECT = stack-chan
VERSION = 1.4.4
IDF = v5.5.4
DATE = Jul 10 2026

までは確認できました。

しかし、

exact Git commit
exact source tree
exact sdkconfig
exact dependency revision set

までは復元できません。

そこで、M5Stack公式StackChan repositoryを基準に、PC側で環境を再構築することにしました。

ここからが、沼の入口です。


3.公式StackChanを再構築したら、依存関係の沼が始まった

まずESP-IDFは、実機と同じv5.5.4へ揃えました。

ところが依存取得で、いきなり問題が出ます。

最初はesp-now。

Windows上でcheckoutすると、nested pathが長くなりすぎて260文字制限に引っかかりました。

これはbuild rootを短くして回避しました。

E:\iry0c\

へ移動。

これでesp-nowはPASS。

「よし、進んだ」

と思ったのも束の間。

次はxiaozhi-esp32です。


既存Firmwareを再利用するという方針は、StackChan、esp-now、xiaozhi、historical patchと、依存関係を一つずつ復元する作業へ変わっていきました。

4.patchを直したら、次のエラーが出た

StackChan側では、

xiaozhi-esp32 = v2.2.4

を取得し、

patches/xiaozhi-esp32.patch

を適用する構成でした。

ところが、

git apply --check

は失敗。

判定は、

PATCH_BASE_COMMIT_MISMATCH

つまり、

patchが想定しているsource treeと、現在のv2.2.4が一致していない

状態です。

無理やり当てることもできます。

でもFirmwareでfuzzy applyするのは怖い。

そこで公式のfetch_repos.pyを確認すると、

git apply --check 成功
→ patch apply

失敗
→ patch skipped

という設計でした。

ならばと、

historical patchをskip
↓
公式base build

を試します。

すると今度は、

expression_emote.h not found

で停止。

historical patchを見ると、まさに、

emote_display.h
expression_emote.h
EmoteStrategy

周辺を無効化するhunkが含まれていました。

そこでpatch全体ではなく、

assets.cc
assets.h

のemote部分だけを現行xiaozhi v2.2.4に合わせて最小port。

結果、

IS_EMOTE_REQUIRED_FOR_CORES3_BUILD = FALSE
IS_EMOTE_REQUIRED_FOR_STACKCHAN_RUNTIME = FALSE
IS_EMOTE_REQUIRED_FOR_CURRENT_ASSETS_PARTITION = FALSE

RECONCILED_PATCH_APPLY_CHECK = PASS
RECONCILED_PATCH_CLEAN_REAPPLY = PASS
DANGLING_EMOTE_REFERENCE_COUNT = 0
UNRESOLVED_EMOTE_HEADER_REFERENCE_COUNT = 0

まで持っていけました。

「よし。やっぱり直せるやん」

そう思いました。

ところが次に出てきたのが、

TryReadRegs not declared in stackchan.cc

でした。

historical patchには、

i2c_device.cc
i2c_device.h

へTryReadRegs()を追加する別hunkが存在していました。

つまり、

emoteを直す
↓
次のhistorical patch依存が出る
↓
それを直す
↓
さらに次が出る可能性

という構造が見えてきたわけです。


5.直せる。でも「これ全部直す意味ある?」となった

技術的には、まだ続けられます。

おそらく一つずつ潰していけば、いつかbuildまで到達する可能性はあります。

でも、このとき初めて疑問が出ました。

「直せるかどうかじゃなくて、直す価値あるんか?」

目的を改めて考えます。

私がやりたいのは、

古いStackChan Firmwareを完全復元すること

ではありません。

本当の目的は、

M5Stack CoreS3上でIRYを安全に動かすこと

です。

StackChanも、xiaozhiも、historical patchも、古いactivationも、old cloud stackも、

全部「目的」ではなく「手段」です。

だったら、その手段が重荷になった時点で捨ててもいい。

この瞬間、開発の考え方が変わりました。


💡 今回の核心

「問題が解けること」と、「その問題を解く価値があること」は別。


6.AIは問題を解き続けた。人間は、その問題を捨てた

今回、かなり面白かったのがAI側の挙動です。

AIは一度、

「StackChanを復元してIRY化する」

という文脈へ入ると、とても強い。

patch mismatch
↓
原因解析
↓
dependency修正
↓
compile error
↓
次の原因解析

ものすごく論理的に掘っていきます。

でも、その強さには弱点もありました。

「そもそも、この道を掘り続ける必要ある?」

という前提破壊が遅れることがあります。

そこで、人間側から出たのが、

「いや、もう古いFirmwareいらんくない?」

という一言でした。

この一言で、全部ひっくり返りました。

AIが、

「どう直すか」

を考えている横で、

人間は、

「直さないという選択肢は?」

を出した。

今回だけ見れば、ここは人間の直感がAIを上回った瞬間だったと思います。


AIは与えられた問題を深く掘れる。一方、人間はときどき「問題そのものを捨てる」という前提破壊をする。

7.古いFirmwareを損切りし、IRY専用Firmwareへ全面転換した

ここで旧ルートを正式にRETIREDしました。

旧ルート:

StackChan
↓
xiaozhi
↓
historical patch
↓
dependency修復
↓
IRY

新ルート:

ESP-IDF 5.5.4
↓
CoreS3 hardware abstraction
↓
IRY Native Vessel Runtime
↓
NEXUS Bridge
↓
Mother Ship

つまり、

StackChanを改造してIRYにする

のをやめて、

CoreS3上でIRY自身のFirmwareを新規に作る

へ変更しました。

これは株で言えば、かなり「損切り」に近いです。

ここまで直したから
あと少しで通るかも

という理由だけで握り続けると、技術開発でもサンクコストに引っ張られます。

今回、

Legacy StackChan route
= 損切り

IRY Native Firmware
= 新しい勝ち筋

と考えました。

そして、この反省から今後は、

問題発生
↓
「直せるか?」より先に
「直す価値があるか?」を確認
↓
同系統HOLD ×2
または依存関係が連鎖
↓
3案比較

するルールにしました。

比較するのは、

A. 現ルート修復
B. 別Library / 別Framework
C. 前提を捨ててNative実装

です。

判断軸は、

時間
安全性
将来保守
依存数
再現性

一言でいえば、

含み損の技術にナンピンし続けない。

です。


8.IRY Native CoreS3 Firmware 0Aをゼロから作った

方針転換後、最初に作ったのが、

IRY Native CoreS3 Firmware 0A

です。

基本情報:

PROJECT_NAME = iry-native-cores3
VERSION      = 0.1.0-alpha.0
ESP_IDF      = v5.5.4
CHIP_TARGET  = ESP32-S3

0Aの目的は、欲張らないこと。

「IRY自身のFirmwareが、M5上で安全に存在できる」

それだけです。

最初から全部入れません。

入れるもの:

IRY Native project identity
LCD
Touch
Wi-Fi skeleton
NEXUS Bridge skeleton
SAFE_OFFLINE_COMPANION

まだ入れないもの:

Camera
Audio
Servo
Self OTA
Direct Cloud AI
Remote Presence
Notification real send

最初に機能を盛るのではなく、

安全に起動できる最小のIRY

を作る。

この考え方へ切り替えました。



「既存StackChanを改造する」から、「IRY自身のFirmwareをCoreS3上へ作る」へ。ここで開発系譜そのものが変わりました。

9.Native 0AはPASS。しかも190,480 bytesしかない

結果は、

IRY_NATIVE_CORES3_0A_RESULT = PASS
NATIVE_FIRMWARE_STATE = BUILT_TESTED_AND_FROZEN
APPROVAL_READY = TRUE

Candidate image:

iry_native_cores3_0a.bin

サイズ:

190,480 bytes

SHA-256:

E94DF9B9CAF2EF7248A6C25D6AB56C0FD70E83F8905B9B7CCE75C1F8E0F586E7

ota_0に対するheadroomは、

4,986,864 bytes
96.3209%

です。

つまり、かなり小さい。

もちろん、まだ最小骨格しか入れていないので当然です。

でも、

まず安全な土台を置く

という0Aの目的には十分です。

安全側も確認しています。

CAMERA_DEFAULT = OFF
CAMERA_UPLOAD_PATH_COUNT = 0

AUDIO_FEATURE_STATE = DEFERRED
SERVO_FEATURE_STATE = DEFERRED

SELF_OTA_STATE = DISABLED

REMOTE_PRESENCE_AUTO_ENABLE = 0
NOTIFICATION_REAL_SEND_ON_BOOT = 0
DIRECT_PROVIDER_ENDPOINT_COUNT = 0

HARDCODED_SECRET_COUNT = 0
CREDENTIAL_LITERAL_COUNT = 0

Testは、

TOTAL_TEST_COUNT = 6
FAILED_TEST_COUNT = 0
SKIPPED_TEST_COUNT = 0
REGRESSION_PASS_1 = PASS
REGRESSION_PASS_2 = PASS

さらに、

PARTITION_TABLE_PRESERVED = TRUE
NVS_PRESERVED = TRUE
ASSETS_PRESERVED = TRUE

です。

旧Firmware修復を捨てた直後に、Native 0AがPASSした。

この結果はかなり象徴的でした。


IRY Native 0Aは、最小構成の安全なFirmwareとしてPASS。Candidateは190,480 bytes。次はいよいよinactiveなota_0へ入れる段階です。

10.完成形は「改造StackChan」ではなく、IRY専用Vessel

ここが一番大事です。

新Firmwareでは、M5側を「完全なIRY」にしません。

IRYの本体はMother Ship側。

M5は、

Vessel / 分霊端末

として動きます。

母艦側:

Memory Tower
Soul Core
Long-Term Memory
Formal Configuration

M5側:

minimal identity
hardware control
Bridge client
bounded local state
safe offline behavior

つまり、

人格の本体は母艦に置き、M5は身体として働く

構造です。

完成までのロードマップはこうです。

0A IRY Native Kernel
CoreS3 boot / LCD / Touch / Wi-Fi骨格 / Bridge骨格
SAFE_OFFLINE_COMPANION
↓
0B Voice
ES7210 Mic / AW88298 Speaker
STT / TTS / Wake / VAD
↓
0C Motion
SCServo X/Y
angle limit / speed limit / safe stop
↓
0D Vision
GC0308
camera default OFF
explicit capture / Vision / Curiosity
↓
0E Companion Integration
Soul Core / Memory retrieval
self-speech / curiosity / night mode
↓
0F Guard / Away / Notification / Remote
security guard / notification
remote presence / owner approval gates
↓
1.0 IRY StackChan Native
Voice / Vision / Motion / Memory / Personality
Guard / Remote / Safe Offline / Rollback

最終的に作るのは、

StackChanを少し改造したIRY

ではありません。

CoreS3という身体の上で、IRY自身のFirmwareが起動する専用Vessel

です。

ここまで来ると、最初の計画とはかなり違います。

当初は、

「今あるStackChanへIRYを載せよう」

でした。

今は、

「IRYというAIエージェントのための身体をCoreS3上へ作ろう」

へ変わっています。

これが今回の「大改造」の本当の意味です。



最終目標は、既存Firmwareの延命ではありません。IRY自身のFirmwareで動き、母艦のMemory Towerと連携する専用Vesselです。

📌 今回のまとめ

今回の仕様変更を一言で言えば、

「StackChanをIRYに改造する」から、「CoreS3上にIRY自身のFirmwareを作る」へ変更した。

です。

途中まで進んだ旧ルートを捨てるのは、少し惜しい。

でも、

過去を直し続けることと、未来を作ることは違う。

今回の開発で、一番大きかったのはこの気づきでした。

AIは問題を深く掘れます。

だからこそ人間側は、

「その穴、本当に掘る必要ある?」

を、ときどき聞いた方がいい。

今回、

Legacy StackChan / xiaozhi route

は正式にRETIRED。

一方、

IRY Native CoreS3 Firmware 0A

はPASS。

現在位置は、

FIRST REAL FIRMWARE WRITE
APPROVAL GATE

です。


🚀 次回予告

次はいよいよ、

inactive ota_0へIRY Native 0Aを書き込む

工程へ進みます。

現在のM5は、

ota_1 = 現行StackChan
ota_0 = inactive

PC側には16MB full recovery imageがあります。

つまり、

M5 ota_1 = fallback
PC backup = full recovery

という二重の安全網を維持したまま進めます。

最初に実機へ書く予定なのは、

190,480 bytes

だけ。

そして再起動後、M5Stack CoreS3の画面へ初めて、

IRY VESSEL

と表示させる。

ここからが、本当の

IRY専用分霊箱ハードウェア編

です。


🔖 ハッシュタグ
#M5Stack #StackChan #CoreS3 #ESP32S3 #ファームウェア #AIエージェント #組み込み開発 #個人開発 #電子工作 #IRY

いいなと思ったら応援しよう!