Commit 052f4d4
fix(ocap-kernel): regenerate incarnationId on resetStorage=true (#950)
## Summary
- Drops \`'incarnationId'\` from \`Kernel.#resetKernelState\`'s
except-list so a state wipe forces a fresh incarnation.
- Adds an e2e regression for the \`resetStorage=true\` path (the
existing #944 test exercises only the fresh-DB path).
## Why
The peer-restart detection added in #948 only works if the sender
signals a new incarnation when its state has been wiped. The except-list
in \`#resetKernelState\` was preserving \`incarnationId\` across
\`resetStorage=true\` resets, so the sender came back signalling the
same incarnation, the receiver's handshake said "no restart",
\`highestReceivedSeq\` stayed put, and the sender's fresh \`seq=1\`
messages were dropped as duplicates.
The browser/extension kernel-worker URL carries \`?reset-storage=true\`
and hits this branch on every offscreen-page reload, so in production
this meant every plugin reload that re-registered a service silently
lost its first message. Repro on metamask-extension chip/agentmask: full
reset → first reload registers cleanly → second reload's PMS
\`registerServiceByRef\` arrives at the matcher with seq=1, matcher logs
\`12D3KooW:: ignoring duplicate message seq=1 (highestReceived=4)\` and
the message disappears.
Confirmed empirically by dumping the matcher's KV after the
second-reload symptom: \`peerIncarnation.<ext-peer-id>\` was equal to
the incarnation the extension was *currently* sending — exactly the case
\`#handleIncarnationChange\` exits early on. The
\`provideIncarnationId\` doc comment already advertised the post-fix
behaviour ("regenerated when storage is cleared (when state is actually
lost)"); the code just wasn't doing it.
## Test plan
- [x] \`yarn workspace @MetaMask/ocap-kernel test\` (2341 passing
locally)
- [x] Production repro on chip/agentmask: full reset, first reload
registers, second reload registers again instead of being dropped
- [ ] CI green, including the new e2e \`detects restart when sender
keeps DB but uses resetStorage=true\`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes how `resetStorage=true` resets persistent kernel state, which
affects remote-communication handshake/dedup behavior across restarts;
mistakes could cause message loss or unexpected peer identity changes.
>
> **Overview**
> Fixes the `resetStorage=true` reset path to **regenerate
`incarnationId`** while still preserving network identity keys
(`keySeed`, `peerId`, `ocapURLKey`), so peers can reliably detect a
state wipe and clear stale seq-dedup/c-list state.
>
> Adds an e2e regression test covering the browser/extension-style
restart where the sender keeps the same DB file but starts with
`resetStorage=true`, ensuring `seq=1` messages are no longer silently
dropped after reloads, and documents the fix in the `CHANGELOG`.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c5cb8ea. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent ec3d701 commit 052f4d4
3 files changed
Lines changed: 90 additions & 3 deletions
File tree
- packages
- kernel-node-runtime/test/e2e
- ocap-kernel
- src
Lines changed: 73 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1118 | 1118 | | |
1119 | 1119 | | |
1120 | 1120 | | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
| 1153 | + | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
| 1177 | + | |
| 1178 | + | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
1121 | 1194 | | |
1122 | 1195 | | |
1123 | 1196 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
40 | 42 | | |
41 | 43 | | |
42 | 44 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
704 | 704 | | |
705 | 705 | | |
706 | 706 | | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
707 | 715 | | |
708 | | - | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
709 | 719 | | |
710 | 720 | | |
711 | 721 | | |
| |||
714 | 724 | | |
715 | 725 | | |
716 | 726 | | |
717 | | - | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
718 | 730 | | |
719 | | - | |
| 731 | + | |
720 | 732 | | |
721 | 733 | | |
722 | 734 | | |
| |||
0 commit comments