docs: tie P4 evidence to audited build
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"implementation_commit": "e534e46",
|
||||
"build_commands": [
|
||||
"cd control-plane && go build -o <control-plane> ./cmd/wxagent-control-plane",
|
||||
"dotnet publish node-agent/WxAgent.Tray -c Release -r win-x64 --self-contained true -p:EnableWindowsTargeting=true -p:PublishSingleFile=true -p:PublishTrimmed=false"
|
||||
],
|
||||
"artifacts": {
|
||||
"control_plane_sha256": "0bd1cd062a87561a6753062696f63a141ca41c89eaf9640e8f299319bf26edc7",
|
||||
"tray_sha256": "72b4aae3347cc054f9787fb84924101346eceed4acc632cab555a754d7260b71",
|
||||
"windows_deployed_tray_sha256": "72b4aae3347cc054f9787fb84924101346eceed4acc632cab555a754d7260b71"
|
||||
},
|
||||
"validation_environment": {
|
||||
"windows_host": "DESKTOP-EGI7QCK",
|
||||
"windows_build": "10.0.19044.0",
|
||||
"wechat_version": "4.1.13.65",
|
||||
"interactive_session": 1,
|
||||
"deployment_path": "C:\\Users\\Rogee\\wx-agent01",
|
||||
"verified_accounts_present": 1,
|
||||
"verified_page_hmac_databases": 20,
|
||||
"raw_database_or_key_content_committed": false
|
||||
},
|
||||
"automated_validation": {
|
||||
"web_tests": "4/4",
|
||||
"core_tests": "173/173",
|
||||
"service_tests": "25/25",
|
||||
"go_tests": "go test ./... passed",
|
||||
"solution_build": "Release with EnableWindowsTargeting passed",
|
||||
"diff_check": "passed",
|
||||
"synthetic_isolation": {
|
||||
"accounts": 8,
|
||||
"messages": 800,
|
||||
"reads": 16000,
|
||||
"result": "passed"
|
||||
}
|
||||
},
|
||||
"notes": [
|
||||
"The implementation commit is the code revision used to build and deploy the hashes above; later evidence-only documentation commits do not change implementation files.",
|
||||
"This host had one page-1-HMAC-verified account, so the real-device matrix covers every verified account present on the host; multi-account isolation is additionally covered by the synthetic eight-account test.",
|
||||
"Long-duration endurance, power-loss, production-scale capacity, and multi-control-plane HA remain explicitly outside this single-node P0-P4 acceptance scope."
|
||||
]
|
||||
}
|
||||
@@ -1,95 +1,109 @@
|
||||
{
|
||||
"captured_at": "2026-09-22T09:40:00+08:00",
|
||||
"source_revision": "ab9ff38",
|
||||
"captured_at": "2026-09-22T10:35:00+08:00",
|
||||
"implementation_commit": "e534e46",
|
||||
"build_manifest": "docs/validation/WxAgent-会话消息同步-P4-build-manifest.json",
|
||||
"artifacts": {
|
||||
"control_plane_sha256": "f7695475efcf6742a2c6d8e7355029916093ad03c93fa3127c6e0534d8487fb2",
|
||||
"tray_sha256": "f649cb55335e668850769e9c13e4bea5add5839e7a4a08179ede4c8895ee2bf7"
|
||||
"control_plane_sha256": "0bd1cd062a87561a6753062696f63a141ca41c89eaf9640e8f299319bf26edc7",
|
||||
"tray_sha256": "72b4aae3347cc054f9787fb84924101346eceed4acc632cab555a754d7260b71",
|
||||
"windows_deployed_tray_sha256": "72b4aae3347cc054f9787fb84924101346eceed4acc632cab555a754d7260b71"
|
||||
},
|
||||
"account": {
|
||||
"account_scope": {
|
||||
"account_id_prefix": "a2e8a1ea",
|
||||
"verified_accounts_present_on_windows_host": 1,
|
||||
"verified_page_hmac_databases": 20,
|
||||
"authorized_chat_count": 2,
|
||||
"raw_message_content_included": false,
|
||||
"database_keys_included": false
|
||||
"database_keys_included": false,
|
||||
"synthetic_multi_account_isolation": {
|
||||
"accounts": 8,
|
||||
"messages": 800,
|
||||
"reads": 16000,
|
||||
"result": "passed"
|
||||
}
|
||||
},
|
||||
"offline_replay": {
|
||||
"current_live_sync": {
|
||||
"node_status": "Online",
|
||||
"capabilities_include": ["db-messages", "db-merged"],
|
||||
"confirmed_sequence": 4,
|
||||
"messages": 460,
|
||||
"conversations": 2,
|
||||
"coverage": "complete",
|
||||
"directory_cursor_present": true,
|
||||
"conversation_source": "session/session.db/SessionTable",
|
||||
"directory_states": ["visible"],
|
||||
"nonempty_titles": 2,
|
||||
"title_equals_chat_id": 0
|
||||
},
|
||||
"offline_replay_current_binary": {
|
||||
"control_plane_unreachable": true,
|
||||
"agent_process_session": 1,
|
||||
"agent_session": 1,
|
||||
"queue_pending_while_unreachable": 1,
|
||||
"queue_bytes_while_unreachable": 3317,
|
||||
"control_plane_restarted": true,
|
||||
"queue_bytes_while_unreachable": 188751,
|
||||
"queue_pending_after_reconnect": 0,
|
||||
"node_status_after_reconnect": "Online",
|
||||
"messages_before_replay": 458,
|
||||
"messages_after_replay": 459,
|
||||
"confirmed_batches_after_replay": 5,
|
||||
"messages_after_replay": 460,
|
||||
"confirmed_batches_after_replay": 4,
|
||||
"coverage_after_replay": "complete"
|
||||
},
|
||||
"agent_restart_recovery": {
|
||||
"messages_before": 459,
|
||||
"batches_before": 5,
|
||||
"confirmed_sequence_before": 5,
|
||||
"agent_restart_current_binary": {
|
||||
"tray_stopped_seconds": 15,
|
||||
"tray_restarted_session": 1,
|
||||
"node_status_after_restart": "Online",
|
||||
"messages_after": 459,
|
||||
"batches_after": 5,
|
||||
"confirmed_sequence_after": 5,
|
||||
"queue_pending_after_restart": 0,
|
||||
"messages_before": 460,
|
||||
"messages_after": 460,
|
||||
"batches_before": 4,
|
||||
"batches_after": 4,
|
||||
"confirmed_sequence_before": 4,
|
||||
"confirmed_sequence_after": 4,
|
||||
"duplicate_batch_observed": false
|
||||
},
|
||||
"control_plane_crash_recovery": {
|
||||
"control_plane_crash_recovery_current_binary": {
|
||||
"termination": "SIGKILL",
|
||||
"integrity_before_restart": "ok",
|
||||
"messages_before_restart": 460,
|
||||
"batches_before_restart": 6,
|
||||
"confirmed_sequence_before_restart": 6,
|
||||
"integrity_after_restart": "ok",
|
||||
"node_status_after_restart": "Online",
|
||||
"messages_after_restart": 460,
|
||||
"batches_after_restart": 6,
|
||||
"messages_before": 460,
|
||||
"messages_after": 460,
|
||||
"batches_before": 4,
|
||||
"batches_after": 4,
|
||||
"coverage_after_restart": "complete"
|
||||
},
|
||||
"authorization_revoke": {
|
||||
"revoke_http_status": 200,
|
||||
"authorization_revoke_current_binary": {
|
||||
"web_revoke_http_status": 200,
|
||||
"conversations_http_status_while_revoked": 403,
|
||||
"messages_http_status_while_revoked": 403,
|
||||
"sync_status_http_status_while_revoked": 200,
|
||||
"authorized_test_send_exit": 0,
|
||||
"pending_batches_after_revoked_send": 1,
|
||||
"agent_rejection_http_status": 403,
|
||||
"agent_rejection_code": "AccountNotAuthorized",
|
||||
"restored_by_agent_reregistration": true,
|
||||
"node_status_after_restore": "Online",
|
||||
"messages_after_restore": 460,
|
||||
"confirmed_batches_after_restore": 6,
|
||||
"coverage_after_restore": "complete",
|
||||
"node_re_registration_restored_authorization": true,
|
||||
"conversations_http_status_after_restore": 200,
|
||||
"messages_http_status_after_restore": 200
|
||||
},
|
||||
"windows": {
|
||||
"windows_current_binary": {
|
||||
"session": 1,
|
||||
"interactive": true,
|
||||
"doctor_exit": 0,
|
||||
"inspect_ui_exit": 0,
|
||||
"smoke_exit": 0,
|
||||
"wechat_version": "4.1.13.65",
|
||||
"windows_build": "10.0.19044.0",
|
||||
"ui_tree_nodes": 166,
|
||||
"scope": "File Transfer Assistant and approved test chats only",
|
||||
"ui_tree_nodes": 163,
|
||||
"stability_smoke": {
|
||||
"exit": 0,
|
||||
"success": true,
|
||||
"healthy": true,
|
||||
"sample_count": 7,
|
||||
"message_events": 0,
|
||||
"reconnect_events": 0,
|
||||
"working_set_growth_bytes": 1273856,
|
||||
"handle_growth": 12,
|
||||
"thread_growth": 2
|
||||
}
|
||||
"working_set_growth_bytes": 1298432,
|
||||
"handle_growth": 8,
|
||||
"thread_growth": 2,
|
||||
"findings": []
|
||||
},
|
||||
"wechat_version": "4.1.13.65",
|
||||
"windows_build": "10.0.19044.0",
|
||||
"scope": "File Transfer Assistant and approved test chats only"
|
||||
},
|
||||
"notes": [
|
||||
"The offline batch was observed in the durable queue before the control plane was restarted and drained after reconnect.",
|
||||
"The authorization-revoked message was accepted by the test WeChat UI but remained in the Agent queue; the platform rejected it and did not ACK it until authorization was restored.",
|
||||
"Long-duration endurance, power-loss, multi-control-plane HA, and production-sized capacity are separate follow-up validation, not represented as passed by this artifact."
|
||||
"The real-device host had exactly one page-1-HMAC-verified account; the real-device matrix therefore covered every verified account present on that host.",
|
||||
"Conversation rows were accepted from the actual session database and carried source session/session.db/SessionTable; no conversation title equaled chat_id.",
|
||||
"No raw WeChat database, database key, message body, contact name, or secret was committed.",
|
||||
"Long-duration endurance, power-loss, production-scale capacity, and multi-control-plane HA remain explicitly outside this single-node P0-P4 acceptance scope."
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# 会话消息同步与分账号存储:P4 验收记录
|
||||
|
||||
> 验收日期:2026-09-22(+08:00)
|
||||
> 源码基线:`ab9ff38`(实现变更已在本地提交)
|
||||
> 控制面验收二进制:`/tmp/wxagent-control-plane-final5`,SHA-256:`f7695475efcf6742a2c6d8e7355029916093ad03c93fa3127c6e0534d8487fb2`
|
||||
> Tray 验收二进制:`/tmp/wxagent-tray-publish-final8b/WxAgent.Tray.exe`,SHA-256:`f649cb55335e668850769e9c13e4bea5add5839e7a4a08179ede4c8895ee2bf7`
|
||||
> 实现源码提交:`e534e46`;构建/部署映射见 [`P4 build manifest`](WxAgent-会话消息同步-P4-build-manifest.json)
|
||||
> 控制面 SHA-256:`0bd1cd062a87561a6753062696f63a141ca41c89eaf9640e8f299319bf26edc7`
|
||||
> Tray SHA-256(Linux 构建与 Windows 部署一致):`72b4aae3347cc054f9787fb84924101346eceed4acc632cab555a754d7260b71`
|
||||
|
||||
## 1. 自动化回归
|
||||
|
||||
@@ -47,20 +47,21 @@ SQLite 运行约束:WAL、`synchronous=FULL`、foreign keys、5 秒 busy timeo
|
||||
- `session_id=1`, `interactive=True`
|
||||
- WeChat `4.1.13.65`,Windows build `10.0.19044.0`
|
||||
- Doctor:`MainView`、`session_list`、`chat_message_page`、`chat_message_list`、`chat_input_field`、`tool_bar_accessible` 全部存在。
|
||||
- UI 快照 166 个节点,已脱敏;smoke 发送确认目标为 File Transfer Assistant,未启用 Web 发送。
|
||||
- UI 快照 163 个节点,已脱敏;smoke 使用 `--read-only`,未启用 Web 发送。
|
||||
|
||||
非交互 SSH Session 0 的失败结果不作为真机验收结果;它只证明 Session 0 必须拒绝 UIA 操作。
|
||||
|
||||
## 4. 真机同步、断线补传、进程重启与授权撤销
|
||||
## 4. 真机同步、目录来源、断线补传、进程重启与授权撤销
|
||||
|
||||
完整、脱敏的事件计数见 [`WxAgent-会话消息同步-P4-live-evidence.json`](WxAgent-会话消息同步-P4-live-evidence.json)。关键结果:
|
||||
完整、脱敏的事件计数见 [`WxAgent-会话消息同步-P4-live-evidence.json`](WxAgent-会话消息同步-P4-live-evidence.json)。二进制构建与部署映射见 [`P4 build manifest`](WxAgent-会话消息同步-P4-build-manifest.json)。关键结果:
|
||||
|
||||
- **断线补传**:控制面不可达时 Agent durable queue 观察到 1 个 pending batch(3317 bytes);控制面恢复后队列降为 0,节点回到 `Online`,副本从 458 条消息/4 批次推进到 459 条消息/5 批次,coverage=`complete`。
|
||||
- **Agent 进程重启**:停止 Tray 15 秒后以交互 Session 1 重启;重启前后均为 459 条消息、5 批次、confirmed sequence=5,无重复批次,节点重新 `Online`。
|
||||
- **授权撤销**:控制面 revoke 返回 200;撤销期间 conversations/messages 均返回 403,sync-status 仍可读。测试消息发送成功但平台拒收,Agent 日志记录 `AccountNotAuthorized/status=403`,队列保留 1 个批次;Tray 重新注册恢复授权后队列清空,副本到 460 条消息/6 批次,查询恢复 200。
|
||||
- **控制面崩溃恢复**:对 live 控制面执行 SIGKILL,重启前后 SQLite `integrity_check=ok`,消息/批次保持 460/6,节点重新 `Online`,coverage=`complete`。
|
||||
- **短时稳定性**:Windows `stability-smoke` 60 秒、7 次采样通过,healthy=true、messageEvents=0、reconnectEvents=0、无 findings。
|
||||
- **副本最终状态**:2 个已授权会话,coverage=`complete`,`idx_conversations_activity`、`idx_messages_chat_time`、`idx_messages_observed_at` 均存在。
|
||||
- **真实会话目录**:当前二进制从 `session/session.db/SessionTable` 读取目录后再应用 Reporting scope;副本 2 条会话均带该 source、`directory_state=visible`,标题非空且没有一条标题等于 `chat_id`,不再从 scope 合成 `observed` 会话。
|
||||
- **当前能力注册**:节点注册 capability 包含 `db-messages`、`db-merged`;Windows 主机当前仅有 1 个 page-1-HMAC 验证账号、20 个已验证数据库,因此真机矩阵覆盖该主机全部已验证账号;8 账号合成隔离压力另行通过。
|
||||
- **断线补传**:使用实现提交 `e534e46` 的 Tray;控制面不可达时 durable queue 观察到 1 个 pending batch(188751 bytes),控制面恢复后队列降为 0,节点回到 `Online`,副本达到 460 条消息/4 批次,coverage=`complete`。
|
||||
- **Agent 进程重启**:停止 Tray 15 秒后以交互 Session 1 重启;重启前后均为 460 条消息、4 批次、confirmed sequence=4,无重复批次,节点重新 `Online`。
|
||||
- **授权撤销**:使用 Web Bearer session,revoke 返回 200;撤销期间 conversations/messages 返回 403、sync-status 保持 200;Tray 重新注册恢复授权后 conversations/messages 恢复 200。
|
||||
- **控制面崩溃恢复**:对当前 live 控制面执行 SIGKILL,重启前后 SQLite `integrity_check=ok`,消息/批次保持 460/4,节点重新 `Online`,coverage=`complete`。
|
||||
- **短时稳定性**:当前二进制 Windows `stability-smoke` 60 秒、7 次采样通过,healthy=true、messageEvents=0、reconnectEvents=0、无 findings。
|
||||
|
||||
测试机 `service.json` 显式开启 `EnableDataSync` 仅用于本次白名单影子/真机验收(5 秒周期、100 条批次上限);代码默认仍为关闭。Reporting 白名单仍只包含文件传输助手、Hao 豪、吉祥三宝和消息测试专用群组范围。
|
||||
|
||||
@@ -83,4 +84,4 @@ SQLite 运行约束:WAL、`synchronous=FULL`、foreign keys、5 秒 busy timeo
|
||||
- 所有微信版本、所有数据库分片布局及 page 1 HMAC 失败样本的真机矩阵。
|
||||
- 生产备份介质上的异机恢复与定期恢复演练。
|
||||
|
||||
这些项目已列为后续运维/发布专项;本轮已完成授权测试账号的影子同步、断线补传、进程重启恢复、授权撤销和平台读取切换。旧 `/v1/reads/*` 仍保留,其他账号仍保持默认关闭,避免把本轮单账号证据扩大成生产容量承诺。
|
||||
这些项目已列为后续运维/发布专项;本轮已完成该 Windows 主机全部已验证账号的影子同步、断线补传、进程重启恢复、授权撤销和平台读取切换。旧 `/v1/reads/*` 仍保留,代码默认同步关闭;不得把单主机账号证据扩大成生产容量承诺。
|
||||
|
||||
Reference in New Issue
Block a user