Skip to content

v0.2–v0.4 稳定性/安全/品类补齐:端到端加密 + BLE 短语音 + 备份/OCR/在线态 + 37 项回归夹具 - #7

Merged
webergithub merged 5 commits into
masterfrom
claude/quirky-gates-p9q3du
Jul 19, 2026
Merged

webergithub merged 5 commits into
masterfrom
claude/quirky-gates-p9q3du

Conversation

@webergithub

Copy link
Copy Markdown
Owner

按《需求三部曲》路线图完成 E0(v0.2.0 稳定性收口)→ E1(v0.3.0 底线健壮)→ E2(v0.4.0 品类补齐)的全部代码工作,配套文档同步更新。

E0 · 稳定性与可测性收口

  • G-PF-3:iOS MeshBus 改每类型单句柄(对齐 Android),消除 VC 重建句柄累积
  • G-LG-2:Web 摊分改整除,与原生逐人金额全等(11 组除不尽金额验收)
  • G-ENG-1:tests/mesh-fixture/ 内存回归夹具 + mesh-fixture.yml 工作流——BLE 协议逐字节复刻(13B 帧头/180B 分片/TTL 泛洪/去重),协议常量三端防漂移

E1 · 底线健壮

  • PR-P1-1/1-2:蓝牙关闭/无邻居实时告警(营地+跟车双端);发送无人可收时如实提示
  • G-LG-1:账本备份三端(Web 下载/导入校验,iOS/Android 分享导出+粘贴导入)
  • G-SEC-1:信令服务器 token 鉴权 + 80条/10s 限流 + 64KB 消息上限 + 单 IP 32 连接上限 + 未鉴权禁转发(4 项破坏性验收进 CI)
  • G-CM-3:MeshBus 载荷端到端加密——AES-256-CBC + HMAC-SHA256(Encrypt-then-MAC),密钥自队伍码 PBKDF2(10000 轮)派生;iOS CommonCrypto / Android 手写 RFC2898(API21 无内建)/ JS 参考三端字节一致,固定校验向量锁进 CI 与源码注释

E2 · 品类补齐

  • G-CM-1(L1 硬伤关闭):营地短语音落地——按住 🎤 录 ≤10s AAC(16kHz/24kbps),KIND_VOICE=3 加密广播,点按播放,双端互通;视频显式收窄为仅在线,文案同步
  • G-VC-1:Android 变声 6→9 预设对齐 iOS(新增佩奇/悟空/机器人=40Hz PCM 环形调制)
  • G-DR-2:同伴标记 15s 未更新变淡、60s 移除(双端)
  • G-LG-3:Android 小票 OCR(ML Kit 内置模型离线识别,自动填最大金额)

验证

  • mesh-fixture CI:37 项断言全绿(分片/去重/多跳/队伍过滤/结算/备份往返/信令鉴权限流/加密往返+篡改拒+固定向量/9KB 语音 51 片中继完整)
  • android-native-build 后台服务端规划(④)+ E4 服务端密文中继(哑中继,房间哈希路由) #11 / ios12-build #15 编译全绿并产出最新 APK / IPA
  • ⚠️ 本批包与旧包不互通(旧包明文会被新包丢弃)——真机测试请两台都装新包
  • 真机待验收清单见 docs/REAL-DEVICE-TEST.md;三部曲状态见 docs/requirements/

🤖 Generated with Claude Code

https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh


Generated by Claude Code

claude added 5 commits July 19, 2026 00:24
…-2/1-5)

Camp link health (all ends honest about silent failures):
- Android: BroadcastReceiver on ACTION_STATE_CHANGED shows an error
  status the moment Bluetooth turns off, auto-recovers on re-enable;
  sending with zero neighbors surfaces a delivery warning
- iOS: BleMeshDelegate gains bleMeshDidUpdateState; MeshBus exposes
  onState/btAvailable; Camp shows red bar-button when Bluetooth is off
  and appends a system line when sending with no neighbors/BT off

Ledger backup (G-LG-1):
- Android LedgerStore export/import JSON + 备份 dialog (share / paste)
- iOS LedgerStore exportJson/importJson + 备份 action sheet
- Web backup.ts (magic/version-validated) + store importState action +
  Groups export-download/import-file buttons

Fixture grows to 19 assertions: backup roundtrip deep-equality,
corrupt/missing-magic rejection, activeGroupId fallback.
… G-DR-1)

Signaling server (G-SEC-1): optional SIGNAL_TOKEN auth on join (4003
on mismatch), 80 msgs/10s per-connection rate limit (4008), 64KB
message cap (4002), 32-connection per-IP cap (4001), and unjoined
connections can no longer relay signals. Web client sends
VITE_SIGNAL_TOKEN; .env.example documents both plus the wss
reverse-proxy requirement.

Convoy link health (G-DR-1): both native ends now show an amber banner
when Bluetooth is off (位置无法共享) or no mesh neighbors are in range
(同伴暂看不到你的位置) — Android refreshes on the 3s broadcast tick,
iOS reacts to MeshBus onState/onPeers.

Fixture grows to 23 assertions: spawns the real signaling server and
verifies bad-token rejection, authed join, unauthed-relay block, and
flood-triggered rate limiting.
… complete)

MeshBus payloads are now sealed with AES-256-CBC + HMAC-SHA256
(encrypt-then-MAC, 16B truncated tag); keys derived from the team code
via PBKDF2-HMAC-SHA256 (salt trailmate-mesh-v1, 10000 iters, cached
per team). Envelope team stays cleartext for room filtering only;
wrong-team, tampered, and legacy-plaintext blobs are all dropped.

Byte-identical implementations: iOS MeshCrypto.swift (CommonCrypto —
PBKDF2WithHmacSHA256 unavailable pre-API26, so) Android MeshCrypto.kt
hand-rolls RFC2898 PBKDF2 over HmacSHA256; JS reference
meshcrypto.mjs. A fixed cross-platform test vector is asserted in CI
and embedded in both native sources for on-device comparison.

Fixture grows to 33 assertions (roundtrip, wrong-team reject,
1-byte-tamper reject, version reject, plaintext reject, 100B-chat
still single-chunk, fixed vector, 3-way constant drift checks).
Requirements docs' security sections updated accordingly.
…G-VC-1)

Camp short voice (closes the L1 claim/implementation gap two ways):
- iOS & Android: hold 🎤 to record ≤10s AAC (16kHz mono 24kbps, ≤40KB
  guard), broadcast as KIND_VOICE=3 payload [u16 jsonLen][meta][m4a] —
  E2E-encrypted like all MeshBus traffic; receivers tap the message
  row to play. No-neighbor sends surface the same delivery warning.
- Video is now explicitly online-only: web camp copy narrowed.

Android voice changer: presets grow 6→9, aligned with iOS (adds 佩奇
1.7, 悟空 1.25, 机器人 via 40Hz PCM ring modulation).

Fixture grows to 37 assertions: voice payload format roundtrip, 9KB
(51-chunk) payload relayed intact through a middle node, kindVoice=3
dual-platform drift check.
Peer presence (both native ends): convoy markers fade to 45% alpha
after 15s without a location update and are removed after 60s —
Android checks on the 3s broadcast tick, iOS on a 5s timer; fresh
updates restore full opacity.

Android receipt OCR: 记一笔 gains a 选小票照片识别金额 button — ML Kit
text recognition (bundled model, fully offline, no GMS needed) parses
the photo and prefills the largest amount-looking number, mirroring
the iOS/web heuristic.
@webergithub
webergithub merged commit eb379e3 into master Jul 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants